From 030bdd1d34dbe5da79a1171b084c5c336fba85b6 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 24 Dec 2020 20:48:09 +0100 Subject: [PATCH] dist: Work around stdlib bug causing erroneous missing module warnings --- direct/src/dist/FreezeTool.py | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index 71b664271e..1977d98ae1 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -2428,6 +2428,76 @@ class PandaModuleFinder(modulefinder.ModuleFinder): self.msg(2, "ImportError:", str(msg)) self._add_badmodule(fullname, caller) + def scan_code(self, co, m): + code = co.co_code + # This was renamed to scan_opcodes in Python 3.6 + if hasattr(self, 'scan_opcodes_25'): + scanner = self.scan_opcodes_25 + else: + scanner = self.scan_opcodes + + for what, args in scanner(co): + if what == "store": + name, = args + m.globalnames[name] = 1 + elif what in ("import", "absolute_import"): + fromlist, name = args + have_star = 0 + if fromlist is not None: + if "*" in fromlist: + have_star = 1 + fromlist = [f for f in fromlist if f != "*"] + if what == "absolute_import": level = 0 + else: level = -1 + self._safe_import_hook(name, m, fromlist, level=level) + if have_star: + # We've encountered an "import *". If it is a Python module, + # the code has already been parsed and we can suck out the + # global names. + mm = None + if m.__path__: + # At this point we don't know whether 'name' is a + # submodule of 'm' or a global module. Let's just try + # the full name first. + mm = self.modules.get(m.__name__ + "." + name) + if mm is None: + mm = self.modules.get(name) + if mm is not None: + m.globalnames.update(mm.globalnames) + m.starimports.update(mm.starimports) + if mm.__code__ is None: + m.starimports[name] = 1 + else: + m.starimports[name] = 1 + elif what == "relative_import": + level, fromlist, name = args + parent = self.determine_parent(m, level=level) + if name: + self._safe_import_hook(name, m, fromlist, level=level) + else: + self._safe_import_hook(parent.__name__, None, fromlist, level=0) + + if fromlist and "*" in fromlist: + if name: + mm = self.modules.get(parent.__name__ + "." + name) + else: + mm = self.modules.get(parent.__name__) + + if mm is not None: + m.globalnames.update(mm.globalnames) + m.starimports.update(mm.starimports) + if mm.__code__ is None: + m.starimports[name] = 1 + else: + m.starimports[name] = 1 + else: + # We don't expect anything else from the generator. + raise RuntimeError(what) + + for c in co.co_consts: + if isinstance(c, type(co)): + self.scan_code(c, m) + def find_module(self, name, path=None, parent=None): """ Finds a module with the indicated name on the given search path (or self.path if None). Returns a tuple like (fp, path, stuff), where