覆盖Python导入而不会导致受限制的执行模式

时间:2014-10-22 16:06:44

标签: python

我需要覆盖lambda函数(compile())中的默认导入器,以便我可以使用某些模块的替代版本。但是,lambda代码不需要与“受限执行”(RE)一起运行,因为只有授权人员才能生成正在编译的代码。我们还要求能够打开文件,这在RE:

中被阻止
IOError: file() constructor not accessible in restricted mode

但是,为了覆盖导入器,我需要复制__builtin __模块并为__import __分配一个新的导入器。但是,使用__builtin __的备用版本具体是导致RE的原因。

如何在不引起RE副作用的情况下简单地覆盖导入器?

编辑:对于那些没有经历过这种情况并且没有想象力的人:

def copy_module(m):
    x = type(m)(m.__name__, m.__doc__)
    x.__dict__.update(m.__dict__)
    return x

# Make sure we get the module in all situations (depending on where 
# __builtins__ is invoked, it may be a dictionary).
builtins = __import__('__builtin__')

custom_builtins = copy_module(builtins)
custom_builtins.__import__ = __import__

l = """\
with open('/dev/null') as f:
    pass
"""

c = compile(l, 'open_test', 'exec')

globals_ = {
    '__builtins__': custom_builtins, 
    '__name__': '__handler__', 
    '__doc__': None, 
    '__package__': None,
}

locals_ = {}

exec c in globals_, locals_

结果:

Traceback (most recent call last):
  File "import_replace_2.py", line 31, in <module>
    exec c in globals_, locals_
  File "open_test", line 1, in <module>
IOError: file() constructor not accessible in restricted mode

1 个答案:

答案 0 :(得分:-2)

我没有收到RE错误。来自python docs:

  

__ import __ :此函数由import语句调用。它可以替换(通过导入__builtin__模块并分配给__builtin __.__ import__)以更改import语句的语义

以下适用于我(它与标准导入相同,但用数学代替垃圾邮件。

>>> import builtins
>>> _import_alias = __import__
>>> builtins.__import__ = lambda module, *args, **kwargs: _import_alias(module.replace("spam", "math"), *args, **kwargs)
>>> import spam as math
>>> math.factorial(10)

您必须创建__import__的别名并覆盖builtins.__import__,而不是标准__import__