summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gi/importer.py28
-rw-r--r--tests/test_import_machinery.py4
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)