From 60ce66780a82af1314fae9d82ace519815e7a3a1 Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Fri, 4 Jan 2019 19:30:03 +0100 Subject: Fix a rare type hint racing condition When building type hints during the PySide build, it can happen that the QtMultimedia module already exists, but the QtMultimediaWidgets module is not yet built. Since during the build also directories exist alongside with the not yet existing modules, it can happen that such a directory is picked up by Python 3, which supports namespace modules without __init__.py . This case was already handled by the mapping modules, but QtMultimediaWidgets was directly imported and not checked. Now the check code has been extracted from the mapping reloader, and there is no more unchecked module left. Task-number: PYSIDE-735 Change-Id: I1a1f53525417651005d0759e417082fe71b02773 Reviewed-by: Cristian Maureira-Fredes --- sources/pyside2/PySide2/support/signature/mapping.py | 2 ++ .../shiboken2/shibokenmodule/support/signature/mapping.py | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/sources/pyside2/PySide2/support/signature/mapping.py b/sources/pyside2/PySide2/support/signature/mapping.py index c39821f05..61fa2d41f 100644 --- a/sources/pyside2/PySide2/support/signature/mapping.py +++ b/sources/pyside2/PySide2/support/signature/mapping.py @@ -311,6 +311,8 @@ def init_QtXmlPatterns(): def init_QtMultimedia(): import PySide2.QtMultimediaWidgets + # Check if foreign import is valid. See mapping.py in shiboken2. + check_module(PySide2.QtMultimediaWidgets) type_map.update({ "QGraphicsVideoItem": PySide2.QtMultimediaWidgets.QGraphicsVideoItem, "QVideoWidget": PySide2.QtMultimediaWidgets.QVideoWidget, diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py index f638bc42b..0195f0280 100644 --- a/sources/shiboken2/shibokenmodule/support/signature/mapping.py +++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py @@ -175,10 +175,7 @@ class Reloader(object): import_name = prefix + mod_name if import_name in sys.modules: # check if this is a real module - obj = sys.modules[import_name] - if not getattr(obj, "__file__", None) or os.path.isdir(obj.__file__): - raise ImportError("Module '{mod_name}' is at most a " - "namespace!".format(**locals())) + check_module(sys.modules[import_name]) # module is real self.uninitialized.remove(mod_name) proc_name = "init_" + mod_name @@ -193,6 +190,16 @@ class Reloader(object): # Modules are in place, we can update the type_map. g.update(g[proc_name]()) +def check_module(mod): + # During a build, there exist the modules already as directories, + # although the '*.so' was not yet created. This causes a problem + # in Python 3, because it accepts folders as namespace modules + # without enforcing an '__init__.py'. + if not getattr(mod, "__file__", None) or os.path.isdir(mod.__file__): + mod_name = mod.__name__ + raise ImportError("Module '{mod_name}' is at most a namespace!" + .format(**locals())) + update_mapping = Reloader().update type_map = {} -- cgit v1.2.3