Emotional Code|

Nolca

园龄:6年9个月粉丝:12关注:9

用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()

本文作者:Nolca

本文链接:https://www.cnblogs.com/nolca/p/18718565

版权声明:本作品采用 收益分享revenue sharing 许可协议进行许可。

posted @   Nolca  阅读(1)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 ⏩intro 山姆精
  2. 2 🎸吉他 马叉
  3. 3 ☁升调 山姆精
  4. 4 🐦Flutter Virtual Riot/Madi
  5. 5 🎶纯律 山姆精
  6. 6 👻yeah~Color Bass! VR
⏩intro - 山姆精
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.