mirror of
https://github.com/python/cpython.git
synced 2025-09-29 11:45:57 +00:00
[3.9] bpo-43517: Fix false positive in detection of circular imports (GH-24895) (GH-24948)
(cherry picked from commit 2fd16ef406
)
Co-authored-by: Antoine Pitrou <antoine@python.org>
Automerge-Triggered-By: GH:pitrou
This commit is contained in:
parent
e8e341993e
commit
ac17ed60f2
5 changed files with 81 additions and 2 deletions
38
Lib/test/test_importlib/partial/cfimport.py
Normal file
38
Lib/test/test_importlib/partial/cfimport.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
NLOOPS = 50
|
||||||
|
NTHREADS = 30
|
||||||
|
|
||||||
|
|
||||||
|
def t1():
|
||||||
|
try:
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
|
def t2():
|
||||||
|
try:
|
||||||
|
from concurrent.futures.thread import ThreadPoolExecutor
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
for j in range(NLOOPS):
|
||||||
|
threads = []
|
||||||
|
for i in range(NTHREADS):
|
||||||
|
threads.append(threading.Thread(target=t2 if i % 1 else t1))
|
||||||
|
for thread in threads:
|
||||||
|
thread.start()
|
||||||
|
for thread in threads:
|
||||||
|
thread.join()
|
||||||
|
sys.modules.pop('concurrent.futures', None)
|
||||||
|
sys.modules.pop('concurrent.futures.thread', None)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
27
Lib/test/test_importlib/partial/pool_in_threads.py
Normal file
27
Lib/test/test_importlib/partial/pool_in_threads.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import multiprocessing
|
||||||
|
import os
|
||||||
|
import threading
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
def t():
|
||||||
|
try:
|
||||||
|
with multiprocessing.Pool(1):
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
threads = []
|
||||||
|
for i in range(20):
|
||||||
|
threads.append(threading.Thread(target=t))
|
||||||
|
for thread in threads:
|
||||||
|
thread.start()
|
||||||
|
for thread in threads:
|
||||||
|
thread.join()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -16,7 +16,7 @@ import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from test.support import (
|
from test.support import (
|
||||||
verbose, run_unittest, TESTFN, reap_threads,
|
verbose, run_unittest, TESTFN, reap_threads,
|
||||||
forget, unlink, rmtree, start_threads)
|
forget, unlink, rmtree, start_threads, script_helper)
|
||||||
|
|
||||||
def task(N, done, done_tasks, errors):
|
def task(N, done, done_tasks, errors):
|
||||||
try:
|
try:
|
||||||
|
@ -244,6 +244,18 @@ class ThreadedImportTests(unittest.TestCase):
|
||||||
__import__(TESTFN)
|
__import__(TESTFN)
|
||||||
del sys.modules[TESTFN]
|
del sys.modules[TESTFN]
|
||||||
|
|
||||||
|
def test_concurrent_futures_circular_import(self):
|
||||||
|
# Regression test for bpo-43515
|
||||||
|
fn = os.path.join(os.path.dirname(__file__),
|
||||||
|
'partial', 'cfimport.py')
|
||||||
|
script_helper.assert_python_ok(fn)
|
||||||
|
|
||||||
|
def test_multiprocessing_pool_circular_import(self):
|
||||||
|
# Regression test for bpo-41567
|
||||||
|
fn = os.path.join(os.path.dirname(__file__),
|
||||||
|
'partial', 'pool_in_threads.py')
|
||||||
|
script_helper.assert_python_ok(fn)
|
||||||
|
|
||||||
|
|
||||||
@reap_threads
|
@reap_threads
|
||||||
def test_main():
|
def test_main():
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix misdetection of circular imports when using ``from pkg.mod import
|
||||||
|
attr``, which caused false positives in non-trivial multi-threaded code.
|
|
@ -1863,7 +1863,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mod != NULL && mod != Py_None) {
|
if (mod != NULL && mod != Py_None) {
|
||||||
if (import_ensure_initialized(tstate, mod, name) < 0) {
|
if (import_ensure_initialized(tstate, mod, abs_name) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue