2 /* Method object implementation */
8 static PyCFunctionObject
*free_list
= NULL
;
11 PyCFunction_New(PyMethodDef
*ml
, PyObject
*self
)
13 PyCFunctionObject
*op
;
16 free_list
= (PyCFunctionObject
*)(op
->m_self
);
17 PyObject_INIT(op
, &PyCFunction_Type
);
20 op
= PyObject_NEW(PyCFunctionObject
, &PyCFunction_Type
);
27 return (PyObject
*)op
;
31 PyCFunction_GetFunction(PyObject
*op
)
33 if (!PyCFunction_Check(op
)) {
34 PyErr_BadInternalCall();
37 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_meth
;
41 PyCFunction_GetSelf(PyObject
*op
)
43 if (!PyCFunction_Check(op
)) {
44 PyErr_BadInternalCall();
47 return ((PyCFunctionObject
*)op
) -> m_self
;
51 PyCFunction_GetFlags(PyObject
*op
)
53 if (!PyCFunction_Check(op
)) {
54 PyErr_BadInternalCall();
57 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_flags
;
60 /* Methods (the standard built-in methods, that is) */
63 meth_dealloc(PyCFunctionObject
*m
)
65 Py_XDECREF(m
->m_self
);
66 m
->m_self
= (PyObject
*)free_list
;
71 meth_getattr(PyCFunctionObject
*m
, char *name
)
73 if (strcmp(name
, "__name__") == 0) {
74 return PyString_FromString(m
->m_ml
->ml_name
);
76 if (strcmp(name
, "__doc__") == 0) {
77 char *doc
= m
->m_ml
->ml_doc
;
79 return PyString_FromString(doc
);
83 if (strcmp(name
, "__self__") == 0) {
85 if (PyEval_GetRestricted()) {
86 PyErr_SetString(PyExc_RuntimeError
,
87 "method.__self__ not accessible in restricted mode");
96 if (strcmp(name
, "__members__") == 0) {
97 return Py_BuildValue("[sss]",
98 "__doc__", "__name__", "__self__");
100 PyErr_SetString(PyExc_AttributeError
, name
);
105 meth_repr(PyCFunctionObject
*m
)
108 if (m
->m_self
== NULL
)
109 sprintf(buf
, "<built-in function %.80s>", m
->m_ml
->ml_name
);
112 "<built-in method %.80s of %.80s object at %p>",
113 m
->m_ml
->ml_name
, m
->m_self
->ob_type
->tp_name
,
115 return PyString_FromString(buf
);
119 meth_compare(PyCFunctionObject
*a
, PyCFunctionObject
*b
)
121 if (a
->m_self
!= b
->m_self
)
122 return (a
->m_self
< b
->m_self
) ? -1 : 1;
123 if (a
->m_ml
->ml_meth
== b
->m_ml
->ml_meth
)
125 if (strcmp(a
->m_ml
->ml_name
, b
->m_ml
->ml_name
) < 0)
132 meth_hash(PyCFunctionObject
*a
)
135 if (a
->m_self
== NULL
)
138 x
= PyObject_Hash(a
->m_self
);
142 y
= _Py_HashPointer((void*)(a
->m_ml
->ml_meth
));
151 PyTypeObject PyCFunction_Type
= {
152 PyObject_HEAD_INIT(&PyType_Type
)
154 "builtin_function_or_method",
155 sizeof(PyCFunctionObject
),
157 (destructor
)meth_dealloc
, /*tp_dealloc*/
159 (getattrfunc
)meth_getattr
, /*tp_getattr*/
161 (cmpfunc
)meth_compare
, /*tp_compare*/
162 (reprfunc
)meth_repr
, /*tp_repr*/
164 0, /*tp_as_sequence*/
166 (hashfunc
)meth_hash
, /*tp_hash*/
169 /* List all methods in a chain -- helper for findmethodinchain */
172 listmethodchain(PyMethodChain
*chain
)
180 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
181 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++)
188 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
189 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++) {
190 PyList_SetItem(v
, i
, PyString_FromString(ml
->ml_name
));
194 if (PyErr_Occurred()) {
202 /* Find a method in a method chain */
205 Py_FindMethodInChain(PyMethodChain
*chain
, PyObject
*self
, char *name
)
207 if (name
[0] == '_' && name
[1] == '_') {
208 if (strcmp(name
, "__methods__") == 0)
209 return listmethodchain(chain
);
210 if (strcmp(name
, "__doc__") == 0) {
211 char *doc
= self
->ob_type
->tp_doc
;
213 return PyString_FromString(doc
);
216 while (chain
!= NULL
) {
217 PyMethodDef
*ml
= chain
->methods
;
218 for (; ml
->ml_name
!= NULL
; ml
++) {
219 if (name
[0] == ml
->ml_name
[0] &&
220 strcmp(name
+1, ml
->ml_name
+1) == 0)
221 return PyCFunction_New(ml
, self
);
225 PyErr_SetString(PyExc_AttributeError
, name
);
229 /* Find a method in a single method list */
232 Py_FindMethod(PyMethodDef
*methods
, PyObject
*self
, char *name
)
235 chain
.methods
= methods
;
237 return Py_FindMethodInChain(&chain
, self
, name
);
240 /* Clear out the free list */
243 PyCFunction_Fini(void)
246 PyCFunctionObject
*v
= free_list
;
247 free_list
= (PyCFunctionObject
*)(v
->m_self
);