来自sh源代码:
# this is a thin wrapper around THIS module (we patch sys.modules[__name__]).
# this is in the case that the user does a "from sh import whatever"
# in other words, they only want to import certain programs, not the whole
# system PATH worth of commands. in this case, we just proxy the
# import lookup to our Environment class
class SelfWrapper(ModuleType):
def __init__(self, self_module, baked_args={}):
# this is super ugly to have to copy attributes like this,
# but it seems to be the only way to make reload() behave
# nicely. if i make these attributes dynamic lookups in
# __getattr__, reload sometimes chokes in weird ways...
for attr in ["__builtins__", "__doc__", "__name__", "__package__"]:
setattr(self, attr, getattr(self_module, attr, None))
# python 3.2 (2.7 and 3.3 work fine) breaks on osx (not ubuntu)
# if we set this to None. and 3.3 needs a value for __path__
self.__path__ = []
self.self_module = self_module
self.env = Environment(globals(), baked_args)
def __setattr__(self, name, value):
if hasattr(self, "env"): self.env[name] = value
ModuleType.__setattr__(self, name, value)
def __getattr__(self, name):
if name == "env": raise AttributeError
return self.env[name]
# accept special keywords argument to define defaults for all operations
# that will be processed with given by return SelfWrapper
def __call__(self, **kwargs):
return SelfWrapper(self.self_module, kwargs)
几行之后,不是主要的
# we're being imported from somewhere
else:
self = sys.modules[__name__]
sys.modules[__name__] = SelfWrapper(self)