diff options
-rw-r--r-- | gi/importer.py | 28 | ||||
-rw-r--r-- | tests/test_import_machinery.py | 4 |
2 files changed, 27 insertions, 5 deletions
diff --git a/gi/importer.py b/gi/importer.py index 22c272b5..9c743c4e 100644 --- a/gi/importer.py +++ b/gi/importer.py @@ -78,6 +78,28 @@ def _check_require_version(namespace, stacklevel): PyGIWarning, stacklevel=stacklevel) +def get_import_stacklevel(import_hook): + """Returns the stacklevel value for warnings.warn() for when the warning + gets emitted by an imported module, but the warning should point at the + code doing the import. + + Pass import_hook=True if the warning gets generated by an import hook + (warn() gets called in load_module(), see PEP302) + """ + + py_version = sys.version_info[:2] + if py_version <= (3, 2): + # 2.7 included + return 4 if import_hook else 2 + elif py_version == (3, 3): + return 8 if import_hook else 10 + elif py_version == (3, 4): + return 10 if import_hook else 8 + else: + # fixed again in 3.5+, see https://bugs.python.org/issue24305 + return 4 if import_hook else 2 + + class DynamicImporter(object): # Note: see PEP302 for the Importer Protocol implemented below. @@ -105,11 +127,7 @@ class DynamicImporter(object): path, namespace = fullname.rsplit('.', 1) - # we want the warning to point to the line doing the import - if sys.version_info >= (3, 0): - stacklevel = 10 - else: - stacklevel = 4 + stacklevel = get_import_stacklevel(import_hook=True) with _check_require_version(namespace, stacklevel=stacklevel): introspection_module = get_introspection_module(namespace) dynamic_module = load_overrides(introspection_module) diff --git a/tests/test_import_machinery.py b/tests/test_import_machinery.py index de9f1e94..3c2572da 100644 --- a/tests/test_import_machinery.py +++ b/tests/test_import_machinery.py @@ -131,3 +131,7 @@ class TestImporter(unittest.TestCase): with check("InvalidGObjectRepositoryModuleName", 1): from gi.repository import InvalidGObjectRepositoryModuleName InvalidGObjectRepositoryModuleName + + def test_get_import_stacklevel(self): + gi.importer.get_import_stacklevel(import_hook=True) + gi.importer.get_import_stacklevel(import_hook=False) |