comparison mercurial/demandimport.py @ 21290:74be3fb1e3b8

demandimport: pass proper level to __import__ in Python 3 demandimport was failing in Python 3 with a ValueError because __import__'s level=-1 has gone away (-1 means to try both relative and absolute imports and relative imports don't exist in Python 3). With this patch, demandimport still doesn't work in Python 3 (it fails when importing a non-package module).
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 10 May 2014 14:57:25 -0700
parents 54af51c18c4c
children 2205d00b6d2b
comparison
equal deleted inserted replaced
21289:c3784e3c3e8d 21290:74be3fb1e3b8
22 22
23 from a import * 23 from a import *
24 b = __import__(a) 24 b = __import__(a)
25 ''' 25 '''
26 26
27 import __builtin__, os 27 import __builtin__, os, sys
28 _origimport = __import__ 28 _origimport = __import__
29 29
30 nothing = object() 30 nothing = object()
31 31
32 try: 32 try:
33 _origimport(__builtin__.__name__, {}, {}, None, -1) 33 # Python 3 doesn't have relative imports nor level -1.
34 level = -1
35 if sys.version_info[0] >= 3:
36 level = 0
37 _origimport(__builtin__.__name__, {}, {}, None, level)
34 except TypeError: # no level argument 38 except TypeError: # no level argument
35 def _import(name, globals, locals, fromlist, level): 39 def _import(name, globals, locals, fromlist, level):
36 "call _origimport with no level argument" 40 "call _origimport with no level argument"
37 return _origimport(name, globals, locals, fromlist) 41 return _origimport(name, globals, locals, fromlist)
38 else: 42 else:
53 # retry to import with "hgext_" prefix 57 # retry to import with "hgext_" prefix
54 return importfunc(hgextname, globals, *args) 58 return importfunc(hgextname, globals, *args)
55 59
56 class _demandmod(object): 60 class _demandmod(object):
57 """module demand-loader and proxy""" 61 """module demand-loader and proxy"""
58 def __init__(self, name, globals, locals, level=-1): 62 def __init__(self, name, globals, locals, level=level):
59 if '.' in name: 63 if '.' in name:
60 head, rest = name.split('.', 1) 64 head, rest = name.split('.', 1)
61 after = [rest] 65 after = [rest]
62 else: 66 else:
63 head = name 67 head = name
103 return getattr(self._module, attr) 107 return getattr(self._module, attr)
104 def __setattr__(self, attr, val): 108 def __setattr__(self, attr, val):
105 self._load() 109 self._load()
106 setattr(self._module, attr, val) 110 setattr(self._module, attr, val)
107 111
108 def _demandimport(name, globals=None, locals=None, fromlist=None, level=-1): 112 def _demandimport(name, globals=None, locals=None, fromlist=None, level=level):
109 if not locals or name in ignore or fromlist == ('*',): 113 if not locals or name in ignore or fromlist == ('*',):
110 # these cases we can't really delay 114 # these cases we can't really delay
111 return _hgextimport(_import, name, globals, locals, fromlist, level) 115 return _hgextimport(_import, name, globals, locals, fromlist, level)
112 elif not fromlist: 116 elif not fromlist:
113 # import a [as b] 117 # import a [as b]