Skip to content

Instantly share code, notes, and snippets.

@riffraff
Last active August 18, 2019 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save riffraff/bbab33b77c259fab58340c9a40f59b01 to your computer and use it in GitHub Desktop.
Save riffraff/bbab33b77c259fab58340c9a40f59b01 to your computer and use it in GitHub Desktop.
from importlib.machinery import ModuleSpec
from .source import make_source
# For some reasons I need to be able to have dynamically generated modules so I can do
#
# from borsa_italiana.isin.<dynamic value> import Source
#
MAGIC_MODULE_NAME = 'borsa_italiana.isin'
MODULE_PATH = [] # dummy, but we need to set it to something, but why?
class ModuleFinder:
"""
Connects ModuleImporter to the import machinery
"""
@classmethod
def find_spec(cls, fullname, path=None, target=None):
"""
If this returns a module spec, use our importer
"""
name_parts = fullname.split('.')
# maybe use startswith on the strings
if name_parts[:2] != MAGIC_MODULE_NAME.split('.') or len(name_parts) > 3:
return None
else:
return ModuleSpec(fullname, ModuleImporter())
class ModuleImporter:
"""
Populates the magic isin.foo modules
"""
@classmethod
def create_module(cls, spec):
"""
Returning None lets Python create a normal empty module.
"""
return None
@classmethod
def exec_module(cls, module):
"""
Fills the module with code
"""
name_parts = module.__name__.split('.')
# __path__ must be set or things explode
if module.__name__ == MAGIC_MODULE_NAME:
module.__path__ = MODULE_PATH # ?? do I need this?
if module.__name__.startswith(MAGIC_MODULE_NAME):
module.Source = make_source(lambda request: name_parts[-1])
else:
assert False, 'Importer tried to handle a module it should not know about %s'.format(module.__name__)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment