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 | version = '' |
|
178 | version = '' | |
179 |
|
179 | |||
180 | # Execute hg out of this directory with a custom environment which |
|
180 | # Execute hg out of this directory with a custom environment which takes care | |
181 | # includes the pure Python modules in mercurial/pure. We also take |
|
181 | # to not use any hgrc files and do no localization. | |
182 | # care to not use any hgrc files and do no localization. |
|
182 | env = {'HGMODULEPOLICY': 'py', | |
183 | pypath = ['mercurial', os.path.join('mercurial', 'pure')] |
|
|||
184 | env = {'PYTHONPATH': os.pathsep.join(pypath), |
|
|||
185 | 'HGRCPATH': '', |
|
183 | 'HGRCPATH': '', | |
186 | 'LANGUAGE': 'C'} |
|
184 | 'LANGUAGE': 'C'} | |
187 | if 'LD_LIBRARY_PATH' in os.environ: |
|
185 | if 'LD_LIBRARY_PATH' in os.environ: |
General Comments 0
You need to be logged in to leave comments.
Login now