core: allow legacy modules to be used in 'hpi module install' for backwards compatibility

but show warning

kinda hacky, but hopefully we will simplify it further when we have more such legacy modules
This commit is contained in:
Dima Gerasimov 2022-06-07 22:37:45 +01:00 committed by karlicoss
parent dbd15a7ee8
commit 119b295d71
3 changed files with 33 additions and 4 deletions

View file

@ -12,7 +12,7 @@ import logzero # type: ignore[import]
logger = logzero.logger
MSG = 'importing my.fbmessenger is DEPRECATED'
MSG = 'my.fbmessenger is DEPRECATED'
def expect(*cmd: str, should_warn: bool=True) -> None:
res = run(cmd, stderr=PIPE)
@ -61,6 +61,7 @@ check_warn('-c', 'from my.fbmessenger import *')
check_warn('-c', 'from my.fbmessenger import messages, dump_chat_history')
check_warn('-m', 'my.core', 'query' , 'my.fbmessenger.messages', '-o', 'pprint', '--limit=10')
check_warn('-m', 'my.core', 'doctor', 'my.fbmessenger')
check_warn('-m', 'my.core', 'module', 'requires', 'my.fbmessenger')
# todo kinda annoying it doesn't work when executed as -c (but does as script!)
# presumably because doesn't have proper line number information?
@ -71,6 +72,7 @@ check_ok ('-c', 'from my.fbmessenger.export import *')
check_ok ('-c', 'from my.fbmessenger.export import messages, dump_chat_history')
check_ok ('-m', 'my.core', 'query' , 'my.fbmessenger.export.messages', '-o', 'pprint', '--limit=10')
check_ok ('-m', 'my.core', 'doctor', 'my.fbmessenger.export')
check_ok ('-m', 'my.core', 'module', 'requires', 'my.fbmessenger.export')
# NOTE:
# to check that overlays work, run something like

View file

@ -339,6 +339,9 @@ def _requires(modules: Sequence[str]) -> Sequence[str]:
mods = [module_by_name(module) for module in modules]
res = []
for mod in mods:
if mod.legacy is not None:
warning(mod.legacy)
reqs = mod.requires
if reqs is None:
error(f"Module {mod.name} has no REQUIRES specification")

View file

@ -34,6 +34,7 @@ class HPIModule(NamedTuple):
doc: Optional[str] = None
file: Optional[Path] = None
requires: Requires = None
legacy: Optional[str] = None # contains reason/deprecation warning
def ignored(m: str) -> bool:
@ -75,9 +76,19 @@ def _is_not_module_src(src: Path) -> bool:
def _is_not_module_ast(a: ast.Module) -> bool:
marker = NOT_HPI_MODULE_VAR
return any(
getattr(node, 'name', None) == NOT_HPI_MODULE_VAR # direct definition
or any(getattr(n, 'name', None) == NOT_HPI_MODULE_VAR for n in getattr(node, 'names', [])) # import from
getattr(node, 'name', None) == marker # direct definition
or any(getattr(n, 'name', None) == marker for n in getattr(node, 'names', [])) # import from
for node in a.body
)
def _is_legacy_module(a: ast.Module) -> bool:
marker = 'handle_legacy_import'
return any(
getattr(node, 'name', None) == marker # direct definition
or any(getattr(n, 'name', None) == marker for n in getattr(node, 'names', [])) # import from
for node in a.body
)
@ -156,7 +167,11 @@ def _modules_under_root(my_root: Path) -> Iterable[HPIModule]:
if ignored(m):
continue
a: ast.Module = ast.parse(f.read_text())
if _is_not_module_ast(a):
# legacy modules are 'forced' to be modules so 'hpi module install' still works for older modules
# a bit messy, will think how to fix it properly later
legacy_module = _is_legacy_module(a)
if _is_not_module_ast(a) and not legacy_module:
continue
doc = ast.get_docstring(a, clean=False)
@ -166,12 +181,15 @@ def _modules_under_root(my_root: Path) -> Iterable[HPIModule]:
except Exception as e:
logging.exception(e)
legacy = f'{m} is DEPRECATED. Please refer to the module documentation.' if legacy_module else None
yield HPIModule(
name=m,
skip_reason=None,
doc=doc,
file=f.relative_to(my_root.parent),
requires=requires,
legacy=legacy,
)
@ -209,6 +227,12 @@ def test_requires() -> None:
assert len(r) == 2 # fragile, but ok for now
def test_legacy_modules() -> None:
# shouldn't crash
module_by_name('my.reddit')
module_by_name('my.fbmessenger')
def test_pure() -> None:
"""
We want to keep this module clean of other HPI imports