mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-44019: Implement operator.call(). (GH-27888)
Having `operator.call(obj, arg)` mean `type(obj).__call__(obj, arg)` is consistent with the other dunder operators. The semantics with `*args, **kwargs` then follow naturally from the single-arg semantics.
This commit is contained in:
parent
8d8729146f
commit
6587fc60d4
6 changed files with 62 additions and 0 deletions
|
@ -250,6 +250,17 @@ Operations which work with sequences (some of them with mappings too) include:
|
|||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
|
||||
The following operation works with callables:
|
||||
|
||||
.. function:: call(obj, / *args, **kwargs)
|
||||
__call__(obj, /, *args, **kwargs)
|
||||
|
||||
Return ``obj(*args, **kwargs)``.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
The :mod:`operator` module also defines tools for generalized attribute and item
|
||||
lookups. These are useful for making fast field extractors as arguments for
|
||||
:func:`map`, :func:`sorted`, :meth:`itertools.groupby`, or other functions that
|
||||
|
|
|
@ -205,6 +205,14 @@ math
|
|||
Dickinson in :issue:`44339`.)
|
||||
|
||||
|
||||
operator
|
||||
--------
|
||||
|
||||
* A new function ``operator.call`` has been added, such that
|
||||
``operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)``.
|
||||
(Contributed by Antony Lee in :issue:`44019`.)
|
||||
|
||||
|
||||
os
|
||||
--
|
||||
|
||||
|
|
|
@ -221,6 +221,12 @@ def length_hint(obj, default=0):
|
|||
raise ValueError(msg)
|
||||
return val
|
||||
|
||||
# Other Operations ************************************************************#
|
||||
|
||||
def call(obj, /, *args, **kwargs):
|
||||
"""Same as obj(*args, **kwargs)."""
|
||||
return obj(*args, **kwargs)
|
||||
|
||||
# Generalized Lookup Objects **************************************************#
|
||||
|
||||
class attrgetter:
|
||||
|
@ -423,6 +429,7 @@ __not__ = not_
|
|||
__abs__ = abs
|
||||
__add__ = add
|
||||
__and__ = and_
|
||||
__call__ = call
|
||||
__floordiv__ = floordiv
|
||||
__index__ = index
|
||||
__inv__ = inv
|
||||
|
|
|
@ -518,6 +518,18 @@ class OperatorTestCase:
|
|||
with self.assertRaises(LookupError):
|
||||
operator.length_hint(X(LookupError))
|
||||
|
||||
def test_call(self):
|
||||
operator = self.module
|
||||
|
||||
def func(*args, **kwargs): return args, kwargs
|
||||
|
||||
self.assertEqual(operator.call(func), ((), {}))
|
||||
self.assertEqual(operator.call(func, 0, 1), ((0, 1), {}))
|
||||
self.assertEqual(operator.call(func, a=2, obj=3),
|
||||
((), {"a": 2, "obj": 3}))
|
||||
self.assertEqual(operator.call(func, 0, 1, a=2, obj=3),
|
||||
((0, 1), {"a": 2, "obj": 3}))
|
||||
|
||||
def test_dunder_is_original(self):
|
||||
operator = self.module
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
A new function ``operator.call`` has been added, such that
|
||||
``operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)``.
|
|
@ -886,6 +886,27 @@ _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
|
|||
return PyBool_FromLong(rc);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_operator_call__doc__,
|
||||
"call($module, obj, /, *args, **kwargs)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Same as obj(*args, **kwargs).");
|
||||
|
||||
#define _OPERATOR_CALL_METHODDEF \
|
||||
{"call", (PyCFunction)(void(*)(void))_operator_call, METH_FASTCALL | METH_KEYWORDS, _operator_call__doc__},
|
||||
|
||||
static PyObject *
|
||||
_operator_call(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
if (!_PyArg_CheckPositional("call", nargs, 1, PY_SSIZE_T_MAX)) {
|
||||
return NULL;
|
||||
}
|
||||
return PyObject_Vectorcall(
|
||||
args[0],
|
||||
&args[1], (PyVectorcall_NARGS(nargs) - 1) | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||
kwnames);
|
||||
}
|
||||
|
||||
/* operator methods **********************************************************/
|
||||
|
||||
static struct PyMethodDef operator_methods[] = {
|
||||
|
@ -942,6 +963,7 @@ static struct PyMethodDef operator_methods[] = {
|
|||
_OPERATOR_GE_METHODDEF
|
||||
_OPERATOR__COMPARE_DIGEST_METHODDEF
|
||||
_OPERATOR_LENGTH_HINT_METHODDEF
|
||||
_OPERATOR_CALL_METHODDEF
|
||||
{NULL, NULL} /* sentinel */
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue