""" This module attempts to emulate the workflow of ghci or lisp repls. It uses importlib to load a namespace from the given path. It then binds 'r()' to a function that reloads the same namespace. """ import importlib import sys def use(ns: str, path: str) -> None: """ Load or reload the module named 'ns' from 'path'. Like `use` in the Guile Scheme repl. """ spec = importlib.util.spec_from_file_location(ns, path) module = importlib.util.module_from_spec(spec) # delete module and its imported names if its already loaded if ns in sys.modules: del sys.modules[ns] for name in module.__dict__: if name in globals(): del globals()[name] sys.modules[ns] = module spec.loader.exec_module(module) names = [x for x in module.__dict__] globals().update({k: getattr(module, k) for k in names}) if __name__ == "__main__": NS = sys.argv[1] PATH = sys.argv[2] use(NS, PATH) def r(): return use(NS, PATH)