1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Method object implementation */
38 static PyCFunctionObject
*free_list
= NULL
;
41 PyCFunction_New(ml
, self
)
45 PyCFunctionObject
*op
;
48 free_list
= (PyCFunctionObject
*)(op
->m_self
);
49 op
->ob_type
= &PyCFunction_Type
;
53 op
= PyObject_NEW(PyCFunctionObject
, &PyCFunction_Type
);
60 return (PyObject
*)op
;
64 PyCFunction_GetFunction(op
)
67 if (!PyCFunction_Check(op
)) {
68 PyErr_BadInternalCall();
71 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_meth
;
75 PyCFunction_GetSelf(op
)
78 if (!PyCFunction_Check(op
)) {
79 PyErr_BadInternalCall();
82 return ((PyCFunctionObject
*)op
) -> m_self
;
86 PyCFunction_GetFlags(op
)
89 if (!PyCFunction_Check(op
)) {
90 PyErr_BadInternalCall();
93 return ((PyCFunctionObject
*)op
) -> m_ml
-> ml_flags
;
96 /* Methods (the standard built-in methods, that is) */
100 PyCFunctionObject
*m
;
102 Py_XDECREF(m
->m_self
);
103 m
->m_self
= (PyObject
*)free_list
;
108 meth_getattr(m
, name
)
109 PyCFunctionObject
*m
;
112 if (strcmp(name
, "__name__") == 0) {
113 return PyString_FromString(m
->m_ml
->ml_name
);
115 if (strcmp(name
, "__doc__") == 0) {
116 char *doc
= m
->m_ml
->ml_doc
;
118 return PyString_FromString(doc
);
122 if (strcmp(name
, "__self__") == 0) {
124 if (PyEval_GetRestricted()) {
125 PyErr_SetString(PyExc_RuntimeError
,
126 "method.__self__ not accessible in restricted mode");
135 if (strcmp(name
, "__members__") == 0) {
136 return Py_BuildValue("[sss]",
137 "__doc__", "__name__", "__self__");
139 PyErr_SetString(PyExc_AttributeError
, name
);
145 PyCFunctionObject
*m
;
148 if (m
->m_self
== NULL
)
149 sprintf(buf
, "<built-in function %.80s>", m
->m_ml
->ml_name
);
152 "<built-in method %.80s of %.80s object at %lx>",
153 m
->m_ml
->ml_name
, m
->m_self
->ob_type
->tp_name
,
155 return PyString_FromString(buf
);
160 PyCFunctionObject
*a
, *b
;
162 if (a
->m_self
!= b
->m_self
)
163 return (a
->m_self
< b
->m_self
) ? -1 : 1;
164 if (a
->m_ml
->ml_meth
== b
->m_ml
->ml_meth
)
166 if (strcmp(a
->m_ml
->ml_name
, b
->m_ml
->ml_name
) < 0)
174 PyCFunctionObject
*a
;
177 if (a
->m_self
== NULL
)
180 x
= PyObject_Hash(a
->m_self
);
184 return x
^ (long) a
->m_ml
->ml_meth
;
187 PyTypeObject PyCFunction_Type
= {
188 PyObject_HEAD_INIT(&PyType_Type
)
190 "builtin_function_or_method",
191 sizeof(PyCFunctionObject
),
193 (destructor
)meth_dealloc
, /*tp_dealloc*/
195 (getattrfunc
)meth_getattr
, /*tp_getattr*/
197 (cmpfunc
)meth_compare
, /*tp_compare*/
198 (reprfunc
)meth_repr
, /*tp_repr*/
200 0, /*tp_as_sequence*/
202 (hashfunc
)meth_hash
, /*tp_hash*/
205 /* List all methods in a chain -- helper for findmethodinchain */
208 listmethodchain(chain
)
209 PyMethodChain
*chain
;
217 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
218 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++)
225 for (c
= chain
; c
!= NULL
; c
= c
->link
) {
226 for (ml
= c
->methods
; ml
->ml_name
!= NULL
; ml
++) {
227 PyList_SetItem(v
, i
, PyString_FromString(ml
->ml_name
));
231 if (PyErr_Occurred()) {
239 /* Find a method in a method chain */
242 Py_FindMethodInChain(chain
, self
, name
)
243 PyMethodChain
*chain
;
247 if (name
[0] == '_' && name
[1] == '_') {
248 if (strcmp(name
, "__methods__") == 0)
249 return listmethodchain(chain
);
250 if (strcmp(name
, "__doc__") == 0) {
251 char *doc
= self
->ob_type
->tp_doc
;
253 return PyString_FromString(doc
);
256 while (chain
!= NULL
) {
257 PyMethodDef
*ml
= chain
->methods
;
258 for (; ml
->ml_name
!= NULL
; ml
++) {
259 if (name
[0] == ml
->ml_name
[0] &&
260 strcmp(name
+1, ml
->ml_name
+1) == 0)
261 return PyCFunction_New(ml
, self
);
265 PyErr_SetString(PyExc_AttributeError
, name
);
269 /* Find a method in a single method list */
272 Py_FindMethod(methods
, self
, name
)
273 PyMethodDef
*methods
;
278 chain
.methods
= methods
;
280 return Py_FindMethodInChain(&chain
, self
, name
);
283 /* Clear out the free list */
289 PyCFunctionObject
*v
= free_list
;
290 free_list
= (PyCFunctionObject
*)(v
->m_self
);