Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 37dc2b2

Browse files
committed
Issue #25486: Resurrect inspect.getargspec in 3.6. Backout a565aad5d6e1.
The decision is that we shouldn't remove popular APIs (however long they are depreacted) from Python 3, while 2.7 is still around and supported.
1 parent ec71f17 commit 37dc2b2

5 files changed

Lines changed: 79 additions & 10 deletions

File tree

Doc/library/inspect.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,24 @@ Classes and functions
796796
classes using multiple inheritance and their descendants will appear multiple
797797
times.
798798

799+
800+
.. function:: getargspec(func)
801+
802+
Get the names and default values of a Python function's arguments. A
803+
:term:`named tuple` ``ArgSpec(args, varargs, keywords, defaults)`` is
804+
returned. *args* is a list of the argument names. *varargs* and *keywords*
805+
are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is a
806+
tuple of default argument values or ``None`` if there are no default
807+
arguments; if this tuple has *n* elements, they correspond to the last
808+
*n* elements listed in *args*.
809+
810+
.. deprecated:: 3.0
811+
Use :func:`signature` and
812+
:ref:`Signature Object <inspect-signature-object>`, which provide a
813+
better introspecting API for callables. This function will be removed
814+
in Python 3.6.
815+
816+
799817
.. function:: getfullargspec(func)
800818

801819
Get the names and default values of a Python function's arguments. A

Doc/whatsnew/3.6.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,6 @@ Removed
218218
API and Feature Removals
219219
------------------------
220220

221-
* ``inspect.getargspec()`` was removed (was deprecated since CPython 3.0).
222-
:func:`inspect.getfullargspec` is an almost drop in replacement.
223-
224221
* ``inspect.getmoduleinfo()`` was removed (was deprecated since CPython 3.3).
225222
:func:`inspect.getmodulename` should be used for obtaining the module
226223
name for a given path.

Lib/inspect.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,31 @@ def _getfullargs(co):
10041004
varkw = co.co_varnames[nargs]
10051005
return args, varargs, kwonlyargs, varkw
10061006

1007+
1008+
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
1009+
1010+
def getargspec(func):
1011+
"""Get the names and default values of a function's arguments.
1012+
1013+
A tuple of four things is returned: (args, varargs, keywords, defaults).
1014+
'args' is a list of the argument names, including keyword-only argument names.
1015+
'varargs' and 'keywords' are the names of the * and ** arguments or None.
1016+
'defaults' is an n-tuple of the default values of the last n arguments.
1017+
1018+
Use the getfullargspec() API for Python 3 code, as annotations
1019+
and keyword arguments are supported. getargspec() will raise ValueError
1020+
if the func has either annotations or keyword arguments.
1021+
"""
1022+
warnings.warn("inspect.getargspec() is deprecated, "
1023+
"use inspect.signature() instead", DeprecationWarning,
1024+
stacklevel=2)
1025+
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1026+
getfullargspec(func)
1027+
if kwonlyargs or ann:
1028+
raise ValueError("Function has keyword-only arguments or annotations"
1029+
", use getfullargspec() API which can support them")
1030+
return ArgSpec(args, varargs, varkw, defaults)
1031+
10071032
FullArgSpec = namedtuple('FullArgSpec',
10081033
'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
10091034

Lib/test/test_inspect.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,18 @@ class D(B, C): pass
628628
got = inspect.getmro(D)
629629
self.assertEqual(expected, got)
630630

631+
def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
632+
varkw_e=None, defaults_e=None, formatted=None):
633+
with self.assertWarns(DeprecationWarning):
634+
args, varargs, varkw, defaults = inspect.getargspec(routine)
635+
self.assertEqual(args, args_e)
636+
self.assertEqual(varargs, varargs_e)
637+
self.assertEqual(varkw, varkw_e)
638+
self.assertEqual(defaults, defaults_e)
639+
if formatted is not None:
640+
self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
641+
formatted)
642+
631643
def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
632644
varkw_e=None, defaults_e=None,
633645
kwonlyargs_e=[], kwonlydefaults_e=None,
@@ -646,6 +658,23 @@ def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
646658
kwonlyargs, kwonlydefaults, ann),
647659
formatted)
648660

661+
def test_getargspec(self):
662+
self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
663+
664+
self.assertArgSpecEquals(mod.spam,
665+
['a', 'b', 'c', 'd', 'e', 'f'],
666+
'g', 'h', (3, 4, 5),
667+
'(a, b, c, d=3, e=4, f=5, *g, **h)')
668+
669+
self.assertRaises(ValueError, self.assertArgSpecEquals,
670+
mod2.keyworded, [])
671+
672+
self.assertRaises(ValueError, self.assertArgSpecEquals,
673+
mod2.annotated, [])
674+
self.assertRaises(ValueError, self.assertArgSpecEquals,
675+
mod2.keyword_only_arg, [])
676+
677+
649678
def test_getfullargspec(self):
650679
self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
651680
kwonlyargs_e=['arg2'],
@@ -659,19 +688,20 @@ def test_getfullargspec(self):
659688
kwonlyargs_e=['arg'],
660689
formatted='(*, arg)')
661690

662-
def test_fullargspec_api_ignores_wrapped(self):
691+
def test_argspec_api_ignores_wrapped(self):
663692
# Issue 20684: low level introspection API must ignore __wrapped__
664693
@functools.wraps(mod.spam)
665694
def ham(x, y):
666695
pass
667696
# Basic check
697+
self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
668698
self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
669699
self.assertFullArgSpecEquals(functools.partial(ham),
670700
['x', 'y'], formatted='(x, y)')
671701
# Other variants
672702
def check_method(f):
673-
self.assertFullArgSpecEquals(f, ['self', 'x', 'y'],
674-
formatted='(self, x, y)')
703+
self.assertArgSpecEquals(f, ['self', 'x', 'y'],
704+
formatted='(self, x, y)')
675705
class C:
676706
@functools.wraps(mod.spam)
677707
def ham(self, x, y):
@@ -749,11 +779,11 @@ def test_getfullagrspec_builtin_func_no_signature(self):
749779
with self.assertRaises(TypeError):
750780
inspect.getfullargspec(builtin)
751781

752-
def test_getfullargspec_method(self):
782+
def test_getargspec_method(self):
753783
class A(object):
754784
def m(self):
755785
pass
756-
self.assertFullArgSpecEquals(A.m, ['self'])
786+
self.assertArgSpecEquals(A.m, ['self'])
757787

758788
def test_classify_newstyle(self):
759789
class A(object):

Misc/NEWS

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,7 @@ Library
429429
- Issue #23661: unittest.mock side_effects can now be exceptions again. This
430430
was a regression vs Python 3.4. Patch from Ignacio Rossi
431431

432-
- Issue #13248: Remove deprecated inspect.getargspec and inspect.getmoduleinfo
433-
functions.
432+
- Issue #13248: Remove deprecated inspect.getmoduleinfo function.
434433

435434
- Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer().
436435

0 commit comments

Comments
 (0)