gh-112331: Fix reference manual description of attribute lookup mechanics#112375
gh-112331: Fix reference manual description of attribute lookup mechanics#112375rhettinger merged 7 commits intopython:mainfrom
Conversation
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
| reference may yield different objects. | ||
|
|
||
| This production can be customized by overriding the | ||
| :meth:`~object.__getattribute__` method or the :meth:`~object.__getattr__` |
There was a problem hiding this comment.
| :meth:`~object.__getattribute__` method or the :meth:`~object.__getattr__` | |
| :meth:`~object.__getattribute__` method and/or the :meth:`~object.__getattr__` |
There was a problem hiding this comment.
I think "or" is fine. The "and/or" is correct but looks weird and doesn't read well.
There was a problem hiding this comment.
I disagree that it looks weird, but won't insist
| method. The :meth:`!__getattribute__` method is called first and either | ||
| returns a value or raises :exc:`AttributeError` if the attribute is not | ||
| available. |
There was a problem hiding this comment.
Of course, it is possible to create badly behaved objects that raise other exceptions from __getattribute__:
>>> class Foo:
... def __getattribute__(self, attr):
... if attr == 'foo':
... raise TypeError('no')
... return object.__getattribute__(self, attr)
...
>>> f = Foo()
>>> f.a = 1
>>> f.a
1
>>> f.b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
f.b
File "<stdin>", line 5, in __getattribute__
return object.__getattribute__(self, attr)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Foo' object has no attribute 'b'
>>> f.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
f.foo
File "<stdin>", line 4, in __getattribute__
raise TypeError('no')
TypeError: noDoes that need to be mentioned here? Or is it too obscure?
There was a problem hiding this comment.
No need. Any code can raise a weird error at any time but we don't need to mention that in the docs in the thousands of places where this could occur:
This wording corresponds to what the code actually does:
def getattr_hook(obj, name):
"Emulate slot_tp_getattr_hook() in Objects/typeobject.c"
try:
return obj.__getattribute__(name)
except AttributeError:
if not hasattr(type(obj), '__getattr__'):
raise
return type(obj).__getattr__(obj, name)
| reference may yield different objects. | ||
|
|
||
| This production can be customized by overriding the | ||
| :meth:`~object.__getattribute__` method or the :meth:`~object.__getattr__` |
There was a problem hiding this comment.
I disagree that it looks weird, but won't insist
|
Thanks @rhettinger for the PR 🌮🎉.. I'm working now to backport this PR to: 3.11, 3.12. |
… mechanics (pythongh-112375) (cherry picked from commit 97f8f28) Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
|
GH-112412 is a backport of this pull request to the 3.12 branch. |
… mechanics (pythongh-112375) (cherry picked from commit 97f8f28) Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
|
GH-112413 is a backport of this pull request to the 3.11 branch. |
Make the lookup mechanics description match the logic found in
slot_tp_getattr_hookin `Objects/typeobject.c'.Notably, mention of
__getattribute__was missing.📚 Documentation preview 📚: https://cpython-previews--112375.org.readthedocs.build/