Ken Struys
Ken Struys

Reputation: 1789

Import lock not working cross threads in pypy

This test passes under python2.6/2.7 but fails under pypy. pypy definitely supports threads and the imp lock seems to work without threads as expected under pypy. It seems like the thread is getting it's own import lock?....

import unittest
import imp
import threading


class Test(unittest.TestCase):

    def test_import_lock(self):
        lock_held = threading.Event()
        test_complete = threading.Event()
        lock_released = threading.Event()

        def other_thread():
            imp.acquire_lock()

            assert imp.lock_held()  # <--- this assertion passes, the imp lock is definitely held

            lock_held.set()
            test_complete.wait()
            imp.release_lock()

            lock_released.set()

        t = threading.Thread(target=other_thread)
        t.setDaemon(True)
        t.start()

        # Wait until the thread is holding the import lock
        lock_held.wait()

        # The import lock should be held at this point. The thread even asserted
        # that it was held!
        lock_was_held = imp.lock_held()

        # Notify the thread to release the lock
        test_complete.set()

        # Wait for the lock to be released
        lock_released.wait()

        # Make sure the lock was held when we expected it to be held
        assert lock_was_held

if __name__ == '__main__':
    unittest.main()

pypy

struys$ python --version
Python 2.7.6 (394146e9bb67, May 08 2014, 16:45:59)
[PyPy 2.3.0 with GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)]
struys$ python -m test
F
======================================================================
FAIL: test_import_lock (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test.py", line 42, in test_import_lock
    assert lock_was_held
AssertionError

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

python 2.7

struys$ python --version
Python 2.7.2
struys$ python test.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Upvotes: 2

Views: 227

Answers (1)

Eevee
Eevee

Reputation: 48556

Looks like PyPy's implementation returns whether the lock is held by this thread: https://bitbucket.org/pypy/pypy/src/6e9376d22e0ecc83bfcdda81d0e37e695b435dd7/pypy/module/imp/importing.py?at=default#cl-753

Whereas CPython's returns whether the lock is held at all: http://hg.python.org/cpython/file/3a1db0d2747e/Python/import.c#l348

So this looks to be a genuine bug in PyPy, which I've ticketed: https://bitbucket.org/pypy/pypy/issue/1775/implock_held-isnt-quite-right

Upvotes: 3

Related Questions