##// END OF EJS Templates
policy: extend API version checks for cffi...
Yuya Nishihara -
r32511:2e431fb9 default
parent child Browse files
Show More
@@ -1,106 +1,106
1 1 # policy.py - module policy logic for Mercurial.
2 2 #
3 3 # Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import os
11 11 import sys
12 12
13 13 # Rules for how modules can be loaded. Values are:
14 14 #
15 15 # c - require C extensions
16 16 # allow - allow pure Python implementation when C loading fails
17 17 # cffi - required cffi versions (implemented within pure module)
18 18 # cffi-allow - allow pure Python implementation if cffi version is missing
19 19 # py - only load pure Python modules
20 20 #
21 21 # By default, fall back to the pure modules so the in-place build can
22 22 # run without recompiling the C extensions. This will be overridden by
23 23 # __modulepolicy__ generated by setup.py.
24 24 policy = b'allow'
25 25 policynoc = (b'cffi', b'cffi-allow', b'py')
26 26 policynocffi = (b'c', b'py')
27 27 _packageprefs = {
28 28 # policy: (versioned package, pure package)
29 29 b'c': (r'cext', None),
30 30 b'allow': (r'cext', r'pure'),
31 31 b'cffi': (None, r'pure'), # TODO: (r'cffi', None)
32 32 b'cffi-allow': (None, r'pure'), # TODO: (r'cffi', r'pure')
33 33 b'py': (None, r'pure'),
34 34 }
35 35
36 36 try:
37 37 from . import __modulepolicy__
38 38 policy = __modulepolicy__.modulepolicy
39 39 except ImportError:
40 40 pass
41 41
42 42 # PyPy doesn't load C extensions.
43 43 #
44 44 # The canonical way to do this is to test platform.python_implementation().
45 45 # But we don't import platform and don't bloat for it here.
46 46 if r'__pypy__' in sys.builtin_module_names:
47 47 policy = b'cffi'
48 48
49 49 # Our C extensions aren't yet compatible with Python 3. So use pure Python
50 50 # on Python 3 for now.
51 51 if sys.version_info[0] >= 3:
52 52 policy = b'py'
53 53
54 54 # Environment variable can always force settings.
55 55 if sys.version_info[0] >= 3:
56 56 if r'HGMODULEPOLICY' in os.environ:
57 57 policy = os.environ[r'HGMODULEPOLICY'].encode(r'utf-8')
58 58 else:
59 59 policy = os.environ.get(r'HGMODULEPOLICY', policy)
60 60
61 61 def _importfrom(pkgname, modname):
62 62 # from .<pkgname> import <modname> (where . is looked through this module)
63 63 fakelocals = {}
64 64 pkg = __import__(pkgname, globals(), fakelocals, [modname], level=1)
65 65 try:
66 66 fakelocals[modname] = mod = getattr(pkg, modname)
67 67 except AttributeError:
68 68 raise ImportError(r'cannot import name %s' % modname)
69 69 # force import; fakelocals[modname] may be replaced with the real module
70 70 getattr(mod, r'__doc__', None)
71 71 return fakelocals[modname]
72 72
73 73 # keep in sync with "version" in C modules
74 74 _cextversions = {
75 r'base85': 1,
76 r'bdiff': 1,
77 r'diffhelpers': 1,
78 r'mpatch': 1,
79 r'osutil': 1,
80 r'parsers': 1,
75 (r'cext', r'base85'): 1,
76 (r'cext', r'bdiff'): 1,
77 (r'cext', r'diffhelpers'): 1,
78 (r'cext', r'mpatch'): 1,
79 (r'cext', r'osutil'): 1,
80 (r'cext', r'parsers'): 1,
81 81 }
82 82
83 83 def _checkmod(pkgname, modname, mod):
84 expected = _cextversions.get(modname)
84 expected = _cextversions.get((pkgname, modname))
85 85 actual = getattr(mod, r'version', None)
86 86 if actual != expected:
87 87 raise ImportError(r'cannot import module %s.%s '
88 88 r'(expected version: %d, actual: %r)'
89 89 % (pkgname, modname, expected, actual))
90 90
91 91 def importmod(modname):
92 92 """Import module according to policy and check API version"""
93 93 try:
94 94 verpkg, purepkg = _packageprefs[policy]
95 95 except KeyError:
96 96 raise ImportError(r'invalid HGMODULEPOLICY %r' % policy)
97 97 assert verpkg or purepkg
98 98 if verpkg:
99 99 try:
100 100 mod = _importfrom(verpkg, modname)
101 101 _checkmod(verpkg, modname, mod)
102 102 return mod
103 103 except ImportError:
104 104 if not purepkg:
105 105 raise
106 106 return _importfrom(purepkg, modname)
General Comments 0
You need to be logged in to leave comments. Login now