From ff9abfff660efc5dc6c664bcd07046b652c45751 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 27 May 2023 16:56:26 +0100 Subject: [PATCH 1/4] gh-105013: Fix inspect.getsource with parenthesized multiline lambdas --- Lib/inspect.py | 3 +++ Lib/test/inspect_fodder2.py | 8 ++++++++ Lib/test/test_inspect.py | 10 ++++++++++ .../2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst | 2 ++ 4 files changed, 23 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst diff --git a/Lib/inspect.py b/Lib/inspect.py index 7709a95003efbd..4fbba303715a9a 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1242,6 +1242,9 @@ def getblock(lines): blockfinder.tokeneater(*_token) except (EndOfBlock, IndentationError): pass + except SyntaxError as e: + if "unmatched ')" not in e.msg: + raise e from None return lines[:blockfinder.last] def getsourcelines(object): diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index 2dc49817087c44..e33e734d2591fc 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -273,3 +273,11 @@ def wrapper(*a, **kwd): @deco_factory(foo=(1 + 2), bar=lambda: 1) def complex_decorated(foo=0, bar=lambda: 0): return foo + bar() + +# line 276 +parenthesized_lambda = ( + lambda: ()) + +# line 281 +post_line_parenthesized_lambda = (lambda: () +) \ No newline at end of file diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index ade32151eaf233..df4c0e7dd62aca 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -776,6 +776,16 @@ def test_twoline_indented_lambda(self): # where the second line _is_ indented. self.assertSourceEqual(mod2.tlli, 33, 34) + def test_parenthesized_multiline_lambda(self): + # Test inspect.getsource with a parenthesized multi-line lambda + # function. + self.assertSourceEqual(mod2.parenthesized_lambda, 279, 279) + + def test_post_line_parenthesized_lambda(self): + # Test inspect.getsource with a parenthesized multi-line lambda + # function. + self.assertSourceEqual(mod2.post_line_parenthesized_lambda, 282, 283) + def test_onelinefunc(self): # Test inspect.getsource with a regular one-line function. self.assertSourceEqual(mod2.onelinefunc, 37, 37) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst new file mode 100644 index 00000000000000..a9917c2849982a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-05-27-16-57-11.gh-issue-105013.IsDgDY.rst @@ -0,0 +1,2 @@ +Fix handling of multiline parenthesized lambdas in +:func:`inspect.getsource`. Patch by Pablo Galindo From 9b9d81025930e9794d4e4961d39c347609db35c3 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 27 May 2023 17:10:41 +0100 Subject: [PATCH 2/4] fixup! gh-105013: Fix inspect.getsource with parenthesized multiline lambdas Signed-off-by: Pablo Galindo --- Lib/inspect.py | 7 ++++++- Lib/test/inspect_fodder2.py | 7 ++++++- Lib/test/test_inspect.py | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 4fbba303715a9a..55530fc780b35c 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1243,8 +1243,13 @@ def getblock(lines): except (EndOfBlock, IndentationError): pass except SyntaxError as e: - if "unmatched ')" not in e.msg: + if "unmatched" not in e.msg: raise e from None + _, *_token_info = _token + try: + blockfinder.tokeneater(tokenize.NEWLINE, *_token_info) + except (EndOfBlock, IndentationError): + pass return lines[:blockfinder.last] def getsourcelines(object): diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index e33e734d2591fc..963333725a176f 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -280,4 +280,9 @@ def complex_decorated(foo=0, bar=lambda: 0): # line 281 post_line_parenthesized_lambda = (lambda: () -) \ No newline at end of file +) + +# line 285 +nested_lambda = ( + lambda right: [].map( + lambda length: ())) \ No newline at end of file diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index df4c0e7dd62aca..40512b6b08eef1 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -786,6 +786,10 @@ def test_post_line_parenthesized_lambda(self): # function. self.assertSourceEqual(mod2.post_line_parenthesized_lambda, 282, 283) + def test_nested_lambda(self): + # Test inspect.getsource with a nested lambda function. + self.assertSourceEqual(mod2.nested_lambda, 287, 288) + def test_onelinefunc(self): # Test inspect.getsource with a regular one-line function. self.assertSourceEqual(mod2.onelinefunc, 37, 37) From 82f0023b69204df821972d53066ea59327c5a006 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 27 May 2023 23:54:46 +0100 Subject: [PATCH 3/4] fixup! fixup! gh-105013: Fix inspect.getsource with parenthesized multiline lambdas --- Lib/test/inspect_fodder2.py | 10 +++++++--- Lib/test/test_inspect.py | 6 ++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index 963333725a176f..c0d15054801675 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -277,12 +277,16 @@ def complex_decorated(foo=0, bar=lambda: 0): # line 276 parenthesized_lambda = ( lambda: ()) +parenthesized_lambda2 = [ + lambda: ()][0] +parenthesized_lambda3 = {0: + lambda: ()}[0] -# line 281 -post_line_parenthesized_lambda = (lambda: () +# line 285 +post_line_parenthesized_lambda1 = (lambda: () ) -# line 285 +# line 289 nested_lambda = ( lambda right: [].map( lambda length: ())) \ No newline at end of file diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 40512b6b08eef1..a7bd680d0f5bcc 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -780,15 +780,17 @@ def test_parenthesized_multiline_lambda(self): # Test inspect.getsource with a parenthesized multi-line lambda # function. self.assertSourceEqual(mod2.parenthesized_lambda, 279, 279) + self.assertSourceEqual(mod2.parenthesized_lambda2, 281, 281) + self.assertSourceEqual(mod2.parenthesized_lambda3, 283, 283) def test_post_line_parenthesized_lambda(self): # Test inspect.getsource with a parenthesized multi-line lambda # function. - self.assertSourceEqual(mod2.post_line_parenthesized_lambda, 282, 283) + self.assertSourceEqual(mod2.post_line_parenthesized_lambda1, 286, 287) def test_nested_lambda(self): # Test inspect.getsource with a nested lambda function. - self.assertSourceEqual(mod2.nested_lambda, 287, 288) + self.assertSourceEqual(mod2.nested_lambda, 291, 292) def test_onelinefunc(self): # Test inspect.getsource with a regular one-line function. From 6d41c1a515859eb2878094b8ce0c005bd1ededb9 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 27 May 2023 23:55:02 +0100 Subject: [PATCH 4/4] fixup! fixup! fixup! gh-105013: Fix inspect.getsource with parenthesized multiline lambdas --- Lib/test/inspect_fodder2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index c0d15054801675..03464613694605 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -289,4 +289,4 @@ def complex_decorated(foo=0, bar=lambda: 0): # line 289 nested_lambda = ( lambda right: [].map( - lambda length: ())) \ No newline at end of file + lambda length: ()))