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: Patch-adding __init__ in a class takes no effect when called from a subinterpreter
Type: behavior Stage: resolved
Components: Subinterpreters Versions: Python 3.11, Python 3.10
process
Status: closed Resolution: duplicate
Dependencies: Superseder:
Assigned To: Nosy List: eric.snow, hroncok, vstinner
Priority: normal Keywords:

Created on 2021-12-10 12:01 by hroncok, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg408196 - (view) Author: Miro Hrončok (hroncok) * Date: 2021-12-10 12:01
Hello,

based on some bug reports reported in:

- https://github.com/GrahamDumpleton/mod_wsgi/issues/729
- https://github.com/poljar/weechat-matrix/issues/293
- https://bugzilla.redhat.com/show_bug.cgi?id=2030621

I have isolated the following reproducer that shows a regression in Python 3.10+. It happens at least with 3.10.0, 3.10.1 and 3.11.0a2. It works as expected in Python 3.9.

The following code is valid and works on 3.9, 3.10, 3.11:

=========================================
class Greeting():
    pass

def new_init(inst, name):
    inst.text = f"Hello, {name}\n"

Greeting.__init__ = new_init

Greeting("Miro")
=========================================


But if we run it via a subinterpreter, it breaks on 3.10+:

=========================================
import _testcapi

code = r"""class Greeting():
    pass

def new_init(inst, name):
    inst.text = f"Hello, {name}\n"

Greeting.__init__ = new_init

Greeting("Miro")"""

_testcapi.run_in_subinterp(code)
=========================================


$ python3.9 reproducer.py
(exits cleanly)

$ python3.10 reproducer.py 
Traceback (most recent call last):
  File "<string>", line 9, in <module>
TypeError: Greeting() takes no arguments

$ python3.11 reproducer.py 
Traceback (most recent call last):
  File "<string>", line 9, in <module>
TypeError: Greeting() takes no arguments


My observation also shows that if the Greeting class already had (any) __init__:

=========================================
class Greeting():
    __init__ = ...
=========================================

It works as expected on 3.9, 3.10, 3.11.



In reality, this is most likely to affect classes with decorators, like:

=========================================
import attr

@attr.s
class TestClass:
    foo = attr.ib()

TestClass("Miro")
=========================================

This works standalone, but fails in a subinterpreter:

$ python3.10 reproducer.py 
Traceback (most recent call last):
  File "<string>", line 7, in <module>
TypeError: TestClass() takes no arguments
msg408199 - (view) Author: Miro Hrončok (hroncok) * Date: 2021-12-10 12:22
git bisect gives:

https://github.com/python/cpython/commit/ea251806b8dffff11b30d2182af1e589caf88acf
msg408200 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2021-12-10 12:29
I mark this issue as a duplicate of bpo-46006. It's not exactly the same issue, but the root cause is the same: in some functions, Python use fast pointer comparisons when two strings are interned, but this now fails if two interned strings belong to two different interpreters.
History
Date User Action Args
2022-04-11 14:59:53adminsetgithub: 90192
2021-12-10 12:29:40vstinnersetstatus: open -> closed
resolution: duplicate
messages: + msg408200

stage: resolved
2021-12-10 12:22:25hroncoksetmessages: + msg408199
2021-12-10 12:01:00hroncokcreate