blob: adeb99e90adacda373df1c6089ba0b2711186be2 [file] [log] [blame]
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001
2#include "Python.h"
3
4PyDoc_STRVAR(operator_doc,
5"Operator interface.\n\
Guido van Rossum037b9401996-07-30 16:55:54 +00006\n\
7This module exports a set of functions implemented in C corresponding\n\
8to the intrinsic operators of Python. For example, operator.add(x, y)\n\
9is equivalent to the expression x+y. The function names are those\n\
Benjamin Petersona0dfa822009-11-13 02:25:08 +000010used for special methods; variants without leading and trailing\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000011'__' are also provided for convenience.");
Guido van Rossum037b9401996-07-30 16:55:54 +000012
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +000013#define spam1(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \
Guido van Rossum037b9401996-07-30 16:55:54 +000014 return AOP(a1); }
15
Fred Drake5639ba42000-07-08 04:12:08 +000016#define spam2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
Guido van Rossum037b9401996-07-30 16:55:54 +000017 PyObject *a1, *a2; \
Raymond Hettingerea3fdf42002-12-29 16:33:45 +000018 if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
Guido van Rossum037b9401996-07-30 16:55:54 +000019 return AOP(a1,a2); }
20
Fred Drake5639ba42000-07-08 04:12:08 +000021#define spamoi(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
Guido van Rossum037b9401996-07-30 16:55:54 +000022 PyObject *a1; int a2; \
Fred Drakeea4d3f02000-09-17 16:09:27 +000023 if(! PyArg_ParseTuple(a,"Oi:" #OP,&a1,&a2)) return NULL; \
Guido van Rossum037b9401996-07-30 16:55:54 +000024 return AOP(a1,a2); }
25
Fred Drake5639ba42000-07-08 04:12:08 +000026#define spam2n(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
Guido van Rossum037b9401996-07-30 16:55:54 +000027 PyObject *a1, *a2; \
Raymond Hettingerea3fdf42002-12-29 16:33:45 +000028 if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
Guido van Rossum037b9401996-07-30 16:55:54 +000029 if(-1 == AOP(a1,a2)) return NULL; \
30 Py_INCREF(Py_None); \
31 return Py_None; }
32
Fred Drake5639ba42000-07-08 04:12:08 +000033#define spam3n(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
Guido van Rossum037b9401996-07-30 16:55:54 +000034 PyObject *a1, *a2, *a3; \
Raymond Hettingerea3fdf42002-12-29 16:33:45 +000035 if(! PyArg_UnpackTuple(a,#OP,3,3,&a1,&a2,&a3)) return NULL; \
Guido van Rossum037b9401996-07-30 16:55:54 +000036 if(-1 == AOP(a1,a2,a3)) return NULL; \
37 Py_INCREF(Py_None); \
38 return Py_None; }
39
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +000040#define spami(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a1) { \
41 long r; \
Guido van Rossum037b9401996-07-30 16:55:54 +000042 if(-1 == (r=AOP(a1))) return NULL; \
Guido van Rossum77f6a652002-04-03 22:41:51 +000043 return PyBool_FromLong(r); }
Guido van Rossum037b9401996-07-30 16:55:54 +000044
Fred Drake5639ba42000-07-08 04:12:08 +000045#define spami2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
Guido van Rossum037b9401996-07-30 16:55:54 +000046 PyObject *a1, *a2; long r; \
Raymond Hettingerea3fdf42002-12-29 16:33:45 +000047 if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
Guido van Rossum037b9401996-07-30 16:55:54 +000048 if(-1 == (r=AOP(a1,a2))) return NULL; \
Christian Heimes217cfd12007-12-02 14:31:20 +000049 return PyLong_FromLong(r); }
Guido van Rossum037b9401996-07-30 16:55:54 +000050
Thomas Wouters477c8d52006-05-27 19:21:47 +000051#define spamn2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
52 PyObject *a1, *a2; Py_ssize_t r; \
53 if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
54 if(-1 == (r=AOP(a1,a2))) return NULL; \
Christian Heimes217cfd12007-12-02 14:31:20 +000055 return PyLong_FromSsize_t(r); }
Thomas Wouters477c8d52006-05-27 19:21:47 +000056
Guido van Rossum77f6a652002-04-03 22:41:51 +000057#define spami2b(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
58 PyObject *a1, *a2; long r; \
Raymond Hettingerea3fdf42002-12-29 16:33:45 +000059 if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
Guido van Rossum77f6a652002-04-03 22:41:51 +000060 if(-1 == (r=AOP(a1,a2))) return NULL; \
61 return PyBool_FromLong(r); }
62
Fred Drake428e75f2001-08-09 20:14:34 +000063#define spamrc(OP,A) static PyObject *OP(PyObject *s, PyObject *a) { \
64 PyObject *a1, *a2; \
Raymond Hettingerea3fdf42002-12-29 16:33:45 +000065 if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
Fred Drake428e75f2001-08-09 20:14:34 +000066 return PyObject_RichCompare(a1,a2,A); }
67
Guido van Rossum037b9401996-07-30 16:55:54 +000068spami(truth , PyObject_IsTrue)
Guido van Rossumc9fb47e1996-08-21 17:40:51 +000069spam2(op_add , PyNumber_Add)
70spam2(op_sub , PyNumber_Subtract)
71spam2(op_mul , PyNumber_Multiply)
Fred Drake428e75f2001-08-09 20:14:34 +000072spam2(op_floordiv , PyNumber_FloorDivide)
73spam2(op_truediv , PyNumber_TrueDivide)
Guido van Rossumc9fb47e1996-08-21 17:40:51 +000074spam2(op_mod , PyNumber_Remainder)
75spam1(op_neg , PyNumber_Negative)
76spam1(op_pos , PyNumber_Positive)
77spam1(op_abs , PyNumber_Absolute)
78spam1(op_inv , PyNumber_Invert)
Fred Drakeea4d3f02000-09-17 16:09:27 +000079spam1(op_invert , PyNumber_Invert)
Guido van Rossumc9fb47e1996-08-21 17:40:51 +000080spam2(op_lshift , PyNumber_Lshift)
81spam2(op_rshift , PyNumber_Rshift)
Guido van Rossum99c185e1998-04-09 17:54:26 +000082spami(op_not_ , PyObject_Not)
Guido van Rossumc9fb47e1996-08-21 17:40:51 +000083spam2(op_and_ , PyNumber_And)
84spam2(op_xor , PyNumber_Xor)
85spam2(op_or_ , PyNumber_Or)
Armin Rigof5bd3b42005-12-29 16:50:42 +000086spam2(op_iadd , PyNumber_InPlaceAdd)
87spam2(op_isub , PyNumber_InPlaceSubtract)
88spam2(op_imul , PyNumber_InPlaceMultiply)
Armin Rigof5bd3b42005-12-29 16:50:42 +000089spam2(op_ifloordiv , PyNumber_InPlaceFloorDivide)
90spam2(op_itruediv , PyNumber_InPlaceTrueDivide)
91spam2(op_imod , PyNumber_InPlaceRemainder)
92spam2(op_ilshift , PyNumber_InPlaceLshift)
93spam2(op_irshift , PyNumber_InPlaceRshift)
94spam2(op_iand , PyNumber_InPlaceAnd)
95spam2(op_ixor , PyNumber_InPlaceXor)
96spam2(op_ior , PyNumber_InPlaceOr)
Guido van Rossumc9fb47e1996-08-21 17:40:51 +000097spam2(op_concat , PySequence_Concat)
Armin Rigof5bd3b42005-12-29 16:50:42 +000098spam2(op_iconcat , PySequence_InPlaceConcat)
Guido van Rossum77f6a652002-04-03 22:41:51 +000099spami2b(op_contains , PySequence_Contains)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000100spamn2(indexOf , PySequence_Index)
101spamn2(countOf , PySequence_Count)
Guido van Rossumc9fb47e1996-08-21 17:40:51 +0000102spam2(op_getitem , PyObject_GetItem)
103spam2n(op_delitem , PyObject_DelItem)
104spam3n(op_setitem , PyObject_SetItem)
Fred Drake428e75f2001-08-09 20:14:34 +0000105spamrc(op_lt , Py_LT)
106spamrc(op_le , Py_LE)
107spamrc(op_eq , Py_EQ)
108spamrc(op_ne , Py_NE)
109spamrc(op_gt , Py_GT)
110spamrc(op_ge , Py_GE)
Guido van Rossum037b9401996-07-30 16:55:54 +0000111
112static PyObject*
Raymond Hettinger5959c552002-08-19 03:19:09 +0000113op_pow(PyObject *s, PyObject *a)
114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 PyObject *a1, *a2;
116 if (PyArg_UnpackTuple(a,"pow", 2, 2, &a1, &a2))
117 return PyNumber_Power(a1, a2, Py_None);
118 return NULL;
Raymond Hettinger5959c552002-08-19 03:19:09 +0000119}
120
121static PyObject*
Armin Rigof5bd3b42005-12-29 16:50:42 +0000122op_ipow(PyObject *s, PyObject *a)
123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 PyObject *a1, *a2;
125 if (PyArg_UnpackTuple(a,"ipow", 2, 2, &a1, &a2))
126 return PyNumber_InPlacePower(a1, a2, Py_None);
127 return NULL;
Armin Rigof5bd3b42005-12-29 16:50:42 +0000128}
129
Guido van Rossum38fff8c2006-03-07 18:50:55 +0000130static PyObject *
131op_index(PyObject *s, PyObject *a)
132{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 return PyNumber_Index(a);
Guido van Rossum38fff8c2006-03-07 18:50:55 +0000134}
135
Armin Rigof5bd3b42005-12-29 16:50:42 +0000136static PyObject*
Raymond Hettinger9543b342003-01-18 23:22:20 +0000137is_(PyObject *s, PyObject *a)
138{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 PyObject *a1, *a2, *result = NULL;
140 if (PyArg_UnpackTuple(a,"is_", 2, 2, &a1, &a2)) {
141 result = (a1 == a2) ? Py_True : Py_False;
142 Py_INCREF(result);
143 }
144 return result;
Raymond Hettinger9543b342003-01-18 23:22:20 +0000145}
146
147static PyObject*
148is_not(PyObject *s, PyObject *a)
149{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 PyObject *a1, *a2, *result = NULL;
151 if (PyArg_UnpackTuple(a,"is_not", 2, 2, &a1, &a2)) {
152 result = (a1 != a2) ? Py_True : Py_False;
153 Py_INCREF(result);
154 }
155 return result;
Raymond Hettinger9543b342003-01-18 23:22:20 +0000156}
157
Guido van Rossum037b9401996-07-30 16:55:54 +0000158#undef spam1
159#undef spam2
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000160#undef spam1o
161#undef spam1o
Christian Heimes6cea6552012-06-24 13:48:32 +0200162
163/* compare_digest **********************************************************/
164
165/*
166 * timing safe compare
167 *
168 * Returns 1 of the strings are equal.
169 * In case of len(a) != len(b) the function tries to keep the timing
170 * dependent on the length of b. CPU cache locally may still alter timing
171 * a bit.
172 */
173static int
174_tscmp(const unsigned char *a, const unsigned char *b,
175 Py_ssize_t len_a, Py_ssize_t len_b)
176{
177 /* The volatile type declarations make sure that the compiler has no
178 * chance to optimize and fold the code in any way that may change
179 * the timing.
180 */
181 volatile Py_ssize_t length;
182 volatile const unsigned char *left;
183 volatile const unsigned char *right;
184 Py_ssize_t i;
185 unsigned char result;
186
187 /* loop count depends on length of b */
188 length = len_b;
189 left = NULL;
190 right = b;
191
192 /* don't use else here to keep the amount of CPU instructions constant,
193 * volatile forces re-evaluation
194 * */
195 if (len_a == length) {
196 left = *((volatile const unsigned char**)&a);
197 result = 0;
198 }
199 if (len_a != length) {
200 left = b;
201 result = 1;
202 }
203
204 for (i=0; i < length; i++) {
205 result |= *left++ ^ *right++;
206 }
207
208 return (result == 0);
209}
210
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200211PyDoc_STRVAR(length_hint__doc__,
212"length_hint(obj, default=0) -> int\n"
213"Return an estimate of the number of items in obj.\n"
214"This is useful for presizing containers when building from an\n"
215"iterable.\n"
216"\n"
217"If the object supports len(), the result will be\n"
218"exact. Otherwise, it may over- or under-estimate by an\n"
219"arbitrary amount. The result will be an integer >= 0.");
220
221static PyObject *length_hint(PyObject *self, PyObject *args)
222{
223 PyObject *obj;
224 Py_ssize_t defaultvalue = 0, res;
225 if (!PyArg_ParseTuple(args, "O|n:length_hint", &obj, &defaultvalue)) {
226 return NULL;
227 }
228 res = PyObject_LengthHint(obj, defaultvalue);
229 if (res == -1 && PyErr_Occurred()) {
230 return NULL;
231 }
232 return PyLong_FromSsize_t(res);
233}
234
235
Christian Heimes6cea6552012-06-24 13:48:32 +0200236PyDoc_STRVAR(compare_digest__doc__,
237"compare_digest(a, b) -> bool\n"
238"\n"
Georg Brandla1bc35f2012-06-24 16:07:33 +0200239"Return 'a == b'. This function uses an approach designed to prevent\n"
240"timing analysis, making it appropriate for cryptography.\n"
241"a and b must both be of the same type: either str (ASCII only),\n"
242"or any type that supports the buffer protocol (e.g. bytes).\n"
Christian Heimes6cea6552012-06-24 13:48:32 +0200243"\n"
Georg Brandla1bc35f2012-06-24 16:07:33 +0200244"Note: If a and b are of different lengths, or if an error occurs,\n"
Larry Hastings48986d62012-06-25 00:59:34 -0700245"a timing attack could theoretically reveal information about the\n"
246"types and lengths of a and b--but not their values.\n");
Christian Heimes6cea6552012-06-24 13:48:32 +0200247
248static PyObject*
249compare_digest(PyObject *self, PyObject *args)
250{
251 PyObject *a, *b;
252 int rc;
Christian Heimes6cea6552012-06-24 13:48:32 +0200253
254 if (!PyArg_ParseTuple(args, "OO:compare_digest", &a, &b)) {
255 return NULL;
256 }
257
258 /* ASCII unicode string */
259 if(PyUnicode_Check(a) && PyUnicode_Check(b)) {
260 if (PyUnicode_READY(a) == -1 || PyUnicode_READY(b) == -1) {
261 return NULL;
262 }
263 if (!PyUnicode_IS_ASCII(a) || !PyUnicode_IS_ASCII(b)) {
264 PyErr_SetString(PyExc_TypeError,
265 "comparing strings with non-ASCII characters is "
266 "not supported");
267 return NULL;
268 }
269
270 rc = _tscmp(PyUnicode_DATA(a),
271 PyUnicode_DATA(b),
272 PyUnicode_GET_LENGTH(a),
273 PyUnicode_GET_LENGTH(b));
274 }
275 /* fallback to buffer interface for bytes, bytesarray and other */
276 else {
277 Py_buffer view_a;
278 Py_buffer view_b;
279
Benjamin Peterson23a192d2014-05-11 16:17:02 -0700280 if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) {
Christian Heimes6cea6552012-06-24 13:48:32 +0200281 PyErr_Format(PyExc_TypeError,
282 "unsupported operand types(s) or combination of types: "
283 "'%.100s' and '%.100s'",
284 Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
285 return NULL;
286 }
287
288 if (PyObject_GetBuffer(a, &view_a, PyBUF_SIMPLE) == -1) {
289 return NULL;
290 }
291 if (view_a.ndim > 1) {
292 PyErr_SetString(PyExc_BufferError,
293 "Buffer must be single dimension");
294 PyBuffer_Release(&view_a);
295 return NULL;
296 }
297
298 if (PyObject_GetBuffer(b, &view_b, PyBUF_SIMPLE) == -1) {
299 PyBuffer_Release(&view_a);
300 return NULL;
301 }
302 if (view_b.ndim > 1) {
303 PyErr_SetString(PyExc_BufferError,
304 "Buffer must be single dimension");
305 PyBuffer_Release(&view_a);
306 PyBuffer_Release(&view_b);
307 return NULL;
308 }
309
310 rc = _tscmp((const unsigned char*)view_a.buf,
311 (const unsigned char*)view_b.buf,
312 view_a.len,
313 view_b.len);
314
315 PyBuffer_Release(&view_a);
316 PyBuffer_Release(&view_b);
317 }
318
Georg Brandl93b7d7e2012-06-24 13:54:51 +0200319 return PyBool_FromLong(rc);
Christian Heimes6cea6552012-06-24 13:48:32 +0200320}
321
322/* operator methods **********************************************************/
323
Neal Norwitz200788c2002-08-13 22:20:41 +0000324#define spam1(OP,DOC) {#OP, OP, METH_VARARGS, PyDoc_STR(DOC)},
Antoine Pitroua85017f2013-04-20 19:21:44 +0200325#define spam2(OP,DOC) {#OP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)},
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000326#define spam1o(OP,DOC) {#OP, OP, METH_O, PyDoc_STR(DOC)},
Antoine Pitroua85017f2013-04-20 19:21:44 +0200327#define spam2o(OP,DOC) {#OP, op_##OP, METH_O, PyDoc_STR(DOC)},
Guido van Rossum037b9401996-07-30 16:55:54 +0000328
329static struct PyMethodDef operator_methods[] = {
Guido van Rossum037b9401996-07-30 16:55:54 +0000330
Raymond Hettinger36cd2bf2003-01-03 08:24:58 +0000331spam1o(truth,
Guido van Rossum77f6a652002-04-03 22:41:51 +0000332 "truth(a) -- Return True if a is true, False otherwise.")
Antoine Pitroua85017f2013-04-20 19:21:44 +0200333spam2(contains,
Guido van Rossum832f6d21998-05-22 18:12:59 +0000334 "contains(a, b) -- Same as b in a (note reversed operands).")
Guido van Rossum17202301996-08-19 22:01:39 +0000335spam1(indexOf,
Guido van Rossum832f6d21998-05-22 18:12:59 +0000336 "indexOf(a, b) -- Return the first index of b in a.")
Guido van Rossum17202301996-08-19 22:01:39 +0000337spam1(countOf,
338 "countOf(a, b) -- Return the number of times b occurs in a.")
Guido van Rossum037b9401996-07-30 16:55:54 +0000339
Raymond Hettinger9543b342003-01-18 23:22:20 +0000340spam1(is_, "is_(a, b) -- Same as a is b.")
341spam1(is_not, "is_not(a, b) -- Same as a is not b.")
Antoine Pitroua85017f2013-04-20 19:21:44 +0200342spam2o(index, "index(a) -- Same as a.__index__()")
343spam2(add, "add(a, b) -- Same as a + b.")
344spam2(sub, "sub(a, b) -- Same as a - b.")
345spam2(mul, "mul(a, b) -- Same as a * b.")
346spam2(floordiv, "floordiv(a, b) -- Same as a // b.")
347spam2(truediv, "truediv(a, b) -- Same as a / b.")
348spam2(mod, "mod(a, b) -- Same as a % b.")
349spam2o(neg, "neg(a) -- Same as -a.")
350spam2o(pos, "pos(a) -- Same as +a.")
351spam2o(abs, "abs(a) -- Same as abs(a).")
352spam2o(inv, "inv(a) -- Same as ~a.")
353spam2o(invert, "invert(a) -- Same as ~a.")
354spam2(lshift, "lshift(a, b) -- Same as a << b.")
355spam2(rshift, "rshift(a, b) -- Same as a >> b.")
356spam2o(not_, "not_(a) -- Same as not a.")
357spam2(and_, "and_(a, b) -- Same as a & b.")
358spam2(xor, "xor(a, b) -- Same as a ^ b.")
359spam2(or_, "or_(a, b) -- Same as a | b.")
360spam2(iadd, "a = iadd(a, b) -- Same as a += b.")
361spam2(isub, "a = isub(a, b) -- Same as a -= b.")
362spam2(imul, "a = imul(a, b) -- Same as a *= b.")
363spam2(ifloordiv, "a = ifloordiv(a, b) -- Same as a //= b.")
364spam2(itruediv, "a = itruediv(a, b) -- Same as a /= b")
365spam2(imod, "a = imod(a, b) -- Same as a %= b.")
366spam2(ilshift, "a = ilshift(a, b) -- Same as a <<= b.")
367spam2(irshift, "a = irshift(a, b) -- Same as a >>= b.")
368spam2(iand, "a = iand(a, b) -- Same as a &= b.")
369spam2(ixor, "a = ixor(a, b) -- Same as a ^= b.")
370spam2(ior, "a = ior(a, b) -- Same as a |= b.")
371spam2(concat,
Guido van Rossum832f6d21998-05-22 18:12:59 +0000372 "concat(a, b) -- Same as a + b, for a and b sequences.")
Antoine Pitroua85017f2013-04-20 19:21:44 +0200373spam2(iconcat,
Benjamin Petersona0dfa822009-11-13 02:25:08 +0000374 "a = iconcat(a, b) -- Same as a += b, for a and b sequences.")
Antoine Pitroua85017f2013-04-20 19:21:44 +0200375spam2(getitem,
Guido van Rossum832f6d21998-05-22 18:12:59 +0000376 "getitem(a, b) -- Same as a[b].")
Antoine Pitroua85017f2013-04-20 19:21:44 +0200377spam2(setitem,
Guido van Rossum832f6d21998-05-22 18:12:59 +0000378 "setitem(a, b, c) -- Same as a[b] = c.")
Antoine Pitroua85017f2013-04-20 19:21:44 +0200379spam2(delitem,
Guido van Rossum832f6d21998-05-22 18:12:59 +0000380 "delitem(a, b) -- Same as del a[b].")
Antoine Pitroua85017f2013-04-20 19:21:44 +0200381spam2(pow, "pow(a, b) -- Same as a ** b.")
382spam2(ipow, "a = ipow(a, b) -- Same as a **= b.")
383spam2(lt, "lt(a, b) -- Same as a<b.")
384spam2(le, "le(a, b) -- Same as a<=b.")
385spam2(eq, "eq(a, b) -- Same as a==b.")
386spam2(ne, "ne(a, b) -- Same as a!=b.")
387spam2(gt, "gt(a, b) -- Same as a>b.")
388spam2(ge, "ge(a, b) -- Same as a>=b.")
Guido van Rossum037b9401996-07-30 16:55:54 +0000389
Christian Heimes6cea6552012-06-24 13:48:32 +0200390 {"_compare_digest", (PyCFunction)compare_digest, METH_VARARGS,
391 compare_digest__doc__},
Armin Ronacheraa9a79d2012-10-06 14:03:24 +0200392 {"length_hint", (PyCFunction)length_hint, METH_VARARGS,
393 length_hint__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 {NULL, NULL} /* sentinel */
Guido van Rossum037b9401996-07-30 16:55:54 +0000395
Guido van Rossum037b9401996-07-30 16:55:54 +0000396};
397
Raymond Hettinger166958b2003-12-01 13:18:39 +0000398/* itemgetter object **********************************************************/
Guido van Rossum037b9401996-07-30 16:55:54 +0000399
Raymond Hettinger166958b2003-12-01 13:18:39 +0000400typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 PyObject_HEAD
402 Py_ssize_t nitems;
403 PyObject *item;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000404} itemgetterobject;
405
406static PyTypeObject itemgetter_type;
407
408static PyObject *
409itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 itemgetterobject *ig;
412 PyObject *item;
413 Py_ssize_t nitems;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 if (!_PyArg_NoKeywords("itemgetter()", kwds))
416 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +0000417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 nitems = PyTuple_GET_SIZE(args);
419 if (nitems <= 1) {
420 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
421 return NULL;
422 } else
423 item = args;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 /* create itemgetterobject structure */
426 ig = PyObject_GC_New(itemgetterobject, &itemgetter_type);
427 if (ig == NULL)
428 return NULL;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000429
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 Py_INCREF(item);
431 ig->item = item;
432 ig->nitems = nitems;
433
434 PyObject_GC_Track(ig);
435 return (PyObject *)ig;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000436}
437
438static void
439itemgetter_dealloc(itemgetterobject *ig)
440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 PyObject_GC_UnTrack(ig);
442 Py_XDECREF(ig->item);
443 PyObject_GC_Del(ig);
Raymond Hettinger166958b2003-12-01 13:18:39 +0000444}
445
446static int
447itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 Py_VISIT(ig->item);
450 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000451}
452
453static PyObject *
454itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
455{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 PyObject *obj, *result;
457 Py_ssize_t i, nitems=ig->nitems;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000458
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj))
460 return NULL;
461 if (nitems == 1)
462 return PyObject_GetItem(obj, ig->item);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 assert(PyTuple_Check(ig->item));
465 assert(PyTuple_GET_SIZE(ig->item) == nitems);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 result = PyTuple_New(nitems);
468 if (result == NULL)
469 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 for (i=0 ; i < nitems ; i++) {
472 PyObject *item, *val;
473 item = PyTuple_GET_ITEM(ig->item, i);
474 val = PyObject_GetItem(obj, item);
475 if (val == NULL) {
476 Py_DECREF(result);
477 return NULL;
478 }
479 PyTuple_SET_ITEM(result, i, val);
480 }
481 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000482}
483
484PyDoc_STRVAR(itemgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000485"itemgetter(item, ...) --> itemgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +0000486\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000487Return a callable object that fetches the given item(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +0300488After f = itemgetter(2), the call f(r) returns r[2].\n\
489After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])");
Raymond Hettinger166958b2003-12-01 13:18:39 +0000490
491static PyTypeObject itemgetter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 PyVarObject_HEAD_INIT(NULL, 0)
493 "operator.itemgetter", /* tp_name */
494 sizeof(itemgetterobject), /* tp_basicsize */
495 0, /* tp_itemsize */
496 /* methods */
497 (destructor)itemgetter_dealloc, /* tp_dealloc */
498 0, /* tp_print */
499 0, /* tp_getattr */
500 0, /* tp_setattr */
501 0, /* tp_reserved */
502 0, /* tp_repr */
503 0, /* tp_as_number */
504 0, /* tp_as_sequence */
505 0, /* tp_as_mapping */
506 0, /* tp_hash */
507 (ternaryfunc)itemgetter_call, /* tp_call */
508 0, /* tp_str */
509 PyObject_GenericGetAttr, /* tp_getattro */
510 0, /* tp_setattro */
511 0, /* tp_as_buffer */
512 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
513 itemgetter_doc, /* tp_doc */
514 (traverseproc)itemgetter_traverse, /* tp_traverse */
515 0, /* tp_clear */
516 0, /* tp_richcompare */
517 0, /* tp_weaklistoffset */
518 0, /* tp_iter */
519 0, /* tp_iternext */
520 0, /* tp_methods */
521 0, /* tp_members */
522 0, /* tp_getset */
523 0, /* tp_base */
524 0, /* tp_dict */
525 0, /* tp_descr_get */
526 0, /* tp_descr_set */
527 0, /* tp_dictoffset */
528 0, /* tp_init */
529 0, /* tp_alloc */
530 itemgetter_new, /* tp_new */
531 0, /* tp_free */
Raymond Hettinger166958b2003-12-01 13:18:39 +0000532};
533
534
535/* attrgetter object **********************************************************/
536
537typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 PyObject_HEAD
539 Py_ssize_t nattrs;
540 PyObject *attr;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000541} attrgetterobject;
542
543static PyTypeObject attrgetter_type;
544
545static PyObject *
546attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
547{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 attrgetterobject *ag;
549 PyObject *attr;
Antoine Pitroue9745712010-10-31 15:26:04 +0000550 Py_ssize_t nattrs, idx, char_idx;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000551
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 if (!_PyArg_NoKeywords("attrgetter()", kwds))
553 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +0000554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 nattrs = PyTuple_GET_SIZE(args);
556 if (nattrs <= 1) {
557 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
558 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +0000559 }
560
561 attr = PyTuple_New(nattrs);
562 if (attr == NULL)
563 return NULL;
564
565 /* prepare attr while checking args */
566 for (idx = 0; idx < nattrs; ++idx) {
567 PyObject *item = PyTuple_GET_ITEM(args, idx);
568 Py_ssize_t item_len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200569 void *data;
570 unsigned int kind;
Antoine Pitroue9745712010-10-31 15:26:04 +0000571 int dot_count;
572
573 if (!PyUnicode_Check(item)) {
574 PyErr_SetString(PyExc_TypeError,
575 "attribute name must be a string");
576 Py_DECREF(attr);
577 return NULL;
578 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200579 if (PyUnicode_READY(item)) {
580 Py_DECREF(attr);
581 return NULL;
582 }
583 item_len = PyUnicode_GET_LENGTH(item);
584 kind = PyUnicode_KIND(item);
585 data = PyUnicode_DATA(item);
Antoine Pitroue9745712010-10-31 15:26:04 +0000586
587 /* check whethere the string is dotted */
588 dot_count = 0;
589 for (char_idx = 0; char_idx < item_len; ++char_idx) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200590 if (PyUnicode_READ(kind, data, char_idx) == '.')
Antoine Pitroue9745712010-10-31 15:26:04 +0000591 ++dot_count;
592 }
593
594 if (dot_count == 0) {
595 Py_INCREF(item);
596 PyUnicode_InternInPlace(&item);
597 PyTuple_SET_ITEM(attr, idx, item);
598 } else { /* make it a tuple of non-dotted attrnames */
599 PyObject *attr_chain = PyTuple_New(dot_count + 1);
600 PyObject *attr_chain_item;
Antoine Pitrou87298c42010-10-31 21:03:01 +0000601 Py_ssize_t unibuff_from = 0;
602 Py_ssize_t unibuff_till = 0;
603 Py_ssize_t attr_chain_idx = 0;
Antoine Pitroue9745712010-10-31 15:26:04 +0000604
605 if (attr_chain == NULL) {
606 Py_DECREF(attr);
607 return NULL;
608 }
609
Antoine Pitroue9745712010-10-31 15:26:04 +0000610 for (; dot_count > 0; --dot_count) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200611 while (PyUnicode_READ(kind, data, unibuff_till) != '.') {
Antoine Pitroue9745712010-10-31 15:26:04 +0000612 ++unibuff_till;
613 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200614 attr_chain_item = PyUnicode_Substring(item,
615 unibuff_from,
616 unibuff_till);
Antoine Pitroue9745712010-10-31 15:26:04 +0000617 if (attr_chain_item == NULL) {
618 Py_DECREF(attr_chain);
619 Py_DECREF(attr);
620 return NULL;
621 }
622 PyUnicode_InternInPlace(&attr_chain_item);
623 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
624 ++attr_chain_idx;
625 unibuff_till = unibuff_from = unibuff_till + 1;
626 }
627
628 /* now add the last dotless name */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200629 attr_chain_item = PyUnicode_Substring(item,
630 unibuff_from, item_len);
Antoine Pitroue9745712010-10-31 15:26:04 +0000631 if (attr_chain_item == NULL) {
632 Py_DECREF(attr_chain);
633 Py_DECREF(attr);
634 return NULL;
635 }
636 PyUnicode_InternInPlace(&attr_chain_item);
637 PyTuple_SET_ITEM(attr_chain, attr_chain_idx, attr_chain_item);
638
639 PyTuple_SET_ITEM(attr, idx, attr_chain);
640 }
641 }
Raymond Hettinger166958b2003-12-01 13:18:39 +0000642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 /* create attrgetterobject structure */
644 ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
Antoine Pitroue9745712010-10-31 15:26:04 +0000645 if (ag == NULL) {
646 Py_DECREF(attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +0000648 }
Raymond Hettinger166958b2003-12-01 13:18:39 +0000649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 ag->attr = attr;
651 ag->nattrs = nattrs;
652
653 PyObject_GC_Track(ag);
654 return (PyObject *)ag;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000655}
656
657static void
658attrgetter_dealloc(attrgetterobject *ag)
659{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 PyObject_GC_UnTrack(ag);
661 Py_XDECREF(ag->attr);
662 PyObject_GC_Del(ag);
Raymond Hettinger166958b2003-12-01 13:18:39 +0000663}
664
665static int
666attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
667{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 Py_VISIT(ag->attr);
669 return 0;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000670}
671
672static PyObject *
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000673dotted_getattr(PyObject *obj, PyObject *attr)
674{
Antoine Pitroue9745712010-10-31 15:26:04 +0000675 PyObject *newobj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000676
Antoine Pitroue9745712010-10-31 15:26:04 +0000677 /* attr is either a tuple or instance of str.
678 Ensured by the setup code of attrgetter_new */
679 if (PyTuple_CheckExact(attr)) { /* chained getattr */
680 Py_ssize_t name_idx = 0, name_count;
681 PyObject *attr_name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000682
Antoine Pitroue9745712010-10-31 15:26:04 +0000683 name_count = PyTuple_GET_SIZE(attr);
684 Py_INCREF(obj);
685 for (name_idx = 0; name_idx < name_count; ++name_idx) {
686 attr_name = PyTuple_GET_ITEM(attr, name_idx);
687 newobj = PyObject_GetAttr(obj, attr_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 Py_DECREF(obj);
Antoine Pitroue9745712010-10-31 15:26:04 +0000689 if (newobj == NULL) {
690 return NULL;
691 }
692 /* here */
693 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 }
Antoine Pitroue9745712010-10-31 15:26:04 +0000695 } else { /* single getattr */
696 newobj = PyObject_GetAttr(obj, attr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 if (newobj == NULL)
698 return NULL;
699 obj = newobj;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000701
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 return obj;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000703}
704
705static PyObject *
Raymond Hettinger166958b2003-12-01 13:18:39 +0000706attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
707{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 PyObject *obj, *result;
709 Py_ssize_t i, nattrs=ag->nattrs;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj))
712 return NULL;
Antoine Pitroue9745712010-10-31 15:26:04 +0000713 if (ag->nattrs == 1) /* ag->attr is always a tuple */
714 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000715
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000716 assert(PyTuple_Check(ag->attr));
717 assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000718
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 result = PyTuple_New(nattrs);
720 if (result == NULL)
721 return NULL;
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 for (i=0 ; i < nattrs ; i++) {
724 PyObject *attr, *val;
725 attr = PyTuple_GET_ITEM(ag->attr, i);
726 val = dotted_getattr(obj, attr);
727 if (val == NULL) {
728 Py_DECREF(result);
729 return NULL;
730 }
731 PyTuple_SET_ITEM(result, i, val);
732 }
733 return result;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000734}
735
736PyDoc_STRVAR(attrgetter_doc,
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000737"attrgetter(attr, ...) --> attrgetter object\n\
Raymond Hettinger166958b2003-12-01 13:18:39 +0000738\n\
Raymond Hettinger984f9bb2005-03-09 16:38:48 +0000739Return a callable object that fetches the given attribute(s) from its operand.\n\
Ezio Melottibabc8222013-05-08 10:53:11 +0300740After f = attrgetter('name'), the call f(r) returns r.name.\n\
741After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\
742After h = attrgetter('name.first', 'name.last'), the call h(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000743(r.name.first, r.name.last).");
Raymond Hettinger166958b2003-12-01 13:18:39 +0000744
745static PyTypeObject attrgetter_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 PyVarObject_HEAD_INIT(NULL, 0)
747 "operator.attrgetter", /* tp_name */
748 sizeof(attrgetterobject), /* tp_basicsize */
749 0, /* tp_itemsize */
750 /* methods */
751 (destructor)attrgetter_dealloc, /* tp_dealloc */
752 0, /* tp_print */
753 0, /* tp_getattr */
754 0, /* tp_setattr */
755 0, /* tp_reserved */
756 0, /* tp_repr */
757 0, /* tp_as_number */
758 0, /* tp_as_sequence */
759 0, /* tp_as_mapping */
760 0, /* tp_hash */
761 (ternaryfunc)attrgetter_call, /* tp_call */
762 0, /* tp_str */
763 PyObject_GenericGetAttr, /* tp_getattro */
764 0, /* tp_setattro */
765 0, /* tp_as_buffer */
766 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
767 attrgetter_doc, /* tp_doc */
768 (traverseproc)attrgetter_traverse, /* tp_traverse */
769 0, /* tp_clear */
770 0, /* tp_richcompare */
771 0, /* tp_weaklistoffset */
772 0, /* tp_iter */
773 0, /* tp_iternext */
774 0, /* tp_methods */
775 0, /* tp_members */
776 0, /* tp_getset */
777 0, /* tp_base */
778 0, /* tp_dict */
779 0, /* tp_descr_get */
780 0, /* tp_descr_set */
781 0, /* tp_dictoffset */
782 0, /* tp_init */
783 0, /* tp_alloc */
784 attrgetter_new, /* tp_new */
785 0, /* tp_free */
Raymond Hettinger166958b2003-12-01 13:18:39 +0000786};
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000787
788
789/* methodcaller object **********************************************************/
790
791typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 PyObject_HEAD
793 PyObject *name;
794 PyObject *args;
795 PyObject *kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000796} methodcallerobject;
797
798static PyTypeObject methodcaller_type;
799
800static PyObject *
801methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 methodcallerobject *mc;
804 PyObject *name, *newargs;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000805
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 if (PyTuple_GET_SIZE(args) < 1) {
807 PyErr_SetString(PyExc_TypeError, "methodcaller needs at least "
808 "one argument, the method name");
809 return NULL;
810 }
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 /* create methodcallerobject structure */
813 mc = PyObject_GC_New(methodcallerobject, &methodcaller_type);
814 if (mc == NULL)
815 return NULL;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000816
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000817 newargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
818 if (newargs == NULL) {
819 Py_DECREF(mc);
820 return NULL;
821 }
822 mc->args = newargs;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000823
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 name = PyTuple_GET_ITEM(args, 0);
825 Py_INCREF(name);
826 mc->name = name;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 Py_XINCREF(kwds);
829 mc->kwds = kwds;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000830
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 PyObject_GC_Track(mc);
832 return (PyObject *)mc;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000833}
834
835static void
836methodcaller_dealloc(methodcallerobject *mc)
837{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 PyObject_GC_UnTrack(mc);
839 Py_XDECREF(mc->name);
840 Py_XDECREF(mc->args);
841 Py_XDECREF(mc->kwds);
842 PyObject_GC_Del(mc);
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000843}
844
845static int
846methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000848 Py_VISIT(mc->args);
849 Py_VISIT(mc->kwds);
850 return 0;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000851}
852
853static PyObject *
854methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 PyObject *method, *obj, *result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 if (!PyArg_UnpackTuple(args, "methodcaller", 1, 1, &obj))
859 return NULL;
860 method = PyObject_GetAttr(obj, mc->name);
861 if (method == NULL)
862 return NULL;
863 result = PyObject_Call(method, mc->args, mc->kwds);
864 Py_DECREF(method);
865 return result;
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000866}
867
868PyDoc_STRVAR(methodcaller_doc,
869"methodcaller(name, ...) --> methodcaller object\n\
870\n\
871Return a callable object that calls the given method on its operand.\n\
Antoine Pitroua85017f2013-04-20 19:21:44 +0200872After f = methodcaller('name'), the call f(r) returns r.name().\n\
873After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000874r.name('date', foo=1).");
875
876static PyTypeObject methodcaller_type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 PyVarObject_HEAD_INIT(NULL, 0)
878 "operator.methodcaller", /* tp_name */
879 sizeof(methodcallerobject), /* tp_basicsize */
880 0, /* tp_itemsize */
881 /* methods */
882 (destructor)methodcaller_dealloc, /* tp_dealloc */
883 0, /* tp_print */
884 0, /* tp_getattr */
885 0, /* tp_setattr */
886 0, /* tp_reserved */
887 0, /* tp_repr */
888 0, /* tp_as_number */
889 0, /* tp_as_sequence */
890 0, /* tp_as_mapping */
891 0, /* tp_hash */
892 (ternaryfunc)methodcaller_call, /* tp_call */
893 0, /* tp_str */
894 PyObject_GenericGetAttr, /* tp_getattro */
895 0, /* tp_setattro */
896 0, /* tp_as_buffer */
897 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
898 methodcaller_doc, /* tp_doc */
899 (traverseproc)methodcaller_traverse, /* tp_traverse */
900 0, /* tp_clear */
901 0, /* tp_richcompare */
902 0, /* tp_weaklistoffset */
903 0, /* tp_iter */
904 0, /* tp_iternext */
905 0, /* tp_methods */
906 0, /* tp_members */
907 0, /* tp_getset */
908 0, /* tp_base */
909 0, /* tp_dict */
910 0, /* tp_descr_get */
911 0, /* tp_descr_set */
912 0, /* tp_dictoffset */
913 0, /* tp_init */
914 0, /* tp_alloc */
915 methodcaller_new, /* tp_new */
916 0, /* tp_free */
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000917};
918
919
Antoine Pitroua85017f2013-04-20 19:21:44 +0200920/* Initialization function for the module (*must* be called PyInit__operator) */
Martin v. Löwis1a214512008-06-11 05:26:20 +0000921
922
923static struct PyModuleDef operatormodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 PyModuleDef_HEAD_INIT,
Antoine Pitroua85017f2013-04-20 19:21:44 +0200925 "_operator",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 operator_doc,
927 -1,
928 operator_methods,
929 NULL,
930 NULL,
931 NULL,
932 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000933};
Guido van Rossum037b9401996-07-30 16:55:54 +0000934
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000935PyMODINIT_FUNC
Antoine Pitroua85017f2013-04-20 19:21:44 +0200936PyInit__operator(void)
Guido van Rossum037b9401996-07-30 16:55:54 +0000937{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 PyObject *m;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 /* Create the module and add the functions */
941 m = PyModule_Create(&operatormodule);
942 if (m == NULL)
943 return NULL;
Raymond Hettinger166958b2003-12-01 13:18:39 +0000944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 if (PyType_Ready(&itemgetter_type) < 0)
946 return NULL;
947 Py_INCREF(&itemgetter_type);
948 PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
Christian Heimesd3eb5a152008-02-24 00:38:49 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 if (PyType_Ready(&attrgetter_type) < 0)
951 return NULL;
952 Py_INCREF(&attrgetter_type);
953 PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
954
955 if (PyType_Ready(&methodcaller_type) < 0)
956 return NULL;
957 Py_INCREF(&methodcaller_type);
958 PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
959 return m;
Guido van Rossum037b9401996-07-30 16:55:54 +0000960}