##// END OF EJS Templates
Add endswithsep() and use it instead of using os.sep and os.altsep directly....
Add endswithsep() and use it instead of using os.sep and os.altsep directly. This change is intended to allow hooking endswithsep() by win32mbcs extension for MBCS support.

File last commit:

r5639:7dd5cf9d default
r5843:83c354c4 default
Show More
demandimport.py
131 lines | 4.3 KiB | text/x-python | PythonLexer
Matt Mackall
Replace demandload with new demandimport
r3877 # demandimport.py - global demand-loading of modules for Mercurial
#
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
Matt Mackall
Replace demandload with new demandimport
r3877 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
'''
demandimport - automatic demandloading of modules
To enable this module, do:
import demandimport; demandimport.enable()
Imports of the following forms will be demand-loaded:
import a, b.c
import a.b as c
from a import b,c # a will be loaded immediately
These imports will not be delayed:
from a import *
b = __import__(a)
'''
_origimport = __import__
class _demandmod(object):
"""module demand-loader and proxy"""
def __init__(self, name, globals, locals):
if '.' in name:
head, rest = name.split('.', 1)
after = [rest]
else:
head = name
after = []
Benoit Boissinot
use parent.__setattr__ instead of __dict__
r3896 object.__setattr__(self, "_data", (head, globals, locals, after))
object.__setattr__(self, "_module", None)
Matt Mackall
Replace demandload with new demandimport
r3877 def _extend(self, name):
"""add to the list of submodules to load"""
self._data[3].append(name)
def _load(self):
if not self._module:
head, globals, locals, after = self._data
mod = _origimport(head, globals, locals)
# load submodules
Matt Mackall
demandimport: fix import x.y.z as a when x.y is already imported.
r3921 def subload(mod, p):
h, t = p, None
if '.' in p:
h, t = p.split('.', 1)
if not hasattr(mod, h):
setattr(mod, h, _demandmod(p, mod.__dict__, mod.__dict__))
Brendan Cully
demandimport: handle already-loaded nested modules in subload
r3926 elif t:
Matt Mackall
demandimport: fix import x.y.z as a when x.y is already imported.
r3921 subload(getattr(mod, h), t)
Matt Mackall
Replace demandload with new demandimport
r3877 for x in after:
Matt Mackall
demandimport: fix import x.y.z as a when x.y is already imported.
r3921 subload(mod, x)
Matt Mackall
Replace demandload with new demandimport
r3877 # are we in the locals dictionary still?
if locals and locals.get(head) == self:
locals[head] = mod
Benoit Boissinot
use parent.__setattr__ instead of __dict__
r3896 object.__setattr__(self, "_module", mod)
Matt Mackall
demandimport: fix issue579 and add a test...
r4631
Matt Mackall
Replace demandload with new demandimport
r3877 def __repr__(self):
Matt Mackall
demandimport: fix issue579 and add a test...
r4631 if self._module:
return "<proxied module '%s'>" % self._data[0]
Matt Mackall
Replace demandload with new demandimport
r3877 return "<unloaded module '%s'>" % self._data[0]
def __call__(self, *args, **kwargs):
Matt Mackall
demandload: give better diagnostic for call of an unloaded module
r5639 raise TypeError("%s object is not callable" % repr(self))
Brendan Cully
Make demandimport pass all tests on python2.5.
r3903 def __getattribute__(self, attr):
if attr in ('_data', '_extend', '_load', '_module'):
return object.__getattribute__(self, attr)
Matt Mackall
Replace demandload with new demandimport
r3877 self._load()
return getattr(self._module, attr)
def __setattr__(self, attr, val):
self._load()
setattr(self._module, attr, val)
def _demandimport(name, globals=None, locals=None, fromlist=None):
if not locals or name in ignore or fromlist == ('*',):
# these cases we can't really delay
return _origimport(name, globals, locals, fromlist)
elif not fromlist:
# import a [as b]
if '.' in name: # a.b
base, rest = name.split('.', 1)
Brendan Cully
Make demandimport pass all tests on python2.5.
r3903 # email.__init__ loading email.mime
if globals and globals.get('__name__', None) == base:
return _origimport(name, globals, locals, fromlist)
Matt Mackall
Replace demandload with new demandimport
r3877 # if a is already demand-loaded, add b to its submodule list
if base in locals:
if isinstance(locals[base], _demandmod):
locals[base]._extend(rest)
return locals[base]
return _demandmod(name, globals, locals)
else:
# from a import b,c,d
mod = _origimport(name, globals, locals)
# recurse down the module chain
for comp in name.split('.')[1:]:
Lee Cantey
Fix for demandimport.py and Windows compiled version....
r4626 if not hasattr(mod, comp):
setattr(mod, comp, _demandmod(comp, mod.__dict__, mod.__dict__))
Matt Mackall
Replace demandload with new demandimport
r3877 mod = getattr(mod, comp)
for x in fromlist:
# set requested submodules for demand load
if not(hasattr(mod, x)):
Matt Mackall
demandimport: fix issue579 and add a test...
r4631 setattr(mod, x, _demandmod(x, mod.__dict__, locals))
Matt Mackall
Replace demandload with new demandimport
r3877 return mod
Patrick Mezard
demandimport: ignore resource module, not available under Windows.
r5098 ignore = [
'_hashlib',
'_xmlplus',
'fcntl',
'win32com.gen_py',
# imported by tarfile, not available under Windows
'pwd',
'grp',
# imported by profile, itself imported by hotshot.stats,
# not available under Windows
'resource',
]
Matt Mackall
Replace demandload with new demandimport
r3877
def enable():
"enable global demand-loading of modules"
__builtins__["__import__"] = _demandimport
def disable():
"disable global demand-loading of modules"
__builtins__["__import__"] = _origimport