Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc0fc88f

Browse files
ericsnowcurrentlyAlexWaygoodhugovk
authored
[3.12]gh-112826: Fix the threading Module When _thread is Missing _is_main_interpreter() (#112850)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
1 parent34e9e20 commitc0fc88f

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

‎Doc/whatsnew/3.12.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,15 @@ Changes in the Python API
18951895
* Mixing tabs and spaces as indentation in the same file is not supported anymore and will
18961896
raise a:exc:`TabError`.
18971897

1898+
* The:mod:`threading` module now expects the:mod:`!_thread` module to have
1899+
an ``_is_main_interpreter`` attribute. It is a function with no
1900+
arguments that returns ``True`` if the current interpreter is the
1901+
main interpreter.
1902+
1903+
Any library or application that provides a custom ``_thread`` module
1904+
should provide ``_is_main_interpreter()``.
1905+
(See:gh:`112826`.)
1906+
18981907
Build Changes
18991908
=============
19001909

‎Lib/test/test_threading.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,34 @@ def test__all__(self):
18271827
support.check__all__(self,threading, ('threading','_thread'),
18281828
extra=extra,not_exported=not_exported)
18291829

1830+
@requires_subprocess()
1831+
deftest_gh112826_missing__thread__is_main_interpreter(self):
1832+
withos_helper.temp_dir()astempdir:
1833+
modname='_thread_fake'
1834+
importos.path
1835+
filename=os.path.join(tempdir,modname+'.py')
1836+
withopen(filename,'w')asoutfile:
1837+
outfile.write("""if True:
1838+
import _thread
1839+
globals().update(vars(_thread))
1840+
del _is_main_interpreter
1841+
""")
1842+
1843+
expected_output=b'success!'
1844+
_,out,err=assert_python_ok("-c",f"""if True:
1845+
import sys
1846+
sys.path.insert(0,{tempdir!r})
1847+
import{modname}
1848+
sys.modules['_thread'] ={modname}
1849+
del sys.modules[{modname!r}]
1850+
1851+
import threading
1852+
print({expected_output.decode('utf-8')!r}, end='')
1853+
""")
1854+
1855+
self.assertEqual(out,expected_output)
1856+
self.assertEqual(err,b'')
1857+
18301858

18311859
classInterruptMainTests(unittest.TestCase):
18321860
defcheck_interrupt_main_with_signal_handler(self,signum):

‎Lib/threading.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,20 @@
3737
_allocate_lock=_thread.allocate_lock
3838
_set_sentinel=_thread._set_sentinel
3939
get_ident=_thread.get_ident
40-
_is_main_interpreter=_thread._is_main_interpreter
40+
try:
41+
_is_main_interpreter=_thread._is_main_interpreter
42+
exceptAttributeError:
43+
# See https://github.com/python/cpython/issues/112826.
44+
# We can pretend a subinterpreter is the main interpreter for the
45+
# sake of _shutdown(), since that only means we do not wait for the
46+
# subinterpreter's threads to finish. Instead, they will be stopped
47+
# later by the mechanism we use for daemon threads. The likelihood
48+
# of this case is small because rarely will the _thread module be
49+
# replaced by a module without _is_main_interpreter().
50+
# Furthermore, this is all irrelevant in applications
51+
# that do not use subinterpreters.
52+
def_is_main_interpreter():
53+
returnTrue
4154
try:
4255
get_native_id=_thread.get_native_id
4356
_HAVE_THREAD_NATIVE_ID=True

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp