mirror of
https://github.com/python/cpython.git
synced 2026-04-27 22:31:21 +00:00
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:
parent
73e5a5b65d
commit
3cf5b1eef9
36 changed files with 170 additions and 357 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue