Mercurial > cpython-lru_cache-weakref
annotate Lib/test/test_threaded_import.py @ 78069:a8aa77458e12 3.2
Add c_size_t and c_ssize_t to the ctypes summary table.
| author | Antoine Pitrou <solipsis@pitrou.net> |
|---|---|
| date | Thu, 12 Jul 2012 20:31:50 +0200 |
| parents | 3c9232a684ae |
| children | 5548197d1f22 |
| rev | line source |
|---|---|
|
17897
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
1 # This is a variant of the very old (early 90's) file |
|
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
2 # Demo/threads/bug.py. It simply provokes a number of threads into |
|
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
3 # trying to import the same module "at the same time". |
|
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
4 # There are no pleasant failure modes -- most likely is that Python |
|
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
5 # complains several times about module random having no attribute |
|
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
6 # randrange, and then Python hangs. |
|
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
7 |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
8 import os |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
9 import imp |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
10 import sys |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
11 import time |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
12 import shutil |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
13 import unittest |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
14 from test.support import verbose, import_module, run_unittest, TESTFN |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
15 thread = import_module('_thread') |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
16 threading = import_module('threading') |
|
17897
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
17 |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
18 def task(N, done, done_tasks, errors): |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
19 try: |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
20 # We don't use modulefinder but still import it in order to stress |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
21 # importing of different modules from several threads. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
22 if len(done_tasks) % 2: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
23 import modulefinder |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
24 import random |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
25 else: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
26 import random |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
27 import modulefinder |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
28 # This will fail if random is not completely initialized |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
29 x = random.randrange(1, 3) |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
30 except Exception as e: |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
31 errors.append(e.with_traceback(None)) |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
32 finally: |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
33 done_tasks.append(thread.get_ident()) |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
34 finished = len(done_tasks) == N |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
35 if finished: |
|
65280
1e72abf073c5
Merged revisions 85444 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
64238
diff
changeset
|
36 done.set() |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
37 |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
38 # Create a circular import structure: A -> C -> B -> D -> A |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
39 # NOTE: `time` is already loaded and therefore doesn't threaten to deadlock. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
40 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
41 circular_imports_modules = { |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
42 'A': """if 1: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
43 import time |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
44 time.sleep(%(delay)s) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
45 x = 'a' |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
46 import C |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
47 """, |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
48 'B': """if 1: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
49 import time |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
50 time.sleep(%(delay)s) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
51 x = 'b' |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
52 import D |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
53 """, |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
54 'C': """import B""", |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
55 'D': """import A""", |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
56 } |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
57 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
58 class Finder: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
59 """A dummy finder to detect concurrent access to its find_module() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
60 method.""" |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
61 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
62 def __init__(self): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
63 self.numcalls = 0 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
64 self.x = 0 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
65 self.lock = thread.allocate_lock() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
66 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
67 def find_module(self, name, path=None): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
68 # Simulate some thread-unsafe behaviour. If calls to find_module() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
69 # are properly serialized, `x` will end up the same as `numcalls`. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
70 # Otherwise not. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
71 with self.lock: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
72 self.numcalls += 1 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
73 x = self.x |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
74 time.sleep(0.1) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
75 self.x = x + 1 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
76 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
77 class FlushingFinder: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
78 """A dummy finder which flushes sys.path_importer_cache when it gets |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
79 called.""" |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
80 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
81 def find_module(self, name, path=None): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
82 sys.path_importer_cache.clear() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
83 |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
84 |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
85 class ThreadedImportTests(unittest.TestCase): |
|
17897
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
86 |
|
63045
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
87 def setUp(self): |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
88 self.old_random = sys.modules.pop('random', None) |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
89 |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
90 def tearDown(self): |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
91 # If the `random` module was already initialized, we restore the |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
92 # old module at the end so that pickling tests don't fail. |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
93 # See http://bugs.python.org/issue3657#msg110461 |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
94 if self.old_random is not None: |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
95 sys.modules['random'] = self.old_random |
|
7cbf8c4e2727
Merged revisions 82919 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63024
diff
changeset
|
96 |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
97 def check_parallel_module_init(self): |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
98 if imp.lock_held(): |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
99 # This triggers on, e.g., from test import autotest. |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
100 raise unittest.SkipTest("can't run when import lock is held") |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
101 |
|
65280
1e72abf073c5
Merged revisions 85444 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
64238
diff
changeset
|
102 done = threading.Event() |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
103 for N in (20, 50) * 3: |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
104 if verbose: |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
105 print("Trying", N, "threads ...", end=' ') |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
106 # Make sure that random and modulefinder get reimported freshly |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
107 for modname in ['random', 'modulefinder']: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
108 try: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
109 del sys.modules[modname] |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
110 except KeyError: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
111 pass |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
112 errors = [] |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
113 done_tasks = [] |
|
65280
1e72abf073c5
Merged revisions 85444 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
64238
diff
changeset
|
114 done.clear() |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
115 for i in range(N): |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
116 thread.start_new_thread(task, (N, done, done_tasks, errors,)) |
|
65280
1e72abf073c5
Merged revisions 85444 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
64238
diff
changeset
|
117 done.wait(60) |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
118 self.assertFalse(errors) |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
119 if verbose: |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
120 print("OK.") |
|
17897
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
121 |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
122 def test_parallel_module_init(self): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
123 self.check_parallel_module_init() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
124 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
125 def test_parallel_meta_path(self): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
126 finder = Finder() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
127 sys.meta_path.append(finder) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
128 try: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
129 self.check_parallel_module_init() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
130 self.assertGreater(finder.numcalls, 0) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
131 self.assertEqual(finder.x, finder.numcalls) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
132 finally: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
133 sys.meta_path.remove(finder) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
134 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
135 def test_parallel_path_hooks(self): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
136 # Here the Finder instance is only used to check concurrent calls |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
137 # to path_hook(). |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
138 finder = Finder() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
139 # In order for our path hook to be called at each import, we need |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
140 # to flush the path_importer_cache, which we do by registering a |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
141 # dedicated meta_path entry. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
142 flushing_finder = FlushingFinder() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
143 def path_hook(path): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
144 finder.find_module('') |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
145 raise ImportError |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
146 sys.path_hooks.append(path_hook) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
147 sys.meta_path.append(flushing_finder) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
148 try: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
149 # Flush the cache a first time |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
150 flushing_finder.find_module('') |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
151 numtests = self.check_parallel_module_init() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
152 self.assertGreater(finder.numcalls, 0) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
153 self.assertEqual(finder.x, finder.numcalls) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
154 finally: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
155 sys.meta_path.remove(flushing_finder) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
156 sys.path_hooks.remove(path_hook) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
157 |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
158 def test_import_hangers(self): |
|
38453
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
32918
diff
changeset
|
159 # In case this test is run again, make sure the helper module |
|
29ae5e0fc348
Much-needed merge (using svnmerge.py this time) of trunk changes into p3yk.
Thomas Wouters <thomas@python.org>
parents:
32918
diff
changeset
|
160 # gets loaded from scratch again. |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
161 try: |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
162 del sys.modules['test.threaded_import_hangers'] |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
163 except KeyError: |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
164 pass |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
165 import test.threaded_import_hangers |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
166 self.assertFalse(test.threaded_import_hangers.errors) |
|
19596
1be18ef869a4
Add a new function imp.lock_held(), and use it to skip test_threaded_import
Tim Peters <tim.peters@gmail.com>
parents:
19564
diff
changeset
|
167 |
|
64238
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
168 def test_circular_imports(self): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
169 # The goal of this test is to exercise implementations of the import |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
170 # lock which use a per-module lock, rather than a global lock. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
171 # In these implementations, there is a possible deadlock with |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
172 # circular imports, for example: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
173 # - thread 1 imports A (grabbing the lock for A) which imports B |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
174 # - thread 2 imports B (grabbing the lock for B) which imports A |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
175 # Such implementations should be able to detect such situations and |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
176 # resolve them one way or the other, without freezing. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
177 # NOTE: our test constructs a slightly less trivial import cycle, |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
178 # in order to better stress the deadlock avoidance mechanism. |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
179 delay = 0.5 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
180 os.mkdir(TESTFN) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
181 self.addCleanup(shutil.rmtree, TESTFN) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
182 sys.path.insert(0, TESTFN) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
183 self.addCleanup(sys.path.remove, TESTFN) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
184 for name, contents in circular_imports_modules.items(): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
185 contents = contents % {'delay': delay} |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
186 with open(os.path.join(TESTFN, name + ".py"), "wb") as f: |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
187 f.write(contents.encode('utf-8')) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
188 self.addCleanup(sys.modules.pop, name, None) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
189 |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
190 results = [] |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
191 def import_ab(): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
192 import A |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
193 results.append(getattr(A, 'x', None)) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
194 def import_ba(): |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
195 import B |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
196 results.append(getattr(B, 'x', None)) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
197 t1 = threading.Thread(target=import_ab) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
198 t2 = threading.Thread(target=import_ba) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
199 t1.start() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
200 t2.start() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
201 t1.join() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
202 t2.join() |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
203 self.assertEqual(set(results), {'a', 'b'}) |
|
716d3d102c0a
Merged revisions 84258,84268 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
63045
diff
changeset
|
204 |
|
19596
1be18ef869a4
Add a new function imp.lock_held(), and use it to skip test_threaded_import
Tim Peters <tim.peters@gmail.com>
parents:
19564
diff
changeset
|
205 |
|
63024
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
206 def test_main(): |
|
3805ffe8ff38
Merged revisions 82885 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents:
52389
diff
changeset
|
207 run_unittest(ThreadedImportTests) |
|
17897
cc984ed26586
New test adapted from the ancient Demo/threads/bug.py.
Tim Peters <tim.peters@gmail.com>
parents:
diff
changeset
|
208 |
|
17913
46909f22170c
Implementing an idea from Guido on the checkins list:
Tim Peters <tim.peters@gmail.com>
parents:
17897
diff
changeset
|
209 if __name__ == "__main__": |
|
46909f22170c
Implementing an idea from Guido on the checkins list:
Tim Peters <tim.peters@gmail.com>
parents:
17897
diff
changeset
|
210 test_main() |
