Title: [3.12] Behavior change: __getattr__ gets called after property raises NotImplementedError · Issue #103551 · python/cpython · GitHub
Open Graph Title: [3.12] Behavior change: __getattr__ gets called after property raises NotImplementedError · Issue #103551 · python/cpython
X Title: [3.12] Behavior change: __getattr__ gets called after property raises NotImplementedError · Issue #103551 · python/cpython
Description: Hi, Version: 3.12.0a7 OS: Windows While testing pytest in 3.12 on Windows, we noticed an odd behavior that we believe might be a bug/regression. Consider this minimal example: class Stat: @property def owner(self): print("--> accessing o...
Open Graph Description: Hi, Version: 3.12.0a7 OS: Windows While testing pytest in 3.12 on Windows, we noticed an odd behavior that we believe might be a bug/regression. Consider this minimal example: class Stat: @property...
X Description: Hi, Version: 3.12.0a7 OS: Windows While testing pytest in 3.12 on Windows, we noticed an odd behavior that we believe might be a bug/regression. Consider this minimal example: class Stat: @property...
Opengraph URL: https://github.com/python/cpython/issues/103551
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[3.12] Behavior change: __getattr__ gets called after property raises NotImplementedError ","articleBody":"Hi,\r\n\r\n**Version**: `3.12.0a7`\r\n**OS**: Windows\r\n\r\nWhile [testing pytest in 3.12](https://github.com/pytest-dev/pytest/pull/10894#issuecomment-1509303587) on Windows, we noticed an odd behavior that we believe might be a bug/regression.\r\n\r\nConsider this minimal example:\r\n\r\n```python\r\nclass Stat:\r\n @property\r\n def owner(self):\r\n print(\"--\u003e accessing owner\")\r\n raise NotImplementedError(\"owner not implemented\")\r\n\r\n def __getattr__(self, item):\r\n return getattr(1, \"foobar\")\r\n\r\n\r\ns = Stat()\r\ns.owner\r\n``` \r\n\r\n(Using `getattr(1, ...)` there just to have an object in-place; in the real code `1` is actually another object, but the outcome is the same).\r\n\r\nRunning this in Python `3.11.2` (and previous versions), we get this output:\r\n\r\n```\r\nλ py -3.11 --version\r\nPython 3.11.2\r\n\r\nλ py -3.11 .tmp\\reproducer.py\r\n--\u003e accessing owner\r\nTraceback (most recent call last):\r\n File \"e:\\projects\\pytest\\.tmp\\reproducer.py\", line 12, in \u003cmodule\u003e\r\n s.owner\r\n File \"e:\\projects\\pytest\\.tmp\\reproducer.py\", line 5, in owner\r\n raise NotImplementedError(\"owner not implemented\")\r\nNotImplementedError: owner not implemented\r\n```\r\n\r\n`NotImplementedError` is raised from the property access, and `__getattr__` is never called.\r\n\r\nIn Python `3.12.0a7` however we get:\r\n\r\n```\r\nλ py -3.12 --version\r\nPython 3.12.0a7\r\n\r\nλ py -3.12 .tmp\\reproducer.py\r\n--\u003e accessing owner\r\nTraceback (most recent call last):\r\n File \"e:\\projects\\pytest\\.tmp\\reproducer.py\", line 12, in \u003cmodule\u003e\r\n s.owner\r\n File \"e:\\projects\\pytest\\.tmp\\reproducer.py\", line 8, in __getattr__\r\n return getattr(1, \"foobar\")\r\n ^^^^^^^^^^^^^^^^^^^^\r\nAttributeError: 'int' object has no attribute 'foobar'\r\n```\r\n\r\nThe property is still being accessed (as shown by the `print` call), but `NotImplementedError` is being swallowed/ignored, and `__getattr__` seems to be getting called as a fallback.\r\n\r\n---\r\n\r\nChanging the example slightly:\r\n\r\n```python\r\nclass Stat:\r\n @property\r\n def owner(self):\r\n print(\"--\u003e accessing owner\")\r\n raise NotImplementedError(\"owner not implemented\")\r\n\r\n def __getattr__(self, item):\r\n raise AttributeError(\"foobar\")\r\n\r\n\r\ns = Stat()\r\ns.owner\r\n```\r\n\r\nIn Python `3.11` the behavior stays the same as before, however in Python `3.12` we now get:\r\n\r\n```\r\nλ py -3.12 .tmp\\reproducer.py\r\n--\u003e accessing owner\r\nTraceback (most recent call last):\r\n File \"e:\\projects\\pytest\\.tmp\\reproducer.py\", line 5, in owner\r\n raise NotImplementedError(\"owner not implemented\")\r\nNotImplementedError: owner not implemented\r\n\r\nThe above exception was the direct cause of the following exception:\r\n\r\nTraceback (most recent call last):\r\n File \"e:\\projects\\pytest\\.tmp\\reproducer.py\", line 12, in \u003cmodule\u003e\r\n s.owner\r\n File \"e:\\projects\\pytest\\.tmp\\reproducer.py\", line 8, in __getattr__\r\n raise AttributeError(\"foobar\")\r\n ^^^^^^^^^^^^^^^^^^^^^^^^\r\nSystemError: \u003cclass 'AttributeError'\u003e returned a result with an exception set\r\n```\r\n\r\nPlease let us know if you need more information.","author":{"url":"https://github.com/nicoddemus","@type":"Person","name":"nicoddemus"},"datePublished":"2023-04-14T23:37:23.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/103551/cpython/issues/103551"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:aa9e8ef6-d3ef-ffc4-3a44-1a4744d0dd98 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8A28:14C034:40733:57D36:6969CAB7 |
| html-safe-nonce | 5fab1deb9250c1a800ef980c2fad60e3ada759e92b8cf460eb2c3c4614a35410 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4QTI4OjE0QzAzNDo0MDczMzo1N0QzNjo2OTY5Q0FCNyIsInZpc2l0b3JfaWQiOiI0MjYwNDE5MDUzMjg1OTE5NDE1IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 6a639efc2066f2a159609e9c14ac509486ea0a47047095efdc724d894767cd87 |
| hovercard-subject-tag | issue:1669052315 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/103551/issue_layout |
| twitter:image | https://opengraph.githubassets.com/c59f6516aedecb557be48f80d73f7d96c4ef5f9d0fa57575abdf8eb7d2ed89cc/python/cpython/issues/103551 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/c59f6516aedecb557be48f80d73f7d96c4ef5f9d0fa57575abdf8eb7d2ed89cc/python/cpython/issues/103551 |
| og:image:alt | Hi, Version: 3.12.0a7 OS: Windows While testing pytest in 3.12 on Windows, we noticed an odd behavior that we believe might be a bug/regression. Consider this minimal example: class Stat: @property... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | nicoddemus |
| hostname | github.com |
| expected-hostname | github.com |
| None | acedec8b5f975d9e3d494ddd8f949b0b8a0de59d393901e26f73df9dcba80056 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 83c08c21cdda978090dc44364b71aa5bc6dcea79 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width