Browse Source

initial prototype

master
Brett Langdon 7 years ago
commit
0c1c3fae10
No known key found for this signature in database GPG Key ID: B664881177781B04
1 changed files with 96 additions and 0 deletions
  1. +96
    -0
      virtualmod.py

+ 96
- 0
virtualmod.py View File

@ -0,0 +1,96 @@
import importlib
from importlib.abc import Loader, MetaPathFinder
import sys
registry = dict()
module_cls = type(sys)
spec_cls = type(sys.__spec__)
class VirtualModule:
__slots__ = ['name', 'module', 'spec']
def __init__(self, name):
self.name = name
self.module = module_cls(name)
self.spec = spec_cls(name=name, loader=VirtualModuleLoader)
setattr(self.module, '__spec__', self.spec)
def set_attribute(self, name, value):
setattr(self.module, name, value)
def delete_attribute(self, name):
delattr(self.module, name)
def create_module(name):
module = VirtualModule(name)
registry[name] = module
return module
def copy_module(module):
name = module.__name__
if hasattr(module, '__spec__'):
name = module.__spec__.name
virt_mod = VirtualModule(name)
for key, value in module.__dict__.items():
if key in ('__spec__', '__name__', '__loader__', '__package__'):
continue
virt_mod.set_attribute(key, value)
registry[name] = virt_mod
importlib.reload(module)
return virt_mod
def as_module(cls_or_name):
if isinstance(cls_or_name, str):
cls = None
name = cls_or_name
elif isinstance(cls_or_name, type):
cls = cls_or_name
name = getattr(cls, '__module_name__', cls.__name__)
else:
raise ValueError('Expected as_module to be passed a string or a class type')
def wrapper(cls):
module = create_module(name)
for key, value in cls.__dict__.items():
if key.startswith('__') and key.endswith('__'):
continue
module.set_attribute(key, value)
return module
if cls is None:
return wrapper
return wrapper(cls)
class VirtualModuleLoader(Loader):
def create_module(spec):
if spec.name not in registry:
return None
return registry[spec.name].module
def exec_module(module):
module_name = module.__name__
if hasattr(module, '__spec__'):
module_name = module.__spec__.name
sys.modules[module_name] = module
class VirtualModuleFinder(MetaPathFinder):
def find_spec(fullname, path, target=None):
if fullname in registry:
return registry[fullname].spec
return None
sys.meta_path.insert(0, VirtualModuleFinder)

Loading…
Cancel
Save