Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-108901: Deprecate inspect.getargvalues and inspect.formatargvalues, provide modern alternative#112639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
gh-108901: Deprecate inspect.getargvalues and inspect.formatargvalues, provide modern alternative
#112639
Changes from all commits
ad7389bd339bdd0edd93ab8d651c2d8fb971c47526File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -472,6 +472,16 @@ def __init__(self, *args, **kwargs): | ||
| git.abuse(7, 8, 9) | ||
| def assertDeprecated(self, name): | ||
| import re | ||
| return self.assertWarnsRegex( | ||
| DeprecationWarning, | ||
| re.escape( | ||
| f"{name!r} is deprecated and slated " | ||
| "for removal in Python 3.15", | ||
| ), | ||
| ) | ||
| def test_abuse_done(self): | ||
| self.istest(inspect.istraceback, 'git.ex.__traceback__') | ||
| self.istest(inspect.isframe, 'mod.fr') | ||
| @@ -518,21 +528,45 @@ def test_trace(self): | ||
| self.assertEqual(frame3.positions, dis.Positions(18, 18, 8, 13)) | ||
| def test_frame(self): | ||
| args, varargs, varkw, locals = inspect.getargvalues(mod.fr) | ||
| with self.assertDeprecated('getargvalues'): | ||
| args, varargs, varkw, locals = inspect.getargvalues(mod.fr) | ||
| self.assertEqual(args, ['x', 'y']) | ||
| self.assertEqual(varargs, None) | ||
| self.assertEqual(varkw, None) | ||
| self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14}) | ||
| self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals), | ||
| '(x=11, y=14)') | ||
| with self.assertDeprecated('formatargvalues'): | ||
| format = inspect.formatargvalues(args, varargs, varkw, locals) | ||
| self.assertEqual(format, '(x=11, y=14)') | ||
| def test_previous_frame(self): | ||
| args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back) | ||
| with self.assertDeprecated('getargvalues'): | ||
| args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back) | ||
| self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f']) | ||
| self.assertEqual(varargs, 'g') | ||
| self.assertEqual(varkw, 'h') | ||
| self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals), | ||
| '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})') | ||
| with self.assertDeprecated('formatargvalues'): | ||
| format = inspect.formatargvalues(args, varargs, varkw, locals) | ||
| self.assertEqual(format, | ||
| '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})') | ||
| def test_frame_with_argument_override(self): | ||
| # This tests shows that the current implementation of `getargvalues`: | ||
| # 1. Does not render `/` correctly | ||
| # 2. Uses not real default values, but can also show redefined values | ||
| def inner(a=1, /, c=5, *, b=2): | ||
| global fr | ||
| a = 3 | ||
| fr = inspect.currentframe() | ||
| b = 4 | ||
| inner() | ||
| with self.assertDeprecated('getargvalues'): | ||
| args, varargs, varkw, locals = inspect.getargvalues(fr) | ||
| with self.assertDeprecated('formatargvalues'): | ||
| format = inspect.formatargvalues(args, varargs, varkw, locals) | ||
| self.assertEqual(format, | ||
| '(a=3, c=5, b=4)') | ||
| class GetSourceBase(unittest.TestCase): | ||
| # Subclasses must override. | ||
| @@ -4623,6 +4657,42 @@ class D2(D1): | ||
| self.assertEqual(inspect.signature(D2), inspect.signature(D1)) | ||
| class TestSignatureFromFrame(unittest.TestCase): | ||
| def test_signature_from_frame(self): | ||
| def inner(a=1, /, b=2, *e, c: int = 3, d, **f) -> None: | ||
| global fr | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a global sounds like a bad idea. You can use a "nonlocal" instead. Sometimes, I use a mutable type instead, which is more or less the same: | ||
| fr = inspect.currentframe() | ||
| inner(d=4) | ||
| self.assertEqual(str(inspect.Signature.from_frame(fr)), | ||
| '(a=1, /, b=2, *e, c=3, d=4, **f)') | ||
| def inner(a, /, b, *e, c: int = 3, d, **f) -> None: | ||
| global fr | ||
| fr = inspect.currentframe() | ||
| inner(1, 2, d=4) | ||
| self.assertEqual(str(inspect.Signature.from_frame(fr)), | ||
| '(a=1, /, b=2, *e, c=3, d=4, **f)') | ||
| def test_signature_from_frame_defaults_change(self): | ||
| def inner(a=1, /, c=5, *, b=2): | ||
| global fr | ||
| a = 3 | ||
| fr = inspect.currentframe() | ||
| b = 4 | ||
| inner() | ||
| self.assertEqual(str(inspect.Signature.from_frame(fr)), | ||
| '(a=3, /, c=5, *, b=4)') | ||
| def test_signature_from_frame_mod(self): | ||
| self.assertEqual(str(inspect.Signature.from_frame(mod.fr)), | ||
| '(x=11, y=14)') | ||
| self.assertEqual(str(inspect.Signature.from_frame(mod.fr.f_back)), | ||
| '(a=7, /, b=8, c=9, d=3, e=4, f=5, *g, **h)') | ||
| class TestParameterObject(unittest.TestCase): | ||
| def test_signature_parameter_kinds(self): | ||
| P = inspect.Parameter | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Deprecate :func:`inspect.getargvalues` and :func:`inspect.formatargvalues`, | ||
| slate it for removal in 3.15; instead use | ||
| :meth:`inspect.Signature.from_frame`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like you can move
if frame.f_locals:out of this loop and the one below.