-
Notifications
You must be signed in to change notification settings - Fork 9
Open
Labels
Description
(Tested with 4.5.1, but this goes back to the very oldest code in this repo.)
The Python version of ExtensionClass applies the check for special methods to all classes:
ExtensionClass/src/ExtensionClass/__init__.py
Lines 210 to 219 in 14c7e10
| def __setattr__(self, name, value): | |
| if name not in ('__get__', '__doc__', '__of__'): | |
| if (name.startswith('__') and name.endswith('__') and | |
| name.count('_') == 4): | |
| raise TypeError( | |
| "can't set attributes of built-in/extension type '%s.%s' " | |
| "if the attribute name begins and ends with __ and " | |
| "contains only 4 _ characters" % | |
| (self.__module__, self.__name__)) | |
| return type.__setattr__(self, name, value) |
But the intent in the C version is to only apply the check to other built-in types:
ExtensionClass/src/ExtensionClass/_ExtensionClass.c
Lines 477 to 486 in 14c7e10
| if (! (type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { | |
| PyObject* as_bytes = convert_name(name); | |
| if (as_bytes == NULL) { | |
| return -1; | |
| } | |
| if (_is_bad_setattr_name(type, as_bytes)) { | |
| Py_DECREF(as_bytes); | |
| return -1; | |
| } |
This leads to a noticeable difference in PURE_PYTHON mode, such that code that works with the C extension fails in PURE_PYTHON. Compare the C version:
>>> os.environ.get("PURE_PYTHON")
None
>>> from ExtensionClass import Base
>>> class X(Base):
... pass
...
>>> X.__eq__ = 'added by decorator'
>>>to the Python version:
>>> os.environ['PURE_PYTHON'] = '1'
>>> from ExtensionClass import Base
>>> class X(Base):
... pass
...
>>> X.__eq__ = 'added by decorator'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/lib/python3.10/site-packages/ExtensionClass/__init__.py", line 214, in __setattr__
raise TypeError(
TypeError: can't set attributes of built-in/extension type '__main__.X' if the attribute name begins and ends with __ and contains only 4 _ charactersI'm not sure how to reliably detect built-in classes in Python, so I'm not sure how to fix this?
Reactions are currently unavailable