diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2022-02-20 13:37:00 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-20 13:37:00 (GMT) |
commit | 83eabc6c8f6757f277d26064a83a626c4779424e (patch) | |
tree | 7fbe2cb47b74cfe5c9bec33c0dfe90c1127f8b7e | |
parent | 64705e6a94a28abeeafeddb8e9a68a8500e1d91b (diff) | |
download | cpython-83eabc6c8f6757f277d26064a83a626c4779424e.zip cpython-83eabc6c8f6757f277d26064a83a626c4779424e.tar.gz cpython-83eabc6c8f6757f277d26064a83a626c4779424e.tar.bz2 |
Improve discussion about how __getattr__ is invoked. (GH-31435) (GH-31438)
-rw-r--r-- | Doc/howto/descriptor.rst | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 9f0dd2f..4b76e06 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -696,10 +696,14 @@ a pure Python equivalent: >>> b.g == b['g'] == ('getattr_hook', b, 'g') True +Note, there is no :meth:`__getattr__` hook in the :meth:`__getattribute__` +code. That is why calling :meth:`__getattribute__` directly or with +``super().__getattribute__`` will bypass :meth:`__getattr__` entirely. -Interestingly, attribute lookup doesn't call :meth:`object.__getattribute__` -directly. Instead, both the dot operator and the :func:`getattr` function -perform attribute lookup by way of a helper function: +Instead, it is the dot operator and the :func:`getattr` function that are +responsible for invoking :meth:`__getattr__` whenever :meth:`__getattribute__` +raises an :exc:`AttributeError`. Their logic is encapsulated in a helper +function: .. testcode:: @@ -744,12 +748,6 @@ perform attribute lookup by way of a helper function: ... AttributeError: 'ClassWithoutGetAttr' object has no attribute 'z' -So if :meth:`__getattr__` exists, it is called whenever :meth:`__getattribute__` -raises :exc:`AttributeError` (either directly or in one of the descriptor calls). - -Also, if a user calls :meth:`object.__getattribute__` directly, the -:meth:`__getattr__` hook is bypassed entirely. - Invocation from a class ----------------------- |