Comments
Patch
@@ -21,4 +21,16 @@ from . import (
modulepolicy = policy.policy
+# Versions for C modules. If a C module does not have the desired version,
+# treat it as "invalid" and do not use it. This makes it impossible to have
+# mismatched .so with .py files.
+_cmoduleversions = {
+ 'mercurial.base85': 1,
+ 'mercurial.bdiff': 1,
+ 'mercurial.diffhelpers': 1,
+ 'mercurial.mpatch': 1,
+ 'mercurial.osutil': 1,
+ 'mercurial.parsers': 1,
+}
+
# Modules that have both Python and C implementations. See also the
# set of .py files under mercurial/pure/.
@@ -32,4 +44,12 @@ modulepolicy = policy.policy
])
+def _checkcmoduleversion(modname, mod):
+ """check version of a C module. raise ImportError if version mismatch"""
+ expected = _cmoduleversions.get(modname, 0)
+ actual = getattr(mod, '_version', 0)
+ if expected != actual:
+ raise ImportError('%s: mismatched version: got %s, expected %s' %
+ (modname, actual, expected))
+
class hgimporter(object):
"""Object that conforms to import hook interface defined in PEP-302."""
@@ -68,4 +88,5 @@ class hgimporter(object):
# indicates the type of module. So just assume what we found
# is OK (even though it could be a pure Python module).
+ _checkcmoduleversion(name, mod)
except ImportError:
if modulepolicy == b'c':
@@ -106,4 +127,6 @@ class hgimporter(object):
'version should exist' % name)
+ mod = imp.load_module(name, *modinfo)
+ _checkcmoduleversion(name, mod)
except ImportError:
if modulepolicy == b'c':
@@ -117,6 +140,6 @@ class hgimporter(object):
raise ImportError('could not find mercurial module %s' %
name)
+ mod = imp.load_module(name, *modinfo)
- mod = imp.load_module(name, *modinfo)
sys.modules[name] = mod
return mod