MCPcopy Index your code
hub / github.com/python/cpython / test_unpickle_module_race

Method test_unpickle_module_race

Lib/test/pickletester.py:1698–1755  ·  view source on GitHub ↗
(self)

Source from the content-addressed store, hash-verified

1696 @threading_helper.reap_threads
1697 @threading_helper.requires_working_threading()
1698 def test_unpickle_module_race(self):
1699 # https://bugs.python.org/issue34572
1700 locker_module = dedent("""
1701 import threading
1702 barrier = threading.Barrier(2)
1703 """)
1704 locking_import_module = dedent("""
1705 import locker
1706 locker.barrier.wait()
1707 class ToBeUnpickled(object):
1708 pass
1709 """)
1710
1711 os.mkdir(TESTFN)
1712 self.addCleanup(shutil.rmtree, TESTFN)
1713 sys.path.insert(0, TESTFN)
1714 self.addCleanup(sys.path.remove, TESTFN)
1715 with open(os.path.join(TESTFN, "locker.py"), "wb") as f:
1716 f.write(locker_module.encode('utf-8'))
1717 with open(os.path.join(TESTFN, "locking_import.py"), "wb") as f:
1718 f.write(locking_import_module.encode('utf-8'))
1719 self.addCleanup(forget, "locker")
1720 self.addCleanup(forget, "locking_import")
1721
1722 import locker
1723
1724 pickle_bytes = (
1725 b'\x80\x03clocking_import\nToBeUnpickled\nq\x00)\x81q\x01.')
1726
1727 # Then try to unpickle two of these simultaneously
1728 # One of them will cause the module import, and we want it to block
1729 # until the other one either:
1730 # - fails (before the patch for this issue)
1731 # - blocks on the import lock for the module, as it should
1732 results = []
1733 barrier = threading.Barrier(3)
1734 def t():
1735 # This ensures the threads have all started
1736 # presumably barrier release is faster than thread startup
1737 barrier.wait()
1738 results.append(pickle.loads(pickle_bytes))
1739
1740 t1 = threading.Thread(target=t)
1741 t2 = threading.Thread(target=t)
1742 t1.start()
1743 t2.start()
1744
1745 barrier.wait()
1746 # could have delay here
1747 locker.barrier.wait()
1748
1749 t1.join()
1750 t2.join()
1751
1752 from locking_import import ToBeUnpickled
1753 self.assertEqual(
1754 [type(x) for x in results],
1755 [ToBeUnpickled] * 2)

Callers

nothing calls this directly

Calls 14

startMethod · 0.95
waitMethod · 0.95
joinMethod · 0.95
dedentFunction · 0.90
addCleanupMethod · 0.80
BarrierMethod · 0.80
openFunction · 0.50
mkdirMethod · 0.45
insertMethod · 0.45
joinMethod · 0.45
writeMethod · 0.45
encodeMethod · 0.45

Tested by

no test coverage detected