Get rid of most of the flags (in tp_flags) that keep track of various

variations of the type struct and its attachments.  In Py3k, all type
structs have to have all fields -- no binary backwards compatibility.
Had to change the complex object to a new-style number!
This commit is contained in:
Guido van Rossum 2006-07-27 21:53:35 +00:00
parent 73e5a5b65d
commit 3cf5b1eef9
36 changed files with 170 additions and 357 deletions

View File

@ -534,8 +534,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
is an iterator, this returns itself. */
#define PyIter_Check(obj) \
(PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_ITER) && \
(obj)->ob_type->tp_iternext != NULL)
((obj)->ob_type->tp_iternext != NULL)
PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *);
/* Takes an iterator object and calls its tp_iternext slot,

View File

@ -147,11 +147,7 @@ typedef int (*visitproc)(PyObject *, void *);
typedef int (*traverseproc)(PyObject *, visitproc, void *);
typedef struct {
/* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all
arguments are guaranteed to be of the object's type (modulo
coercion hacks -- i.e. if the type's coercion function
returns other types, then these are allowed as well). Numbers that
have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both*
/* Number implementations should check *both*
arguments for proper type and implement the necessary conversions
in the slot functions themselves. */
@ -444,7 +440,9 @@ Arbitration of the flag bit positions will need to be coordinated among
all extension writers who publically release their extensions (this will
be fewer than you might expect!)..
Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs.
Most flags were removed as of Python 3.0 to make room for new flags. (Some
flags are not for backwards compatibility but to indicate the presence of an
optional feature; these flags remain of course.)
Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value.
@ -452,34 +450,6 @@ Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
given type object has a specified feature.
*/
/* PyBufferProcs contains bf_getcharbuffer */
#define Py_TPFLAGS_HAVE_GETCHARBUFFER (1L<<0)
/* PySequenceMethods contains sq_contains */
#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1)
/* This is here for backwards compatibility. Extensions that use the old GC
* API will still compile but the objects will not be tracked by the GC. */
#define Py_TPFLAGS_GC 0 /* used to be (1L<<2) */
/* PySequenceMethods and PyNumberMethods contain in-place operators */
#define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3)
/* PyNumberMethods do their own coercion */
#define Py_TPFLAGS_CHECKTYPES (1L<<4)
/* tp_richcompare is defined */
#define Py_TPFLAGS_HAVE_RICHCOMPARE (1L<<5)
/* Objects which are weakly referencable if their tp_weaklistoffset is >0 */
#define Py_TPFLAGS_HAVE_WEAKREFS (1L<<6)
/* tp_iter is defined */
#define Py_TPFLAGS_HAVE_ITER (1L<<7)
/* New members introduced by Python 2.2 exist */
#define Py_TPFLAGS_HAVE_CLASS (1L<<8)
/* Set if the type object is dynamically allocated */
#define Py_TPFLAGS_HEAPTYPE (1L<<9)
@ -502,19 +472,8 @@ given type object has a specified feature.
#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0
#endif
/* Objects support nb_index in PyNumberMethods */
#define Py_TPFLAGS_HAVE_INDEX (1L<<17)
#define Py_TPFLAGS_DEFAULT ( \
Py_TPFLAGS_HAVE_GETCHARBUFFER | \
Py_TPFLAGS_HAVE_SEQUENCE_IN | \
Py_TPFLAGS_HAVE_INPLACEOPS | \
Py_TPFLAGS_HAVE_RICHCOMPARE | \
Py_TPFLAGS_HAVE_WEAKREFS | \
Py_TPFLAGS_HAVE_ITER | \
Py_TPFLAGS_HAVE_CLASS | \
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
Py_TPFLAGS_HAVE_INDEX | \
0)
#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0)

View File

@ -323,9 +323,7 @@ PyAPI_FUNC(void) PyObject_GC_Del(void *);
/* Test if a type supports weak references */
#define PyType_SUPPORTS_WEAKREFS(t) \
(PyType_HasFeature((t), Py_TPFLAGS_HAVE_WEAKREFS) \
&& ((t)->tp_weaklistoffset > 0))
#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
#define PyObject_GET_WEAKREFS_LISTPTR(o) \
((PyObject **) (((char *) (o)) + (o)->ob_type->tp_weaklistoffset))

View File

@ -169,7 +169,7 @@ class TalkTo:
signature = self._signature
if type(signature) == AEDescType:
self.target = signature
elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
elif hasattr(signature, '__aepack__'):
self.target = signature.__aepack__()
elif type(signature) == StringType and len(signature) == 4:
self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)

View File

@ -49,7 +49,6 @@ testmeths = [
]
# These need to return something other than None
# "coerce",
# "hash",
# "str",
# "repr",
@ -65,10 +64,6 @@ testmeths = [
# "delattr",
class AllTests:
def __coerce__(self, *args):
print "__coerce__:", args
return (self,) + args
def __hash__(self, *args):
print "__hash__:", args
return hash(id(self))

View File

@ -713,8 +713,7 @@ class MappingTestCase(TestBase):
#
dict, objects = self.make_weak_valued_dict()
for o in objects:
self.assert_(weakref.getweakrefcount(o) == 1,
"wrong number of weak references to %r!" % o)
self.assertEqual(weakref.getweakrefcount(o), 1)
self.assert_(o is dict[o.arg],
"wrong object returned by weak dict!")
items1 = dict.items()

View File

@ -5350,7 +5350,7 @@ static PyTypeObject DB_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -5383,7 +5383,7 @@ static PyTypeObject DBCursor_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -5416,7 +5416,7 @@ static PyTypeObject DBEnv_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -5448,7 +5448,7 @@ static PyTypeObject DBTxn_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -5481,7 +5481,7 @@ static PyTypeObject DBLock_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -5514,7 +5514,7 @@ static PyTypeObject DBSequence_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -128,8 +128,6 @@ PyType_stgdict(PyObject *obj)
if (!PyType_Check(obj))
return NULL;
type = (PyTypeObject *)obj;
if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS))
return NULL;
if (!type->tp_dict || !StgDict_Check(type->tp_dict))
return NULL;
return (StgDictObject *)type->tp_dict;

View File

@ -219,7 +219,7 @@ static PyTypeObject partial_type = {
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_BASETYPE, /* tp_flags */
partial_doc, /* tp_doc */
(traverseproc)partial_traverse, /* tp_traverse */
0, /* tp_clear */

View File

@ -998,7 +998,7 @@ PyTypeObject CursorType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
cursor_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -403,7 +403,7 @@ PyTypeObject StatementType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -2628,7 +2628,7 @@ static PyTypeObject Pattern_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
pattern_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -1706,7 +1706,7 @@ PyTypeObject PyStructType = {
PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
s__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -1570,13 +1570,11 @@ array_repr(arrayobject *a)
return s;
}
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
static PyObject*
array_subscr(arrayobject* self, PyObject* item)
{
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(item);
if (i==-1 && PyErr_Occurred()) {
return NULL;
@ -1626,7 +1624,7 @@ static int
array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
{
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(item);
if (i==-1 && PyErr_Occurred())
return -1;
@ -1984,7 +1982,7 @@ static PyTypeObject Arraytype = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&array_as_buffer, /* tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
arraytype_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -846,8 +846,8 @@ static PyTypeObject deque_type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_HAVE_GC, /* tp_flags */
deque_doc, /* tp_doc */
(traverseproc)deque_traverse, /* tp_traverse */
(inquiry)deque_clear, /* tp_clear */
@ -1299,8 +1299,8 @@ static PyTypeObject defdict_type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_HAVE_GC, /* tp_flags */
defdict_doc, /* tp_doc */
defdict_traverse, /* tp_traverse */
(inquiry)defdict_tp_clear, /* tp_clear */

View File

@ -2141,8 +2141,7 @@ static PyTypeObject PyDateTime_DeltaType = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
delta_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -2698,8 +2697,7 @@ static PyTypeObject PyDateTime_DateType = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
date_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -2954,8 +2952,7 @@ static PyTypeObject PyDateTime_TZInfoType = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
tzinfo_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -3473,8 +3470,7 @@ static PyTypeObject PyDateTime_TimeType = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
time_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -4568,8 +4564,7 @@ static PyTypeObject PyDateTime_DateTimeType = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
datetime_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -800,13 +800,11 @@ static PyTypeObject mmap_object_type = {
0, /*tp_getattro*/
0, /*tp_setattro*/
&mmap_as_buffer, /*tp_as_buffer*/
Py_TPFLAGS_HAVE_GETCHARBUFFER, /*tp_flags*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
};
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
/* extract the map size from the given PyObject
Returns -1 on error, with an appropriate Python exception raised. On
@ -815,7 +813,7 @@ static Py_ssize_t
_GetMapSize(PyObject *o)
{
PyNumberMethods *nb = o->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(o) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(o);
if (i==-1 && PyErr_Occurred())
return -1;

View File

@ -5,11 +5,6 @@
#include "structmember.h" /* we need the offsetof() macro from there */
#include "longintrepr.h"
#define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \
Py_TPFLAGS_CHECKTYPES)
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
/* Shorthands to return certain errors */
@ -123,7 +118,7 @@ PyObject_GetItem(PyObject *o, PyObject *key)
if (o->ob_type->tp_as_sequence) {
PyNumberMethods *nb = key->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(key) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t key_value = nb->nb_index(key);
if (key_value == -1 && PyErr_Occurred())
return NULL;
@ -151,7 +146,7 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
if (o->ob_type->tp_as_sequence) {
PyNumberMethods *nb = key->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(key) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t key_value = nb->nb_index(key);
if (key_value == -1 && PyErr_Occurred())
return -1;
@ -182,7 +177,7 @@ PyObject_DelItem(PyObject *o, PyObject *key)
if (o->ob_type->tp_as_sequence) {
PyNumberMethods *nb = key->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(key) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t key_value = nb->nb_index(key);
if (key_value == -1 && PyErr_Occurred())
return -1;
@ -378,10 +373,10 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)
binaryfunc slotv = NULL;
binaryfunc slotw = NULL;
if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v))
if (v->ob_type->tp_as_number != NULL)
slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot);
if (w->ob_type != v->ob_type &&
w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) {
w->ob_type->tp_as_number != NULL) {
slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot);
if (slotw == slotv)
slotw = NULL;
@ -405,28 +400,6 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)
return x;
Py_DECREF(x); /* can't do it */
}
if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) {
int err = PyNumber_CoerceEx(&v, &w);
if (err < 0) {
return NULL;
}
if (err == 0) {
PyNumberMethods *mv = v->ob_type->tp_as_number;
if (mv) {
binaryfunc slot;
slot = NB_BINOP(mv, op_slot);
if (slot) {
x = slot(v, w);
Py_DECREF(v);
Py_DECREF(w);
return x;
}
}
/* CoerceEx incremented the reference counts */
Py_DECREF(v);
Py_DECREF(w);
}
}
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
@ -497,10 +470,10 @@ ternary_op(PyObject *v,
mv = v->ob_type->tp_as_number;
mw = w->ob_type->tp_as_number;
if (mv != NULL && NEW_STYLE_NUMBER(v))
if (mv != NULL)
slotv = NB_TERNOP(mv, op_slot);
if (w->ob_type != v->ob_type &&
mw != NULL && NEW_STYLE_NUMBER(w)) {
mw != NULL) {
slotw = NB_TERNOP(mw, op_slot);
if (slotw == slotv)
slotw = NULL;
@ -525,7 +498,7 @@ ternary_op(PyObject *v,
Py_DECREF(x); /* can't do it */
}
mz = z->ob_type->tp_as_number;
if (mz != NULL && NEW_STYLE_NUMBER(z)) {
if (mz != NULL) {
slotz = NB_TERNOP(mz, op_slot);
if (slotz == slotv || slotz == slotw)
slotz = NULL;
@ -537,66 +510,6 @@ ternary_op(PyObject *v,
}
}
if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w) ||
(z != Py_None && !NEW_STYLE_NUMBER(z))) {
/* we have an old style operand, coerce */
PyObject *v1, *z1, *w2, *z2;
int c;
c = PyNumber_Coerce(&v, &w);
if (c != 0)
goto error3;
/* Special case: if the third argument is None, it is
treated as absent argument and not coerced. */
if (z == Py_None) {
if (v->ob_type->tp_as_number) {
slotz = NB_TERNOP(v->ob_type->tp_as_number,
op_slot);
if (slotz)
x = slotz(v, w, z);
else
c = -1;
}
else
c = -1;
goto error2;
}
v1 = v;
z1 = z;
c = PyNumber_Coerce(&v1, &z1);
if (c != 0)
goto error2;
w2 = w;
z2 = z1;
c = PyNumber_Coerce(&w2, &z2);
if (c != 0)
goto error1;
if (v1->ob_type->tp_as_number != NULL) {
slotv = NB_TERNOP(v1->ob_type->tp_as_number,
op_slot);
if (slotv)
x = slotv(v1, w2, z2);
else
c = -1;
}
else
c = -1;
Py_DECREF(w2);
Py_DECREF(z2);
error1:
Py_DECREF(v1);
Py_DECREF(z1);
error2:
Py_DECREF(v);
Py_DECREF(w);
error3:
if (c >= 0)
return x;
}
if (z == Py_None)
PyErr_Format(
PyExc_TypeError,
@ -649,7 +562,7 @@ sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
{
Py_ssize_t count;
PyNumberMethods *nb = n->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(n) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
count = nb->nb_index(n);
if (count == -1 && PyErr_Occurred())
return NULL;
@ -722,14 +635,11 @@ PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
*/
#define HASINPLACE(t) \
PyType_HasFeature((t)->ob_type, Py_TPFLAGS_HAVE_INPLACEOPS)
static PyObject *
binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
{
PyNumberMethods *mv = v->ob_type->tp_as_number;
if (mv != NULL && HASINPLACE(v)) {
if (mv != NULL) {
binaryfunc slot = NB_BINOP(mv, iop_slot);
if (slot) {
PyObject *x = (slot)(v, w);
@ -793,8 +703,7 @@ PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
Py_DECREF(result);
if (m != NULL) {
binaryfunc f = NULL;
if (HASINPLACE(v))
f = m->sq_inplace_concat;
f = m->sq_inplace_concat;
if (f == NULL)
f = m->sq_concat;
if (f != NULL)
@ -816,8 +725,7 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
PySequenceMethods *mw = w->ob_type->tp_as_sequence;
Py_DECREF(result);
if (mv != NULL) {
if (HASINPLACE(v))
f = mv->sq_inplace_repeat;
f = mv->sq_inplace_repeat;
if (f == NULL)
f = mv->sq_repeat;
if (f != NULL)
@ -845,7 +753,7 @@ PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
PyObject *
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
{
if (HASINPLACE(v) && v->ob_type->tp_as_number &&
if (v->ob_type->tp_as_number &&
v->ob_type->tp_as_number->nb_inplace_power != NULL) {
return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
}
@ -938,7 +846,7 @@ PyNumber_Index(PyObject *item)
{
Py_ssize_t value = -1;
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
value = nb->nb_index(item);
}
else {
@ -1180,7 +1088,7 @@ PySequence_InPlaceConcat(PyObject *s, PyObject *o)
return null_error();
m = s->ob_type->tp_as_sequence;
if (m && HASINPLACE(s) && m->sq_inplace_concat)
if (m && m->sq_inplace_concat)
return m->sq_inplace_concat(s, o);
if (m && m->sq_concat)
return m->sq_concat(s, o);
@ -1204,7 +1112,7 @@ PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
return null_error();
m = o->ob_type->tp_as_sequence;
if (m && HASINPLACE(o) && m->sq_inplace_repeat)
if (m && m->sq_inplace_repeat)
return m->sq_inplace_repeat(o, count);
if (m && m->sq_repeat)
return m->sq_repeat(o, count);
@ -1646,11 +1554,9 @@ int
PySequence_Contains(PyObject *seq, PyObject *ob)
{
Py_ssize_t result;
if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) {
PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
if (sqm != NULL && sqm->sq_contains != NULL)
return (*sqm->sq_contains)(seq, ob);
}
PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
if (sqm != NULL && sqm->sq_contains != NULL)
return (*sqm->sq_contains)(seq, ob);
result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
}
@ -2260,8 +2166,7 @@ PyObject_GetIter(PyObject *o)
{
PyTypeObject *t = o->ob_type;
getiterfunc f = NULL;
if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
f = t->tp_iter;
f = t->tp_iter;
if (f == NULL) {
if (PySequence_Check(o))
return PySeqIter_New(o);

View File

@ -164,7 +164,7 @@ PyTypeObject PyBool_Type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
bool_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -743,8 +743,9 @@ bytes_join(PyObject *cls, PyObject *it)
if (!PyBytes_Check(obj)) {
PyErr_Format(PyExc_TypeError,
"can only join an iterable of bytes "
"(item %d has type '%.100s')",
i, obj->ob_type->tp_name);
"(item %ld has type '%.100s')",
/* XXX %ld isn't right on Win64 */
(long)i, obj->ob_type->tp_name);
goto error;
}
totalsize += PyBytes_GET_SIZE(obj);
@ -838,7 +839,7 @@ PyTypeObject PyBytes_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&bytes_as_buffer, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
/* bytes is 'final' or 'sealed' */
bytes_doc, /* tp_doc */
0, /* tp_traverse */

View File

@ -4,8 +4,7 @@
#include "Python.h"
#include "structmember.h"
#define TP_DESCR_GET(t) \
(PyType_HasFeature(t, Py_TPFLAGS_HAVE_CLASS) ? (t)->tp_descr_get : NULL)
#define TP_DESCR_GET(t) ((t)->tp_descr_get)
/* Forward */
@ -2045,7 +2044,7 @@ PyTypeObject PyInstance_Type = {
(getattrofunc)instance_getattr, /* tp_getattro */
(setattrofunc)instance_setattr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES,/*tp_flags*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
instance_doc, /* tp_doc */
(traverseproc)instance_traverse, /* tp_traverse */
0, /* tp_clear */
@ -2149,7 +2148,7 @@ instancemethod_getattro(PyObject *obj, PyObject *name)
PyTypeObject *tp = obj->ob_type;
PyObject *descr = NULL;
if (PyType_HasFeature(tp, Py_TPFLAGS_HAVE_CLASS)) {
{
if (tp->tp_dict == NULL) {
if (PyType_Ready(tp) < 0)
return NULL;
@ -2468,7 +2467,7 @@ PyTypeObject PyMethod_Type = {
instancemethod_getattro, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
instancemethod_doc, /* tp_doc */
(traverseproc)instancemethod_traverse, /* tp_traverse */
0, /* tp_clear */

View File

@ -336,43 +336,90 @@ complex_hash(PyComplexObject *v)
return combined;
}
/* This macro may return! */
#define TO_COMPLEX(obj, c) \
if (PyComplex_Check(obj)) \
c = ((PyComplexObject *)(obj))->cval; \
else if (to_complex(&(obj), &(c)) < 0) \
return (obj)
static int
to_complex(PyObject **pobj, Py_complex *pc)
{
PyObject *obj = *pobj;
pc->real = pc->imag = 0.0;
if (PyInt_Check(obj)) {
pc->real = PyInt_AS_LONG(obj);
return 0;
}
if (PyLong_Check(obj)) {
pc->real = PyLong_AsDouble(obj);
if (pc->real == -1.0 && PyErr_Occurred()) {
*pobj = NULL;
return -1;
}
return 0;
}
if (PyFloat_Check(obj)) {
pc->real = PyFloat_AsDouble(obj);
return 0;
}
Py_INCREF(Py_NotImplemented);
*pobj = Py_NotImplemented;
return -1;
}
static PyObject *
complex_add(PyComplexObject *v, PyComplexObject *w)
complex_add(PyObject *v, PyObject *w)
{
Py_complex result;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_add", return 0)
result = c_sum(v->cval,w->cval);
result = c_sum(a, b);
PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result);
}
static PyObject *
complex_sub(PyComplexObject *v, PyComplexObject *w)
complex_sub(PyObject *v, PyObject *w)
{
Py_complex result;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_sub", return 0)
result = c_diff(v->cval,w->cval);
result = c_diff(a, b);
PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result);
}
static PyObject *
complex_mul(PyComplexObject *v, PyComplexObject *w)
complex_mul(PyObject *v, PyObject *w)
{
Py_complex result;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_mul", return 0)
result = c_prod(v->cval,w->cval);
result = c_prod(a, b);
PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result);
}
static PyObject *
complex_div(PyComplexObject *v, PyComplexObject *w)
complex_div(PyObject *v, PyObject *w)
{
Py_complex quot;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_div", return 0)
errno = 0;
quot = c_quot(v->cval,w->cval);
quot = c_quot(a, b);
PyFPE_END_PROTECT(quot)
if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
@ -382,47 +429,53 @@ complex_div(PyComplexObject *v, PyComplexObject *w)
}
static PyObject *
complex_remainder(PyComplexObject *v, PyComplexObject *w)
complex_remainder(PyObject *v, PyObject *w)
{
Py_complex div, mod;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
if (PyErr_Warn(PyExc_DeprecationWarning,
"complex divmod(), // and % are deprecated") < 0)
return NULL;
errno = 0;
div = c_quot(v->cval,w->cval); /* The raw divisor value. */
div = c_quot(a, b); /* The raw divisor value. */
if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
return NULL;
}
div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0;
mod = c_diff(v->cval, c_prod(w->cval, div));
mod = c_diff(a, c_prod(b, div));
return PyComplex_FromCComplex(mod);
}
static PyObject *
complex_divmod(PyComplexObject *v, PyComplexObject *w)
complex_divmod(PyObject *v, PyObject *w)
{
Py_complex div, mod;
PyObject *d, *m, *z;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
if (PyErr_Warn(PyExc_DeprecationWarning,
"complex divmod(), // and % are deprecated") < 0)
return NULL;
errno = 0;
div = c_quot(v->cval,w->cval); /* The raw divisor value. */
div = c_quot(a, b); /* The raw divisor value. */
if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
return NULL;
}
div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0;
mod = c_diff(v->cval, c_prod(w->cval, div));
mod = c_diff(a, c_prod(b, div));
d = PyComplex_FromCComplex(div);
m = PyComplex_FromCComplex(mod);
z = PyTuple_Pack(2, d, m);
@ -432,24 +485,27 @@ complex_divmod(PyComplexObject *v, PyComplexObject *w)
}
static PyObject *
complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
complex_pow(PyObject *v, PyObject *w, PyObject *z)
{
Py_complex p;
Py_complex exponent;
long int_exponent;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
if ((PyObject *)z!=Py_None) {
if (z != Py_None) {
PyErr_SetString(PyExc_ValueError, "complex modulo");
return NULL;
}
PyFPE_START_PROTECT("complex_pow", return 0)
errno = 0;
exponent = ((PyComplexObject*)w)->cval;
exponent = b;
int_exponent = (long)exponent.real;
if (exponent.imag == 0. && exponent.real == int_exponent)
p = c_powi(v->cval,int_exponent);
p = c_powi(a, int_exponent);
else
p = c_pow(v->cval,exponent);
p = c_pow(a, exponent);
PyFPE_END_PROTECT(p)
Py_ADJUST_ERANGE2(p.real, p.imag);
@ -467,7 +523,7 @@ complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
}
static PyObject *
complex_int_div(PyComplexObject *v, PyComplexObject *w)
complex_int_div(PyObject *v, PyObject *w)
{
PyObject *t, *r;

View File

@ -2073,7 +2073,7 @@ PyTypeObject PyFile_Type = {
/* softspace is writable: we must supply tp_setattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
file_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -1162,8 +1162,7 @@ PyTypeObject PyFloat_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
float_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -1080,8 +1080,7 @@ PyTypeObject PyInt_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
int_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -1833,8 +1833,7 @@ static PyTypeObject sortwrapper_type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_HAVE_RICHCOMPARE, /* tp_flags */
Py_TPFLAGS_DEFAULT, /* tp_flags */
sortwrapper_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@ -2448,13 +2447,11 @@ PyDoc_STRVAR(list_doc,
"list() -> new list\n"
"list(sequence) -> new list initialized from sequence's items");
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
static PyObject *
list_subscript(PyListObject* self, PyObject* item)
{
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(item);
if (i == -1 && PyErr_Occurred())
return NULL;
@ -2503,7 +2500,7 @@ static int
list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
{
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(item);
if (i == -1 && PyErr_Occurred())
return -1;

View File

@ -3411,8 +3411,7 @@ PyTypeObject PyLong_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
long_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -546,8 +546,7 @@ adjust_tp_compare(int c)
/* Macro to get the tp_richcompare field of a type if defined */
#define RICHCOMPARE(t) (PyType_HasFeature((t), Py_TPFLAGS_HAVE_RICHCOMPARE) \
? (t)->tp_richcompare : NULL)
#define RICHCOMPARE(t) ((t)->tp_richcompare)
/* Map rich comparison operators to their swapped version, e.g. LT --> GT */
int _Py_SwappedOp[] = {Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE};
@ -1224,8 +1223,6 @@ _PyObject_GetDictPtr(PyObject *obj)
Py_ssize_t dictoffset;
PyTypeObject *tp = obj->ob_type;
if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
return NULL;
dictoffset = tp->tp_dictoffset;
if (dictoffset == 0)
return NULL;
@ -1318,8 +1315,7 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
Py_XINCREF(descr);
f = NULL;
if (descr != NULL &&
PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
if (descr != NULL) {
f = descr->ob_type->tp_descr_get;
if (f != NULL && PyDescr_IsData(descr)) {
res = f(descr, obj, (PyObject *)obj->ob_type);
@ -1414,8 +1410,7 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
descr = _PyType_Lookup(tp, name);
f = NULL;
if (descr != NULL &&
PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
if (descr != NULL) {
f = descr->ob_type->tp_descr_set;
if (f != NULL && PyDescr_IsData(descr)) {
res = f(descr, obj, value);
@ -1518,14 +1513,6 @@ PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
register PyObject *w = *pw;
int res;
/* Shortcut only for old-style types */
if (v->ob_type == w->ob_type &&
!PyType_HasFeature(v->ob_type, Py_TPFLAGS_CHECKTYPES))
{
Py_INCREF(v);
Py_INCREF(w);
return 0;
}
if (v->ob_type->tp_as_number && v->ob_type->tp_as_number->nb_coerce) {
res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw);
if (res <= 0)

View File

@ -1819,7 +1819,7 @@ PyTypeObject PySet_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
set_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */
@ -1913,7 +1913,7 @@ PyTypeObject PyFrozenSet_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
frozenset_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */

View File

@ -1184,13 +1184,11 @@ string_hash(PyStringObject *a)
return x;
}
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
static PyObject*
string_subscript(PyStringObject* self, PyObject* item)
{
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(item);
if (i == -1 && PyErr_Occurred())
return NULL;
@ -4004,8 +4002,7 @@ PyTypeObject PyString_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&string_as_buffer, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
string_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -577,13 +577,11 @@ static PySequenceMethods tuple_as_sequence = {
(objobjproc)tuplecontains, /* sq_contains */
};
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
static PyObject*
tuplesubscript(PyTupleObject* self, PyObject* item)
{
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(item);
if (i == -1 && PyErr_Occurred())
return NULL;

View File

@ -433,8 +433,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (!PyType_IsSubtype(obj->ob_type, type))
return obj;
type = obj->ob_type;
if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS) &&
type->tp_init != NULL &&
if (type->tp_init != NULL &&
type->tp_init(obj, args, kwds) < 0) {
Py_DECREF(obj);
obj = NULL;
@ -813,9 +812,6 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
{
PyObject *mro;
if (!(a->tp_flags & Py_TPFLAGS_HAVE_CLASS))
return b == a || b == &PyBaseObject_Type;
mro = a->tp_mro;
if (mro != NULL) {
/* Deal with multiple inheritance without recursion
@ -1844,12 +1840,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
if (base->tp_flags & Py_TPFLAGS_HAVE_GC)
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
/* It's a new-style number unless it specifically inherits any
old-style numeric behavior */
if ((base->tp_flags & Py_TPFLAGS_CHECKTYPES) ||
(base->tp_as_number == NULL))
type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
/* Initialize essential fields */
type->tp_as_number = &et->as_number;
type->tp_as_sequence = &et->as_sequence;
@ -2881,39 +2871,11 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
{
Py_ssize_t oldsize, newsize;
/* Special flag magic */
if (!type->tp_as_buffer && base->tp_as_buffer) {
type->tp_flags &= ~Py_TPFLAGS_HAVE_GETCHARBUFFER;
type->tp_flags |=
base->tp_flags & Py_TPFLAGS_HAVE_GETCHARBUFFER;
}
if (!type->tp_as_sequence && base->tp_as_sequence) {
type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN;
type->tp_flags |= base->tp_flags & Py_TPFLAGS_HAVE_SEQUENCE_IN;
}
if ((type->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS) !=
(base->tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS)) {
if ((!type->tp_as_number && base->tp_as_number) ||
(!type->tp_as_sequence && base->tp_as_sequence)) {
type->tp_flags &= ~Py_TPFLAGS_HAVE_INPLACEOPS;
if (!type->tp_as_number && !type->tp_as_sequence) {
type->tp_flags |= base->tp_flags &
Py_TPFLAGS_HAVE_INPLACEOPS;
}
}
/* Wow */
}
if (!type->tp_as_number && base->tp_as_number) {
type->tp_flags &= ~Py_TPFLAGS_CHECKTYPES;
type->tp_flags |= base->tp_flags & Py_TPFLAGS_CHECKTYPES;
}
/* Copying basicsize is connected to the GC flags */
oldsize = base->tp_basicsize;
newsize = type->tp_basicsize ? type->tp_basicsize : oldsize;
if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) &&
(base->tp_flags & Py_TPFLAGS_HAVE_GC) &&
(type->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE/*GC slots exist*/) &&
(!type->tp_traverse && !type->tp_clear)) {
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
if (type->tp_traverse == NULL)
@ -2921,7 +2883,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
if (type->tp_clear == NULL)
type->tp_clear = base->tp_clear;
}
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
{
/* The condition below could use some explanation.
It appears that tp_new is not inherited for static types
whose base class is 'object'; this seems to be a precaution
@ -2947,12 +2909,8 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
if (type->SLOT == 0) type->SLOT = base->SLOT
COPYVAL(tp_itemsize);
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_WEAKREFS) {
COPYVAL(tp_weaklistoffset);
}
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
COPYVAL(tp_dictoffset);
}
COPYVAL(tp_weaklistoffset);
COPYVAL(tp_dictoffset);
}
static void
@ -3022,10 +2980,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
COPYNUM(nb_floor_divide);
COPYNUM(nb_inplace_true_divide);
COPYNUM(nb_inplace_floor_divide);
/* XXX(nnorwitz): we don't need to check flags do we? */
if (base->tp_flags & Py_TPFLAGS_HAVE_INDEX) {
COPYNUM(nb_index);
}
COPYNUM(nb_index);
}
if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
@ -3080,7 +3035,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
/* tp_hash see tp_richcompare */
COPYSLOT(tp_call);
COPYSLOT(tp_str);
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) {
{
if (type->tp_compare == NULL &&
type->tp_richcompare == NULL &&
type->tp_hash == NULL)
@ -3090,14 +3045,11 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
type->tp_hash = base->tp_hash;
}
}
else {
COPYSLOT(tp_compare);
}
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_ITER) {
{
COPYSLOT(tp_iter);
COPYSLOT(tp_iternext);
}
if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
{
COPYSLOT(tp_descr_get);
COPYSLOT(tp_descr_set);
COPYSLOT(tp_dictoffset);
@ -3419,11 +3371,6 @@ wrap_binaryfunc_l(PyObject *self, PyObject *args, void *wrapped)
if (!check_num_args(args, 1))
return NULL;
other = PyTuple_GET_ITEM(args, 0);
if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
!PyType_IsSubtype(other->ob_type, self->ob_type)) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
return (*func)(self, other);
}
@ -3436,8 +3383,7 @@ wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
if (!check_num_args(args, 1))
return NULL;
other = PyTuple_GET_ITEM(args, 0);
if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
!PyType_IsSubtype(other->ob_type, self->ob_type)) {
if (!PyType_IsSubtype(other->ob_type, self->ob_type)) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}

View File

@ -6818,13 +6818,11 @@ static PySequenceMethods unicode_as_sequence = {
PyUnicode_Contains, /* sq_contains */
};
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
static PyObject*
unicode_subscript(PyUnicodeObject* self, PyObject* item)
{
PyNumberMethods *nb = item->ob_type->tp_as_number;
if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
if (nb != NULL && nb->nb_index != NULL) {
Py_ssize_t i = nb->nb_index(item);
if (i == -1 && PyErr_Occurred())
return NULL;
@ -7706,8 +7704,7 @@ PyTypeObject PyUnicode_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
&unicode_as_buffer, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
unicode_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */

View File

@ -349,7 +349,7 @@ _PyWeakref_RefType = {
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_RICHCOMPARE
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_BASETYPE, /*tp_flags*/
0, /*tp_doc*/
(traverseproc)gc_traverse, /*tp_traverse*/
@ -660,8 +660,7 @@ _PyWeakref_ProxyType = {
proxy_getattr, /* tp_getattro */
(setattrofunc)proxy_setattr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_CHECKTYPES, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)gc_traverse, /* tp_traverse */
(inquiry)gc_clear, /* tp_clear */
@ -695,8 +694,7 @@ _PyWeakref_CallableProxyType = {
proxy_getattr, /* tp_getattro */
(setattrofunc)proxy_setattr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_CHECKTYPES, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)gc_traverse, /* tp_traverse */
(inquiry)gc_clear, /* tp_clear */

View File

@ -3833,8 +3833,7 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
x = PyInt_AsSsize_t(v);
}
else if (v->ob_type->tp_as_number &&
PyType_HasFeature(v->ob_type, Py_TPFLAGS_HAVE_INDEX)
&& v->ob_type->tp_as_number->nb_index) {
v->ob_type->tp_as_number->nb_index) {
x = v->ob_type->tp_as_number->nb_index(v);
if (x == -1 && PyErr_Occurred())
return 0;
@ -3853,8 +3852,7 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
#undef ISINDEX
#define ISINDEX(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x) || \
((x)->ob_type->tp_as_number && \
PyType_HasFeature((x)->ob_type, Py_TPFLAGS_HAVE_INDEX) \
&& (x)->ob_type->tp_as_number->nb_index))
(x)->ob_type->tp_as_number->nb_index))
static PyObject *
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */

View File

@ -1162,9 +1162,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
return converterr(
"invalid use of 't' format character",
arg, msgbuf, bufsize);
if (!PyType_HasFeature(arg->ob_type,
Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
pb == NULL || pb->bf_getcharbuffer == NULL ||
if (pb == NULL || pb->bf_getcharbuffer == NULL ||
pb->bf_getsegcount == NULL)
return converterr(
"string or read-only character buffer",