From 6716770f2ae1a1619229d70c21e5751c38d22d79 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Mon, 12 Jun 2017 16:37:46 +0100 Subject: [PATCH 1/6] bpo-30639: Lazily compute repr for error --- Lib/inspect.py | 13 +++++++++++-- Lib/test/test_inspect.py | 8 ++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 9a843d6420e2e0..d04ed5da81a368 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -640,6 +640,16 @@ def cleandoc(doc): lines.pop(0) return '\n'.join(lines) +class SourceNotFindableError(TypeError): + """Exception raised by getfile() when the object has no link to its source. + """ + def __init__(self, obj): + self.obj = obj + + def __str__(self): + return ('{!r} is not a module, class, method, ' + 'function, traceback, frame, or code object').format(self.obj) + def getfile(object): """Work out which source or compiled file an object was defined in.""" if ismodule(object): @@ -662,8 +672,7 @@ def getfile(object): object = object.f_code if iscode(object): return object.co_filename - raise TypeError('{!r} is not a module, class, method, ' - 'function, traceback, frame, or code object'.format(object)) + raise SourceNotFindableError(object) def getmodulename(path): """Return the module name for a given file, or None.""" diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 350d5dbd776ac2..f7b1eb2a29155b 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -463,6 +463,14 @@ class C(metaclass=CM): with self.assertRaises(TypeError): inspect.getfile(C) + def test_getfile_broken_repr(self): + class ErrorRepr: + def __repr__(self): + raise Exception('xyz') + er = ErrorRepr() + with self.assertRaises(TypeError): + inspect.getfile(er) + def test_getmodule_recursion(self): from types import ModuleType name = '__inspect_dummy' From ab346203aa86cd00df6e5272733c0134bc587f97 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Mon, 12 Jun 2017 20:09:47 +0100 Subject: [PATCH 2/6] Only show the type of the object, not its repr --- Lib/inspect.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index d04ed5da81a368..e2dd7b4aec5a20 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -640,15 +640,6 @@ def cleandoc(doc): lines.pop(0) return '\n'.join(lines) -class SourceNotFindableError(TypeError): - """Exception raised by getfile() when the object has no link to its source. - """ - def __init__(self, obj): - self.obj = obj - - def __str__(self): - return ('{!r} is not a module, class, method, ' - 'function, traceback, frame, or code object').format(self.obj) def getfile(object): """Work out which source or compiled file an object was defined in.""" @@ -672,7 +663,9 @@ def getfile(object): object = object.f_code if iscode(object): return object.co_filename - raise SourceNotFindableError(object) + raise TypeError('object of type {} is not a module, class, method, ' + 'function, traceback, frame, or code object'.format( + type(object).__name__)) def getmodulename(path): """Return the module name for a given file, or None.""" From 5e1c06168665b46304b3980f2e39910dc80760c5 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Wed, 14 Jun 2017 17:19:11 +0100 Subject: [PATCH 3/6] Eliminate extra newline --- Lib/inspect.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index e2dd7b4aec5a20..fe0711152e353f 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -640,7 +640,6 @@ def cleandoc(doc): lines.pop(0) return '\n'.join(lines) - def getfile(object): """Work out which source or compiled file an object was defined in.""" if ismodule(object): From 7bbe37f2d10d52f7b442c3e01d3013b164781e1f Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Wed, 14 Jun 2017 17:31:18 +0100 Subject: [PATCH 4/6] Fix alignment --- Lib/inspect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index fe0711152e353f..8ba5afc38d390b 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -664,7 +664,7 @@ def getfile(object): return object.co_filename raise TypeError('object of type {} is not a module, class, method, ' 'function, traceback, frame, or code object'.format( - type(object).__name__)) + type(object).__name__)) def getmodulename(path): """Return the module name for a given file, or None.""" From fd1f08ea2188e950177d733900ceeb322603c9b9 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 24 Oct 2017 12:17:35 +0100 Subject: [PATCH 5/6] Change error message as suggested --- Lib/inspect.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 8ba5afc38d390b..6d6fde9ee40401 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -662,8 +662,8 @@ def getfile(object): object = object.f_code if iscode(object): return object.co_filename - raise TypeError('object of type {} is not a module, class, method, ' - 'function, traceback, frame, or code object'.format( + raise TypeError('module, class, method, function, traceback, frame, or ' + 'code object was expected, got {}'.format( type(object).__name__)) def getmodulename(path): From cde477ee1eb8d74f29f1ec0710e51652a9dca488 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Tue, 24 Oct 2017 12:25:10 +0100 Subject: [PATCH 6/6] Add news with blurb tool --- .../next/Library/2017-10-24-12-24-56.bpo-30639.ptNM9a.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-10-24-12-24-56.bpo-30639.ptNM9a.rst diff --git a/Misc/NEWS.d/next/Library/2017-10-24-12-24-56.bpo-30639.ptNM9a.rst b/Misc/NEWS.d/next/Library/2017-10-24-12-24-56.bpo-30639.ptNM9a.rst new file mode 100644 index 00000000000000..c6aeb2356f6200 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-24-12-24-56.bpo-30639.ptNM9a.rst @@ -0,0 +1,2 @@ +:func:`inspect.getfile` no longer computes the repr of unknown objects to +display in an error message, to protect against badly behaved custom reprs.