Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
741a0abc
Commit
741a0abc
authored
Jul 08, 2012
by
Antoine Pitrou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #15110: Fix the tracebacks generated by "import xxx" to not show the importlib stack frames.
parent
b4e3cea9
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
2721 additions
and
2463 deletions
+2721
-2463
Lib/importlib/_bootstrap.py
Lib/importlib/_bootstrap.py
+22
-3
Lib/test/test_import.py
Lib/test/test_import.py
+93
-0
Misc/NEWS
Misc/NEWS
+3
-0
Python/import.c
Python/import.c
+66
-0
Python/importlib.h
Python/importlib.h
+2537
-2460
No files found.
Lib/importlib/_bootstrap.py
View file @
741a0abc
...
@@ -541,7 +541,7 @@ class FrozenImporter:
...
@@ -541,7 +541,7 @@ class FrozenImporter:
"""Load a frozen module."""
"""Load a frozen module."""
is_reload
=
fullname
in
sys
.
modules
is_reload
=
fullname
in
sys
.
modules
try
:
try
:
m
=
_imp
.
init_frozen
(
fullname
)
m
=
cls
.
_exec_module
(
fullname
)
# Let our own module_repr() method produce a suitable repr.
# Let our own module_repr() method produce a suitable repr.
del
m
.
__file__
del
m
.
__file__
return
m
return
m
...
@@ -568,6 +568,13 @@ class FrozenImporter:
...
@@ -568,6 +568,13 @@ class FrozenImporter:
"""Return if the frozen module is a package."""
"""Return if the frozen module is a package."""
return
_imp
.
is_frozen_package
(
fullname
)
return
_imp
.
is_frozen_package
(
fullname
)
@
classmethod
def
_exec_module
(
cls
,
fullname
):
"""Helper for load_module, allowing to isolate easily (when
looking at a traceback) whether an error comes from executing
an imported module's code."""
return
_imp
.
init_frozen
(
fullname
)
class
_LoaderBasics
:
class
_LoaderBasics
:
...
@@ -644,9 +651,15 @@ class _LoaderBasics:
...
@@ -644,9 +651,15 @@ class _LoaderBasics:
else
:
else
:
module
.
__package__
=
module
.
__package__
.
rpartition
(
'.'
)[
0
]
module
.
__package__
=
module
.
__package__
.
rpartition
(
'.'
)[
0
]
module
.
__loader__
=
self
module
.
__loader__
=
self
exec
(
code_object
,
module
.
__dict__
)
self
.
_exec_module
(
code_object
,
module
.
__dict__
)
return
module
return
module
def
_exec_module
(
self
,
code_object
,
module_dict
):
"""Helper for _load_module, allowing to isolate easily (when
looking at a traceback) whether an error comes from executing
an imported module's code."""
exec
(
code_object
,
module_dict
)
class
SourceLoader
(
_LoaderBasics
):
class
SourceLoader
(
_LoaderBasics
):
...
@@ -869,7 +882,7 @@ class ExtensionFileLoader:
...
@@ -869,7 +882,7 @@ class ExtensionFileLoader:
"""Load an extension module."""
"""Load an extension module."""
is_reload
=
fullname
in
sys
.
modules
is_reload
=
fullname
in
sys
.
modules
try
:
try
:
module
=
_imp
.
load_dynamic
(
fullname
,
self
.
path
)
module
=
self
.
_exec_module
(
fullname
,
self
.
path
)
_verbose_message
(
'extension module loaded from {!r}'
,
self
.
path
)
_verbose_message
(
'extension module loaded from {!r}'
,
self
.
path
)
return
module
return
module
except
:
except
:
...
@@ -889,6 +902,12 @@ class ExtensionFileLoader:
...
@@ -889,6 +902,12 @@ class ExtensionFileLoader:
"""Return None as extension modules have no source code."""
"""Return None as extension modules have no source code."""
return
None
return
None
def
_exec_module
(
self
,
fullname
,
path
):
"""Helper for load_module, allowing to isolate easily (when
looking at a traceback) whether an error comes from executing
an imported module's code."""
return
_imp
.
load_dynamic
(
fullname
,
path
)
class
_NamespacePath
:
class
_NamespacePath
:
"""Represents a namespace package's path. It uses the module name
"""Represents a namespace package's path. It uses the module name
...
...
Lib/test/test_import.py
View file @
741a0abc
...
@@ -768,6 +768,98 @@ class ImportlibBootstrapTests(unittest.TestCase):
...
@@ -768,6 +768,98 @@ class ImportlibBootstrapTests(unittest.TestCase):
self
.
assertTrue
(
mod
.
__file__
.
endswith
(
'_bootstrap.py'
),
mod
.
__file__
)
self
.
assertTrue
(
mod
.
__file__
.
endswith
(
'_bootstrap.py'
),
mod
.
__file__
)
class
ImportTracebackTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
os
.
mkdir
(
TESTFN
)
self
.
old_path
=
sys
.
path
[:]
sys
.
path
.
insert
(
0
,
TESTFN
)
def
tearDown
(
self
):
sys
.
path
[:]
=
self
.
old_path
rmtree
(
TESTFN
)
def
create_module
(
self
,
mod
,
contents
):
with
open
(
os
.
path
.
join
(
TESTFN
,
mod
+
".py"
),
"w"
)
as
f
:
f
.
write
(
contents
)
self
.
addCleanup
(
unload
,
mod
)
importlib
.
invalidate_caches
()
def
assert_traceback
(
self
,
tb
,
files
):
deduped_files
=
[]
while
tb
:
code
=
tb
.
tb_frame
.
f_code
fn
=
code
.
co_filename
if
not
deduped_files
or
fn
!=
deduped_files
[
-
1
]:
deduped_files
.
append
(
fn
)
tb
=
tb
.
tb_next
self
.
assertEqual
(
len
(
deduped_files
),
len
(
files
),
deduped_files
)
for
fn
,
pat
in
zip
(
deduped_files
,
files
):
self
.
assertRegex
(
fn
,
pat
)
def
test_nonexistent_module
(
self
):
try
:
# assertRaises() clears __traceback__
import
nonexistent_xyzzy
except
ImportError
as
e
:
tb
=
e
.
__traceback__
else
:
self
.
fail
(
"ImportError should have been raised"
)
self
.
assert_traceback
(
tb
,
[
__file__
])
def
test_nonexistent_module_nested
(
self
):
self
.
create_module
(
"foo"
,
"import nonexistent_xyzzy"
)
try
:
import
foo
except
ImportError
as
e
:
tb
=
e
.
__traceback__
else
:
self
.
fail
(
"ImportError should have been raised"
)
self
.
assert_traceback
(
tb
,
[
__file__
,
'foo.py'
])
def
test_exec_failure
(
self
):
self
.
create_module
(
"foo"
,
"1/0"
)
try
:
import
foo
except
ZeroDivisionError
as
e
:
tb
=
e
.
__traceback__
else
:
self
.
fail
(
"ZeroDivisionError should have been raised"
)
self
.
assert_traceback
(
tb
,
[
__file__
,
'foo.py'
])
def
test_exec_failure_nested
(
self
):
self
.
create_module
(
"foo"
,
"import bar"
)
self
.
create_module
(
"bar"
,
"1/0"
)
try
:
import
foo
except
ZeroDivisionError
as
e
:
tb
=
e
.
__traceback__
else
:
self
.
fail
(
"ZeroDivisionError should have been raised"
)
self
.
assert_traceback
(
tb
,
[
__file__
,
'foo.py'
,
'bar.py'
])
@
cpython_only
def
test_import_bug
(
self
):
# We simulate a bug in importlib and check that it's not stripped
# away from the traceback.
self
.
create_module
(
"foo"
,
""
)
importlib
=
sys
.
modules
[
'_frozen_importlib'
]
old_load_module
=
importlib
.
SourceLoader
.
load_module
try
:
def
load_module
(
*
args
):
1
/
0
importlib
.
SourceLoader
.
load_module
=
load_module
try
:
import
foo
except
ZeroDivisionError
as
e
:
tb
=
e
.
__traceback__
else
:
self
.
fail
(
"ZeroDivisionError should have been raised"
)
self
.
assert_traceback
(
tb
,
[
__file__
,
'<frozen importlib'
,
__file__
])
finally
:
importlib
.
SourceLoader
.
load_module
=
old_load_module
def
test_main
(
verbose
=
None
):
def
test_main
(
verbose
=
None
):
flag
=
importlib_util
.
using___import__
flag
=
importlib_util
.
using___import__
try
:
try
:
...
@@ -777,6 +869,7 @@ def test_main(verbose=None):
...
@@ -777,6 +869,7 @@ def test_main(verbose=None):
OverridingImportBuiltinTests
,
OverridingImportBuiltinTests
,
ImportlibBootstrapTests
,
ImportlibBootstrapTests
,
TestSymbolicallyLinkedPackage
,
TestSymbolicallyLinkedPackage
,
ImportTracebackTests
,
importlib_import_test_suite
())
importlib_import_test_suite
())
finally
:
finally
:
importlib_util
.
using___import__
=
flag
importlib_util
.
using___import__
=
flag
...
...
Misc/NEWS
View file @
741a0abc
...
@@ -10,6 +10,9 @@ What's New in Python 3.3.0 Beta 2?
...
@@ -10,6 +10,9 @@ What's New in Python 3.3.0 Beta 2?
Core and Builtins
Core and Builtins
-----------------
-----------------
- Issue #15110: Fix the tracebacks generated by "import xxx" to not show
the importlib stack frames.
- Issue #15020: The program name used to search for Python'
s
path
is
now
- Issue #15020: The program name used to search for Python'
s
path
is
now
"python3"
under
Unix
,
not
"python"
.
"python3"
under
Unix
,
not
"python"
.
...
...
Python/import.c
View file @
741a0abc
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
#include "errcode.h"
#include "errcode.h"
#include "marshal.h"
#include "marshal.h"
#include "code.h"
#include "code.h"
#include "frameobject.h"
#include "osdefs.h"
#include "osdefs.h"
#include "importdl.h"
#include "importdl.h"
...
@@ -1375,6 +1376,69 @@ PyImport_ImportModuleNoBlock(const char *name)
...
@@ -1375,6 +1376,69 @@ PyImport_ImportModuleNoBlock(const char *name)
}
}
/* Remove importlib frames from the traceback,
* except in Verbose mode. */
static
void
remove_importlib_frames
(
void
)
{
const
char
*
importlib_filename
=
"<frozen importlib._bootstrap>"
;
const
char
*
exec_funcname
=
"_exec_module"
;
int
always_trim
=
0
;
int
in_importlib
;
PyObject
*
exception
,
*
value
,
*
base_tb
,
*
tb
;
PyObject
**
prev_link
,
**
outer_link
;
/* Synopsis: if it's an ImportError, we trim all importlib chunks
from the traceback. Otherwise, we trim only those chunks which
end with a call to "_exec_module". */
PyErr_Fetch
(
&
exception
,
&
value
,
&
base_tb
);
if
(
!
exception
||
Py_VerboseFlag
)
goto
done
;
if
(
PyType_IsSubtype
((
PyTypeObject
*
)
exception
,
(
PyTypeObject
*
)
PyExc_ImportError
))
always_trim
=
1
;
prev_link
=
&
base_tb
;
tb
=
base_tb
;
in_importlib
=
0
;
while
(
tb
!=
NULL
)
{
PyTracebackObject
*
traceback
=
(
PyTracebackObject
*
)
tb
;
PyObject
*
next
=
(
PyObject
*
)
traceback
->
tb_next
;
PyFrameObject
*
frame
=
traceback
->
tb_frame
;
PyCodeObject
*
code
=
frame
->
f_code
;
int
now_in_importlib
;
assert
(
PyTraceBack_Check
(
tb
));
now_in_importlib
=
(
PyUnicode_CompareWithASCIIString
(
code
->
co_filename
,
importlib_filename
)
==
0
);
if
(
now_in_importlib
&&
!
in_importlib
)
{
/* This is the link to this chunk of importlib tracebacks */
outer_link
=
prev_link
;
}
in_importlib
=
now_in_importlib
;
if
(
in_importlib
&&
(
always_trim
||
PyUnicode_CompareWithASCIIString
(
code
->
co_name
,
exec_funcname
)
==
0
))
{
PyObject
*
tmp
=
*
outer_link
;
*
outer_link
=
next
;
Py_XINCREF
(
next
);
Py_DECREF
(
tmp
);
prev_link
=
outer_link
;
}
else
{
prev_link
=
(
PyObject
**
)
&
traceback
->
tb_next
;
}
tb
=
next
;
}
done:
PyErr_Restore
(
exception
,
value
,
base_tb
);
}
PyObject
*
PyObject
*
PyImport_ImportModuleLevelObject
(
PyObject
*
name
,
PyObject
*
given_globals
,
PyImport_ImportModuleLevelObject
(
PyObject
*
name
,
PyObject
*
given_globals
,
PyObject
*
locals
,
PyObject
*
given_fromlist
,
PyObject
*
locals
,
PyObject
*
given_fromlist
,
...
@@ -1693,6 +1757,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
...
@@ -1693,6 +1757,8 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
Py_XDECREF
(
package
);
Py_XDECREF
(
package
);
Py_XDECREF
(
globals
);
Py_XDECREF
(
globals
);
Py_XDECREF
(
fromlist
);
Py_XDECREF
(
fromlist
);
if
(
final_mod
==
NULL
)
remove_importlib_frames
();
return
final_mod
;
return
final_mod
;
}
}
...
...
Python/importlib.h
View file @
741a0abc
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment