##// END OF EJS Templates
policy: add cffi policy for PyPy...
Maciej Fijalkowski -
r29490:b4d117ce default
parent child Browse files
Show More
@@ -1,129 +1,129
1 1 # __init__.py - Startup and module loading 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 imp
11 11 import os
12 12 import sys
13 13 import zipimport
14 14
15 15 from . import (
16 16 policy
17 17 )
18 18
19 19 __all__ = []
20 20
21 21 modulepolicy = policy.policy
22 22
23 23 # Modules that have both Python and C implementations. See also the
24 24 # set of .py files under mercurial/pure/.
25 25 _dualmodules = set([
26 26 'mercurial.base85',
27 27 'mercurial.bdiff',
28 28 'mercurial.diffhelpers',
29 29 'mercurial.mpatch',
30 30 'mercurial.osutil',
31 31 'mercurial.parsers',
32 32 ])
33 33
34 34 class hgimporter(object):
35 35 """Object that conforms to import hook interface defined in PEP-302."""
36 36 def find_module(self, name, path=None):
37 37 # We only care about modules that have both C and pure implementations.
38 38 if name in _dualmodules:
39 39 return self
40 40 return None
41 41
42 42 def load_module(self, name):
43 43 mod = sys.modules.get(name, None)
44 44 if mod:
45 45 return mod
46 46
47 47 mercurial = sys.modules['mercurial']
48 48
49 49 # The zip importer behaves sufficiently differently from the default
50 50 # importer to warrant its own code path.
51 51 loader = getattr(mercurial, '__loader__', None)
52 52 if isinstance(loader, zipimport.zipimporter):
53 53 def ziploader(*paths):
54 54 """Obtain a zipimporter for a directory under the main zip."""
55 55 path = os.path.join(loader.archive, *paths)
56 56 zl = sys.path_importer_cache.get(path)
57 57 if not zl:
58 58 zl = zipimport.zipimporter(path)
59 59 return zl
60 60
61 61 try:
62 if modulepolicy == 'py':
62 if modulepolicy in policy.policynoc:
63 63 raise ImportError()
64 64
65 65 zl = ziploader('mercurial')
66 66 mod = zl.load_module(name)
67 67 # Unlike imp, ziploader doesn't expose module metadata that
68 68 # indicates the type of module. So just assume what we found
69 69 # is OK (even though it could be a pure Python module).
70 70 except ImportError:
71 71 if modulepolicy == 'c':
72 72 raise
73 73 zl = ziploader('mercurial', 'pure')
74 74 mod = zl.load_module(name)
75 75
76 76 sys.modules[name] = mod
77 77 return mod
78 78
79 79 # Unlike the default importer which searches special locations and
80 80 # sys.path, we only look in the directory where "mercurial" was
81 81 # imported from.
82 82
83 83 # imp.find_module doesn't support submodules (modules with ".").
84 84 # Instead you have to pass the parent package's __path__ attribute
85 85 # as the path argument.
86 86 stem = name.split('.')[-1]
87 87
88 88 try:
89 if modulepolicy == 'py':
89 if modulepolicy in policy.policynoc:
90 90 raise ImportError()
91 91
92 92 modinfo = imp.find_module(stem, mercurial.__path__)
93 93
94 94 # The Mercurial installer used to copy files from
95 95 # mercurial/pure/*.py to mercurial/*.py. Therefore, it's possible
96 96 # for some installations to have .py files under mercurial/*.
97 97 # Loading Python modules when we expected C versions could result
98 98 # in a) poor performance b) loading a version from a previous
99 99 # Mercurial version, potentially leading to incompatibility. Either
100 100 # scenario is bad. So we verify that modules loaded from
101 101 # mercurial/* are C extensions. If the current policy allows the
102 102 # loading of .py modules, the module will be re-imported from
103 103 # mercurial/pure/* below.
104 104 if modinfo[2][2] != imp.C_EXTENSION:
105 105 raise ImportError('.py version of %s found where C '
106 106 'version should exist' % name)
107 107
108 108 except ImportError:
109 109 if modulepolicy == 'c':
110 110 raise
111 111
112 112 # Could not load the C extension and pure Python is allowed. So
113 113 # try to load them.
114 114 from . import pure
115 115 modinfo = imp.find_module(stem, pure.__path__)
116 116 if not modinfo:
117 117 raise ImportError('could not find mercurial module %s' %
118 118 name)
119 119
120 120 mod = imp.load_module(name, *modinfo)
121 121 sys.modules[name] = mod
122 122 return mod
123 123
124 124 # We automagically register our custom importer as a side-effect of loading.
125 125 # This is necessary to ensure that any entry points are able to import
126 126 # mercurial.* modules without having to perform this registration themselves.
127 127 if not any(isinstance(x, hgimporter) for x in sys.meta_path):
128 128 # meta_path is used before any implicit finders and before sys.path.
129 129 sys.meta_path.insert(0, hgimporter())
@@ -1,40 +1,45
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 # cffi - required cffi versions (implemented within pure module)
18 # cffi-allow - allow pure Python implementation if cffi version is missing
17 19 # py - only load pure Python modules
18 20 #
19 21 # By default, require the C extensions for performance reasons.
20 22 policy = 'c'
23 policynoc = ('cffi', 'cffi-allow', 'py')
24 policynocffi = ('c', 'py')
25
21 26 try:
22 27 from . import __modulepolicy__
23 28 policy = __modulepolicy__.modulepolicy
24 29 except ImportError:
25 30 pass
26 31
27 32 # PyPy doesn't load C extensions.
28 33 #
29 34 # The canonical way to do this is to test platform.python_implementation().
30 35 # But we don't import platform and don't bloat for it here.
31 36 if '__pypy__' in sys.builtin_module_names:
32 policy = 'py'
37 policy = 'cffi'
33 38
34 39 # Our C extensions aren't yet compatible with Python 3. So use pure Python
35 40 # on Python 3 for now.
36 41 if sys.version_info[0] >= 3:
37 42 policy = 'py'
38 43
39 44 # Environment variable can always force settings.
40 45 policy = os.environ.get('HGMODULEPOLICY', policy)
General Comments 0
You need to be logged in to leave comments. Login now