From 2852746d59e4d60c37ac4373e0696eec64c9f526 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 16 Feb 2024 08:29:50 -0500 Subject: [PATCH] fix: import error messages fix import error messages by fixing compliance with the metapath protocol. instead of always returning a module loader which errors out if it can't find a module, return None early (from find_module) if we can't find the module. this lets the system fall back to the system error handling for not-found modules. --- boa/interpret.py | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/boa/interpret.py b/boa/interpret.py index ae13c338..d9fac315 100644 --- a/boa/interpret.py +++ b/boa/interpret.py @@ -27,29 +27,38 @@ class BoaImporter(importlib.abc.MetaPathFinder): + def __init__(self): + self._path_lookup = {} + def find_module(self, fullname, package_path, target=None): - # Return a loader - return self + # note: maybe instead of looping, append path to package_path + path = Path(fullname.replace(".", "/")).with_suffix(".vy") + + for prefix in package_path: + # for fullname == "x.y.z" + # prefix looks something like "<...>/site-packages/x" + to_try = Path(prefix).parent / path + + if to_try.exists(): + self._path_lookup[fullname] = to_try + return self + + return None def load_module(self, fullname): - # Return a module if fullname in sys.modules: return sys.modules[fullname] - path = Path(fullname.replace(".", "/")).with_suffix(".vy") - for prefix in sys.path: - to_try = Path(prefix) / path - try: - ret = load_partial(to_try) - break - except (FileNotFoundError, NotADirectoryError): - pass - else: - raise ImportError(fullname) + # import system should guarantee this, but be paranoid + if fullname not in self._path_lookup: + raise ImportError(f"invariant violated: no lookup for {fullname}") + + path = self._path_lookup[fullname] + ret = load_partial(path) # comply with PEP-302: - ret.__name__ = to_try.name - ret.__file__ = str(to_try) + ret.__name__ = path.name + ret.__file__ = str(path) sys.modules[fullname] = ret return ret