source: trunk/essentials/dev-lang/python/Modules/_functoolsmodule.c@ 3403

Last change on this file since 3403 was 3225, checked in by bird, 19 years ago

Python 2.5

File size: 6.2 KB
Line 
1
2#include "Python.h"
3#include "structmember.h"
4
5/* _functools module written and maintained
6 by Hye-Shik Chang <[email protected]>
7 with adaptations by Raymond Hettinger <[email protected]>
8 Copyright (c) 2004, 2005, 2006 Python Software Foundation.
9 All rights reserved.
10*/
11
12/* partial object **********************************************************/
13
14typedef struct {
15 PyObject_HEAD
16 PyObject *fn;
17 PyObject *args;
18 PyObject *kw;
19 PyObject *dict;
20 PyObject *weakreflist; /* List of weak references */
21} partialobject;
22
23static PyTypeObject partial_type;
24
25static PyObject *
26partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
27{
28 PyObject *func;
29 partialobject *pto;
30
31 if (PyTuple_GET_SIZE(args) < 1) {
32 PyErr_SetString(PyExc_TypeError,
33 "type 'partial' takes at least one argument");
34 return NULL;
35 }
36
37 func = PyTuple_GET_ITEM(args, 0);
38 if (!PyCallable_Check(func)) {
39 PyErr_SetString(PyExc_TypeError,
40 "the first argument must be callable");
41 return NULL;
42 }
43
44 /* create partialobject structure */
45 pto = (partialobject *)type->tp_alloc(type, 0);
46 if (pto == NULL)
47 return NULL;
48
49 pto->fn = func;
50 Py_INCREF(func);
51 pto->args = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
52 if (pto->args == NULL) {
53 pto->kw = NULL;
54 Py_DECREF(pto);
55 return NULL;
56 }
57 if (kw != NULL) {
58 pto->kw = PyDict_Copy(kw);
59 if (pto->kw == NULL) {
60 Py_DECREF(pto);
61 return NULL;
62 }
63 } else {
64 pto->kw = Py_None;
65 Py_INCREF(Py_None);
66 }
67
68 pto->weakreflist = NULL;
69 pto->dict = NULL;
70
71 return (PyObject *)pto;
72}
73
74static void
75partial_dealloc(partialobject *pto)
76{
77 PyObject_GC_UnTrack(pto);
78 if (pto->weakreflist != NULL)
79 PyObject_ClearWeakRefs((PyObject *) pto);
80 Py_XDECREF(pto->fn);
81 Py_XDECREF(pto->args);
82 Py_XDECREF(pto->kw);
83 Py_XDECREF(pto->dict);
84 pto->ob_type->tp_free(pto);
85}
86
87static PyObject *
88partial_call(partialobject *pto, PyObject *args, PyObject *kw)
89{
90 PyObject *ret;
91 PyObject *argappl = NULL, *kwappl = NULL;
92
93 assert (PyCallable_Check(pto->fn));
94 assert (PyTuple_Check(pto->args));
95 assert (pto->kw == Py_None || PyDict_Check(pto->kw));
96
97 if (PyTuple_GET_SIZE(pto->args) == 0) {
98 argappl = args;
99 Py_INCREF(args);
100 } else if (PyTuple_GET_SIZE(args) == 0) {
101 argappl = pto->args;
102 Py_INCREF(pto->args);
103 } else {
104 argappl = PySequence_Concat(pto->args, args);
105 if (argappl == NULL)
106 return NULL;
107 }
108
109 if (pto->kw == Py_None) {
110 kwappl = kw;
111 Py_XINCREF(kw);
112 } else {
113 kwappl = PyDict_Copy(pto->kw);
114 if (kwappl == NULL) {
115 Py_DECREF(argappl);
116 return NULL;
117 }
118 if (kw != NULL) {
119 if (PyDict_Merge(kwappl, kw, 1) != 0) {
120 Py_DECREF(argappl);
121 Py_DECREF(kwappl);
122 return NULL;
123 }
124 }