2 /* Method object implementation */
6 static PyCFunctionObject
*free_list
= NULL
;
9 PyCFunction_New(PyMethodDef
*ml
, PyObject
*self
)
11 PyCFunctionObject
*op
;
14 free_list
= (PyCFunctionObject
*)(op
->m_self
);
15 PyObject_INIT(op
, &PyCFunction_Type
);
18 op
= PyObject_NEW(PyCFunctionObject
, &PyCFunction_Type
);
26 return (PyObject
*)op
;
30 PyCFunction_GetFunction(PyObject
*op
)
32 if (!PyCFunction_Check(op
)) {
33 PyErr_BadInternalCall();
36 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_meth
;
40 PyCFunction_GetSelf(PyObject
*op
)
42 if (!PyCFunction_Check(op
)) {
43 PyErr_BadInternalCall();
46 return ((PyCFunctionObject
*)op
) -> m_self
;
50 PyCFunction_GetFlags(PyObject
*op
)
52 if (!PyCFunction_Check(op
)) {
53 PyErr_BadInternalCall();
56 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_flags
;
60 PyCFunction_Call(PyObject
*func
, PyObject
*arg
, PyObject
*kw
)
62 PyCFunctionObject
* f
= (PyCFunctionObject
*)func
;
63 PyCFunction meth
= PyCFunction_GET_FUNCTION(func
);
64 PyObject
*self
= PyCFunction_GET_SELF(func
);
65 int flags
= PyCFunction_GET_FLAGS(func
);
66 int size
= PyTuple_GET_SIZE(arg
);
68 if (flags
& METH_KEYWORDS
) {
69 return (*(PyCFunctionWithKeywords
)meth
)(self
, arg
, kw
);
71 if (kw
!= NULL
&& PyDict_Size(kw
) != 0) {
72 PyErr_Format(PyExc_TypeError
,
73 "%.200s() takes no keyword arguments",
80 return (*meth
)(self
, arg
);
84 return (*meth
)(self
, NULL
);
85 PyErr_Format(PyExc_TypeError
,
86 "%.200s() takes no arguments (%d given)",
87 f
->m_ml
->ml_name
, size
);
92 return (*meth
)(self
, PyTuple_GET_ITEM(arg
, 0));
93 PyErr_Format(PyExc_TypeError
,
94 "%.200s() takes exactly one argument (%d given)",
95 f
->m_ml
->ml_name
, size
);
99 /* the really old style */
101 arg
= PyTuple_GET_ITEM(arg
, 0);
104 return (*meth
)(self
, arg
);
106 /* should never get here ??? */
107 PyErr_BadInternalCall();
112 /* Methods (the standard built-in methods, that is) */
115 meth_dealloc(PyCFunctionObject
*m
)
118 Py_XDECREF(m
->m_self
);
119 m
->m_self
= (PyObject
*)free_list
;
124 meth_get__doc__(PyCFunctionObject
*m
, void *closure
)
126 char *doc
= m
->m_ml
->ml_doc
;
129 return PyString_FromString(doc
);
135 meth_get__name__(PyCFunctionObject
*m
, void *closure
)
137 return PyString_FromString(m
->m_ml
->ml_name
);
141 meth_traverse(PyCFunctionObject
*m
, visitproc visit
, void *arg
)
143 if (m
->m_self
!= NULL
)
144 return visit(m
->m_self
, arg
);
150 meth_get__self__(PyCFunctionObject
*m
, void *closure
)
153 if (PyEval_GetRestricted()) {
154 PyErr_SetString(PyExc_RuntimeError
,
155 "method.__self__ not accessible in restricted mode");
165 static struct getsetlist meth_getsets
[] = {
166 {"__doc__", (getter
)meth_get__doc__
, NULL
, NULL
},
167 {"__name__", (getter
)meth_get__name__
, NULL
, NULL
},
168 {"__self__", (getter
)meth_get__self__
, NULL
, NULL
},
173 meth_repr(PyCFunctionObject
*m
)
176 if (m
->m_self
== NULL
)
177 sprintf(buf
, "<built-in function %.80s>", m
->m_ml
->ml_name
);
180 "<built-in method %.80s of %.80s object at %p>",
181 m
->m_ml
->ml_name
, m
->m_self
->ob_type
->tp_name
,
183 return PyString_FromString(buf
);
187 meth_compare(PyCFunctionObject
*a
, PyCFunctionObject
*b
)
189 if (a
->m_self
!= b
->m_self
)
190 return (a
->m_self
< b
->m_self
) ? -1 : 1;
191 if (a
->m_ml
->ml_meth
== b
->m_ml
->ml_meth
)
193 if (strcmp(a
->m_ml
->ml_name
, b
->m_ml
->ml_name
) < 0)
200 meth_hash(PyCFunctionObject
*a
)
203 if (a
->m_self
== NULL
)
206 x
= PyObject_Hash(a
->m_self
);
210 y
= _Py_HashPointer((void*)(a
->m_ml
->ml_meth
));
220 PyTypeObject PyCFunction_Type
= {
221 PyObject_HEAD_INIT(&PyType_Type
)
223 "builtin_function_or_method",
224 sizeof(PyCFunctionObject
) + PyGC_HEAD_SIZE
,
226 (destructor
)meth_dealloc
, /* tp_dealloc */
230 (cmpfunc
)meth_compare
, /* tp_compare */
231 (reprfunc
)meth_repr
, /* tp_repr */
232 0, /* tp_as_number */
233 0, /* tp_as_sequence */
234 0, /* tp_as_mapping */
235 (hashfunc
)meth_hash
, /* tp_hash */
236 PyCFunction_Call
, /* tp_call */
238 PyObject_GenericGetAttr
, /* tp_getattro */
240 0, /* tp_as_buffer */
241 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_GC
, /* tp_flags */
243 (traverseproc
)meth_traverse
, /* tp_traverse */
245 0, /* tp_richcompare */
246 0, /* tp_weaklistoffset */
251 meth_getsets
, /* tp_getset */
256 /* List all methods in a chain -- helper for findmethodinchain */
259 listmethodchain(PyMethodChain
*chain
)
267 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
268 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++)
275 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
276 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++) {
277 PyList_SetItem(v
, i
, PyString_FromString(ml
->ml_name
));
281 if (PyErr_Occurred()) {
289 /* Find a method in a method chain */
292 Py_FindMethodInChain(PyMethodChain
*chain
, PyObject
*self
, char *name
)
294 if (name
[0] == '_' && name
[1] == '_') {
295 if (strcmp(name
, "__methods__") == 0)
296 return listmethodchain(chain
);
297 if (strcmp(name
, "__doc__") == 0) {
298 char *doc
= self
->ob_type
->tp_doc
;
300 return PyString_FromString(doc
);
303 while (chain
!= NULL
) {
304 PyMethodDef
*ml
= chain
->methods
;
305 for (; ml
->ml_name
!= NULL
; ml
++) {
306 if (name
[0] == ml
->ml_name
[0] &&
307 strcmp(name
+1, ml
->ml_name
+1) == 0)
308 return PyCFunction_New(ml
, self
);
312 PyErr_SetString(PyExc_AttributeError
, name
);
316 /* Find a method in a single method list */
319 Py_FindMethod(PyMethodDef
*methods
, PyObject
*self
, char *name
)
322 chain
.methods
= methods
;
324 return Py_FindMethodInChain(&chain
, self
, name
);
327 /* Clear out the free list */
330 PyCFunction_Fini(void)
333 PyCFunctionObject
*v
= free_list
;
334 free_list
= (PyCFunctionObject
*)(v
->m_self
);
335 v
= (PyCFunctionObject
*) PyObject_AS_GC(v
);