Skip to content

Commit bd9aef9

Browse files
committed
Implement the identity function in the operator module
1 parent e329f74 commit bd9aef9

File tree

10 files changed

+64
-55
lines changed

10 files changed

+64
-55
lines changed

Doc/library/operator.rst

+7
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,13 @@ expect a function argument.
384384
return caller
385385

386386

387+
.. function:: identity(obj, /)
388+
389+
Returns *obj* unchanged.
390+
391+
.. versionadded:: next
392+
393+
387394
.. _operator-map:
388395

389396
Mapping Operators to Functions

Lib/operator.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
__all__ = ['abs', 'add', 'and_', 'attrgetter', 'call', 'concat', 'contains', 'countOf',
1414
'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand',
15-
'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul',
15+
'iconcat', 'identity', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul',
1616
'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift',
1717
'is_', 'is_none', 'is_not', 'is_not_none', 'isub', 'itemgetter', 'itruediv',
1818
'ixor', 'le', 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod',
@@ -231,6 +231,10 @@ def length_hint(obj, default=0):
231231

232232
# Other Operations ************************************************************#
233233

234+
def identity(obj, /):
235+
"""Return the argument unchanged."""
236+
return obj
237+
234238
def call(obj, /, *args, **kwargs):
235239
"""Same as obj(*args, **kwargs)."""
236240
return obj(*args, **kwargs)

Lib/test/test_operator.py

+21
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,27 @@ class Y: pass
614614
operator.length_hint(X(2), "abc")
615615
self.assertEqual(operator.length_hint(Y(), 10), 10)
616616

617+
def test_identity(self):
618+
operator = self.module
619+
a = 'spam'
620+
b = []
621+
b.append(b)
622+
c = None
623+
d = object()
624+
try:
625+
1/0
626+
except ZeroDivisionError as exc:
627+
e = exc
628+
f = {a, c, d, 'ham' * 1000}
629+
630+
self.assertRaises(TypeError, operator.identity)
631+
self.assertIs(operator.identity(a), a)
632+
self.assertIs(operator.identity(b), b)
633+
self.assertIs(operator.identity(c), c)
634+
self.assertIs(operator.identity(d), d)
635+
self.assertIs(operator.identity(e), e)
636+
self.assertIs(operator.identity(f), f)
637+
617638
def test_call(self):
618639
operator = self.module
619640

Lib/test/test_typing.py

-8
Original file line numberDiff line numberDiff line change
@@ -7868,14 +7868,6 @@ def foo(a: A) -> Optional[BaseException]:
78687868
self.assertIsNone(foo(None))
78697869

78707870

7871-
class TestModules(TestCase):
7872-
func_names = ['_idfunc']
7873-
7874-
def test_c_functions(self):
7875-
for fname in self.func_names:
7876-
self.assertEqual(getattr(typing, fname).__module__, '_typing')
7877-
7878-
78797871
class NewTypeTests(BaseTestCase):
78807872
@classmethod
78817873
def setUpClass(cls):

Lib/typing.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
from types import GenericAlias
3131

3232
from _typing import (
33-
_idfunc,
3433
TypeVar,
3534
ParamSpec,
3635
TypeVarTuple,
@@ -3359,7 +3358,7 @@ def name_by_id(user_id: UserId) -> str:
33593358
num = UserId(5) + 1 # type: int
33603359
"""
33613360

3362-
__call__ = _idfunc
3361+
__call__ = operator.identity
33633362

33643363
def __init__(self, name, tp):
33653364
self.__qualname__ = name
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add :func:`operator.identity`, the identity function.
2+
Patch by Adam Turner.

Modules/_operator.c

+17
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,22 @@ _operator__compare_digest_impl(PyObject *module, PyObject *a, PyObject *b)
915915
return PyBool_FromLong(rc);
916916
}
917917

918+
/*[clinic input]
919+
_operator.identity -> object
920+
921+
obj: object
922+
/
923+
924+
Return the argument unchanged.
925+
[clinic start generated code]*/
926+
927+
static PyObject *
928+
_operator_identity(PyObject *module, PyObject *obj)
929+
/*[clinic end generated code: output=deede47105fe0dd8 input=72f5a615c2a823c2]*/
930+
{
931+
return Py_NewRef(obj);
932+
}
933+
918934
PyDoc_STRVAR(_operator_call__doc__,
919935
"call($module, obj, /, *args, **kwargs)\n"
920936
"--\n"
@@ -994,6 +1010,7 @@ static struct PyMethodDef operator_methods[] = {
9941010
_OPERATOR_GE_METHODDEF
9951011
_OPERATOR__COMPARE_DIGEST_METHODDEF
9961012
_OPERATOR_LENGTH_HINT_METHODDEF
1013+
_OPERATOR_IDENTITY_METHODDEF
9971014
_OPERATOR_CALL_METHODDEF
9981015
{NULL, NULL} /* sentinel */
9991016

Modules/_typingmodule.c

+1-31
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,6 @@
99
#include "internal/pycore_typevarobject.h"
1010
#include "internal/pycore_unionobject.h" // _PyUnion_Type
1111
#include "pycore_pystate.h" // _PyInterpreterState_GET()
12-
#include "clinic/_typingmodule.c.h"
13-
14-
/*[clinic input]
15-
module _typing
16-
17-
[clinic start generated code]*/
18-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1db35baf1c72942b]*/
19-
20-
/* helper function to make typing.NewType.__call__ method faster */
21-
22-
/*[clinic input]
23-
_typing._idfunc -> object
24-
25-
x: object
26-
/
27-
28-
[clinic start generated code]*/
29-
30-
static PyObject *
31-
_typing__idfunc(PyObject *module, PyObject *x)
32-
/*[clinic end generated code: output=63c38be4a6ec5f2c input=49f17284b43de451]*/
33-
{
34-
return Py_NewRef(x);
35-
}
36-
37-
38-
static PyMethodDef typing_methods[] = {
39-
_TYPING__IDFUNC_METHODDEF
40-
{NULL, NULL, 0, NULL}
41-
};
4212

4313
PyDoc_STRVAR(typing_doc,
4414
"Primitives and accelerators for the typing module.\n");
@@ -85,7 +55,7 @@ static struct PyModuleDef typingmodule = {
8555
"_typing",
8656
typing_doc,
8757
0,
88-
typing_methods,
58+
NULL,
8959
_typingmodule_slots,
9060
NULL,
9161
NULL,

Modules/clinic/_operator.c.h

+10-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/clinic/_typingmodule.c.h

-12
This file was deleted.

0 commit comments

Comments
 (0)