Created
July 8, 2025 23:46
-
-
Save CNSeniorious000/f159109f8a0db709cc75ac7cf1d3e26d to your computer and use it in GitHub Desktop.
Generated with AI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from importlib.abc import Loader, MetaPathFinder | |
from importlib.util import spec_from_file_location | |
from pathlib import Path | |
from types import ModuleType | |
class ProtectedModule(ModuleType): | |
def __getattribute__(self, name): | |
if name in ("__dict__", "__class__", "__name__", "__file__", "__all__", "__doc__", "__package__", "__loader__", "__spec__"): | |
return super().__getattribute__(name) | |
allowed = super().__getattribute__("__all__") if hasattr(self, "__all__") else [] | |
if name in allowed: | |
return super().__getattribute__(name) | |
raise AttributeError(f"module '{self.__name__}' has no attribute '{name}'") | |
def __dir__(self): | |
base = ["__dict__", "__class__", "__name__", "__file__", "__all__", "__doc__", "__package__", "__loader__", "__spec__"] | |
allowed = self.__all__ if hasattr(self, "__all__") else [] | |
return [*base, *allowed] | |
class ProtectedModuleLoader(Loader): | |
def create_module(self, spec): | |
return ProtectedModule(spec.name) | |
def exec_module(self, module): | |
origin = getattr(module.__spec__, "origin", None) | |
if not origin: | |
raise ImportError(f"Cannot load module {module.__name__}: no origin found.") | |
with Path(origin).open(encoding="utf-8") as f: | |
code = compile(f.read(), origin, "exec") | |
exec(code, module.__dict__) | |
# 确保 __all__ 存在且为 list 或 tuple | |
if "__all__" not in module.__dict__ or not isinstance(module.__dict__["__all__"], list | tuple): | |
module.__dict__["__all__"] = [] | |
class ProtectedModuleFinder(MetaPathFinder): | |
def __init__(self, protected_names): | |
self.protected_names = set(protected_names) | |
def find_spec(self, fullname, path=None, target=None): | |
if fullname not in self.protected_names: | |
return None | |
# 跳过自身, 防止递归 | |
for finder in sys.meta_path: | |
if finder is self: | |
continue | |
if hasattr(finder, "find_spec"): | |
spec = finder.find_spec(fullname, path, target) | |
if spec is not None and getattr(spec, "origin", None): | |
return spec_from_file_location(fullname, spec.origin, loader=ProtectedModuleLoader()) | |
return None | |
# 注册到 sys.meta_path, 保护指定模块 | |
PROTECTED_MODULES = ["example_module"] | |
sys.meta_path.insert(0, ProtectedModuleFinder(PROTECTED_MODULES)) | |
# 测试用例 | |
if __name__ == "__main__": | |
import example_module | |
print(dir(example_module)) # 只显示 __all__ 和内置属性 | |
print(example_module.some_exported_name) # 可以访问 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment