Importing a python module without actually executing it

后端 未结 6 2015
抹茶落季
抹茶落季 2020-12-10 01:48

In the context of a complex application, I need to import user-supplied \'scripts\'. Ideally, a script would have

def init():
    blah

def execute():
    mo         


        
6条回答
  •  自闭症患者
    2020-12-10 02:22

    My attempt using the ast module:

    import ast
    
    # which syntax elements are allowed at module level?
    whitelist = [
      # docstring
      lambda x: isinstance(x, ast.Expr) \
                 and isinstance(x.value, ast.Str),
      # import
      lambda x: isinstance(x, ast.Import),
      # class
      lambda x: isinstance(x, ast.ClassDef),
      # function
      lambda x: isinstance(x, ast.FunctionDef),
    ]
    
    def validate(source, required_functions):
      tree = ast.parse(source)
    
      functions = set()
      required_functions = set(required_functions)
    
      for item in tree.body:
        if isinstance(item, ast.FunctionDef):
          functions.add(item.name)
          continue
    
        if all(not checker(item) for checker in whitelist):
          return False
    
      # at least the required functions must be there
      return len(required_functions - functions) == 0
    
    
    if __name__ == "__main__":
      required_funcs = [ "init", "execute", "cleanup" ]
      with open("/tmp/test.py", "rb") as f:
        print("yay!" if validate(f.read(), required_funcs) else "d'oh!")
    

提交回复
热议问题