用python做配置文件
受zig语言启发,图灵完备的配置文件可能是个不错的选择,只要严格限制权限就行。
用importlib
目标:
- 禁止二次导入,去除import语句
- 提供模块白名单、黑名单
import ast from sys import meta_path from importlib.abc import Loader, MetaPathFinder from importlib.util import spec_from_loader, find_spec from mocap_wrapper.logger import Log class CustomLoader(Loader): def __init__(self, original_spec): self.original_spec = original_spec def create_module(self, spec): # 使用默认模块创建逻辑 return None def exec_module(self, module): # 获取原始源代码 source = self.original_spec.loader.get_source(module.__name__) if source is None: raise ImportError(f"Can't get module {module.__name__} source code.") # 解析为AST并删除所有import节点 tree = ast.parse(source) transformer = ImportRemover() modified_tree = transformer.visit(tree) ast.fix_missing_locations(modified_tree) # 修复AST节点位置 # 编译修改后的AST code = compile(modified_tree, module.__spec__.origin, 'exec') # 注入system函数到模块的全局命名空间 # module.system = os.system # 执行修改后的代码 exec(code, module.__dict__) class ImportRemover(ast.NodeTransformer): ... # def visit_Import(self, node): # """删除所有Import节点""" # return None # def visit_ImportFrom(self, node): # """删除所有ImportFrom节点""" # return None class CustomFinder(MetaPathFinder): def find_spec(self, fullname, path, target=None): Log.debug(fullname) # 仅处理特定模块 # if not fullname.startswith('mocap_wrapper.config'): # return None # 临时移除 CustomFinder 以避免递归 meta_path.remove(self) try: # 查找原始模块的Spec original_spec = find_spec(fullname) finally: # 重新添加 CustomFinder meta_path.insert(0, self) if not original_spec: # 未找到 return None # 使用自定义Loader替换原加载器 loader = CustomLoader(original_spec) return spec_from_loader( fullname, loader, origin=original_spec.origin ) class Import: singleton = None @staticmethod def init(): """注册自定义Finder到meta_path""" if not Import.singleton: Import.singleton = CustomFinder() if Import.singleton not in meta_path: meta_path.insert(0, Import.singleton) Log.debug(meta_path) @staticmethod def reset(): if Import.singleton in meta_path: meta_path.remove(Import.singleton) Import.singleton = None Log.debug(meta_path) def test(): Import.init() import mocap_wrapper.config.template as c Import.reset() Log.debug(c.Aria2.port) return c if __name__ == '__main__': c = test()
分类:
开发
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步