You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Using _multibytecodec module on Windows, test_threading/embed get failure #87012
After 0b858cd
(bpo-1635741: Convert _multibytecodec to multi-phase init),
On Windows x64/x86 with chinese/japanese/korean system-locale,
MultibyteCodec_Check() in multibytecodec.c returns false and
PyExc_TypeError follows. This affects some tests and PGO training.
Traceback (most recent call last):
File "C:\cpython-0b858\lib\test\test_threading.py", line 1124, in test_da
emon_threads_fatal_error
self.assertIn("Fatal Python error: Py_EndInterpreter: "AssertionError: 'Fatal Python error: Py_EndInterpreter: not the last thread
' not found in 'TypeError: codec is unexpected type\nFatal Python error: _P
yThreadState_Delete: tstate 00000000003FF980 is still current\nPython runti
me state: initialized\n\nThread 0x00000710 (most recent call first):\n<no P
ython frame>\n'
It took me a while to understand it, the _multibytecodec module itself is fine. The issue comes from the _codecs_jp module which uses the legacy module API:
This test runs code in a subinterpreter which is run in a subprocess. The problem is not in the code run in the subinterpreter, but the creation of sys.stdout in the subprocess.
The test creates a subprocess and redirects its stdout and stderr. In this case, Python doesn't create a _io._WindowsConsoleIO for sys.stdout.buffer.raw, but a regular _io.FileIO object. When the raw I/O is a _WindowsConsoleIO instance, create_stdio() of Python/pylifecycle.c forces the usage of the UTF-8 encoding. But for FileIO, it keeps the locale encoding.
If the locale encoding is "cp932", a CJK multicodec is used. In the main interpreter, it's fine. In a subinterpreter, we hit the bug of the _codecs_jp which doesn't use the new multi-phase initialization API.
By default, UTF-8 is used, everything is fine:
-----
C:\> python t.py
sys.stdout.encoding='utf-8'
-----
Disable _WindowsConsoleIO with PYTHONLEGACYWINDOWSSTDIO env var, we get the issue:
-----
C:\> set PYTHONLEGACYWINDOWSSTDIO=1
C:\> python t.py
Running Debug|x64 interpreter...
sys.stdout.encoding='cp932'
TypeError: codec is unexpected type
Fatal Python error: (...)
-----
Or redirect the output into a program or a file to disable _WindowsConsoleIO to also reproduce the issue:
-----
C:\> python t.py|more
sys.stdout.encoding='cp932'
TypeError: codec is unexpected type
(...)
-----
Ah, if you don't want to change the ANSI code page to cp932 (Japanese language) just to reproduce the issue, you can just set the stdio encoding:
-----
C:\> set PYTHONIOENCODING=cp932
C:\> python t.py|more
sys.stdout.encoding='cp1250'
bpo-42846: Convert CJK codec extensions to multiphase init (GH-24157)
I added a new test and new test spotted a reference leak, likely an existing one: bpo-42866 "test test_multibytecodec: Test_IncrementalEncoder.test_subinterp() leaks references".
Activity
neonene commentedon Jan 6, 2021
After 0b858cd
(bpo-1635741: Convert _multibytecodec to multi-phase init),
On Windows x64/x86 with chinese/japanese/korean system-locale,
MultibyteCodec_Check() in multibytecodec.c returns false and
PyExc_TypeError follows. This affects some tests and PGO training.
======================================================================
FAIL: test_daemon_threads_fatal_error (test.test_threading.SubinterpThreadi
ngTests)
----------------------------------------------------------------------
======================================================================
FAIL: test_audit_subinterpreter (test.test_embed.AuditingTests)
----------------------------------------------------------------------
======================================================================
FAIL: test_subinterps_different_ids (test.test_embed.EmbeddingTests)
----------------------------------------------------------------------
======================================================================
FAIL: test_subinterps_distinct_state (test.test_embed.EmbeddingTests)
----------------------------------------------------------------------
======================================================================
FAIL: test_subinterps_main (test.test_embed.EmbeddingTests)
----------------------------------------------------------------------
erlend-aasland commentedon Jan 7, 2021
I'm unable to reproduce this on Windows 10 (amd64). What's your exact locale setting? Are you compiling with HEAD at 0b858cd?
vstinner commentedon Jan 7, 2021
I can reproduce the issue on Windows configured in Japanese language: ANSI code page cp932.
I managed to reproduce the bug on Linux with attached bug.py
vstinner commentedon Jan 7, 2021
It took me a while to understand it, the _multibytecodec module itself is fine. The issue comes from the _codecs_jp module which uses the legacy module API:
erlend-aasland commentedon Jan 7, 2021
It should be sufficient to convert cjkcodecs.h to multi-phase init then? From what I can see, the support modules are state less, right?
vstinner commentedon Jan 7, 2021
I'm working on a fix.
vstinner commentedon Jan 7, 2021
Attached PR 24157 should fix the issue.
This test runs code in a subinterpreter which is run in a subprocess. The problem is not in the code run in the subinterpreter, but the creation of sys.stdout in the subprocess.
The test creates a subprocess and redirects its stdout and stderr. In this case, Python doesn't create a _io._WindowsConsoleIO for sys.stdout.buffer.raw, but a regular _io.FileIO object. When the raw I/O is a _WindowsConsoleIO instance, create_stdio() of Python/pylifecycle.c forces the usage of the UTF-8 encoding. But for FileIO, it keeps the locale encoding.
If the locale encoding is "cp932", a CJK multicodec is used. In the main interpreter, it's fine. In a subinterpreter, we hit the bug of the _codecs_jp which doesn't use the new multi-phase initialization API.
vstinner commentedon Jan 7, 2021
Simpler way to reproduce the issue with t.py script:
---
By default, UTF-8 is used, everything is fine:
-----
C:\> python t.py
sys.stdout.encoding='utf-8'
-----
Disable _WindowsConsoleIO with PYTHONLEGACYWINDOWSSTDIO env var, we get the issue:
-----
C:\> set PYTHONLEGACYWINDOWSSTDIO=1
C:\> python t.py
Running Debug|x64 interpreter...
sys.stdout.encoding='cp932'
TypeError: codec is unexpected type
Fatal Python error: (...)
-----
Or redirect the output into a program or a file to disable _WindowsConsoleIO to also reproduce the issue:
-----
C:\> python t.py|more
sys.stdout.encoding='cp932'
TypeError: codec is unexpected type
(...)
-----
vstinner commentedon Jan 7, 2021
Ah, if you don't want to change the ANSI code page to cp932 (Japanese language) just to reproduce the issue, you can just set the stdio encoding:
-----
C:\> set PYTHONIOENCODING=cp932
C:\> python t.py|more
sys.stdout.encoding='cp1250'
TypeError: codec is unexpected type
(...)
-----
vstinner commentedon Jan 7, 2021
New changeset 07f2cee by Victor Stinner in branch 'master':
bpo-42846: Convert CJK codec extensions to multiphase init (GH-24157)
07f2cee
vstinner commentedon Jan 7, 2021
I ran manually these two tests with cp932 ANSI code page: they now pass with my fix.
I also added a regression test to test_multibytecodec.py.
Thanks for your quick bug report neonene! It's now fixed.
vstinner commentedon Jan 8, 2021
I added a new test and new test spotted a reference leak, likely an existing one: bpo-42866 "test test_multibytecodec: Test_IncrementalEncoder.test_subinterp() leaks references".