classobject.c 18.7 KB
Newer Older
1
/* Class object implementation (dead now except for methods) */
Guido van Rossum's avatar
Guido van Rossum committed
2

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

6
#define TP_DESCR_GET(t) ((t)->tp_descr_get)
7

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

17
_Py_IDENTIFIER(__name__);
18
_Py_IDENTIFIER(__qualname__);
19

20 21 22
PyObject *
PyMethod_Function(PyObject *im)
{
23 24 25 26 27
    if (!PyMethod_Check(im)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    return ((PyMethodObject *)im)->im_func;
28 29 30 31 32
}

PyObject *
PyMethod_Self(PyObject *im)
{
33 34 35 36 37
    if (!PyMethod_Check(im)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    return ((PyMethodObject *)im)->im_self;
38 39
}

40 41 42
/* Method objects are used for bound instance methods returned by
   instancename.methodname. ClassName.methodname returns an ordinary
   function.
43
*/
Guido van Rossum's avatar
Guido van Rossum committed
44

45
PyObject *
46
PyMethod_New(PyObject *func, PyObject *self)
Guido van Rossum's avatar
Guido van Rossum committed
47
{
48
    PyMethodObject *im;
49 50 51 52 53 54 55
    if (self == NULL) {
        PyErr_BadInternalCall();
        return NULL;
    }
    im = free_list;
    if (im != NULL) {
        free_list = (PyMethodObject *)(im->im_self);
56
        (void)PyObject_INIT(im, &PyMethod_Type);
57 58 59 60 61 62 63 64 65 66 67 68 69 70
        numfree--;
    }
    else {
        im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
        if (im == NULL)
            return NULL;
    }
    im->im_weakreflist = NULL;
    Py_INCREF(func);
    im->im_func = func;
    Py_XINCREF(self);
    im->im_self = self;
    _PyObject_GC_TRACK(im);
    return (PyObject *)im;
Guido van Rossum's avatar
Guido van Rossum committed
71 72
}

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
static PyObject *
method_reduce(PyMethodObject *im)
{
    PyObject *self = PyMethod_GET_SELF(im);
    PyObject *func = PyMethod_GET_FUNCTION(im);
    PyObject *builtins;
    PyObject *getattr;
    PyObject *funcname;
    _Py_IDENTIFIER(getattr);

    funcname = _PyObject_GetAttrId(func, &PyId___name__);
    if (funcname == NULL) {
        return NULL;
    }
    builtins = PyEval_GetBuiltins();
    getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
    return Py_BuildValue("O(ON)", getattr, self, funcname);
}

static PyMethodDef method_methods[] = {
    {"__reduce__", (PyCFunction)method_reduce, METH_NOARGS, NULL},
    {NULL, NULL}
};

97 98
/* Descriptors for PyMethod attributes */

99
/* im_func and im_self are stored in the PyMethod object */
Guido van Rossum's avatar
Guido van Rossum committed
100

101
#define MO_OFF(x) offsetof(PyMethodObject, x)
Guido van Rossum's avatar
Guido van Rossum committed
102

103
static PyMemberDef method_memberlist[] = {
104 105 106 107 108
    {"__func__", T_OBJECT, MO_OFF(im_func), READONLY|RESTRICTED,
     "the function (or other callable) implementing a method"},
    {"__self__", T_OBJECT, MO_OFF(im_self), READONLY|RESTRICTED,
     "the instance to which a method is bound"},
    {NULL}      /* Sentinel */
Guido van Rossum's avatar
Guido van Rossum committed
109 110
};

111 112 113 114 115 116
/* Christian Tismer argued convincingly that method attributes should
   (nearly) always override function attributes.
   The one exception is __doc__; there's a default __doc__ which
   should only be used for the class, not for instances */

static PyObject *
117
method_get_doc(PyMethodObject *im, void *context)
118
{
119 120 121 122 123 124 125
    static PyObject *docstr;
    if (docstr == NULL) {
        docstr= PyUnicode_InternFromString("__doc__");
        if (docstr == NULL)
            return NULL;
    }
    return PyObject_GetAttr(im->im_func, docstr);
126 127
}

128
static PyGetSetDef method_getset[] = {
129 130
    {"__doc__", (getter)method_get_doc, NULL, NULL},
    {0}
131
};
132

133
static PyObject *
134
method_getattro(PyObject *obj, PyObject *name)
Guido van Rossum's avatar
Guido van Rossum committed
135
{
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
    PyMethodObject *im = (PyMethodObject *)obj;
    PyTypeObject *tp = obj->ob_type;
    PyObject *descr = NULL;

    {
        if (tp->tp_dict == NULL) {
            if (PyType_Ready(tp) < 0)
                return NULL;
        }
        descr = _PyType_Lookup(tp, name);
    }

    if (descr != NULL) {
        descrgetfunc f = TP_DESCR_GET(descr->ob_type);
        if (f != NULL)
            return f(descr, obj, (PyObject *)obj->ob_type);
        else {
            Py_INCREF(descr);
            return descr;
        }
    }

    return PyObject_GetAttr(im->im_func, name);
Guido van Rossum's avatar
Guido van Rossum committed
159 160
}

161
PyDoc_STRVAR(method_doc,
162
"method(function, instance)\n\
163
\n\
164
Create a bound instance method object.");
165 166

static PyObject *
167
method_new(PyTypeObject* type, PyObject* args, PyObject *kw)
168
{
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    PyObject *func;
    PyObject *self;

    if (!_PyArg_NoKeywords("method", kw))
        return NULL;
    if (!PyArg_UnpackTuple(args, "method", 2, 2,
                          &func, &self))
        return NULL;
    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be callable");
        return NULL;
    }
    if (self == NULL || self == Py_None) {
        PyErr_SetString(PyExc_TypeError,
            "self must not be None");
        return NULL;
    }

    return PyMethod_New(func, self);
189 190
}

Guido van Rossum's avatar
Guido van Rossum committed
191
static void
192
method_dealloc(PyMethodObject *im)
Guido van Rossum's avatar
Guido van Rossum committed
193
{
194 195 196 197 198 199 200 201 202 203 204 205 206
    _PyObject_GC_UNTRACK(im);
    if (im->im_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *)im);
    Py_DECREF(im->im_func);
    Py_XDECREF(im->im_self);
    if (numfree < PyMethod_MAXFREELIST) {
        im->im_self = (PyObject *)free_list;
        free_list = im;
        numfree++;
    }
    else {
        PyObject_GC_Del(im);
    }
Guido van Rossum's avatar
Guido van Rossum committed
207 208
}

209 210
static PyObject *
method_richcompare(PyObject *self, PyObject *other, int op)
211
{
212 213 214 215 216 217 218 219
    PyMethodObject *a, *b;
    PyObject *res;
    int eq;

    if ((op != Py_EQ && op != Py_NE) ||
        !PyMethod_Check(self) ||
        !PyMethod_Check(other))
    {
220
        Py_RETURN_NOTIMPLEMENTED;
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
    }
    a = (PyMethodObject *)self;
    b = (PyMethodObject *)other;
    eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ);
    if (eq == 1) {
        if (a->im_self == NULL || b->im_self == NULL)
            eq = a->im_self == b->im_self;
        else
            eq = PyObject_RichCompareBool(a->im_self, b->im_self,
                                          Py_EQ);
    }
    if (eq < 0)
        return NULL;
    if (op == Py_EQ)
        res = eq ? Py_True : Py_False;
    else
        res = eq ? Py_False : Py_True;
    Py_INCREF(res);
    return res;
240 241
}

242
static PyObject *
243
method_repr(PyMethodObject *a)
244
{
245 246
    PyObject *self = a->im_self;
    PyObject *func = a->im_func;
247 248
    PyObject *funcname = NULL, *result = NULL;
    const char *defname = "?";
249

250
    funcname = _PyObject_GetAttrId(func, &PyId___qualname__);
251 252 253 254 255
    if (funcname == NULL) {
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
            return NULL;
        PyErr_Clear();

256 257 258
        funcname = _PyObject_GetAttrId(func, &PyId___name__);
        if (funcname == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
259 260 261
                return NULL;
            PyErr_Clear();
        }
262
    }
263

264 265 266
    if (funcname != NULL && !PyUnicode_Check(funcname)) {
        Py_DECREF(funcname);
        funcname = NULL;
267 268 269
    }

    /* XXX Shouldn't use repr()/%R here! */
270
    result = PyUnicode_FromFormat("<bound method %V of %R>",
271 272 273 274
                                  funcname, defname, self);

    Py_XDECREF(funcname);
    return result;
275 276
}

277
static Py_hash_t
278
method_hash(PyMethodObject *a)
279
{
280
    Py_hash_t x, y;
281 282 283 284 285 286 287 288 289 290 291 292 293
    if (a->im_self == NULL)
        x = PyObject_Hash(Py_None);
    else
        x = PyObject_Hash(a->im_self);
    if (x == -1)
        return -1;
    y = PyObject_Hash(a->im_func);
    if (y == -1)
        return -1;
    x = x ^ y;
    if (x == -1)
        x = -2;
    return x;
294 295
}

296
static int
297
method_traverse(PyMethodObject *im, visitproc visit, void *arg)
298
{
299 300 301
    Py_VISIT(im->im_func);
    Py_VISIT(im->im_self);
    return 0;
302 303
}

304
static PyObject *
305
method_call(PyObject *func, PyObject *arg, PyObject *kw)
306
{
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
    PyObject *self = PyMethod_GET_SELF(func);
    PyObject *result;

    func = PyMethod_GET_FUNCTION(func);
    if (self == NULL) {
        PyErr_BadInternalCall();
        return NULL;
    }
    else {
        Py_ssize_t argcount = PyTuple_Size(arg);
        PyObject *newarg = PyTuple_New(argcount + 1);
        int i;
        if (newarg == NULL)
            return NULL;
        Py_INCREF(self);
        PyTuple_SET_ITEM(newarg, 0, self);
        for (i = 0; i < argcount; i++) {
            PyObject *v = PyTuple_GET_ITEM(arg, i);
            Py_XINCREF(v);
            PyTuple_SET_ITEM(newarg, i+1, v);
        }
        arg = newarg;
    }
    result = PyObject_Call((PyObject *)func, arg, kw);
    Py_DECREF(arg);
    return result;
333 334
}

335
static PyObject *
336
method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
337
{
338 339 340 341 342 343 344 345 346
    /* Don't rebind an already bound method of a class that's not a base
       class of cls. */
    if (PyMethod_GET_SELF(meth) != NULL) {
        /* Already bound */
        Py_INCREF(meth);
        return meth;
    }
    /* Bind it to obj */
    return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj);
347 348
}

349
PyTypeObject PyMethod_Type = {
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "method",
    sizeof(PyMethodObject),
    0,
    (destructor)method_dealloc,                 /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc)method_repr,                      /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc)method_hash,                      /* tp_hash */
    method_call,                                /* tp_call */
    0,                                          /* tp_str */
    method_getattro,                            /* tp_getattro */
    PyObject_GenericSetAttr,                    /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
    method_doc,                                 /* tp_doc */
    (traverseproc)method_traverse,              /* tp_traverse */
    0,                                          /* tp_clear */
    method_richcompare,                         /* tp_richcompare */
    offsetof(PyMethodObject, im_weakreflist), /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
377
    method_methods,                             /* tp_methods */
378 379 380 381 382 383 384 385 386 387
    method_memberlist,                          /* tp_members */
    method_getset,                              /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    method_descr_get,                           /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    method_new,                                 /* tp_new */
Guido van Rossum's avatar
Guido van Rossum committed
388
};
389 390 391

/* Clear out the free list */

Christian Heimes's avatar
Christian Heimes committed
392 393
int
PyMethod_ClearFreeList(void)
394
{
395 396 397 398 399 400 401 402 403 404
    int freelist_size = numfree;

    while (free_list) {
        PyMethodObject *im = free_list;
        free_list = (PyMethodObject *)(im->im_self);
        PyObject_GC_Del(im);
        numfree--;
    }
    assert(numfree == 0);
    return freelist_size;
Christian Heimes's avatar
Christian Heimes committed
405 406 407 408 409
}

void
PyMethod_Fini(void)
{
410
    (void)PyMethod_ClearFreeList();
411
}
412

413 414 415 416 417 418 419 420 421
/* Print summary info about the state of the optimized allocator */
void
_PyMethod_DebugMallocStats(FILE *out)
{
    _PyDebugAllocatorStats(out,
                           "free PyMethodObject",
                           numfree, sizeof(PyMethodObject));
}

422 423 424 425 426 427
/* ------------------------------------------------------------------------
 * instance method
 */

PyObject *
PyInstanceMethod_New(PyObject *func) {
428 429 430 431 432 433 434 435
    PyInstanceMethodObject *method;
    method = PyObject_GC_New(PyInstanceMethodObject,
                             &PyInstanceMethod_Type);
    if (method == NULL) return NULL;
    Py_INCREF(func);
    method->func = func;
    _PyObject_GC_TRACK(method);
    return (PyObject *)method;
436 437 438 439 440
}

PyObject *
PyInstanceMethod_Function(PyObject *im)
{
441 442 443 444 445
    if (!PyInstanceMethod_Check(im)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    return PyInstanceMethod_GET_FUNCTION(im);
446 447 448 449 450
}

#define IMO_OFF(x) offsetof(PyInstanceMethodObject, x)

static PyMemberDef instancemethod_memberlist[] = {
451 452 453
    {"__func__", T_OBJECT, IMO_OFF(func), READONLY|RESTRICTED,
     "the function (or other callable) implementing a method"},
    {NULL}      /* Sentinel */
454 455 456 457 458
};

static PyObject *
instancemethod_get_doc(PyObject *self, void *context)
{
459 460 461 462 463 464 465
    static PyObject *docstr;
    if (docstr == NULL) {
        docstr = PyUnicode_InternFromString("__doc__");
        if (docstr == NULL)
            return NULL;
    }
    return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), docstr);
466 467 468
}

static PyGetSetDef instancemethod_getset[] = {
469 470
    {"__doc__", (getter)instancemethod_get_doc, NULL, NULL},
    {0}
471 472 473 474 475
};

static PyObject *
instancemethod_getattro(PyObject *self, PyObject *name)
{
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
    PyTypeObject *tp = self->ob_type;
    PyObject *descr = NULL;

    if (tp->tp_dict == NULL) {
        if (PyType_Ready(tp) < 0)
            return NULL;
    }
    descr = _PyType_Lookup(tp, name);

    if (descr != NULL) {
        descrgetfunc f = TP_DESCR_GET(descr->ob_type);
        if (f != NULL)
            return f(descr, self, (PyObject *)self->ob_type);
        else {
            Py_INCREF(descr);
            return descr;
        }
    }

    return PyObject_GetAttr(PyInstanceMethod_GET_FUNCTION(self), name);
496 497 498 499
}

static void
instancemethod_dealloc(PyObject *self) {
500 501 502
    _PyObject_GC_UNTRACK(self);
    Py_DECREF(PyInstanceMethod_GET_FUNCTION(self));
    PyObject_GC_Del(self);
503 504 505 506
}

static int
instancemethod_traverse(PyObject *self, visitproc visit, void *arg) {
507 508
    Py_VISIT(PyInstanceMethod_GET_FUNCTION(self));
    return 0;
509 510 511 512 513
}

static PyObject *
instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw)
{
514
    return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw);
515 516 517 518
}

static PyObject *
instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) {
519
    PyObject *func = PyInstanceMethod_GET_FUNCTION(descr);
520 521 522 523 524 525
    if (obj == NULL) {
        Py_INCREF(func);
        return func;
    }
    else
        return PyMethod_New(func, obj);
526 527 528 529 530
}

static PyObject *
instancemethod_richcompare(PyObject *self, PyObject *other, int op)
{
531 532 533 534 535 536 537 538
    PyInstanceMethodObject *a, *b;
    PyObject *res;
    int eq;

    if ((op != Py_EQ && op != Py_NE) ||
        !PyInstanceMethod_Check(self) ||
        !PyInstanceMethod_Check(other))
    {
539
        Py_RETURN_NOTIMPLEMENTED;
540 541 542 543 544 545 546 547 548 549 550 551
    }
    a = (PyInstanceMethodObject *)self;
    b = (PyInstanceMethodObject *)other;
    eq = PyObject_RichCompareBool(a->func, b->func, Py_EQ);
    if (eq < 0)
        return NULL;
    if (op == Py_EQ)
        res = eq ? Py_True : Py_False;
    else
        res = eq ? Py_False : Py_True;
    Py_INCREF(res);
    return res;
552 553 554 555 556
}

static PyObject *
instancemethod_repr(PyObject *self)
{
557 558 559 560 561 562 563 564 565
    PyObject *func = PyInstanceMethod_Function(self);
    PyObject *funcname = NULL , *result = NULL;
    char *defname = "?";

    if (func == NULL) {
        PyErr_BadInternalCall();
        return NULL;
    }

566
    funcname = _PyObject_GetAttrId(func, &PyId___name__);
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    if (funcname == NULL) {
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
            return NULL;
        PyErr_Clear();
    }
    else if (!PyUnicode_Check(funcname)) {
        Py_DECREF(funcname);
        funcname = NULL;
    }

    result = PyUnicode_FromFormat("<instancemethod %V at %p>",
                                  funcname, defname, self);

    Py_XDECREF(funcname);
    return result;
582 583 584 585 586 587
}

/*
static long
instancemethod_hash(PyObject *self)
{
588 589 590 591 592 593 594 595 596
    long x, y;
    x = (long)self;
    y = PyObject_Hash(PyInstanceMethod_GET_FUNCTION(self));
    if (y == -1)
        return -1;
    x = x ^ y;
    if (x == -1)
        x = -2;
    return x;
597 598 599 600 601 602 603 604 605 606 607
}
*/

PyDoc_STRVAR(instancemethod_doc,
"instancemethod(function)\n\
\n\
Bind a function to a class.");

static PyObject *
instancemethod_new(PyTypeObject* type, PyObject* args, PyObject *kw)
{
608 609 610 611 612 613 614 615 616 617 618 619 620
    PyObject *func;

    if (!_PyArg_NoKeywords("instancemethod", kw))
        return NULL;
    if (!PyArg_UnpackTuple(args, "instancemethod", 1, 1, &func))
        return NULL;
    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError,
                        "first argument must be callable");
        return NULL;
    }

    return PyInstanceMethod_New(func);
621 622 623
}

PyTypeObject PyInstanceMethod_Type = {
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "instancemethod",                           /* tp_name */
    sizeof(PyInstanceMethodObject),             /* tp_basicsize */
    0,                                          /* tp_itemsize */
    instancemethod_dealloc,                     /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc)instancemethod_repr,              /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0, /*(hashfunc)instancemethod_hash,         tp_hash  */
    instancemethod_call,                        /* tp_call */
    0,                                          /* tp_str */
    instancemethod_getattro,                    /* tp_getattro */
    PyObject_GenericSetAttr,                    /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT
        | Py_TPFLAGS_HAVE_GC,                   /* tp_flags */
    instancemethod_doc,                         /* tp_doc */
    instancemethod_traverse,                    /* tp_traverse */
    0,                                          /* tp_clear */
    instancemethod_richcompare,                 /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    instancemethod_memberlist,                  /* tp_members */
    instancemethod_getset,                      /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    instancemethod_descr_get,                   /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    instancemethod_new,                         /* tp_new */
663
};