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

Skip to content

Commit 2cca8ef

Browse files
Rémi Lapeyremethane
authored andcommitted
bpo-36350: inspect: Replace OrderedDict with dict. (GH-12412)
1 parent 0be3246 commit 2cca8ef

4 files changed

Lines changed: 39 additions & 29 deletions

File tree

Doc/library/inspect.rst

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -624,15 +624,18 @@ function.
624624

625625
.. attribute:: Signature.parameters
626626

627-
An ordered mapping of parameters' names to the corresponding
628-
:class:`Parameter` objects. Parameters appear in strict definition
629-
order, including keyword-only parameters.
627+
An dictionary of :class:`Parameter` objects. Parameters appear in strict
628+
definition order, including keyword-only parameters.
630629

631630
.. versionchanged:: 3.7
632631
Python only explicitly guaranteed that it preserved the declaration
633632
order of keyword-only parameters as of version 3.7, although in practice
634633
this order had always been preserved in Python 3.
635634

635+
.. versionchanged:: 3.9
636+
:attr:`parameters` is now of type :class:`dict`. Formerly, it was of
637+
type :class:`collections.OrderedDict`.
638+
636639
.. attribute:: Signature.return_annotation
637640

638641
The "return" annotation for the callable. If the callable has no "return"
@@ -821,10 +824,9 @@ function.
821824

822825
.. attribute:: BoundArguments.arguments
823826

824-
An ordered, mutable mapping (:class:`collections.OrderedDict`) of
825-
parameters' names to arguments' values. Contains only explicitly bound
826-
arguments. Changes in :attr:`arguments` will reflect in :attr:`args` and
827-
:attr:`kwargs`.
827+
An ordered, mutable mapping of parameters' names to arguments' values.
828+
Contains only explicitly bound arguments. Changes in :attr:`arguments`
829+
will reflect in :attr:`args` and :attr:`kwargs`.
828830

829831
Should be used in conjunction with :attr:`Signature.parameters` for any
830832
argument processing purposes.
@@ -836,6 +838,10 @@ function.
836838
However, if needed, use :meth:`BoundArguments.apply_defaults` to add
837839
them.
838840

841+
.. versionchanged:: 3.9
842+
:attr:`arguments` is now of type :class:`dict`. Formerly, it was of
843+
type :class:`collections.OrderedDict`.
844+
839845
.. attribute:: BoundArguments.args
840846

841847
A tuple of positional arguments values. Dynamically computed from the
@@ -866,7 +872,7 @@ function.
866872
>>> ba = inspect.signature(foo).bind('spam')
867873
>>> ba.apply_defaults()
868874
>>> ba.arguments
869-
OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())])
875+
{'a': 'spam', 'b': 'ham', 'args': ()}
870876

871877
.. versionadded:: 3.5
872878

Lib/inspect.py

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import functools
4949
import builtins
5050
from operator import attrgetter
51-
from collections import namedtuple, OrderedDict
51+
from collections import namedtuple
5252

5353
# Create constants for the compiler flags in Include/code.h
5454
# We try to get them from dis to avoid duplication
@@ -1727,7 +1727,7 @@ def _signature_get_partial(wrapped_sig, partial, extra_args=()):
17271727
"""
17281728

17291729
old_params = wrapped_sig.parameters
1730-
new_params = OrderedDict(old_params.items())
1730+
new_params = {}
17311731

17321732
partial_args = partial.args or ()
17331733
partial_keywords = partial.keywords or {}
@@ -1743,6 +1743,7 @@ def _signature_get_partial(wrapped_sig, partial, extra_args=()):
17431743

17441744

17451745
transform_to_kwonly = False
1746+
kwonly_params = {} # Keyword only parameters are moved to end.
17461747
for param_name, param in old_params.items():
17471748
try:
17481749
arg_value = ba.arguments[param_name]
@@ -1752,7 +1753,6 @@ def _signature_get_partial(wrapped_sig, partial, extra_args=()):
17521753
if param.kind is _POSITIONAL_ONLY:
17531754
# If positional-only parameter is bound by partial,
17541755
# it effectively disappears from the signature
1755-
new_params.pop(param_name)
17561756
continue
17571757

17581758
if param.kind is _POSITIONAL_OR_KEYWORD:
@@ -1771,28 +1771,26 @@ def _signature_get_partial(wrapped_sig, partial, extra_args=()):
17711771
# multiple values.
17721772
transform_to_kwonly = True
17731773
# Set the new default value
1774-
new_params[param_name] = param.replace(default=arg_value)
1774+
param = param.replace(default=arg_value)
17751775
else:
17761776
# was passed as a positional argument
1777-
new_params.pop(param.name)
17781777
continue
17791778

17801779
if param.kind is _KEYWORD_ONLY:
17811780
# Set the new default value
1782-
new_params[param_name] = param.replace(default=arg_value)
1781+
param = param.replace(default=arg_value)
17831782

17841783
if transform_to_kwonly:
17851784
assert param.kind is not _POSITIONAL_ONLY
17861785

17871786
if param.kind is _POSITIONAL_OR_KEYWORD:
1788-
new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY)
1789-
new_params[param_name] = new_param
1790-
new_params.move_to_end(param_name)
1787+
kwonly_params[param_name] = param.replace(kind=_KEYWORD_ONLY)
17911788
elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD):
1792-
new_params.move_to_end(param_name)
1793-
elif param.kind is _VAR_POSITIONAL:
1794-
new_params.pop(param.name)
1789+
kwonly_params[param_name] = param
1790+
else:
1791+
new_params[param_name] = param
17951792

1793+
new_params.update(kwonly_params)
17961794
return wrapped_sig.replace(parameters=new_params.values())
17971795

17981796

@@ -2602,7 +2600,7 @@ class BoundArguments:
26022600
26032601
Has the following public attributes:
26042602
2605-
* arguments : OrderedDict
2603+
* arguments : dict
26062604
An ordered mutable mapping of parameters' names to arguments' values.
26072605
Does not contain arguments' default values.
26082606
* signature : Signature
@@ -2702,7 +2700,7 @@ def apply_defaults(self):
27022700
# Signature.bind_partial().
27032701
continue
27042702
new_arguments.append((name, val))
2705-
self.arguments = OrderedDict(new_arguments)
2703+
self.arguments = dict(new_arguments)
27062704

27072705
def __eq__(self, other):
27082706
if self is other:
@@ -2733,7 +2731,7 @@ class Signature:
27332731
27342732
A Signature object has the following public attributes and methods:
27352733
2736-
* parameters : OrderedDict
2734+
* parameters : dict
27372735
An ordered mapping of parameters' names to the corresponding
27382736
Parameter objects (keyword-only arguments are in the same order
27392737
as listed in `code.co_varnames`).
@@ -2763,14 +2761,14 @@ def __init__(self, parameters=None, *, return_annotation=_empty,
27632761
"""
27642762

27652763
if parameters is None:
2766-
params = OrderedDict()
2764+
params = {}
27672765
else:
27682766
if __validate_parameters__:
2769-
params = OrderedDict()
2767+
params = {}
27702768
top_kind = _POSITIONAL_ONLY
27712769
kind_defaults = False
27722770

2773-
for idx, param in enumerate(parameters):
2771+
for param in parameters:
27742772
kind = param.kind
27752773
name = param.name
27762774

@@ -2805,8 +2803,7 @@ def __init__(self, parameters=None, *, return_annotation=_empty,
28052803

28062804
params[name] = param
28072805
else:
2808-
params = OrderedDict(((param.name, param)
2809-
for param in parameters))
2806+
params = {param.name: param for param in parameters}
28102807

28112808
self._parameters = types.MappingProxyType(params)
28122809
self._return_annotation = return_annotation
@@ -2888,7 +2885,7 @@ def __eq__(self, other):
28882885
def _bind(self, args, kwargs, *, partial=False):
28892886
"""Private method. Don't use directly."""
28902887

2891-
arguments = OrderedDict()
2888+
arguments = {}
28922889

28932890
parameters = iter(self.parameters.values())
28942891
parameters_ex = ()

Lib/test/test_inspect.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,6 +2077,7 @@ def test_signature_object(self):
20772077
P = inspect.Parameter
20782078

20792079
self.assertEqual(str(S()), '()')
2080+
self.assertEqual(repr(S().parameters), 'mappingproxy({})')
20802081

20812082
def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
20822083
pass
@@ -3681,6 +3682,10 @@ def foo(a='spam'): pass
36813682
ba.apply_defaults()
36823683
self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
36833684

3685+
def test_signature_bound_arguments_arguments_type(self):
3686+
def foo(a): pass
3687+
ba = inspect.signature(foo).bind(1)
3688+
self.assertIs(type(ba.arguments), dict)
36843689

36853690
class TestSignaturePrivateHelpers(unittest.TestCase):
36863691
def test_signature_get_bound_param(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`inspect.Signature.parameters` and `inspect.BoundArguments.arguments` are
2+
now dicts instead of OrderedDicts. Patch contributed by Rémi Lapeyre.

0 commit comments

Comments
 (0)