PEP 726: Correct and expand specification (#3320)

Co-authored-by: Oscar Benjamin <oscar.j.benjamin@gmail.com>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
Sergey B Kirpichev 2023-09-01 08:11:23 +03:00 committed by GitHub
parent d90efc2f99
commit 513dc168af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 41 additions and 3 deletions

View File

@ -134,9 +134,47 @@ module ``__dict__``. If present, the appropriate function is called to
customize setting the attribute or its deletion, else the normal
mechanism (storing/deleting the value in the module dictionary) will work.
Defining ``__setattr__`` or ``__delattr__`` only affect lookups made
using the attribute access syntax---directly accessing the module
globals is unaffected, e.g. ``sys.modules[__name__].some_global = 'spam'``.
Defining module ``__setattr__`` or ``__delattr__`` only affects lookups made
using the attribute access syntax---directly accessing the module globals
(whether by ``globals()`` within the module, or via a reference to the module's
globals dictionary) is unaffected. For example:
.. code:: pycon
>>> import mod
>>> mod.__dict__['foo'] = 'spam' # bypasses __setattr__, defined in mod.py
or
.. code:: python
# mod.py
def __setattr__(name, value):
...
foo = 'spam' # bypasses __setattr__
globals()['bar'] = 'spam' # here too
def f():
global x
x = 123
f() # and here
To use a module global and trigger ``__setattr__`` (or ``__delattr__``),
one can access it via ``sys.modules[__name__]`` within the module's code:
.. code:: python
# mod.py
sys.modules[__name__].foo = 'spam' # bypasses __setattr__
def __setattr__(name, value):
...
sys.modules[__name__].bar = 'spam' # triggers __setattr__
How to Teach This