blob: 9cc0c35dce4f4c3ad362a788f50ba18d027b1703 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
"""
Improve the standard Python REPL.
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 logging
import sys
from Biz import Log
def use(ns: str, path: str) -> None:
"""
Load or reload the module named 'ns' from 'path'.
Like `use` in the Guile Scheme repl.
"""
logging.info("loading %s from %s", ns, path)
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 = list(module.__dict__)
globals().update({k: getattr(module, k) for k in names})
if __name__ == "__main__":
Log.setup()
NS = sys.argv[1]
PATH = sys.argv[2]
use(NS, PATH)
logging.info("use reload() or _r() after making changes")
sys.ps1 = f"{NS}> "
sys.ps2 = f"{NS}| "
def reload() -> None:
"""Reload the namespace."""
return use(NS, PATH)
def _r() -> None:
"""Shorthand: Reload the namespace."""
return use(NS, PATH)
|