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. */ is an iterator, this returns itself. */
#define PyIter_Check(obj) \ #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 *); PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *);
/* Takes an iterator object and calls its tp_iternext slot, /* 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 int (*traverseproc)(PyObject *, visitproc, void *);
typedef struct { typedef struct {
/* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all /* Number implementations should check *both*
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*
arguments for proper type and implement the necessary conversions arguments for proper type and implement the necessary conversions
in the slot functions themselves. */ 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 all extension writers who publically release their extensions (this will
be fewer than you might expect!).. 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. 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. 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 */ /* Set if the type object is dynamically allocated */
#define Py_TPFLAGS_HEAPTYPE (1L<<9) #define Py_TPFLAGS_HEAPTYPE (1L<<9)
@ -502,19 +472,8 @@ given type object has a specified feature.
#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 #define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0
#endif #endif
/* Objects support nb_index in PyNumberMethods */
#define Py_TPFLAGS_HAVE_INDEX (1L<<17)
#define Py_TPFLAGS_DEFAULT ( \ #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_STACKLESS_EXTENSION | \
Py_TPFLAGS_HAVE_INDEX | \
0) 0)
#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 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 */ /* Test if a type supports weak references */
#define PyType_SUPPORTS_WEAKREFS(t) \ #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
(PyType_HasFeature((t), Py_TPFLAGS_HAVE_WEAKREFS) \
&& ((t)->tp_weaklistoffset > 0))
#define PyObject_GET_WEAKREFS_LISTPTR(o) \ #define PyObject_GET_WEAKREFS_LISTPTR(o) \
((PyObject **) (((char *) (o)) + (o)->ob_type->tp_weaklistoffset)) ((PyObject **) (((char *) (o)) + (o)->ob_type->tp_weaklistoffset))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -219,7 +219,7 @@ static PyTypeObject partial_type = {
PyObject_GenericSetAttr, /* tp_setattro */ PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 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 */ partial_doc, /* tp_doc */
(traverseproc)partial_traverse, /* tp_traverse */ (traverseproc)partial_traverse, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */

View File

@ -998,7 +998,7 @@ PyTypeObject CursorType = {
0, /* tp_getattro */ 0, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 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 */ cursor_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */

View File

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

View File

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

View File

@ -1706,7 +1706,7 @@ PyTypeObject PyStructType = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */ PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */ 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 */ s__doc__, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */

View File

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

View File

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

View File

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

View File

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

View File

@ -5,11 +5,6 @@
#include "structmember.h" /* we need the offsetof() macro from there */ #include "structmember.h" /* we need the offsetof() macro from there */
#include "longintrepr.h" #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 */ /* Shorthands to return certain errors */
@ -123,7 +118,7 @@ PyObject_GetItem(PyObject *o, PyObject *key)
if (o->ob_type->tp_as_sequence) { if (o->ob_type->tp_as_sequence) {
PyNumberMethods *nb = key->ob_type->tp_as_number; 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); Py_ssize_t key_value = nb->nb_index(key);
if (key_value == -1 && PyErr_Occurred()) if (key_value == -1 && PyErr_Occurred())
return NULL; return NULL;
@ -151,7 +146,7 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
if (o->ob_type->tp_as_sequence) { if (o->ob_type->tp_as_sequence) {
PyNumberMethods *nb = key->ob_type->tp_as_number; 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); Py_ssize_t key_value = nb->nb_index(key);
if (key_value == -1 && PyErr_Occurred()) if (key_value == -1 && PyErr_Occurred())
return -1; return -1;
@ -182,7 +177,7 @@ PyObject_DelItem(PyObject *o, PyObject *key)
if (o->ob_type->tp_as_sequence) { if (o->ob_type->tp_as_sequence) {
PyNumberMethods *nb = key->ob_type->tp_as_number; 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); Py_ssize_t key_value = nb->nb_index(key);
if (key_value == -1 && PyErr_Occurred()) if (key_value == -1 && PyErr_Occurred())
return -1; return -1;
@ -378,10 +373,10 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)
binaryfunc slotv = NULL; binaryfunc slotv = NULL;
binaryfunc slotw = 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); slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot);
if (w->ob_type != v->ob_type && 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); slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot);
if (slotw == slotv) if (slotw == slotv)
slotw = NULL; slotw = NULL;
@ -405,28 +400,6 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)
return x; return x;
Py_DECREF(x); /* can't do it */ 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); Py_INCREF(Py_NotImplemented);
return Py_NotImplemented; return Py_NotImplemented;
} }
@ -497,10 +470,10 @@ ternary_op(PyObject *v,
mv = v->ob_type->tp_as_number; mv = v->ob_type->tp_as_number;
mw = w->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); slotv = NB_TERNOP(mv, op_slot);
if (w->ob_type != v->ob_type && if (w->ob_type != v->ob_type &&
mw != NULL && NEW_STYLE_NUMBER(w)) { mw != NULL) {
slotw = NB_TERNOP(mw, op_slot); slotw = NB_TERNOP(mw, op_slot);
if (slotw == slotv) if (slotw == slotv)
slotw = NULL; slotw = NULL;
@ -525,7 +498,7 @@ ternary_op(PyObject *v,
Py_DECREF(x); /* can't do it */ Py_DECREF(x); /* can't do it */
} }
mz = z->ob_type->tp_as_number; mz = z->ob_type->tp_as_number;
if (mz != NULL && NEW_STYLE_NUMBER(z)) { if (mz != NULL) {
slotz = NB_TERNOP(mz, op_slot); slotz = NB_TERNOP(mz, op_slot);
if (slotz == slotv || slotz == slotw) if (slotz == slotv || slotz == slotw)
slotz = NULL; 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) if (z == Py_None)
PyErr_Format( PyErr_Format(
PyExc_TypeError, PyExc_TypeError,
@ -649,7 +562,7 @@ sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
{ {
Py_ssize_t count; Py_ssize_t count;
PyNumberMethods *nb = n->ob_type->tp_as_number; 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); count = nb->nb_index(n);
if (count == -1 && PyErr_Occurred()) if (count == -1 && PyErr_Occurred())
return NULL; 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 * static PyObject *
binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot) binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
{ {
PyNumberMethods *mv = v->ob_type->tp_as_number; PyNumberMethods *mv = v->ob_type->tp_as_number;
if (mv != NULL && HASINPLACE(v)) { if (mv != NULL) {
binaryfunc slot = NB_BINOP(mv, iop_slot); binaryfunc slot = NB_BINOP(mv, iop_slot);
if (slot) { if (slot) {
PyObject *x = (slot)(v, w); PyObject *x = (slot)(v, w);
@ -793,8 +703,7 @@ PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
Py_DECREF(result); Py_DECREF(result);
if (m != NULL) { if (m != NULL) {
binaryfunc f = NULL; binaryfunc f = NULL;
if (HASINPLACE(v)) f = m->sq_inplace_concat;
f = m->sq_inplace_concat;
if (f == NULL) if (f == NULL)
f = m->sq_concat; f = m->sq_concat;
if (f != NULL) if (f != NULL)
@ -816,8 +725,7 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
PySequenceMethods *mw = w->ob_type->tp_as_sequence; PySequenceMethods *mw = w->ob_type->tp_as_sequence;
Py_DECREF(result); Py_DECREF(result);
if (mv != NULL) { if (mv != NULL) {
if (HASINPLACE(v)) f = mv->sq_inplace_repeat;
f = mv->sq_inplace_repeat;
if (f == NULL) if (f == NULL)
f = mv->sq_repeat; f = mv->sq_repeat;
if (f != NULL) if (f != NULL)
@ -845,7 +753,7 @@ PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
PyObject * PyObject *
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) 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) { v->ob_type->tp_as_number->nb_inplace_power != NULL) {
return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**="); return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
} }
@ -938,7 +846,7 @@ PyNumber_Index(PyObject *item)
{ {
Py_ssize_t value = -1; Py_ssize_t value = -1;
PyNumberMethods *nb = item->ob_type->tp_as_number; 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); value = nb->nb_index(item);
} }
else { else {
@ -1180,7 +1088,7 @@ PySequence_InPlaceConcat(PyObject *s, PyObject *o)
return null_error(); return null_error();
m = s->ob_type->tp_as_sequence; 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); return m->sq_inplace_concat(s, o);
if (m && m->sq_concat) if (m && m->sq_concat)
return m->sq_concat(s, o); return m->sq_concat(s, o);
@ -1204,7 +1112,7 @@ PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
return null_error(); return null_error();
m = o->ob_type->tp_as_sequence; 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); return m->sq_inplace_repeat(o, count);
if (m && m->sq_repeat) if (m && m->sq_repeat)
return m->sq_repeat(o, count); return m->sq_repeat(o, count);
@ -1646,11 +1554,9 @@ int
PySequence_Contains(PyObject *seq, PyObject *ob) PySequence_Contains(PyObject *seq, PyObject *ob)
{ {
Py_ssize_t result; Py_ssize_t result;
if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) { PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
PySequenceMethods *sqm = seq->ob_type->tp_as_sequence; if (sqm != NULL && sqm->sq_contains != NULL)
if (sqm != NULL && sqm->sq_contains != NULL) return (*sqm->sq_contains)(seq, ob);
return (*sqm->sq_contains)(seq, ob);
}
result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
} }
@ -2260,8 +2166,7 @@ PyObject_GetIter(PyObject *o)
{ {
PyTypeObject *t = o->ob_type; PyTypeObject *t = o->ob_type;
getiterfunc f = NULL; getiterfunc f = NULL;
if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER)) f = t->tp_iter;
f = t->tp_iter;
if (f == NULL) { if (f == NULL) {
if (PySequence_Check(o)) if (PySequence_Check(o))
return PySeqIter_New(o); return PySeqIter_New(o);

View File

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

View File

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

View File

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

View File

@ -336,43 +336,90 @@ complex_hash(PyComplexObject *v)
return combined; 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 * static PyObject *
complex_add(PyComplexObject *v, PyComplexObject *w) complex_add(PyObject *v, PyObject *w)
{ {
Py_complex result; Py_complex result;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_add", return 0) PyFPE_START_PROTECT("complex_add", return 0)
result = c_sum(v->cval,w->cval); result = c_sum(a, b);
PyFPE_END_PROTECT(result) PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result); return PyComplex_FromCComplex(result);
} }
static PyObject * static PyObject *
complex_sub(PyComplexObject *v, PyComplexObject *w) complex_sub(PyObject *v, PyObject *w)
{ {
Py_complex result; Py_complex result;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_sub", return 0) PyFPE_START_PROTECT("complex_sub", return 0)
result = c_diff(v->cval,w->cval); result = c_diff(a, b);
PyFPE_END_PROTECT(result) PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result); return PyComplex_FromCComplex(result);
} }
static PyObject * static PyObject *
complex_mul(PyComplexObject *v, PyComplexObject *w) complex_mul(PyObject *v, PyObject *w)
{ {
Py_complex result; Py_complex result;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_mul", return 0) PyFPE_START_PROTECT("complex_mul", return 0)
result = c_prod(v->cval,w->cval); result = c_prod(a, b);
PyFPE_END_PROTECT(result) PyFPE_END_PROTECT(result)
return PyComplex_FromCComplex(result); return PyComplex_FromCComplex(result);
} }
static PyObject * static PyObject *
complex_div(PyComplexObject *v, PyComplexObject *w) complex_div(PyObject *v, PyObject *w)
{ {
Py_complex quot; Py_complex quot;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
PyFPE_START_PROTECT("complex_div", return 0) PyFPE_START_PROTECT("complex_div", return 0)
errno = 0; errno = 0;
quot = c_quot(v->cval,w->cval); quot = c_quot(a, b);
PyFPE_END_PROTECT(quot) PyFPE_END_PROTECT(quot)
if (errno == EDOM) { if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex division"); PyErr_SetString(PyExc_ZeroDivisionError, "complex division");
@ -382,47 +429,53 @@ complex_div(PyComplexObject *v, PyComplexObject *w)
} }
static PyObject * static PyObject *
complex_remainder(PyComplexObject *v, PyComplexObject *w) complex_remainder(PyObject *v, PyObject *w)
{ {
Py_complex div, mod; Py_complex div, mod;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
if (PyErr_Warn(PyExc_DeprecationWarning, if (PyErr_Warn(PyExc_DeprecationWarning,
"complex divmod(), // and % are deprecated") < 0) "complex divmod(), // and % are deprecated") < 0)
return NULL; return NULL;
errno = 0; 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) { if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder"); PyErr_SetString(PyExc_ZeroDivisionError, "complex remainder");
return NULL; return NULL;
} }
div.real = floor(div.real); /* Use the floor of the real part. */ div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0; 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); return PyComplex_FromCComplex(mod);
} }
static PyObject * static PyObject *
complex_divmod(PyComplexObject *v, PyComplexObject *w) complex_divmod(PyObject *v, PyObject *w)
{ {
Py_complex div, mod; Py_complex div, mod;
PyObject *d, *m, *z; PyObject *d, *m, *z;
Py_complex a, b;
TO_COMPLEX(v, a);
TO_COMPLEX(w, b);
if (PyErr_Warn(PyExc_DeprecationWarning, if (PyErr_Warn(PyExc_DeprecationWarning,
"complex divmod(), // and % are deprecated") < 0) "complex divmod(), // and % are deprecated") < 0)
return NULL; return NULL;
errno = 0; 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) { if (errno == EDOM) {
PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()"); PyErr_SetString(PyExc_ZeroDivisionError, "complex divmod()");
return NULL; return NULL;
} }
div.real = floor(div.real); /* Use the floor of the real part. */ div.real = floor(div.real); /* Use the floor of the real part. */
div.imag = 0.0; 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); d = PyComplex_FromCComplex(div);
m = PyComplex_FromCComplex(mod); m = PyComplex_FromCComplex(mod);
z = PyTuple_Pack(2, d, m); z = PyTuple_Pack(2, d, m);
@ -432,24 +485,27 @@ complex_divmod(PyComplexObject *v, PyComplexObject *w)
} }
static PyObject * static PyObject *
complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z) complex_pow(PyObject *v, PyObject *w, PyObject *z)
{ {
Py_complex p; Py_complex p;
Py_complex exponent; Py_complex exponent;
long int_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"); PyErr_SetString(PyExc_ValueError, "complex modulo");
return NULL; return NULL;
} }
PyFPE_START_PROTECT("complex_pow", return 0) PyFPE_START_PROTECT("complex_pow", return 0)
errno = 0; errno = 0;
exponent = ((PyComplexObject*)w)->cval; exponent = b;
int_exponent = (long)exponent.real; int_exponent = (long)exponent.real;
if (exponent.imag == 0. && exponent.real == int_exponent) if (exponent.imag == 0. && exponent.real == int_exponent)
p = c_powi(v->cval,int_exponent); p = c_powi(a, int_exponent);
else else
p = c_pow(v->cval,exponent); p = c_pow(a, exponent);
PyFPE_END_PROTECT(p) PyFPE_END_PROTECT(p)
Py_ADJUST_ERANGE2(p.real, p.imag); Py_ADJUST_ERANGE2(p.real, p.imag);
@ -467,7 +523,7 @@ complex_pow(PyComplexObject *v, PyObject *w, PyComplexObject *z)
} }
static PyObject * static PyObject *
complex_int_div(PyComplexObject *v, PyComplexObject *w) complex_int_div(PyObject *v, PyObject *w)
{ {
PyObject *t, *r; PyObject *t, *r;

View File

@ -2073,7 +2073,7 @@ PyTypeObject PyFile_Type = {
/* softspace is writable: we must supply tp_setattro */ /* softspace is writable: we must supply tp_setattro */
PyObject_GenericSetAttr, /* tp_setattro */ PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */ 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 */ file_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */

View File

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

View File

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

View File

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

View File

@ -3411,8 +3411,7 @@ PyTypeObject PyLong_Type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Py_TPFLAGS_BASETYPE, /* tp_flags */
long_doc, /* tp_doc */ long_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 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 */ /* Macro to get the tp_richcompare field of a type if defined */
#define RICHCOMPARE(t) (PyType_HasFeature((t), Py_TPFLAGS_HAVE_RICHCOMPARE) \ #define RICHCOMPARE(t) ((t)->tp_richcompare)
? (t)->tp_richcompare : NULL)
/* Map rich comparison operators to their swapped version, e.g. LT --> GT */ /* 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}; 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; Py_ssize_t dictoffset;
PyTypeObject *tp = obj->ob_type; PyTypeObject *tp = obj->ob_type;
if (!(tp->tp_flags & Py_TPFLAGS_HAVE_CLASS))
return NULL;
dictoffset = tp->tp_dictoffset; dictoffset = tp->tp_dictoffset;
if (dictoffset == 0) if (dictoffset == 0)
return NULL; return NULL;
@ -1318,8 +1315,7 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
Py_XINCREF(descr); Py_XINCREF(descr);
f = NULL; f = NULL;
if (descr != NULL && if (descr != NULL) {
PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
f = descr->ob_type->tp_descr_get; f = descr->ob_type->tp_descr_get;
if (f != NULL && PyDescr_IsData(descr)) { if (f != NULL && PyDescr_IsData(descr)) {
res = f(descr, obj, (PyObject *)obj->ob_type); 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); descr = _PyType_Lookup(tp, name);
f = NULL; f = NULL;
if (descr != NULL && if (descr != NULL) {
PyType_HasFeature(descr->ob_type, Py_TPFLAGS_HAVE_CLASS)) {
f = descr->ob_type->tp_descr_set; f = descr->ob_type->tp_descr_set;
if (f != NULL && PyDescr_IsData(descr)) { if (f != NULL && PyDescr_IsData(descr)) {
res = f(descr, obj, value); res = f(descr, obj, value);
@ -1518,14 +1513,6 @@ PyNumber_CoerceEx(PyObject **pv, PyObject **pw)
register PyObject *w = *pw; register PyObject *w = *pw;
int res; 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) { 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); res = (*v->ob_type->tp_as_number->nb_coerce)(pv, pw);
if (res <= 0) if (res <= 0)

View File

@ -1819,7 +1819,7 @@ PyTypeObject PySet_Type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 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 */ Py_TPFLAGS_BASETYPE, /* tp_flags */
set_doc, /* tp_doc */ set_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */ (traverseproc)set_traverse, /* tp_traverse */
@ -1913,7 +1913,7 @@ PyTypeObject PyFrozenSet_Type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 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 */ Py_TPFLAGS_BASETYPE, /* tp_flags */
frozenset_doc, /* tp_doc */ frozenset_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */ (traverseproc)set_traverse, /* tp_traverse */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3833,8 +3833,7 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
x = PyInt_AsSsize_t(v); x = PyInt_AsSsize_t(v);
} }
else if (v->ob_type->tp_as_number && 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); x = v->ob_type->tp_as_number->nb_index(v);
if (x == -1 && PyErr_Occurred()) if (x == -1 && PyErr_Occurred())
return 0; return 0;
@ -3853,8 +3852,7 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
#undef ISINDEX #undef ISINDEX
#define ISINDEX(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x) || \ #define ISINDEX(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x) || \
((x)->ob_type->tp_as_number && \ ((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 * static PyObject *
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */ 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( return converterr(
"invalid use of 't' format character", "invalid use of 't' format character",
arg, msgbuf, bufsize); arg, msgbuf, bufsize);
if (!PyType_HasFeature(arg->ob_type, if (pb == NULL || pb->bf_getcharbuffer == NULL ||
Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
pb == NULL || pb->bf_getcharbuffer == NULL ||
pb->bf_getsegcount == NULL) pb->bf_getsegcount == NULL)
return converterr( return converterr(
"string or read-only character buffer", "string or read-only character buffer",