summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2022-02-20 05:25:57 (GMT)
committerGitHub <noreply@github.com>2022-02-20 05:25:57 (GMT)
commitea3e0421b04a6081d604786a40e7f27ff854b428 (patch)
tree65ab2c487fde81dba050d852e587c5e5c4ed3855
parent75c5dbc27eb6d02677543b06e9001523e03a169a (diff)
downloadcpython-ea3e0421b04a6081d604786a40e7f27ff854b428.zip
cpython-ea3e0421b04a6081d604786a40e7f27ff854b428.tar.gz
cpython-ea3e0421b04a6081d604786a40e7f27ff854b428.tar.bz2
Improve discussion about how __getattr__ is invoked. (GH-31435) (GH-31437)
-rw-r--r--Doc/howto/descriptor.rst16
1 files changed, 7 insertions, 9 deletions
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index f8b1e00..f2e2f7e 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
-----------------------