##// END OF EJS Templates
demandimport: drop Py3 workarounds from Py2 implementation
Yuya Nishihara -
r33530:05e3fa25 default
parent child Browse files
Show More
@@ -1,312 +1,302 b''
1 # demandimport.py - global demand-loading of modules for Mercurial
1 # demandimport.py - global demand-loading of modules for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
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.
6 # GNU General Public License version 2 or any later version.
7
7
8 '''
8 '''
9 demandimport - automatic demandloading of modules
9 demandimport - automatic demandloading of modules
10
10
11 To enable this module, do:
11 To enable this module, do:
12
12
13 import demandimport; demandimport.enable()
13 import demandimport; demandimport.enable()
14
14
15 Imports of the following forms will be demand-loaded:
15 Imports of the following forms will be demand-loaded:
16
16
17 import a, b.c
17 import a, b.c
18 import a.b as c
18 import a.b as c
19 from a import b,c # a will be loaded immediately
19 from a import b,c # a will be loaded immediately
20
20
21 These imports will not be delayed:
21 These imports will not be delayed:
22
22
23 from a import *
23 from a import *
24 b = __import__(a)
24 b = __import__(a)
25 '''
25 '''
26
26
27 from __future__ import absolute_import
27 from __future__ import absolute_import
28
28
29 import __builtin__ as builtins
29 import contextlib
30 import contextlib
30 import os
31 import os
31 import sys
32 import sys
32
33
33 # __builtin__ in Python 2, builtins in Python 3.
34 try:
35 import __builtin__ as builtins
36 except ImportError:
37 import builtins
38
39 contextmanager = contextlib.contextmanager
34 contextmanager = contextlib.contextmanager
40
35
41 _origimport = __import__
36 _origimport = __import__
42
37
43 nothing = object()
38 nothing = object()
44
39
45 # Python 3 doesn't have relative imports nor level -1.
46 level = -1
47 if sys.version_info[0] >= 3:
48 level = 0
49
50 def _hgextimport(importfunc, name, globals, *args, **kwargs):
40 def _hgextimport(importfunc, name, globals, *args, **kwargs):
51 try:
41 try:
52 return importfunc(name, globals, *args, **kwargs)
42 return importfunc(name, globals, *args, **kwargs)
53 except ImportError:
43 except ImportError:
54 if not globals:
44 if not globals:
55 raise
45 raise
56 # extensions are loaded with "hgext_" prefix
46 # extensions are loaded with "hgext_" prefix
57 hgextname = 'hgext_%s' % name
47 hgextname = 'hgext_%s' % name
58 nameroot = hgextname.split('.', 1)[0]
48 nameroot = hgextname.split('.', 1)[0]
59 contextroot = globals.get('__name__', '').split('.', 1)[0]
49 contextroot = globals.get('__name__', '').split('.', 1)[0]
60 if nameroot != contextroot:
50 if nameroot != contextroot:
61 raise
51 raise
62 # retry to import with "hgext_" prefix
52 # retry to import with "hgext_" prefix
63 return importfunc(hgextname, globals, *args, **kwargs)
53 return importfunc(hgextname, globals, *args, **kwargs)
64
54
65 class _demandmod(object):
55 class _demandmod(object):
66 """module demand-loader and proxy
56 """module demand-loader and proxy
67
57
68 Specify 1 as 'level' argument at construction, to import module
58 Specify 1 as 'level' argument at construction, to import module
69 relatively.
59 relatively.
70 """
60 """
71
61
72 def __init__(self, name, globals, locals, level):
62 def __init__(self, name, globals, locals, level):
73 if '.' in name:
63 if '.' in name:
74 head, rest = name.split('.', 1)
64 head, rest = name.split('.', 1)
75 after = [rest]
65 after = [rest]
76 else:
66 else:
77 head = name
67 head = name
78 after = []
68 after = []
79 object.__setattr__(self, r"_data",
69 object.__setattr__(self, r"_data",
80 (head, globals, locals, after, level, set()))
70 (head, globals, locals, after, level, set()))
81 object.__setattr__(self, r"_module", None)
71 object.__setattr__(self, r"_module", None)
82
72
83 def _extend(self, name):
73 def _extend(self, name):
84 """add to the list of submodules to load"""
74 """add to the list of submodules to load"""
85 self._data[3].append(name)
75 self._data[3].append(name)
86
76
87 def _addref(self, name):
77 def _addref(self, name):
88 """Record that the named module ``name`` imports this module.
78 """Record that the named module ``name`` imports this module.
89
79
90 References to this proxy class having the name of this module will be
80 References to this proxy class having the name of this module will be
91 replaced at module load time. We assume the symbol inside the importing
81 replaced at module load time. We assume the symbol inside the importing
92 module is identical to the "head" name of this module. We don't
82 module is identical to the "head" name of this module. We don't
93 actually know if "as X" syntax is being used to change the symbol name
83 actually know if "as X" syntax is being used to change the symbol name
94 because this information isn't exposed to __import__.
84 because this information isn't exposed to __import__.
95 """
85 """
96 self._data[5].add(name)
86 self._data[5].add(name)
97
87
98 def _load(self):
88 def _load(self):
99 if not self._module:
89 if not self._module:
100 head, globals, locals, after, level, modrefs = self._data
90 head, globals, locals, after, level, modrefs = self._data
101 mod = _hgextimport(_origimport, head, globals, locals, None, level)
91 mod = _hgextimport(_origimport, head, globals, locals, None, level)
102 if mod is self:
92 if mod is self:
103 # In this case, _hgextimport() above should imply
93 # In this case, _hgextimport() above should imply
104 # _demandimport(). Otherwise, _hgextimport() never
94 # _demandimport(). Otherwise, _hgextimport() never
105 # returns _demandmod. This isn't intentional behavior,
95 # returns _demandmod. This isn't intentional behavior,
106 # in fact. (see also issue5304 for detail)
96 # in fact. (see also issue5304 for detail)
107 #
97 #
108 # If self._module is already bound at this point, self
98 # If self._module is already bound at this point, self
109 # should be already _load()-ed while _hgextimport().
99 # should be already _load()-ed while _hgextimport().
110 # Otherwise, there is no way to import actual module
100 # Otherwise, there is no way to import actual module
111 # as expected, because (re-)invoking _hgextimport()
101 # as expected, because (re-)invoking _hgextimport()
112 # should cause same result.
102 # should cause same result.
113 # This is reason why _load() returns without any more
103 # This is reason why _load() returns without any more
114 # setup but assumes self to be already bound.
104 # setup but assumes self to be already bound.
115 mod = self._module
105 mod = self._module
116 assert mod and mod is not self, "%s, %s" % (self, mod)
106 assert mod and mod is not self, "%s, %s" % (self, mod)
117 return
107 return
118
108
119 # load submodules
109 # load submodules
120 def subload(mod, p):
110 def subload(mod, p):
121 h, t = p, None
111 h, t = p, None
122 if '.' in p:
112 if '.' in p:
123 h, t = p.split('.', 1)
113 h, t = p.split('.', 1)
124 if getattr(mod, h, nothing) is nothing:
114 if getattr(mod, h, nothing) is nothing:
125 setattr(mod, h, _demandmod(p, mod.__dict__, mod.__dict__,
115 setattr(mod, h, _demandmod(p, mod.__dict__, mod.__dict__,
126 level=1))
116 level=1))
127 elif t:
117 elif t:
128 subload(getattr(mod, h), t)
118 subload(getattr(mod, h), t)
129
119
130 for x in after:
120 for x in after:
131 subload(mod, x)
121 subload(mod, x)
132
122
133 # Replace references to this proxy instance with the actual module.
123 # Replace references to this proxy instance with the actual module.
134 if locals:
124 if locals:
135 if locals.get(head) is self:
125 if locals.get(head) is self:
136 locals[head] = mod
126 locals[head] = mod
137 elif locals.get(head + r'mod') is self:
127 elif locals.get(head + r'mod') is self:
138 locals[head + r'mod'] = mod
128 locals[head + r'mod'] = mod
139
129
140 for modname in modrefs:
130 for modname in modrefs:
141 modref = sys.modules.get(modname, None)
131 modref = sys.modules.get(modname, None)
142 if modref and getattr(modref, head, None) is self:
132 if modref and getattr(modref, head, None) is self:
143 setattr(modref, head, mod)
133 setattr(modref, head, mod)
144
134
145 object.__setattr__(self, r"_module", mod)
135 object.__setattr__(self, r"_module", mod)
146
136
147 def __repr__(self):
137 def __repr__(self):
148 if self._module:
138 if self._module:
149 return "<proxied module '%s'>" % self._data[0]
139 return "<proxied module '%s'>" % self._data[0]
150 return "<unloaded module '%s'>" % self._data[0]
140 return "<unloaded module '%s'>" % self._data[0]
151
141
152 def __call__(self, *args, **kwargs):
142 def __call__(self, *args, **kwargs):
153 raise TypeError("%s object is not callable" % repr(self))
143 raise TypeError("%s object is not callable" % repr(self))
154
144
155 def __getattr__(self, attr):
145 def __getattr__(self, attr):
156 self._load()
146 self._load()
157 return getattr(self._module, attr)
147 return getattr(self._module, attr)
158
148
159 def __setattr__(self, attr, val):
149 def __setattr__(self, attr, val):
160 self._load()
150 self._load()
161 setattr(self._module, attr, val)
151 setattr(self._module, attr, val)
162
152
163 @property
153 @property
164 def __dict__(self):
154 def __dict__(self):
165 self._load()
155 self._load()
166 return self._module.__dict__
156 return self._module.__dict__
167
157
168 @property
158 @property
169 def __doc__(self):
159 def __doc__(self):
170 self._load()
160 self._load()
171 return self._module.__doc__
161 return self._module.__doc__
172
162
173 _pypy = '__pypy__' in sys.builtin_module_names
163 _pypy = '__pypy__' in sys.builtin_module_names
174
164
175 def _demandimport(name, globals=None, locals=None, fromlist=None, level=level):
165 def _demandimport(name, globals=None, locals=None, fromlist=None, level=-1):
176 if locals is None or name in ignore or fromlist == ('*',):
166 if locals is None or name in ignore or fromlist == ('*',):
177 # these cases we can't really delay
167 # these cases we can't really delay
178 return _hgextimport(_origimport, name, globals, locals, fromlist, level)
168 return _hgextimport(_origimport, name, globals, locals, fromlist, level)
179 elif not fromlist:
169 elif not fromlist:
180 # import a [as b]
170 # import a [as b]
181 if '.' in name: # a.b
171 if '.' in name: # a.b
182 base, rest = name.split('.', 1)
172 base, rest = name.split('.', 1)
183 # email.__init__ loading email.mime
173 # email.__init__ loading email.mime
184 if globals and globals.get('__name__', None) == base:
174 if globals and globals.get('__name__', None) == base:
185 return _origimport(name, globals, locals, fromlist, level)
175 return _origimport(name, globals, locals, fromlist, level)
186 # if a is already demand-loaded, add b to its submodule list
176 # if a is already demand-loaded, add b to its submodule list
187 if base in locals:
177 if base in locals:
188 if isinstance(locals[base], _demandmod):
178 if isinstance(locals[base], _demandmod):
189 locals[base]._extend(rest)
179 locals[base]._extend(rest)
190 return locals[base]
180 return locals[base]
191 return _demandmod(name, globals, locals, level)
181 return _demandmod(name, globals, locals, level)
192 else:
182 else:
193 # There is a fromlist.
183 # There is a fromlist.
194 # from a import b,c,d
184 # from a import b,c,d
195 # from . import b,c,d
185 # from . import b,c,d
196 # from .a import b,c,d
186 # from .a import b,c,d
197
187
198 # level == -1: relative and absolute attempted (Python 2 only).
188 # level == -1: relative and absolute attempted (Python 2 only).
199 # level >= 0: absolute only (Python 2 w/ absolute_import and Python 3).
189 # level >= 0: absolute only (Python 2 w/ absolute_import and Python 3).
200 # The modern Mercurial convention is to use absolute_import everywhere,
190 # The modern Mercurial convention is to use absolute_import everywhere,
201 # so modern Mercurial code will have level >= 0.
191 # so modern Mercurial code will have level >= 0.
202
192
203 # The name of the module the import statement is located in.
193 # The name of the module the import statement is located in.
204 globalname = globals.get('__name__')
194 globalname = globals.get('__name__')
205
195
206 def processfromitem(mod, attr):
196 def processfromitem(mod, attr):
207 """Process an imported symbol in the import statement.
197 """Process an imported symbol in the import statement.
208
198
209 If the symbol doesn't exist in the parent module, and if the
199 If the symbol doesn't exist in the parent module, and if the
210 parent module is a package, it must be a module. We set missing
200 parent module is a package, it must be a module. We set missing
211 modules up as _demandmod instances.
201 modules up as _demandmod instances.
212 """
202 """
213 symbol = getattr(mod, attr, nothing)
203 symbol = getattr(mod, attr, nothing)
214 nonpkg = getattr(mod, '__path__', nothing) is nothing
204 nonpkg = getattr(mod, '__path__', nothing) is nothing
215 if symbol is nothing:
205 if symbol is nothing:
216 if nonpkg:
206 if nonpkg:
217 # do not try relative import, which would raise ValueError,
207 # do not try relative import, which would raise ValueError,
218 # and leave unknown attribute as the default __import__()
208 # and leave unknown attribute as the default __import__()
219 # would do. the missing attribute will be detected later
209 # would do. the missing attribute will be detected later
220 # while processing the import statement.
210 # while processing the import statement.
221 return
211 return
222 mn = '%s.%s' % (mod.__name__, attr)
212 mn = '%s.%s' % (mod.__name__, attr)
223 if mn in ignore:
213 if mn in ignore:
224 importfunc = _origimport
214 importfunc = _origimport
225 else:
215 else:
226 importfunc = _demandmod
216 importfunc = _demandmod
227 symbol = importfunc(attr, mod.__dict__, locals, level=1)
217 symbol = importfunc(attr, mod.__dict__, locals, level=1)
228 setattr(mod, attr, symbol)
218 setattr(mod, attr, symbol)
229
219
230 # Record the importing module references this symbol so we can
220 # Record the importing module references this symbol so we can
231 # replace the symbol with the actual module instance at load
221 # replace the symbol with the actual module instance at load
232 # time.
222 # time.
233 if globalname and isinstance(symbol, _demandmod):
223 if globalname and isinstance(symbol, _demandmod):
234 symbol._addref(globalname)
224 symbol._addref(globalname)
235
225
236 def chainmodules(rootmod, modname):
226 def chainmodules(rootmod, modname):
237 # recurse down the module chain, and return the leaf module
227 # recurse down the module chain, and return the leaf module
238 mod = rootmod
228 mod = rootmod
239 for comp in modname.split('.')[1:]:
229 for comp in modname.split('.')[1:]:
240 if getattr(mod, comp, nothing) is nothing:
230 if getattr(mod, comp, nothing) is nothing:
241 setattr(mod, comp, _demandmod(comp, mod.__dict__,
231 setattr(mod, comp, _demandmod(comp, mod.__dict__,
242 mod.__dict__, level=1))
232 mod.__dict__, level=1))
243 mod = getattr(mod, comp)
233 mod = getattr(mod, comp)
244 return mod
234 return mod
245
235
246 if level >= 0:
236 if level >= 0:
247 if name:
237 if name:
248 # "from a import b" or "from .a import b" style
238 # "from a import b" or "from .a import b" style
249 rootmod = _hgextimport(_origimport, name, globals, locals,
239 rootmod = _hgextimport(_origimport, name, globals, locals,
250 level=level)
240 level=level)
251 mod = chainmodules(rootmod, name)
241 mod = chainmodules(rootmod, name)
252 elif _pypy:
242 elif _pypy:
253 # PyPy's __import__ throws an exception if invoked
243 # PyPy's __import__ throws an exception if invoked
254 # with an empty name and no fromlist. Recreate the
244 # with an empty name and no fromlist. Recreate the
255 # desired behaviour by hand.
245 # desired behaviour by hand.
256 mn = globalname
246 mn = globalname
257 mod = sys.modules[mn]
247 mod = sys.modules[mn]
258 if getattr(mod, '__path__', nothing) is nothing:
248 if getattr(mod, '__path__', nothing) is nothing:
259 mn = mn.rsplit('.', 1)[0]
249 mn = mn.rsplit('.', 1)[0]
260 mod = sys.modules[mn]
250 mod = sys.modules[mn]
261 if level > 1:
251 if level > 1:
262 mn = mn.rsplit('.', level - 1)[0]
252 mn = mn.rsplit('.', level - 1)[0]
263 mod = sys.modules[mn]
253 mod = sys.modules[mn]
264 else:
254 else:
265 mod = _hgextimport(_origimport, name, globals, locals,
255 mod = _hgextimport(_origimport, name, globals, locals,
266 level=level)
256 level=level)
267
257
268 for x in fromlist:
258 for x in fromlist:
269 processfromitem(mod, x)
259 processfromitem(mod, x)
270
260
271 return mod
261 return mod
272
262
273 # But, we still need to support lazy loading of standard library and 3rd
263 # But, we still need to support lazy loading of standard library and 3rd
274 # party modules. So handle level == -1.
264 # party modules. So handle level == -1.
275 mod = _hgextimport(_origimport, name, globals, locals)
265 mod = _hgextimport(_origimport, name, globals, locals)
276 mod = chainmodules(mod, name)
266 mod = chainmodules(mod, name)
277
267
278 for x in fromlist:
268 for x in fromlist:
279 processfromitem(mod, x)
269 processfromitem(mod, x)
280
270
281 return mod
271 return mod
282
272
283 ignore = []
273 ignore = []
284
274
285 def init(ignorelist):
275 def init(ignorelist):
286 global ignore
276 global ignore
287 ignore = ignorelist
277 ignore = ignorelist
288
278
289 def isenabled():
279 def isenabled():
290 return builtins.__import__ == _demandimport
280 return builtins.__import__ == _demandimport
291
281
292 def enable():
282 def enable():
293 "enable global demand-loading of modules"
283 "enable global demand-loading of modules"
294 if os.environ.get('HGDEMANDIMPORT') != 'disable':
284 if os.environ.get('HGDEMANDIMPORT') != 'disable':
295 builtins.__import__ = _demandimport
285 builtins.__import__ = _demandimport
296
286
297 def disable():
287 def disable():
298 "disable global demand-loading of modules"
288 "disable global demand-loading of modules"
299 builtins.__import__ = _origimport
289 builtins.__import__ = _origimport
300
290
301 @contextmanager
291 @contextmanager
302 def deactivated():
292 def deactivated():
303 "context manager for disabling demandimport in 'with' blocks"
293 "context manager for disabling demandimport in 'with' blocks"
304 demandenabled = isenabled()
294 demandenabled = isenabled()
305 if demandenabled:
295 if demandenabled:
306 disable()
296 disable()
307
297
308 try:
298 try:
309 yield
299 yield
310 finally:
300 finally:
311 if demandenabled:
301 if demandenabled:
312 enable()
302 enable()
@@ -1,46 +1,48 b''
1 #require test-repo
1 #require test-repo
2
2
3 $ . "$TESTDIR/helpers-testrepo.sh"
3 $ . "$TESTDIR/helpers-testrepo.sh"
4 $ cd "$TESTDIR"/..
4 $ cd "$TESTDIR"/..
5
5
6 $ testrepohg files 'set:(**.py)' | sed 's|\\|/|g' \
6 $ testrepohg files 'set:(**.py)' \
7 > | xargs $PYTHON contrib/check-py3-compat.py
7 > -X hgdemandimport/demandimportpy2.py \
8 > | sed 's|\\|/|g' | xargs $PYTHON contrib/check-py3-compat.py
8 contrib/python-zstandard/setup.py not using absolute_import
9 contrib/python-zstandard/setup.py not using absolute_import
9 contrib/python-zstandard/setup_zstd.py not using absolute_import
10 contrib/python-zstandard/setup_zstd.py not using absolute_import
10 contrib/python-zstandard/tests/common.py not using absolute_import
11 contrib/python-zstandard/tests/common.py not using absolute_import
11 contrib/python-zstandard/tests/test_buffer_util.py not using absolute_import
12 contrib/python-zstandard/tests/test_buffer_util.py not using absolute_import
12 contrib/python-zstandard/tests/test_compressor.py not using absolute_import
13 contrib/python-zstandard/tests/test_compressor.py not using absolute_import
13 contrib/python-zstandard/tests/test_compressor_fuzzing.py not using absolute_import
14 contrib/python-zstandard/tests/test_compressor_fuzzing.py not using absolute_import
14 contrib/python-zstandard/tests/test_data_structures.py not using absolute_import
15 contrib/python-zstandard/tests/test_data_structures.py not using absolute_import
15 contrib/python-zstandard/tests/test_data_structures_fuzzing.py not using absolute_import
16 contrib/python-zstandard/tests/test_data_structures_fuzzing.py not using absolute_import
16 contrib/python-zstandard/tests/test_decompressor.py not using absolute_import
17 contrib/python-zstandard/tests/test_decompressor.py not using absolute_import
17 contrib/python-zstandard/tests/test_decompressor_fuzzing.py not using absolute_import
18 contrib/python-zstandard/tests/test_decompressor_fuzzing.py not using absolute_import
18 contrib/python-zstandard/tests/test_estimate_sizes.py not using absolute_import
19 contrib/python-zstandard/tests/test_estimate_sizes.py not using absolute_import
19 contrib/python-zstandard/tests/test_module_attributes.py not using absolute_import
20 contrib/python-zstandard/tests/test_module_attributes.py not using absolute_import
20 contrib/python-zstandard/tests/test_train_dictionary.py not using absolute_import
21 contrib/python-zstandard/tests/test_train_dictionary.py not using absolute_import
21 i18n/check-translation.py not using absolute_import
22 i18n/check-translation.py not using absolute_import
22 setup.py not using absolute_import
23 setup.py not using absolute_import
23 tests/test-demandimport.py not using absolute_import
24 tests/test-demandimport.py not using absolute_import
24
25
25 #if py3exe
26 #if py3exe
26 $ testrepohg files 'set:(**.py) - grep(pygments)' \
27 $ testrepohg files 'set:(**.py) - grep(pygments)' \
28 > -X hgdemandimport/demandimportpy2.py \
27 > -X hgext/fsmonitor/pywatchman \
29 > -X hgext/fsmonitor/pywatchman \
28 > | sed 's|\\|/|g' | xargs $PYTHON3 contrib/check-py3-compat.py \
30 > | sed 's|\\|/|g' | xargs $PYTHON3 contrib/check-py3-compat.py \
29 > | sed 's/[0-9][0-9]*)$/*)/'
31 > | sed 's/[0-9][0-9]*)$/*)/'
30 hgext/convert/transport.py: error importing: <*Error> No module named 'svn.client' (error at transport.py:*) (glob)
32 hgext/convert/transport.py: error importing: <*Error> No module named 'svn.client' (error at transport.py:*) (glob)
31 mercurial/cffi/bdiff.py: error importing: <ImportError> cannot import name '_bdiff' (error at bdiff.py:*)
33 mercurial/cffi/bdiff.py: error importing: <ImportError> cannot import name '_bdiff' (error at bdiff.py:*)
32 mercurial/cffi/bdiffbuild.py: error importing: <ImportError> No module named 'cffi' (error at bdiffbuild.py:*)
34 mercurial/cffi/bdiffbuild.py: error importing: <ImportError> No module named 'cffi' (error at bdiffbuild.py:*)
33 mercurial/cffi/mpatch.py: error importing: <ImportError> cannot import name '_mpatch' (error at mpatch.py:*)
35 mercurial/cffi/mpatch.py: error importing: <ImportError> cannot import name '_mpatch' (error at mpatch.py:*)
34 mercurial/cffi/mpatchbuild.py: error importing: <ImportError> No module named 'cffi' (error at mpatchbuild.py:*)
36 mercurial/cffi/mpatchbuild.py: error importing: <ImportError> No module named 'cffi' (error at mpatchbuild.py:*)
35 mercurial/cffi/osutilbuild.py: error importing: <ImportError> No module named 'cffi' (error at osutilbuild.py:*)
37 mercurial/cffi/osutilbuild.py: error importing: <ImportError> No module named 'cffi' (error at osutilbuild.py:*)
36 mercurial/scmwindows.py: error importing: <*Error> No module named 'msvcrt' (error at win32.py:*) (glob)
38 mercurial/scmwindows.py: error importing: <*Error> No module named 'msvcrt' (error at win32.py:*) (glob)
37 mercurial/win32.py: error importing: <*Error> No module named 'msvcrt' (error at win32.py:*) (glob)
39 mercurial/win32.py: error importing: <*Error> No module named 'msvcrt' (error at win32.py:*) (glob)
38 mercurial/windows.py: error importing: <*Error> No module named 'msvcrt' (error at windows.py:*) (glob)
40 mercurial/windows.py: error importing: <*Error> No module named 'msvcrt' (error at windows.py:*) (glob)
39
41
40 #endif
42 #endif
41
43
42 #if py3exe py3pygments
44 #if py3exe py3pygments
43 $ testrepohg files 'set:(**.py) and grep(pygments)' | sed 's|\\|/|g' \
45 $ testrepohg files 'set:(**.py) and grep(pygments)' | sed 's|\\|/|g' \
44 > | xargs $PYTHON3 contrib/check-py3-compat.py \
46 > | xargs $PYTHON3 contrib/check-py3-compat.py \
45 > | sed 's/[0-9][0-9]*)$/*)/'
47 > | sed 's/[0-9][0-9]*)$/*)/'
46 #endif
48 #endif
General Comments 0
You need to be logged in to leave comments. Login now