[pygobject] Fix import warnings pointing to the wrong code with CPython 3.3/3.5
- From: Christoph Reiter <creiter src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Fix import warnings pointing to the wrong code with CPython 3.3/3.5
- Date: Thu, 12 Nov 2015 16:28:05 +0000 (UTC)
commit 12022437d663f49ba3a2a2f884da30dd5ca08ff6
Author: Christoph Reiter <creiter src gnome org>
Date: Fri Oct 30 13:07:57 2015 +0100
Fix import warnings pointing to the wrong code with CPython 3.3/3.5
For making warnings point to the code doing the import, the stack frames
of the import system need to be skipped. The frame count number varries
between CPython versions and in 3.5 all frames of the import system are
skipped for warnings (https://bugs.python.org/issue24305).
This hardcodes the frame counts for all supported CPython versions
which fixes the import warning output for CPython 3.3 and 3.5.
This also fixes/works around a bug in CPython 3 where if a too
large stacklevel value was passed to warn(), CPython would try to
interpret a file called "sys" in the same directory of the
executed script (https://bugs.python.org/issue25493
and https://bugzilla.gnome.org/show_bug.cgi?id=757184).
https://bugzilla.gnome.org/show_bug.cgi?id=757184
gi/importer.py | 28 +++++++++++++++++++++++-----
tests/test_import_machinery.py | 4 ++++
2 files changed, 27 insertions(+), 5 deletions(-)
---
diff --git a/gi/importer.py b/gi/importer.py
index 5060584..4ed6196 100644
--- a/gi/importer.py
+++ b/gi/importer.py
@@ -79,6 +79,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.
@@ -110,11 +132,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):
try:
introspection_module = get_introspection_module(namespace)
diff --git a/tests/test_import_machinery.py b/tests/test_import_machinery.py
index e1432b1..ad1f330 100644
--- a/tests/test_import_machinery.py
+++ b/tests/test_import_machinery.py
@@ -144,3 +144,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)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]