bpo-45320: Remove long-deprecated inspect methods (GH-28618)

This commit is contained in:
Hugo van Kemenade 2021-10-20 21:48:55 +03:00 committed by GitHub
parent d8e1819251
commit d89fb9a5a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 260 deletions

View file

@ -567,9 +567,6 @@ expression. Currently the following are explicitly supported:
* Simple symbolic constants like ``sys.maxsize``, which must
start with the name of the module
In case you're curious, this is implemented in ``from_builtin()``
in ``Lib/inspect.py``.
(In the future, this may need to get even more elaborate,
to allow full expressions like ``CONSTANT - 1``.)

View file

@ -935,26 +935,6 @@ Classes and functions
times.
.. function:: getargspec(func)
Get the names and default values of a Python function's parameters. A
:term:`named tuple` ``ArgSpec(args, varargs, keywords, defaults)`` is
returned. *args* is a list of the parameter names. *varargs* and *keywords*
are the names of the ``*`` and ``**`` parameters or ``None``. *defaults* is a
tuple of default argument values or ``None`` if there are no default
arguments; if this tuple has *n* elements, they correspond to the last
*n* elements listed in *args*.
.. deprecated:: 3.0
Use :func:`getfullargspec` for an updated API that is usually a drop-in
replacement, but also correctly handles function annotations and
keyword-only parameters.
Alternatively, use :func:`signature` and
:ref:`Signature Object <inspect-signature-object>`, which provide a
more structured introspection API for callables.
.. function:: getfullargspec(func)
Get the names and default values of a Python function's parameters. A
@ -1015,33 +995,6 @@ Classes and functions
This function was inadvertently marked as deprecated in Python 3.5.
.. function:: formatargspec(args[, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations[, formatarg, formatvarargs, formatvarkw, formatvalue, formatreturns, formatannotations]])
Format a pretty argument spec from the values returned by
:func:`getfullargspec`.
The first seven arguments are (``args``, ``varargs``, ``varkw``,
``defaults``, ``kwonlyargs``, ``kwonlydefaults``, ``annotations``).
The other six arguments are functions that are called to turn argument names,
``*`` argument name, ``**`` argument name, default values, return annotation
and individual annotations into strings, respectively.
For example:
>>> from inspect import formatargspec, getfullargspec
>>> def f(a: int, b: float):
... pass
...
>>> formatargspec(*getfullargspec(f))
'(a: int, b: float)'
.. deprecated:: 3.5
Use :func:`signature` and
:ref:`Signature Object <inspect-signature-object>`, which provide a
better introspecting API for callables.
.. function:: formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue])
Format a pretty argument spec from the four values returned by

View file

@ -363,7 +363,7 @@ Removed
``SO_REUSEADDR`` in UDP.
(Contributed by Hugo van Kemenade in :issue:`45129`.)
* Remove :meth:`__getitem__` methods of
* Removed :meth:`__getitem__` methods of
:class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper`
and :class:`fileinput.FileInput`, deprecated since Python 3.9.
(Contributed by Hugo van Kemenade in :issue:`45132`.)
@ -402,7 +402,7 @@ Removed
the ``l*gettext()`` functions.
(Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.)
* Remove from the :mod:`configparser` module:
* Removed from the :mod:`configparser` module:
the :class:`SafeConfigParser` class,
the :attr:`filename` property of the :class:`ParsingError` class,
the :meth:`readfp` method of the :class:`ConfigParser` class,
@ -419,9 +419,25 @@ Removed
generator-based coroutine objects in the debug mode.
(Contributed by Illia Volochii in :issue:`43216`.)
* Remove the deprecated ``split()`` method of :class:`_tkinter.TkappType`.
* Removed the deprecated ``split()`` method of :class:`_tkinter.TkappType`.
(Contributed by Erlend E. Aasland in :issue:`38371`.)
* Removed from the :mod:`inspect` module:
* the ``getargspec`` function, deprecated since Python 3.0;
use :func:`inspect.signature` or :func:`inspect.getfullargspec` instead.
* the ``formatargspec`` function, deprecated since Python 3.5;
use the :func:`inspect.signature` function and :class:`Signature` object
directly.
* the undocumented ``Signature.from_callable`` and ``Signature.from_function``
functions, deprecated since Python 3.5; use the
:meth:`Signature.from_callable() <inspect.Signature.from_callable>` method
instead.
(Contributed by Hugo van Kemenade in :issue:`45320`.)
Porting to Python 3.11
======================

View file

@ -47,7 +47,6 @@
import tokenize
import token
import types
import warnings
import functools
import builtins
from operator import attrgetter
@ -1214,37 +1213,6 @@ def getargs(co):
varkw = co.co_varnames[nargs]
return Arguments(args + kwonlyargs, varargs, varkw)
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
def getargspec(func):
"""Get the names and default values of a function's parameters.
A tuple of four things is returned: (args, varargs, keywords, defaults).
'args' is a list of the argument names, including keyword-only argument names.
'varargs' and 'keywords' are the names of the * and ** parameters or None.
'defaults' is an n-tuple of the default values of the last n parameters.
This function is deprecated, as it does not support annotations or
keyword-only parameters and will raise ValueError if either is present
on the supplied callable.
For a more structured introspection API, use inspect.signature() instead.
Alternatively, use getfullargspec() for an API with a similar namedtuple
based interface, but full support for annotations and keyword-only
parameters.
Deprecated since Python 3.5, use `inspect.getfullargspec()`.
"""
warnings.warn("inspect.getargspec() is deprecated since Python 3.0, "
"use inspect.signature() or inspect.getfullargspec()",
DeprecationWarning, stacklevel=2)
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
getfullargspec(func)
if kwonlyargs or ann:
raise ValueError("Function has keyword-only parameters or annotations"
", use inspect.signature() API which can support them")
return ArgSpec(args, varargs, varkw, defaults)
FullArgSpec = namedtuple('FullArgSpec',
'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations')
@ -1369,63 +1337,6 @@ def _formatannotation(annotation):
return formatannotation(annotation, module)
return _formatannotation
def formatargspec(args, varargs=None, varkw=None, defaults=None,
kwonlyargs=(), kwonlydefaults={}, annotations={},
formatarg=str,
formatvarargs=lambda name: '*' + name,
formatvarkw=lambda name: '**' + name,
formatvalue=lambda value: '=' + repr(value),
formatreturns=lambda text: ' -> ' + text,
formatannotation=formatannotation):
"""Format an argument spec from the values returned by getfullargspec.
The first seven arguments are (args, varargs, varkw, defaults,
kwonlyargs, kwonlydefaults, annotations). The other five arguments
are the corresponding optional formatting functions that are called to
turn names and values into strings. The last argument is an optional
function to format the sequence of arguments.
Deprecated since Python 3.5: use the `signature` function and `Signature`
objects.
"""
from warnings import warn
warn("`formatargspec` is deprecated since Python 3.5. Use `signature` and "
"the `Signature` object directly",
DeprecationWarning,
stacklevel=2)
def formatargandannotation(arg):
result = formatarg(arg)
if arg in annotations:
result += ': ' + formatannotation(annotations[arg])
return result
specs = []
if defaults:
firstdefault = len(args) - len(defaults)
for i, arg in enumerate(args):
spec = formatargandannotation(arg)
if defaults and i >= firstdefault:
spec = spec + formatvalue(defaults[i - firstdefault])
specs.append(spec)
if varargs is not None:
specs.append(formatvarargs(formatargandannotation(varargs)))
else:
if kwonlyargs:
specs.append('*')
if kwonlyargs:
for kwonlyarg in kwonlyargs:
spec = formatargandannotation(kwonlyarg)
if kwonlydefaults and kwonlyarg in kwonlydefaults:
spec += formatvalue(kwonlydefaults[kwonlyarg])
specs.append(spec)
if varkw is not None:
specs.append(formatvarkw(formatargandannotation(varkw)))
result = '(' + ', '.join(specs) + ')'
if 'return' in annotations:
result += formatreturns(formatannotation(annotations['return']))
return result
def formatargvalues(args, varargs, varkw, locals,
formatarg=str,
@ -2932,30 +2843,6 @@ def __init__(self, parameters=None, *, return_annotation=_empty,
self._parameters = types.MappingProxyType(params)
self._return_annotation = return_annotation
@classmethod
def from_function(cls, func):
"""Constructs Signature for the given python function.
Deprecated since Python 3.5, use `Signature.from_callable()`.
"""
warnings.warn("inspect.Signature.from_function() is deprecated since "
"Python 3.5, use Signature.from_callable()",
DeprecationWarning, stacklevel=2)
return _signature_from_function(cls, func)
@classmethod
def from_builtin(cls, func):
"""Constructs Signature for the given builtin function.
Deprecated since Python 3.5, use `Signature.from_callable()`.
"""
warnings.warn("inspect.Signature.from_builtin() is deprecated since "
"Python 3.5, use Signature.from_callable()",
DeprecationWarning, stacklevel=2)
return _signature_from_builtin(cls, func)
@classmethod
def from_callable(cls, obj, *,
follow_wrapped=True, globals=None, locals=None, eval_str=False):

View file

@ -43,7 +43,7 @@
# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
# getclasstree, getargvalues, formatargspec, formatargvalues,
# getclasstree, getargvalues, formatargvalues,
# currentframe, stack, trace, isdatadescriptor
# NOTE: There are some additional tests relating to interaction with
@ -844,24 +844,11 @@ class D(B, C): pass
got = inspect.getmro(D)
self.assertEqual(expected, got)
def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
varkw_e=None, defaults_e=None, formatted=None):
with self.assertWarns(DeprecationWarning):
args, varargs, varkw, defaults = inspect.getargspec(routine)
self.assertEqual(args, args_e)
self.assertEqual(varargs, varargs_e)
self.assertEqual(varkw, varkw_e)
self.assertEqual(defaults, defaults_e)
if formatted is not None:
with self.assertWarns(DeprecationWarning):
self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
formatted)
def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
varkw_e=None, defaults_e=None,
posonlyargs_e=[], kwonlyargs_e=[],
kwonlydefaults_e=None,
ann_e={}, formatted=None):
ann_e={}):
args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
inspect.getfullargspec(routine)
self.assertEqual(args, args_e)
@ -871,58 +858,30 @@ def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
self.assertEqual(kwonlyargs, kwonlyargs_e)
self.assertEqual(kwonlydefaults, kwonlydefaults_e)
self.assertEqual(ann, ann_e)
if formatted is not None:
with self.assertWarns(DeprecationWarning):
self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
kwonlyargs, kwonlydefaults, ann),
formatted)
def test_getargspec(self):
self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
self.assertArgSpecEquals(mod.spam,
['a', 'b', 'c', 'd', 'e', 'f'],
'g', 'h', (3, 4, 5),
'(a, b, c, d=3, e=4, f=5, *g, **h)')
self.assertRaises(ValueError, self.assertArgSpecEquals,
mod2.keyworded, [])
self.assertRaises(ValueError, self.assertArgSpecEquals,
mod2.annotated, [])
self.assertRaises(ValueError, self.assertArgSpecEquals,
mod2.keyword_only_arg, [])
def test_getfullargspec(self):
self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
kwonlyargs_e=['arg2'],
kwonlydefaults_e={'arg2':1},
formatted='(*arg1, arg2=1)')
kwonlydefaults_e={'arg2':1})
self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
ann_e={'arg1' : list},
formatted='(arg1: list)')
ann_e={'arg1' : list})
self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
kwonlyargs_e=['arg'],
formatted='(*, arg)')
kwonlyargs_e=['arg'])
self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
kwonlyargs_e=['e', 'f'],
formatted='(a, b, c, d, *, e, f)')
kwonlyargs_e=['e', 'f'])
self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
['a', 'b', 'c', 'd'],
varargs_e='args',
varkw_e='kwargs',
kwonlyargs_e=['e', 'f'],
formatted='(a, b, c, d, *args, e, f, **kwargs)')
kwonlyargs_e=['e', 'f'])
self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
defaults_e=(1,2,3),
kwonlyargs_e=['e', 'f'],
kwonlydefaults_e={'e': 4, 'f': 5},
formatted='(a, b=1, c=2, d=3, *, e=4, f=5)')
kwonlydefaults_e={'e': 4, 'f': 5})
def test_argspec_api_ignores_wrapped(self):
# Issue 20684: low level introspection API must ignore __wrapped__
@ -930,39 +889,9 @@ def test_argspec_api_ignores_wrapped(self):
def ham(x, y):
pass
# Basic check
self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
self.assertFullArgSpecEquals(ham, ['x', 'y'])
self.assertFullArgSpecEquals(functools.partial(ham),
['x', 'y'], formatted='(x, y)')
# Other variants
def check_method(f):
self.assertArgSpecEquals(f, ['self', 'x', 'y'],
formatted='(self, x, y)')
class C:
@functools.wraps(mod.spam)
def ham(self, x, y):
pass
pham = functools.partialmethod(ham)
@functools.wraps(mod.spam)
def __call__(self, x, y):
pass
check_method(C())
check_method(C.ham)
check_method(C().ham)
check_method(C.pham)
check_method(C().pham)
class C_new:
@functools.wraps(mod.spam)
def __new__(self, x, y):
pass
check_method(C_new)
class C_init:
@functools.wraps(mod.spam)
def __init__(self, x, y):
pass
check_method(C_init)
['x', 'y'])
def test_getfullargspec_signature_attr(self):
def test():
@ -970,7 +899,7 @@ def test():
spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
test.__signature__ = inspect.Signature(parameters=(spam_param,))
self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)')
self.assertFullArgSpecEquals(test, ['spam'])
def test_getfullargspec_signature_annos(self):
def test(a:'spam') -> 'ham': pass
@ -984,18 +913,15 @@ def test(): pass
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_getfullargspec_builtin_methods(self):
self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'],
formatted='(self, obj)')
self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'])
self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'],
formatted='(self, obj)')
self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'])
self.assertFullArgSpecEquals(
os.stat,
args_e=['path'],
kwonlyargs_e=['dir_fd', 'follow_symlinks'],
kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
formatted='(path, *, dir_fd=None, follow_symlinks=True)')
kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True})
@cpython_only
@unittest.skipIf(MISSING_C_DOCSTRINGS,
@ -1026,12 +952,6 @@ def test_getfullargspec_definition_order_preserved_on_kwonly(self):
l = list(signature.kwonlyargs)
self.assertEqual(l, unsorted_keyword_only_parameters)
def test_getargspec_method(self):
class A(object):
def m(self):
pass
self.assertArgSpecEquals(A.m, ['self'])
def test_classify_newstyle(self):
class A(object):

View file

@ -0,0 +1,15 @@
Removed from the :mod:`inspect` module:
* the ``getargspec`` function, deprecated since Python 3.0;
use :func:`inspect.signature` or :func:`inspect.getfullargspec` instead.
* the ``formatargspec`` function, deprecated since Python 3.5;
use the :func:`inspect.signature` function and :class:`Signature` object
directly.
* the undocumented ``Signature.from_callable`` and ``Signature.from_function``
functions, deprecated since Python 3.5; use the
:meth:`Signature.from_callable() <inspect.Signature.from_callable>` method
instead.
Patch by Hugo van Kemenade.