__hash__ method in str child class causing unintended side effects
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 36k
- PR merge metrics
- PR metrics pending
Description
Bug report
Consider the following example:
class MyStr(str):
def __init__(self, value, *args, **kwargs):
super().__init__(*args, **kwargs)
self.value = value
def __hash__(self) -> int:
return hash(str(self))
def __str__(self) -> str:
return str(self.value)
def dummy_func(x):
class MyClass:
def __init__(self, data):
self.data = data
def __str__(self):
return self.data
str(MyClass(x))
dummy_func is a function that should have absolutely no side effects.
However, checkout:
a = MyStr("teststring")
a in {}
# False
dummy_func(a)
a in {}
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "<stdin>", line 6, in __hash__
# File "<stdin>", line 6, in __hash__
# File "<stdin>", line 8, in __str__
# File "<stdin>", line 8, in __str__
# File "<stdin>", line 8, in __str__
# [Previous line repeated 329 more times]
# RecursionError: maximum recursion depth exceeded while calling a Python object
assert id(a.value.data) == id(a)
In this case, dummy_func mutates the input, and creates a weird circular dependency (i.e. id(a.value.data) == id(a)).
The issue can be fixed by removing the __hash__ method of MyStr.
Please confirm the behavior is unintended.
Environment
- CPython versions tested on: Python 3.10.5
- Operating system and architecture: CentOS, x86_64
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No source file or test is identified. Start by reproducing the example on CPython 3.10.5 and investigate the interaction between the custom str subclass's hash and str; done would require confirming whether the behavior is unintended and identifying a narrowly scoped regression test or change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 22/100