-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Open
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
Edited at 2024.09.30 10:07 AM.
Example of code
import weakref
d = weakref.WeakKeyDictionary()
d.update(x=1)
Traceback
Traceback (most recent call last):
File "/home/username/example.py", line 4, in <module>
d.update(x=1)
~~~~~~~~^^^^^
File "/home/username/.pyenv/versions/3.13.0rc2/lib/python3.13/weakref.py", line 518, in update
self.update(kwargs)
~~~~~~~~~~~^^^^^^^^
File "/home/username/.pyenv/versions/3.13.0rc2/lib/python3.13/weakref.py", line 516, in update
d[ref(key, self._remove)] = value
~~~^^^^^^^^^^^^^^^^^^^
TypeError: cannot create weak reference to 'str' object
Source of error
class WeakKeyDictionary(_collections_abc.MutableMapping):
...
def update(self, dict=None, /, **kwargs): # `kwargs` always use 'str' for keys
d = self.data
if dict is not None:
if not hasattr(dict, "items"):
dict = type({})(dict)
for key, value in dict.items():
d[ref(key, self._remove)] = value
if len(kwargs): # If true, then `kwargs` contains a key of `str` type
self.update(kwargs) # So this line always raises `TypeError`
Proposals
Option 1
a) Add a clear exception and delete last two lines:
class WeakKeyDictionary(_collections_abc.MutableMapping):
...
def update(self, dict=None, /, **kwargs):
if kwargs:
raise TypeError(
"Keyword arguments are not supported. "
"Can not create weak references to `str` keys."
)
d = self.data
if dict is not None:
if not hasattr(dict, "items"):
dict = type({})(dict)
for key, value in dict.items():
d[ref(key, self._remove)] = value
b) Write about this behavior in the documentation.
Option 2
a) Remove the kwargs
parameter from WeakKeyDicionary.update()
.
b) Inherit WeakKeyDicionary
from Mapping
to avoid violating of the Liskov Substitution Principle with MutableMapping
.
class WeakKeyDictionary(_collections_abc.Mapping):
...
def update(self, dict=None):
d = self.data
if dict is not None:
if not hasattr(dict, "items"):
dict = type({})(dict)
for key, value in dict.items():
d[ref(key, self._remove)] = value
Thanks
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs
Metadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error