methodobject.c 10.1 KB
Newer Older
1

Guido van Rossum's avatar
Guido van Rossum committed
2 3
/* Method object implementation */

4
#include "Python.h"
5
#include "structmember.h"
Guido van Rossum's avatar
Guido van Rossum committed
6

Christian Heimes's avatar
Christian Heimes committed
7 8 9
/* Free list for method objects to safe malloc/free overhead
 * The m_self element is used to chain the objects.
 */
10
static PyCFunctionObject *free_list = NULL;
Christian Heimes's avatar
Christian Heimes committed
11 12 13 14
static int numfree = 0;
#ifndef PyCFunction_MAXFREELIST
#define PyCFunction_MAXFREELIST 256
#endif
15

16
PyObject *
17
PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
Guido van Rossum's avatar
Guido van Rossum committed
18
{
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
    PyCFunctionObject *op;
    op = free_list;
    if (op != NULL) {
        free_list = (PyCFunctionObject *)(op->m_self);
        PyObject_INIT(op, &PyCFunction_Type);
        numfree--;
    }
    else {
        op = PyObject_GC_New(PyCFunctionObject, &PyCFunction_Type);
        if (op == NULL)
            return NULL;
    }
    op->m_ml = ml;
    Py_XINCREF(self);
    op->m_self = self;
    Py_XINCREF(module);
    op->m_module = module;
    _PyObject_GC_TRACK(op);
    return (PyObject *)op;
Guido van Rossum's avatar
Guido van Rossum committed
38 39
}

40
PyCFunction
41
PyCFunction_GetFunction(PyObject *op)
Guido van Rossum's avatar
Guido van Rossum committed
42
{
43 44 45 46
    if (!PyCFunction_Check(op)) {
        PyErr_BadInternalCall();
        return NULL;
    }
47
    return PyCFunction_GET_FUNCTION(op);
Guido van Rossum's avatar
Guido van Rossum committed
48 49
}

50
PyObject *
51
PyCFunction_GetSelf(PyObject *op)
Guido van Rossum's avatar
Guido van Rossum committed
52
{
53 54 55 56
    if (!PyCFunction_Check(op)) {
        PyErr_BadInternalCall();
        return NULL;
    }
57
    return PyCFunction_GET_SELF(op);
Guido van Rossum's avatar
Guido van Rossum committed
58 59
}

60
int
61
PyCFunction_GetFlags(PyObject *op)
62
{
63 64 65 66
    if (!PyCFunction_Check(op)) {
        PyErr_BadInternalCall();
        return -1;
    }
67
    return PyCFunction_GET_FLAGS(op);
68 69
}

70 71 72
PyObject *
PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw)
{
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    PyCFunctionObject* f = (PyCFunctionObject*)func;
    PyCFunction meth = PyCFunction_GET_FUNCTION(func);
    PyObject *self = PyCFunction_GET_SELF(func);
    Py_ssize_t size;

    switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
    case METH_VARARGS:
        if (kw == NULL || PyDict_Size(kw) == 0)
            return (*meth)(self, arg);
        break;
    case METH_VARARGS | METH_KEYWORDS:
        return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
    case METH_NOARGS:
        if (kw == NULL || PyDict_Size(kw) == 0) {
            size = PyTuple_GET_SIZE(arg);
            if (size == 0)
                return (*meth)(self, NULL);
            PyErr_Format(PyExc_TypeError,
                "%.200s() takes no arguments (%zd given)",
                f->m_ml->ml_name, size);
            return NULL;
        }
        break;
    case METH_O:
        if (kw == NULL || PyDict_Size(kw) == 0) {
            size = PyTuple_GET_SIZE(arg);
            if (size == 1)
                return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
            PyErr_Format(PyExc_TypeError,
                "%.200s() takes exactly one argument (%zd given)",
                f->m_ml->ml_name, size);
            return NULL;
        }
        break;
    default:
        PyErr_SetString(PyExc_SystemError, "Bad call flags in "
                        "PyCFunction_Call. METH_OLDARGS is no "
                        "longer supported!");

        return NULL;
    }
    PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
                 f->m_ml->ml_name);
    return NULL;
117 118
}

Guido van Rossum's avatar
Guido van Rossum committed
119 120 121
/* Methods (the standard built-in methods, that is) */

static void
122
meth_dealloc(PyCFunctionObject *m)
Guido van Rossum's avatar
Guido van Rossum committed
123
{
124 125 126 127 128 129 130 131 132 133 134
    _PyObject_GC_UNTRACK(m);
    Py_XDECREF(m->m_self);
    Py_XDECREF(m->m_module);
    if (numfree < PyCFunction_MAXFREELIST) {
        m->m_self = (PyObject *)free_list;
        free_list = m;
        numfree++;
    }
    else {
        PyObject_GC_Del(m);
    }
Guido van Rossum's avatar
Guido van Rossum committed
135 136
}

137 138 139
static PyObject *
meth_get__doc__(PyCFunctionObject *m, void *closure)
{
140
    const char *doc = m->m_ml->ml_doc;
141

142 143 144 145
    if (doc != NULL)
        return PyUnicode_FromString(doc);
    Py_INCREF(Py_None);
    return Py_None;
146 147 148 149 150
}

static PyObject *
meth_get__name__(PyCFunctionObject *m, void *closure)
{
151
    return PyUnicode_FromString(m->m_ml->ml_name);
152 153
}

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
static PyObject *
meth_get__qualname__(PyCFunctionObject *m, void *closure)
{
    /* If __self__ is a module or NULL, return m.__name__
       (e.g. len.__qualname__ == 'len')

       If __self__ is a type, return m.__self__.__qualname__ + '.' + m.__name__
       (e.g. dict.fromkeys.__qualname__ == 'dict.fromkeys')

       Otherwise return type(m.__self__).__qualname__ + '.' + m.__name__
       (e.g. [].append.__qualname__ == 'list.append') */
    PyObject *type, *type_qualname, *res;
    _Py_IDENTIFIER(__qualname__);

    if (m->m_self == NULL || PyModule_Check(m->m_self))
        return PyUnicode_FromString(m->m_ml->ml_name);

    type = PyType_Check(m->m_self) ? m->m_self : (PyObject*)Py_TYPE(m->m_self);

    type_qualname = _PyObject_GetAttrId(type, &PyId___qualname__);
    if (type_qualname == NULL)
        return NULL;

    if (!PyUnicode_Check(type_qualname)) {
        PyErr_SetString(PyExc_TypeError, "<method>.__class__."
                        "__qualname__ is not a unicode object");
        Py_XDECREF(type_qualname);
        return NULL;
    }

    res = PyUnicode_FromFormat("%S.%s", type_qualname, m->m_ml->ml_name);
    Py_DECREF(type_qualname);
    return res;
}

189 190 191
static int
meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg)
{
192 193 194
    Py_VISIT(m->m_self);
    Py_VISIT(m->m_module);
    return 0;
195 196
}

197
static PyObject *
198
meth_get__self__(PyCFunctionObject *m, void *closure)
199
{
200
    PyObject *self;
201

202
    self = PyCFunction_GET_SELF(m);
203 204 205 206
    if (self == NULL)
        self = Py_None;
    Py_INCREF(self);
    return self;
207 208
}

209
static PyGetSetDef meth_getsets [] = {
210 211
    {"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
    {"__name__", (getter)meth_get__name__, NULL, NULL},
212
    {"__qualname__", (getter)meth_get__qualname__, NULL, NULL},
213 214
    {"__self__", (getter)meth_get__self__, NULL, NULL},
    {0}
215 216
};

217 218 219
#define OFF(x) offsetof(PyCFunctionObject, x)

static PyMemberDef meth_members[] = {
220 221
    {"__module__",    T_OBJECT,     OFF(m_module), PY_WRITE_RESTRICTED},
    {NULL}
222 223
};

224
static PyObject *
225
meth_repr(PyCFunctionObject *m)
Guido van Rossum's avatar
Guido van Rossum committed
226
{
227 228 229 230 231 232 233
    if (m->m_self == NULL || PyModule_Check(m->m_self))
        return PyUnicode_FromFormat("<built-in function %s>",
                                   m->m_ml->ml_name);
    return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
                               m->m_ml->ml_name,
                               m->m_self->ob_type->tp_name,
                               m->m_self);
Guido van Rossum's avatar
Guido van Rossum committed
234 235
}

236 237
static PyObject *
meth_richcompare(PyObject *self, PyObject *other, int op)
238
{
239 240 241 242 243 244 245 246
    PyCFunctionObject *a, *b;
    PyObject *res;
    int eq;

    if ((op != Py_EQ && op != Py_NE) ||
        !PyCFunction_Check(self) ||
        !PyCFunction_Check(other))
    {
247
        Py_RETURN_NOTIMPLEMENTED;
248 249 250 251 252 253 254 255 256 257 258 259
    }
    a = (PyCFunctionObject *)self;
    b = (PyCFunctionObject *)other;
    eq = a->m_self == b->m_self;
    if (eq)
        eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
    if (op == Py_EQ)
        res = eq ? Py_True : Py_False;
    else
        res = eq ? Py_False : Py_True;
    Py_INCREF(res);
    return res;
260 261
}

262
static Py_hash_t
263
meth_hash(PyCFunctionObject *a)
264
{
265
    Py_hash_t x, y;
266 267 268 269 270 271 272 273 274 275 276 277 278 279
    if (a->m_self == NULL)
        x = 0;
    else {
        x = PyObject_Hash(a->m_self);
        if (x == -1)
            return -1;
    }
    y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
    if (y == -1)
        return -1;
    x ^= y;
    if (x == -1)
        x = -2;
    return x;
280 281
}

282

283
PyTypeObject PyCFunction_Type = {
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "builtin_function_or_method",
    sizeof(PyCFunctionObject),
    0,
    (destructor)meth_dealloc,                   /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc)meth_repr,                        /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc)meth_hash,                        /* tp_hash */
    PyCFunction_Call,                           /* tp_call */
    0,                                          /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
    0,                                          /* tp_doc */
    (traverseproc)meth_traverse,                /* tp_traverse */
    0,                                          /* tp_clear */
    meth_richcompare,                           /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    meth_members,                               /* tp_members */
    meth_getsets,                               /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
Guido van Rossum's avatar
Guido van Rossum committed
316
};
Guido van Rossum's avatar
Guido van Rossum committed
317

318 319
/* Clear out the free list */

Christian Heimes's avatar
Christian Heimes committed
320 321
int
PyCFunction_ClearFreeList(void)
322
{
323 324 325 326 327 328 329 330 331 332
    int freelist_size = numfree;

    while (free_list) {
        PyCFunctionObject *v = free_list;
        free_list = (PyCFunctionObject *)(v->m_self);
        PyObject_GC_Del(v);
        numfree--;
    }
    assert(numfree == 0);
    return freelist_size;
Christian Heimes's avatar
Christian Heimes committed
333 334 335 336 337
}

void
PyCFunction_Fini(void)
{
338
    (void)PyCFunction_ClearFreeList();
339
}
340

341 342 343 344 345 346 347 348 349
/* Print summary info about the state of the optimized allocator */
void
_PyCFunction_DebugMallocStats(FILE *out)
{
    _PyDebugAllocatorStats(out,
                           "free PyCFunction",
                           numfree, sizeof(PyCFunction));
}

350 351 352 353
/* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
   but it's part of the API so we need to keep a function around that
   existing C extensions can call.
*/
Christian Heimes's avatar
Christian Heimes committed
354

355 356 357 358 359 360
#undef PyCFunction_New
PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *, PyObject *);

PyObject *
PyCFunction_New(PyMethodDef *ml, PyObject *self)
{
361
    return PyCFunction_NewEx(ml, self, NULL);
362
}