Show More
@@ -0,0 +1,109 b'' | |||
|
1 | # __init__.py - Startup and module loading logic for Mercurial. | |
|
2 | # | |
|
3 | # Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com> | |
|
4 | # | |
|
5 | # This software may be used and distributed according to the terms of the | |
|
6 | # GNU General Public License version 2 or any later version. | |
|
7 | ||
|
8 | from __future__ import absolute_import | |
|
9 | ||
|
10 | import imp | |
|
11 | import os | |
|
12 | import sys | |
|
13 | ||
|
14 | __all__ = [] | |
|
15 | ||
|
16 | # Rules for how modules can be loaded. Values are: | |
|
17 | # | |
|
18 | # c - require C extensions | |
|
19 | # allow - allow pure Python implementation when C loading fails | |
|
20 | # py - only load pure Python modules | |
|
21 | modulepolicy = '@MODULELOADPOLICY@' | |
|
22 | ||
|
23 | # By default, require the C extensions for performance reasons. | |
|
24 | if modulepolicy == '@' 'MODULELOADPOLICY' '@': | |
|
25 | # TODO change to 'c' once installer is changed. | |
|
26 | modulepolicy = 'allow' | |
|
27 | ||
|
28 | # Environment variable can always force settings. | |
|
29 | modulepolicy = os.environ.get('HGMODULEPOLICY', modulepolicy) | |
|
30 | ||
|
31 | # Modules that have both Python and C implementations. See also the | |
|
32 | # set of .py files under mercurial/pure/. | |
|
33 | _dualmodules = set([ | |
|
34 | 'mercurial.base85', | |
|
35 | 'mercurial.bdiff', | |
|
36 | 'mercurial.diffhelpers', | |
|
37 | 'mercurial.mpatch', | |
|
38 | 'mercurial.osutil', | |
|
39 | 'mercurial.parsers', | |
|
40 | ]) | |
|
41 | ||
|
42 | class hgimporter(object): | |
|
43 | """Object that conforms to import hook interface defined in PEP-302.""" | |
|
44 | def find_module(self, name, path=None): | |
|
45 | # We only care about modules that have both C and pure implementations. | |
|
46 | if name in _dualmodules: | |
|
47 | return self | |
|
48 | return None | |
|
49 | ||
|
50 | def load_module(self, name): | |
|
51 | mod = sys.modules.get(name, None) | |
|
52 | if mod: | |
|
53 | return mod | |
|
54 | ||
|
55 | mercurial = sys.modules['mercurial'] | |
|
56 | ||
|
57 | # Unlike the default importer which searches special locations and | |
|
58 | # sys.path, we only look in the directory where "mercurial" was | |
|
59 | # imported from. | |
|
60 | ||
|
61 | # imp.find_module doesn't support submodules (modules with "."). | |
|
62 | # Instead you have to pass the parent package's __path__ attribute | |
|
63 | # as the path argument. | |
|
64 | stem = name.split('.')[-1] | |
|
65 | ||
|
66 | try: | |
|
67 | if modulepolicy == 'py': | |
|
68 | raise ImportError() | |
|
69 | ||
|
70 | modinfo = imp.find_module(stem, mercurial.__path__) | |
|
71 | ||
|
72 | # The Mercurial installer used to copy files from | |
|
73 | # mercurial/pure/*.py to mercurial/*.py. Therefore, it's possible | |
|
74 | # for some installations to have .py files under mercurial/*. | |
|
75 | # Loading Python modules when we expected C versions could result | |
|
76 | # in a) poor performance b) loading a version from a previous | |
|
77 | # Mercurial version, potentially leading to incompatibility. Either | |
|
78 | # scenario is bad. So we verify that modules loaded from | |
|
79 | # mercurial/* are C extensions. If the current policy allows the | |
|
80 | # loading of .py modules, the module will be re-imported from | |
|
81 | # mercurial/pure/* below. | |
|
82 | # TODO uncomment once setup.py is updated to actually install | |
|
83 | # into mercurial/pure. | |
|
84 | #if modinfo[2][2] != imp.C_EXTENSION: | |
|
85 | # raise ImportError('.py version of %s found where C ' | |
|
86 | # 'version should exist' % name) | |
|
87 | ||
|
88 | except ImportError: | |
|
89 | if modulepolicy == 'c': | |
|
90 | raise | |
|
91 | ||
|
92 | # Could not load the C extension and pure Python is allowed. So | |
|
93 | # try to load them. | |
|
94 | from . import pure | |
|
95 | modinfo = imp.find_module(stem, pure.__path__) | |
|
96 | if not modinfo: | |
|
97 | raise ImportError('could not find mercurial module %s' % | |
|
98 | name) | |
|
99 | ||
|
100 | mod = imp.load_module(name, *modinfo) | |
|
101 | sys.modules[name] = mod | |
|
102 | return mod | |
|
103 | ||
|
104 | # We automagically register our custom importer as a side-effect of loading. | |
|
105 | # This is necessary to ensure that any entry points are able to import | |
|
106 | # mercurial.* modules without having to perform this registration themselves. | |
|
107 | if not any(isinstance(x, hgimporter) for x in sys.meta_path): | |
|
108 | # meta_path is used before any implicit finders and before sys.path. | |
|
109 | sys.meta_path.insert(0, hgimporter()) |
@@ -177,11 +177,9 b' def runhg(cmd, env):' | |||
|
177 | 177 | |
|
178 | 178 | version = '' |
|
179 | 179 | |
|
180 | # Execute hg out of this directory with a custom environment which | |
|
181 | # includes the pure Python modules in mercurial/pure. We also take | |
|
182 | # care to not use any hgrc files and do no localization. | |
|
183 | pypath = ['mercurial', os.path.join('mercurial', 'pure')] | |
|
184 | env = {'PYTHONPATH': os.pathsep.join(pypath), | |
|
180 | # Execute hg out of this directory with a custom environment which takes care | |
|
181 | # to not use any hgrc files and do no localization. | |
|
182 | env = {'HGMODULEPOLICY': 'py', | |
|
185 | 183 | 'HGRCPATH': '', |
|
186 | 184 | 'LANGUAGE': 'C'} |
|
187 | 185 | if 'LD_LIBRARY_PATH' in os.environ: |
General Comments 0
You need to be logged in to leave comments.
Login now