~pythonregexp2.7/python/issue2636-20

« back to all changes in this revision

Viewing changes to Objects/typeobject.c

  • Committer: Jeffrey C. "The TimeHorse" Jacobs
  • Date: 2008-09-21 13:47:31 UTC
  • mfrom: (39021.1.404 Regexp-2.7)
  • Revision ID: darklord@timehorse.com-20080921134731-rudomuzeh1b2tz1y
Merged in changes from the latest python source snapshot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
571
571
        return result;
572
572
}
573
573
 
 
574
static PyObject *
 
575
type___instancecheck__(PyObject *type, PyObject *inst)
 
576
{
 
577
        switch (_PyObject_RealIsInstance(inst, type)) {
 
578
        case -1:
 
579
                return NULL;
 
580
        case 0:
 
581
                Py_RETURN_FALSE;
 
582
        default:
 
583
                Py_RETURN_TRUE;
 
584
        }
 
585
}
 
586
 
 
587
 
 
588
static PyObject *
 
589
type_get_instancecheck(PyObject *type, void *context)
 
590
{
 
591
        static PyMethodDef ml = {"__instancecheck__",
 
592
                                 type___instancecheck__, METH_O };
 
593
        return PyCFunction_New(&ml, type);
 
594
}
 
595
 
 
596
static PyObject *
 
597
type___subclasscheck__(PyObject *type, PyObject *inst)
 
598
{
 
599
        switch (_PyObject_RealIsSubclass(inst, type)) {
 
600
        case -1:
 
601
                return NULL;
 
602
        case 0:
 
603
                Py_RETURN_FALSE;
 
604
        default:
 
605
                Py_RETURN_TRUE;
 
606
        }
 
607
}
 
608
 
 
609
static PyObject *
 
610
type_get_subclasscheck(PyObject *type, void *context)
 
611
{
 
612
        static PyMethodDef ml = {"__subclasscheck__",
 
613
                                 type___subclasscheck__, METH_O };
 
614
        return PyCFunction_New(&ml, type);
 
615
}
 
616
 
574
617
static PyGetSetDef type_getsets[] = {
575
618
        {"__name__", (getter)type_name, (setter)type_set_name, NULL},
576
619
        {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL},
579
622
         (setter)type_set_abstractmethods, NULL},
580
623
        {"__dict__",  (getter)type_dict,  NULL, NULL},
581
624
        {"__doc__", (getter)type_get_doc, NULL, NULL},
 
625
        {"__instancecheck__", (getter)type_get_instancecheck, NULL, NULL},
 
626
        {"__subclasscheck__", (getter)type_get_subclasscheck, NULL, NULL},
582
627
        {0}
583
628
};
584
629
 
3648
3693
                type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
3649
3694
}
3650
3695
 
3651
 
static char *hash_name_op[] = {
3652
 
        "__eq__",
3653
 
        "__cmp__",
3654
 
        "__hash__",
3655
 
        NULL
3656
 
};
3657
 
 
3658
3696
static int
3659
 
overrides_hash(PyTypeObject *type)
 
3697
overrides_name(PyTypeObject *type, char *name)
3660
3698
{
3661
 
        char **p;
3662
3699
        PyObject *dict = type->tp_dict;
3663
3700
 
3664
3701
        assert(dict != NULL);
3665
 
        for (p = hash_name_op; *p; p++) {
3666
 
                if (PyDict_GetItemString(dict, *p) != NULL)
3667
 
                        return 1;
 
3702
        if (PyDict_GetItemString(dict, name) != NULL) {
 
3703
                return 1;
3668
3704
        }
3669
3705
        return 0;
3670
3706
}
3671
3707
 
 
3708
#define OVERRIDES_HASH(x)       overrides_name(x, "__hash__")
 
3709
#define OVERRIDES_CMP(x)        overrides_name(x, "__cmp__")
 
3710
#define OVERRIDES_EQ(x)         overrides_name(x, "__eq__")
 
3711
 
3672
3712
static void
3673
3713
inherit_slots(PyTypeObject *type, PyTypeObject *base)
3674
3714
{
3802
3842
        if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) {
3803
3843
                if (type->tp_compare == NULL &&
3804
3844
                    type->tp_richcompare == NULL &&
3805
 
                    type->tp_hash == NULL &&
3806
 
                    !overrides_hash(type))
 
3845
                    type->tp_hash == NULL)
3807
3846
                {
3808
3847
                        type->tp_compare = base->tp_compare;
3809
3848
                        type->tp_richcompare = base->tp_richcompare;
3810
3849
                        type->tp_hash = base->tp_hash;
 
3850
                        /* Check for changes to inherited methods in Py3k*/
 
3851
                        if (Py_Py3kWarningFlag) {
 
3852
                                if (base->tp_hash &&
 
3853
                                                (base->tp_hash != PyObject_HashNotImplemented) &&
 
3854
                                                !OVERRIDES_HASH(type)) {
 
3855
                                        if (OVERRIDES_CMP(type)) {
 
3856
                                                PyErr_WarnPy3k("Overriding "
 
3857
                                                  "__cmp__ blocks inheritance "
 
3858
                                                  "of __hash__ in 3.x",
 
3859
                                                  1);
 
3860
                                        }
 
3861
                                        if (OVERRIDES_EQ(type)) {
 
3862
                                                PyErr_WarnPy3k("Overriding "
 
3863
                                                  "__eq__ blocks inheritance "
 
3864
                                                  "of __hash__ in 3.x",
 
3865
                                                  1);
 
3866
                                        }
 
3867
                                }
 
3868
                        }
3811
3869
                }
3812
3870
        }
3813
3871
        else {
3984
4042
                }
3985
4043
        }
3986
4044
 
3987
 
        /* Hack for tp_hash and __hash__.
3988
 
           If after all that, tp_hash is still NULL, and __hash__ is not in
3989
 
           tp_dict, set tp_dict['__hash__'] equal to None.
3990
 
           This signals that __hash__ is not inherited.
3991
 
        */
3992
 
        if (type->tp_hash == NULL &&
3993
 
            PyDict_GetItemString(type->tp_dict, "__hash__") == NULL &&
3994
 
            PyDict_SetItemString(type->tp_dict, "__hash__", Py_None) < 0)
3995
 
        {
3996
 
                goto error;
3997
 
        }
3998
 
 
3999
4045
        /* Some more special stuff */
4000
4046
        base = type->tp_base;
4001
4047
        if (base != NULL) {
4896
4942
        return NULL;
4897
4943
}
4898
4944
 
4899
 
SLOT2(slot_sq_slice, "__getslice__", Py_ssize_t, Py_ssize_t, "nn")
 
4945
static PyObject*
 
4946
slot_sq_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j)
 
4947
{
 
4948
        static PyObject *getslice_str;
 
4949
        
 
4950
        if (PyErr_WarnPy3k("in 3.x, __getslice__ has been removed; "
 
4951
                            "use __getitem__", 1) < 0)
 
4952
                return NULL;
 
4953
        return call_method(self, "__getslice__", &getslice_str,
 
4954
                "nn", i, j);
 
4955
}
4900
4956
 
4901
4957
static int
4902
4958
slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
4921
4977
{
4922
4978
        PyObject *res;
4923
4979
        static PyObject *delslice_str, *setslice_str;
4924
 
 
4925
 
        if (value == NULL)
 
4980
        
 
4981
        if (value == NULL) {
 
4982
                if (PyErr_WarnPy3k("in 3.x, __delslice__ has been removed; "
 
4983
                                   "use __delitem__", 1) < 0)
 
4984
                        return -1;
4926
4985
                res = call_method(self, "__delslice__", &delslice_str,
4927
4986
                                  "(nn)", i, j);
4928
 
        else
 
4987
        }
 
4988
        else {
 
4989
                if (PyErr_WarnPy3k("in 3.x, __setslice__ has been removed; "
 
4990
                                        "use __setitem__", 1) < 0)
 
4991
                        return -1;              
4929
4992
                res = call_method(self, "__setslice__", &setslice_str,
4930
 
                                  "(nnO)", i, j, value);
 
4993
                          "(nnO)", i, j, value);
 
4994
        }
4931
4995
        if (res == NULL)
4932
4996
                return -1;
4933
4997
        Py_DECREF(res);
5280
5344
                        func = lookup_method(self, "__cmp__", &cmp_str);
5281
5345
                }
5282
5346
                if (func != NULL) {
5283
 
                        PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
5284
 
                                     self->ob_type->tp_name);
5285
5347
                        Py_DECREF(func);
5286
 
                        return -1;
 
5348
                        return PyObject_HashNotImplemented(self);
5287
5349
                }
5288
5350
                PyErr_Clear();
5289
5351
                h = _Py_HashPointer((void *)self);
6034
6096
                           sanity checks.  I'll buy the first person to
6035
6097
                           point out a bug in this reasoning a beer. */
6036
6098
                }
 
6099
                else if (descr == Py_None &&
 
6100
                         strcmp(p->name, "__hash__") == 0) {
 
6101
                        /* We specifically allow __hash__ to be set to None
 
6102
                           to prevent inheritance of the default
 
6103
                           implementation from object.__hash__ */
 
6104
                        specific = PyObject_HashNotImplemented;
 
6105
                }
6037
6106
                else {
6038
6107
                        use_generic = 1;
6039
6108
                        generic = p->function;
6247
6316
                        continue;
6248
6317
                if (PyDict_GetItem(dict, p->name_strobj))
6249
6318
                        continue;
6250
 
                descr = PyDescr_NewWrapper(type, p, *ptr);
6251
 
                if (descr == NULL)
6252
 
                        return -1;
6253
 
                if (PyDict_SetItem(dict, p->name_strobj, descr) < 0)
6254
 
                        return -1;
6255
 
                Py_DECREF(descr);
 
6319
                if (*ptr == PyObject_HashNotImplemented) {
 
6320
                        /* Classes may prevent the inheritance of the tp_hash
 
6321
                           slot by storing PyObject_HashNotImplemented in it. Make it
 
6322
                           visible as a None value for the __hash__ attribute. */
 
6323
                        if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0)
 
6324
                                return -1;
 
6325
                }
 
6326
                else {
 
6327
                        descr = PyDescr_NewWrapper(type, p, *ptr);
 
6328
                        if (descr == NULL)
 
6329
                                return -1;
 
6330
                        if (PyDict_SetItem(dict, p->name_strobj, descr) < 0)
 
6331
                                return -1;
 
6332
                        Py_DECREF(descr);
 
6333
                }
6256
6334
        }
6257
6335
        if (type->tp_new != NULL) {
6258
6336
                if (add_tp_new_wrapper(type) < 0)