Skip to content

Commit

Permalink
fix the version check on CPython: on a failed version check, the brok…
Browse files Browse the repository at this point in the history
…en module was left inside sys.modules, with the consequence that a second import seemed to succeed O_o
  • Loading branch information
antocuni committed Feb 9, 2018
1 parent 7d8194e commit 82dcfe5
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
2 changes: 1 addition & 1 deletion capnpy/compiler/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def emit(self, m):
#
m.w('__capnpy_version__ = {version!r}', version=capnpy.__version__)
if m.version_check:
m.w('_check_version(__capnpy_version__)')
m.w('_check_version(__name__, __capnpy_version__)')
else:
m.w('# schema compiled with --no-version-check, skipping the call to _check_version')
self._declare_imports(m)
Expand Down
14 changes: 9 additions & 5 deletions capnpy/testing/compiler/test_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,12 @@ def test_version_check(self, monkeypatch):
}
""")
monkeypatch.setattr(capnpy, '__version__', 'Fake 2.0')
exc = py.test.raises(ImportError, "self.import_('example')")
expected = ('Version mismatch: the module has been compiled with capnpy '
'Fake 1.0, but the current version of capnpy is Fake 2.0. '
'Please recompile.')
assert str(exc.value) == expected
# try to import it twice: we need to take extra case to make sure that
# when in PYX mode, the module is not left inside sys.modules in case
# of version mismatch
for i in range(2):
exc = py.test.raises(ImportError, "self.import_('example')")
expected = ('Version mismatch: the module has been compiled with '
'capnpy Fake 1.0, but the current version of capnpy '
'is Fake 2.0. Please recompile.')
assert str(exc.value) == expected
7 changes: 6 additions & 1 deletion capnpy/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,13 @@ def extend_module_maybe(globals, filename=None, modname=None):
code = compile(src, str(extmod), 'exec')
exec(code, globals)

def check_version(version):
def check_version(modname, version):
if version != capnpy.__version__:
# explicitly remove modname from sys.modules: apparently, CPython does
# not do it automatically if the module is an extension (which happens
# in PYX mode). See also
# testing/compiler/test_standalone:test_version_check
sys.modules.pop(modname, None)
msg = ('Version mismatch: the module has been compiled with capnpy '
'{v1}, but the current version of capnpy is {v2}. '
'Please recompile.').format(v1=version, v2=capnpy.__version__)
Expand Down

0 comments on commit 82dcfe5

Please sign in to comment.