Skip to content

Commit ff422bd

Browse files
gh-141560: Add annotation_format parameter to getfullargspec (#149457)
1 parent 8cad740 commit ff422bd

4 files changed

Lines changed: 36 additions & 7 deletions

File tree

Doc/library/inspect.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,7 @@ Classes and functions
11891189
times.
11901190

11911191

1192-
.. function:: getfullargspec(func)
1192+
.. function:: getfullargspec(func, *, annotation_format=Format.VALUE)
11931193

11941194
Get the names and default values of a Python function's parameters. A
11951195
:term:`named tuple` is returned:
@@ -1219,6 +1219,14 @@ Classes and functions
12191219
APIs. This function is retained primarily for use in code that needs to
12201220
maintain compatibility with the Python 2 ``inspect`` module API.
12211221

1222+
A member of the
1223+
:class:`annotationlib.Format` enum can be passed to the
1224+
*annotation_format* parameter to control the format of the returned
1225+
annotations. For example, use
1226+
``annotation_format=annotationlib.Format.STRING`` to return annotations in string
1227+
format. Note that with the default ``VALUE`` format, creation of some argspecs
1228+
may raise an exception.
1229+
12221230
.. versionchanged:: 3.4
12231231
This function is now based on :func:`signature`, but still ignores
12241232
``__wrapped__`` attributes and includes the already bound first
@@ -1236,6 +1244,9 @@ Classes and functions
12361244
order of keyword-only parameters as of version 3.7, although in practice
12371245
this order had always been preserved in Python 3.
12381246

1247+
.. versionchanged:: next
1248+
The *annotation_format* parameter was added.
1249+
12391250

12401251
.. function:: getargvalues(frame)
12411252

Lib/inspect.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,18 +1254,20 @@ def getargs(co):
12541254
FullArgSpec = namedtuple('FullArgSpec',
12551255
'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
12561256

1257-
def getfullargspec(func):
1257+
def getfullargspec(func, *, annotation_format=Format.VALUE):
12581258
"""Get the names and default values of a callable object's parameters.
12591259
1260-
A tuple of seven things is returned:
1261-
(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations).
1260+
A FullArgSpec namedtuple is returned, which has the following attributes:
12621261
'args' is a list of the parameter names.
12631262
'varargs' and 'varkw' are the names of the * and ** parameters or None.
12641263
'defaults' is an n-tuple of the default values of the last n parameters.
12651264
'kwonlyargs' is a list of keyword-only parameter names.
12661265
'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults.
12671266
'annotations' is a dictionary mapping parameter names to annotations.
12681267
1268+
The *annotation_format* parameter controls the format of the annotations.
1269+
See the annotationlib documentation for details.
1270+
12691271
Notable differences from inspect.signature():
12701272
- the "self" parameter is always reported, even for bound methods
12711273
- wrapper chains defined by __wrapped__ *not* unwrapped automatically
@@ -1291,7 +1293,8 @@ def getfullargspec(func):
12911293
follow_wrapper_chains=False,
12921294
skip_bound_arg=False,
12931295
sigcls=Signature,
1294-
eval_str=False)
1296+
eval_str=False,
1297+
annotation_format=annotation_format)
12951298
except Exception as ex:
12961299
# Most of the times 'signature' will raise ValueError.
12971300
# But, it can also raise AttributeError, and, maybe something

Lib/test/test_inspect/test_inspect.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,9 +1355,10 @@ def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
13551355
varkw_e=None, defaults_e=None,
13561356
posonlyargs_e=[], kwonlyargs_e=[],
13571357
kwonlydefaults_e=None,
1358-
ann_e={}):
1358+
ann_e={},
1359+
annotation_format=Format.VALUE):
13591360
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1360-
inspect.getfullargspec(routine)
1361+
inspect.getfullargspec(routine, annotation_format=annotation_format)
13611362
self.assertEqual(args, args_e)
13621363
self.assertEqual(varargs, varargs_e)
13631364
self.assertEqual(varkw, varkw_e)
@@ -1390,6 +1391,19 @@ def test_getfullargspec(self):
13901391
kwonlyargs_e=['e', 'f'],
13911392
kwonlydefaults_e={'e': 4, 'f': 5})
13921393

1394+
def get_getfullargspec_with_undefined_names_in_annotations(self):
1395+
def my_func(a: undefined_name):
1396+
pass
1397+
1398+
with self.assertRaises(NameError):
1399+
inspect.getfullargspec(my_func)
1400+
1401+
self.assertFullArgSpecEquals(my_func, ['a'], ann_e={'a': 'undefined_name'},
1402+
annotation_format=Format.STRING)
1403+
1404+
arg_spec = inspect.getfullargspec(my_func, annotation_format=Format.FORWARDREF)
1405+
self.assertIsInstance(arg_spec.annotations['a'], ForwardRef)
1406+
13931407
def test_argspec_api_ignores_wrapped(self):
13941408
# Issue 20684: low level introspection API must ignore __wrapped__
13951409
@functools.wraps(mod.spam)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add an *annotation_format* parameter to :func:`inspect.getfullargspec`.

0 commit comments

Comments
 (0)