[pypy-commit] pypy multiphase: Ensure that reloading an extension is a no-op

rlamy pypy.commits at gmail.com
Sat Aug 12 14:23:50 EDT 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: multiphase
Changeset: r92135:b086a8161ab6
Date: 2017-08-12 20:23 +0200
http://bitbucket.org/pypy/pypy/changeset/b086a8161ab6/

Log:	Ensure that reloading an extension is a no-op

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -1595,6 +1595,8 @@
         return
     space.getbuiltinmodule("cpyext")
     mod_as_pyobj = rawrefcount.from_obj(PyObject, w_mod)
+    if cts.cast('PyModuleObject*', mod_as_pyobj).c_md_state:
+        return
     if mod_as_pyobj:
         return exec_def(space, w_mod, mod_as_pyobj)
 
diff --git a/pypy/module/cpyext/modsupport.py b/pypy/module/cpyext/modsupport.py
--- a/pypy/module/cpyext/modsupport.py
+++ b/pypy/module/cpyext/modsupport.py
@@ -142,6 +142,11 @@
     mod = rffi.cast(PyModuleObject, mod_as_pyobj)
     moddef = mod.c_md_def
     cur_slot = rffi.cast(rffi.CArrayPtr(PyModuleDef_Slot), moddef.c_m_slots)
+    if moddef.c_m_size >= 0 and not mod.c_md_state:
+        # Always set md_state, to use as marker for exec_extension_module()
+        # (cf. CPython's PyModule_ExecDef)
+        mod.c_md_state = lltype.malloc(
+            rffi.VOIDP.TO, moddef.c_m_size, flavor='raw', zero=True)
     while cur_slot and rffi.cast(lltype.Signed, cur_slot[0].c_slot):
         if rffi.cast(lltype.Signed, cur_slot[0].c_slot) == 2:
             execf = rffi.cast(execfunctype, cur_slot[0].c_value)
diff --git a/pypy/module/cpyext/test/test_module.py b/pypy/module/cpyext/test/test_module.py
--- a/pypy/module/cpyext/test/test_module.py
+++ b/pypy/module/cpyext/test/test_module.py
@@ -175,7 +175,8 @@
         import importlib
         module = self.import_module(name=self.name)
         ex_class = module.Example
-        importlib.reload(module)
+        # Simulate what importlib.reload() does, without recomputing the spec
+        module.__spec__.loader.exec_module(module)
         assert ex_class is module.Example
 
     def w_load_from_name(self, name, origin=None, use_prefix=True):


More information about the pypy-commit mailing list