2 /* Method object implementation */
5 #include "structmember.h"
7 static PyCFunctionObject
*free_list
= NULL
;
10 PyCFunction_NewEx(PyMethodDef
*ml
, PyObject
*self
, PyObject
*module
)
12 PyCFunctionObject
*op
;
15 free_list
= (PyCFunctionObject
*)(op
->m_self
);
16 PyObject_INIT(op
, &PyCFunction_Type
);
19 op
= PyObject_GC_New(PyCFunctionObject
, &PyCFunction_Type
);
27 op
->m_module
= module
;
28 _PyObject_GC_TRACK(op
);
29 return (PyObject
*)op
;
33 PyCFunction_GetFunction(PyObject
*op
)
35 if (!PyCFunction_Check(op
)) {
36 PyErr_BadInternalCall();
39 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_meth
;
43 PyCFunction_GetSelf(PyObject
*op
)
45 if (!PyCFunction_Check(op
)) {
46 PyErr_BadInternalCall();
49 return ((PyCFunctionObject
*)op
) -> m_self
;
53 PyCFunction_GetFlags(PyObject
*op
)
55 if (!PyCFunction_Check(op
)) {
56 PyErr_BadInternalCall();
59 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_flags
;
63 PyCFunction_Call(PyObject
*func
, PyObject
*arg
, PyObject
*kw
)
65 PyCFunctionObject
* f
= (PyCFunctionObject
*)func
;
66 PyCFunction meth
= PyCFunction_GET_FUNCTION(func
);
67 PyObject
*self
= PyCFunction_GET_SELF(func
);
70 switch (PyCFunction_GET_FLAGS(func
) & ~(METH_CLASS
| METH_STATIC
| METH_COEXIST
)) {
72 if (kw
== NULL
|| PyDict_Size(kw
) == 0)
73 return (*meth
)(self
, arg
);
75 case METH_VARARGS
| METH_KEYWORDS
:
76 case METH_OLDARGS
| METH_KEYWORDS
:
77 return (*(PyCFunctionWithKeywords
)meth
)(self
, arg
, kw
);
79 if (kw
== NULL
|| PyDict_Size(kw
) == 0) {
80 size
= PyTuple_GET_SIZE(arg
);
82 return (*meth
)(self
, NULL
);
83 PyErr_Format(PyExc_TypeError
,
84 "%.200s() takes no arguments (%d given)",
85 f
->m_ml
->ml_name
, size
);
90 if (kw
== NULL
|| PyDict_Size(kw
) == 0) {
91 size
= PyTuple_GET_SIZE(arg
);
93 return (*meth
)(self
, PyTuple_GET_ITEM(arg
, 0));
94 PyErr_Format(PyExc_TypeError
,
95 "%.200s() takes exactly one argument (%d given)",
96 f
->m_ml
->ml_name
, size
);
101 /* the really old style */
102 if (kw
== NULL
|| PyDict_Size(kw
) == 0) {
103 size
= PyTuple_GET_SIZE(arg
);
105 arg
= PyTuple_GET_ITEM(arg
, 0);
108 return (*meth
)(self
, arg
);
112 PyErr_BadInternalCall();
115 PyErr_Format(PyExc_TypeError
, "%.200s() takes no keyword arguments",
120 /* Methods (the standard built-in methods, that is) */
123 meth_dealloc(PyCFunctionObject
*m
)
125 _PyObject_GC_UNTRACK(m
);
126 Py_XDECREF(m
->m_self
);
127 Py_XDECREF(m
->m_module
);
128 m
->m_self
= (PyObject
*)free_list
;
133 meth_get__doc__(PyCFunctionObject
*m
, void *closure
)
135 const char *doc
= m
->m_ml
->ml_doc
;
138 return PyString_FromString(doc
);
144 meth_get__name__(PyCFunctionObject
*m
, void *closure
)
146 return PyString_FromString(m
->m_ml
->ml_name
);
150 meth_traverse(PyCFunctionObject
*m
, visitproc visit
, void *arg
)
153 if (m
->m_self
!= NULL
) {
154 err
= visit(m
->m_self
, arg
);
158 if (m
->m_module
!= NULL
) {
159 err
= visit(m
->m_module
, arg
);
167 meth_get__self__(PyCFunctionObject
*m
, void *closure
)
170 if (PyEval_GetRestricted()) {
171 PyErr_SetString(PyExc_RuntimeError
,
172 "method.__self__ not accessible in restricted mode");
182 static PyGetSetDef meth_getsets
[] = {
183 {"__doc__", (getter
)meth_get__doc__
, NULL
, NULL
},
184 {"__name__", (getter
)meth_get__name__
, NULL
, NULL
},
185 {"__self__", (getter
)meth_get__self__
, NULL
, NULL
},
189 #define OFF(x) offsetof(PyCFunctionObject, x)
191 static PyMemberDef meth_members
[] = {
192 {"__module__", T_OBJECT
, OFF(m_module
), WRITE_RESTRICTED
},
197 meth_repr(PyCFunctionObject
*m
)
199 if (m
->m_self
== NULL
)
200 return PyString_FromFormat("<built-in function %s>",
202 return PyString_FromFormat("<built-in method %s of %s object at %p>",
204 m
->m_self
->ob_type
->tp_name
,
209 meth_compare(PyCFunctionObject
*a
, PyCFunctionObject
*b
)
211 if (a
->m_self
!= b
->m_self
)
212 return (a
->m_self
< b
->m_self
) ? -1 : 1;
213 if (a
->m_ml
->ml_meth
== b
->m_ml
->ml_meth
)
215 if (strcmp(a
->m_ml
->ml_name
, b
->m_ml
->ml_name
) < 0)
222 meth_hash(PyCFunctionObject
*a
)
225 if (a
->m_self
== NULL
)
228 x
= PyObject_Hash(a
->m_self
);
232 y
= _Py_HashPointer((void*)(a
->m_ml
->ml_meth
));
242 PyTypeObject PyCFunction_Type
= {
243 PyObject_HEAD_INIT(&PyType_Type
)
245 "builtin_function_or_method",
246 sizeof(PyCFunctionObject
),
248 (destructor
)meth_dealloc
, /* tp_dealloc */
252 (cmpfunc
)meth_compare
, /* tp_compare */
253 (reprfunc
)meth_repr
, /* tp_repr */
254 0, /* tp_as_number */
255 0, /* tp_as_sequence */
256 0, /* tp_as_mapping */
257 (hashfunc
)meth_hash
, /* tp_hash */
258 PyCFunction_Call
, /* tp_call */
260 PyObject_GenericGetAttr
, /* tp_getattro */
262 0, /* tp_as_buffer */
263 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
265 (traverseproc
)meth_traverse
, /* tp_traverse */
267 0, /* tp_richcompare */
268 0, /* tp_weaklistoffset */
272 meth_members
, /* tp_members */
273 meth_getsets
, /* tp_getset */
278 /* List all methods in a chain -- helper for findmethodinchain */
281 listmethodchain(PyMethodChain
*chain
)
289 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
290 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++)
297 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
298 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++) {
299 PyList_SetItem(v
, i
, PyString_FromString(ml
->ml_name
));
303 if (PyErr_Occurred()) {
311 /* Find a method in a method chain */
314 Py_FindMethodInChain(PyMethodChain
*chain
, PyObject
*self
, const char *name
)
316 if (name
[0] == '_' && name
[1] == '_') {
317 if (strcmp(name
, "__methods__") == 0)
318 return listmethodchain(chain
);
319 if (strcmp(name
, "__doc__") == 0) {
320 const char *doc
= self
->ob_type
->tp_doc
;
322 return PyString_FromString(doc
);
325 while (chain
!= NULL
) {
326 PyMethodDef
*ml
= chain
->methods
;
327 for (; ml
->ml_name
!= NULL
; ml
++) {
328 if (name
[0] == ml
->ml_name
[0] &&
329 strcmp(name
+1, ml
->ml_name
+1) == 0)
331 return PyCFunction_New(ml
, self
);
335 PyErr_SetString(PyExc_AttributeError
, name
);
339 /* Find a method in a single method list */
342 Py_FindMethod(PyMethodDef
*methods
, PyObject
*self
, const char *name
)
345 chain
.methods
= methods
;
347 return Py_FindMethodInChain(&chain
, self
, name
);
350 /* Clear out the free list */
353 PyCFunction_Fini(void)
356 PyCFunctionObject
*v
= free_list
;
357 free_list
= (PyCFunctionObject
*)(v
->m_self
);
362 /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
363 but it's part of the API so we need to keep a function around that
364 existing C extensions can call.
367 #undef PyCFunction_New
368 PyAPI_FUNC(PyObject
*) PyCFunction_New(PyMethodDef
*, PyObject
*);
371 PyCFunction_New(PyMethodDef
*ml
, PyObject
*self
)
373 return PyCFunction_NewEx(ml
, self
, NULL
);