diff --git a/eventlet/patcher.py b/eventlet/patcher.py index 0d5cc65..1164848 100644 --- a/eventlet/patcher.py +++ b/eventlet/patcher.py @@ -283,6 +283,12 @@ def monkey_patch(**on): finally: imp.release_lock() + if sys.version_info >= (3, 3): + import importlib._bootstrap + thread = original('_thread') + # importlib must use real thread locks, not eventlet.Semaphore + importlib._bootstrap._thread = thread + def is_monkey_patched(module): """Returns True if the given module is monkeypatched currently, False if diff --git a/tests/patcher_test.py b/tests/patcher_test.py index f80b589..5c9076f 100644 --- a/tests/patcher_test.py +++ b/tests/patcher_test.py @@ -492,5 +492,10 @@ t2.join() self.assertEqual(lines[1], "True", lines[1]) +def test_importlib_lock(): + output = run_python('tests/patcher_test_importlib_lock.py') + assert output.rstrip() == b'ok' + + if __name__ == '__main__': main() diff --git a/tests/patcher_test_importlib_lock.py b/tests/patcher_test_importlib_lock.py new file mode 100644 index 0000000..8f7cea7 --- /dev/null +++ b/tests/patcher_test_importlib_lock.py @@ -0,0 +1,30 @@ +from __future__ import print_function + +import sys + +import eventlet + + +# no standard tests in this file, ignore +__test__ = False + + +def do_import(): + import encodings.idna + + +if __name__ == '__main__': + eventlet.monkey_patch() + threading = eventlet.patcher.original('threading') + + sys.modules.pop('encodings.idna', None) + + # call "import encodings.idna" in a new thread + thread = threading.Thread(target=do_import) + thread.start() + + # call "import encodings.idna" in the main thread + do_import() + + thread.join() + print('ok')