This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Customizing module attribute access example raises RecursionError
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.8, Python 3.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: denis-osipov, docs@python, levkivskyi, ronaldoussoren, xtreak
Priority: normal Keywords: patch

Created on 2018-10-31 04:26 by denis-osipov, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 10323 merged denis-osipov, 2018-11-04 19:16
PR 10348 merged miss-islington, 2018-11-06 01:53
Messages (8)
msg328966 - (view) Author: Denis Osipov (denis-osipov) * Date: 2018-10-31 04:26
Customizing module attribute access example raises RecursionError:

>>> import sys
>>> from types import ModuleType
>>> class VerboseModule(ModuleType):
...     def __repr__(self):
...         return f'Verbose {self.__name__}'
...     def __setattr__(self, attr, value):
...         print(f'Setting {attr}...')
...         setattr(self, attr, value)
...
>>> sys.modules[__name__].__class__ = VerboseModule
>>> sys.modules[__name__].a = 5
Setting a...
<...>
Setting a...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in __setattr__
  File "<stdin>", line 6, in __setattr__
  File "<stdin>", line 6, in __setattr__
  [Previous line repeated 495 more times]
  File "<stdin>", line 5, in __setattr__
RecursionError: maximum recursion depth exceeded while calling a Python object
Setting a...>>>

Something like this can fix it:

def __setattr__(self, attr, value):
...         print(f'Setting {attr}...')
...         super().setattr(self, attr, value)
msg328994 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2018-10-31 12:52
Thanks for the report Denis. Would you like to propose a PR for this? The file is at https://github.com/python/cpython/blob/master/Doc/reference/datamodel.rst . This was added as part of 5364b5cd757. I am adding Ivan who added the example for confirmation and review.
msg328999 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2018-10-31 15:59
I'm not convinced that any change is needed, this is completely expected behaviour (and not special to modules).

The following code also raises RecursionError:

class VerboseObject:
    def __setattr__(self, nm, value):
        print(f"Setting {nm} to {value}")
        setattr(self, nm, value)

o = VerboseObject()
o.a = 42

This is because setattr() calls the __setattr__ method, which calls setattr() again, ... .


The fix is to call super().__setattr__ instead:

class VerboseObject:
    def __setattr__(self, nm, value):
        print(f"Setting {nm} to {value}")
        super().__setattr__(nm, value)

o = VerboseObject()
o.a = 42
msg329019 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-10-31 22:33
Yes, this is expected, you should use ``super().__setattr__()``.
msg329239 - (view) Author: Denis Osipov (denis-osipov) * Date: 2018-11-04 17:19
I understand that it's expected behavior. But why don't use completely working example in the docs, which one could just copy and paste? It requires to add just seven chars)
msg329243 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-11-04 17:40
Ah, sorry, I didn't understand this was a documentation issue. Please feel free to submit a PR that fixes the example to use `super().__setattr__()`.
msg329325 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-11-06 01:53
New changeset 0bee3c36d406e47fa9f99cfc1e07b701512c4f3f by Ivan Levkivskyi (Denis Osipov) in branch 'master':
bpo-35119: Fix RecursionError in example of customizing module attribute access. (GH-10323)
https://github.com/python/cpython/commit/0bee3c36d406e47fa9f99cfc1e07b701512c4f3f
msg329327 - (view) Author: miss-islington (miss-islington) Date: 2018-11-06 01:59
New changeset 558dc8adbec0b85e0ff257fcedc85c5d89cd2825 by Miss Islington (bot) in branch '3.7':
bpo-35119: Fix RecursionError in example of customizing module attribute access. (GH-10323)
https://github.com/python/cpython/commit/558dc8adbec0b85e0ff257fcedc85c5d89cd2825
History
Date User Action Args
2022-04-11 14:59:07adminsetgithub: 79300
2018-11-06 02:00:37levkivskyisetstatus: open -> closed
nosy: - miss-islington

resolution: fixed
stage: patch review -> resolved
2018-11-06 01:59:19miss-islingtonsetnosy: + miss-islington
messages: + msg329327
2018-11-06 01:53:35miss-islingtonsetpull_requests: + pull_request9648
2018-11-06 01:53:25levkivskyisetmessages: + msg329325
2018-11-04 19:16:54denis-osipovsetkeywords: + patch
stage: needs patch -> patch review
pull_requests: + pull_request9625
2018-11-04 17:40:10levkivskyisetstatus: closed -> open
resolution: not a bug -> (no value)
messages: + msg329243

stage: resolved -> needs patch
2018-11-04 17:19:15denis-osipovsetmessages: + msg329239
2018-10-31 22:33:23levkivskyisetstatus: open -> closed
resolution: not a bug
messages: + msg329019

stage: resolved
2018-10-31 15:59:07ronaldoussorensetnosy: + ronaldoussoren
messages: + msg328999
2018-10-31 12:52:22xtreaksetnosy: + levkivskyi, xtreak
messages: + msg328994
2018-10-31 04:26:14denis-osipovcreate