[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.109,2.110
Guido van Rossum
gvanrossum@users.sourceforge.net
2001年10月20日 17:44:33 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv25887/Objects
Modified Files:
typeobject.c
Log Message:
Big internal change that should have no external effects: unify the
'slotdef' structure typedef and 'struct wrapperbase'. By adding the
wrapper docstrings to the slotdef structure, the slotdefs array can
serve as the data structure that drives add_operators(); the wrapper
descriptor contains a pointer to slotdef structure. This replaces
lots of custom code from add_operators() by a loop over the slotdefs
array, and does away with all the tab_xxx tables.
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.109
retrieving revision 2.110
diff -C2 -d -r2.109 -r2.110
*** typeobject.c 2001年10月18日 15:49:21 2.109
--- typeobject.c 2001年10月21日 00:44:31 2.110
***************
*** 1894,1902 ****
}
- static struct wrapperbase tab_len[] = {
- {"__len__", (wrapperfunc)wrap_inquiry, "x.__len__() <==> len(x)"},
- {0}
- };
-
static PyObject *
wrap_binaryfunc(PyObject *self, PyObject *args, void *wrapped)
--- 1894,1897 ----
***************
*** 1942,1969 ****
}
- #undef BINARY
- #define BINARY(NAME, OP) \
- static struct wrapperbase tab_##NAME[] = { \
- {"__" #NAME "__", \
- (wrapperfunc)wrap_binaryfunc_l, \
- "x.__" #NAME "__(y) <==> " #OP}, \
- {"__r" #NAME "__", \
- (wrapperfunc)wrap_binaryfunc_r, \
- "y.__r" #NAME "__(x) <==> " #OP}, \
- {0} \
- }
-
- BINARY(add, "x+y");
- BINARY(sub, "x-y");
- BINARY(mul, "x*y");
- BINARY(div, "x/y");
- BINARY(mod, "x%y");
- BINARY(divmod, "divmod(x,y)");
- BINARY(lshift, "x<<y");
- BINARY(rshift, "x>>y");
- BINARY(and, "x&y");
- BINARY(xor, "x^y");
- BINARY(or, "x|y");
-
static PyObject *
wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped)
--- 1937,1940 ----
***************
*** 1993,2005 ****
}
- static struct wrapperbase tab_coerce[] = {
- {"__coerce__", (wrapperfunc)wrap_coercefunc,
- "x.__coerce__(y) <==> coerce(x, y)"},
- {0}
- };
-
- BINARY(floordiv, "x//y");
- BINARY(truediv, "x/y # true division");
-
static PyObject *
wrap_ternaryfunc(PyObject *self, PyObject *args, void *wrapped)
--- 1964,1967 ----
***************
*** 2030,2056 ****
}
- #undef TERNARY
- #define TERNARY(NAME, OP) \
- static struct wrapperbase tab_##NAME[] = { \
- {"__" #NAME "__", \
- (wrapperfunc)wrap_ternaryfunc, \
- "x.__" #NAME "__(y, z) <==> " #OP}, \
- {"__r" #NAME "__", \
- (wrapperfunc)wrap_ternaryfunc_r, \
- "y.__r" #NAME "__(x, z) <==> " #OP}, \
- {0} \
- }
-
- TERNARY(pow, "(x**y) % z");
-
- #undef UNARY
- #define UNARY(NAME, OP) \
- static struct wrapperbase tab_##NAME[] = { \
- {"__" #NAME "__", \
- (wrapperfunc)wrap_unaryfunc, \
- "x.__" #NAME "__() <==> " #OP}, \
- {0} \
- }
-
static PyObject *
wrap_unaryfunc(PyObject *self, PyObject *args, void *wrapped)
--- 1992,1995 ----
***************
*** 2063,2116 ****
}
- UNARY(neg, "-x");
- UNARY(pos, "+x");
- UNARY(abs, "abs(x)");
- UNARY(nonzero, "x != 0");
- UNARY(invert, "~x");
- UNARY(int, "int(x)");
- UNARY(long, "long(x)");
- UNARY(float, "float(x)");
- UNARY(oct, "oct(x)");
- UNARY(hex, "hex(x)");
-
- #undef IBINARY
- #define IBINARY(NAME, OP) \
- static struct wrapperbase tab_##NAME[] = { \
- {"__" #NAME "__", \
- (wrapperfunc)wrap_binaryfunc, \
- "x.__" #NAME "__(y) <==> " #OP}, \
- {0} \
- }
-
- IBINARY(iadd, "x+=y");
- IBINARY(isub, "x-=y");
- IBINARY(imul, "x*=y");
- IBINARY(idiv, "x/=y");
- IBINARY(imod, "x%=y");
- IBINARY(ilshift, "x<<=y");
- IBINARY(irshift, "x>>=y");
- IBINARY(iand, "x&=y");
- IBINARY(ixor, "x^=y");
- IBINARY(ior, "x|=y");
- IBINARY(ifloordiv, "x//=y");
- IBINARY(itruediv, "x/=y # true division");
-
- #undef ITERNARY
- #define ITERNARY(NAME, OP) \
- static struct wrapperbase tab_##NAME[] = { \
- {"__" #NAME "__", \
- (wrapperfunc)wrap_ternaryfunc, \
- "x.__" #NAME "__(y) <==> " #OP}, \
- {0} \
- }
-
- ITERNARY(ipow, "x = (x**y) % z");
-
- static struct wrapperbase tab_getitem[] = {
- {"__getitem__", (wrapperfunc)wrap_binaryfunc,
- "x.__getitem__(y) <==> x[y]"},
- {0}
- };
-
static PyObject *
wrap_intargfunc(PyObject *self, PyObject *args, void *wrapped)
--- 2002,2005 ----
***************
*** 2124,2143 ****
}
- static struct wrapperbase tab_mul_int[] = {
- {"__mul__", (wrapperfunc)wrap_intargfunc, "x.__mul__(n) <==> x*n"},
- {"__rmul__", (wrapperfunc)wrap_intargfunc, "x.__rmul__(n) <==> n*x"},
- {0}
- };
-
- static struct wrapperbase tab_concat[] = {
- {"__add__", (wrapperfunc)wrap_binaryfunc, "x.__add__(y) <==> x+y"},
- {0}
- };
-
- static struct wrapperbase tab_imul_int[] = {
- {"__imul__", (wrapperfunc)wrap_intargfunc, "x.__imul__(n) <==> x*=n"},
- {0}
- };
-
static int
getindex(PyObject *self, PyObject *arg)
--- 2013,2016 ----
***************
*** 2179,2188 ****
}
- static struct wrapperbase tab_getitem_int[] = {
- {"__getitem__", (wrapperfunc)wrap_sq_item,
- "x.__getitem__(i) <==> x[i]"},
- {0}
- };
-
static PyObject *
wrap_intintargfunc(PyObject *self, PyObject *args, void *wrapped)
--- 2052,2055 ----
***************
*** 2196,2205 ****
}
- static struct wrapperbase tab_getslice[] = {
- {"__getslice__", (wrapperfunc)wrap_intintargfunc,
- "x.__getslice__(i, j) <==> x[i:j]"},
- {0}
- };
-
static PyObject *
wrap_sq_setitem(PyObject *self, PyObject *args, void *wrapped)
--- 2063,2066 ----
***************
*** 2240,2251 ****
}
- static struct wrapperbase tab_setitem_int[] = {
- {"__setitem__", (wrapperfunc)wrap_sq_setitem,
- "x.__setitem__(i, y) <==> x[i]=y"},
- {"__delitem__", (wrapperfunc)wrap_sq_delitem,
- "x.__delitem__(y) <==> del x[y]"},
- {0}
- };
-
static PyObject *
wrap_intintobjargproc(PyObject *self, PyObject *args, void *wrapped)
--- 2101,2104 ----
***************
*** 2279,2290 ****
}
- static struct wrapperbase tab_setslice[] = {
- {"__setslice__", (wrapperfunc)wrap_intintobjargproc,
- "x.__setslice__(i, j, y) <==> x[i:j]=y"},
- {"__delslice__", (wrapperfunc)wrap_delslice,
- "x.__delslice__(i, j) <==> del x[i:j]"},
- {0}
- };
-
/* XXX objobjproc is a misnomer; should be objargpred */
static PyObject *
--- 2132,2135 ----
***************
*** 2303,2312 ****
}
- static struct wrapperbase tab_contains[] = {
- {"__contains__", (wrapperfunc)wrap_objobjproc,
- "x.__contains__(y) <==> y in x"},
- {0}
- };
-
static PyObject *
wrap_objobjargproc(PyObject *self, PyObject *args, void *wrapped)
--- 2148,2151 ----
***************
*** 2341,2352 ****
}
- static struct wrapperbase tab_setitem[] = {
- {"__setitem__", (wrapperfunc)wrap_objobjargproc,
- "x.__setitem__(y, z) <==> x[y]=z"},
- {"__delitem__", (wrapperfunc)wrap_delitem,
- "x.__delitem__(y) <==> del x[y]"},
- {0}
- };
-
static PyObject *
wrap_cmpfunc(PyObject *self, PyObject *args, void *wrapped)
--- 2180,2183 ----
***************
*** 2374,2395 ****
}
- static struct wrapperbase tab_cmp[] = {
- {"__cmp__", (wrapperfunc)wrap_cmpfunc,
- "x.__cmp__(y) <==> cmp(x,y)"},
- {0}
- };
-
- static struct wrapperbase tab_repr[] = {
- {"__repr__", (wrapperfunc)wrap_unaryfunc,
- "x.__repr__() <==> repr(x)"},
- {0}
- };
-
- static struct wrapperbase tab_getattr[] = {
- {"__getattribute__", (wrapperfunc)wrap_binaryfunc,
- "x.__getattribute__('name') <==> x.name"},
- {0}
- };
-
static PyObject *
wrap_setattr(PyObject *self, PyObject *args, void *wrapped)
--- 2205,2208 ----
***************
*** 2424,2435 ****
}
- static struct wrapperbase tab_setattr[] = {
- {"__setattr__", (wrapperfunc)wrap_setattr,
- "x.__setattr__('name', value) <==> x.name = value"},
- {"__delattr__", (wrapperfunc)wrap_delattr,
- "x.__delattr__('name') <==> del x.name"},
- {0}
- };
-
static PyObject *
wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
--- 2237,2240 ----
***************
*** 2446,2455 ****
}
- static struct wrapperbase tab_hash[] = {
- {"__hash__", (wrapperfunc)wrap_hashfunc,
- "x.__hash__() <==> hash(x)"},
- {0}
- };
-
static PyObject *
wrap_call(PyObject *self, PyObject *args, void *wrapped)
--- 2251,2254 ----
***************
*** 2461,2476 ****
}
- static struct wrapperbase tab_call[] = {
- {"__call__", (wrapperfunc)wrap_call,
- "x.__call__(...) <==> x(...)"},
- {0}
- };
-
- static struct wrapperbase tab_str[] = {
- {"__str__", (wrapperfunc)wrap_unaryfunc,
- "x.__str__() <==> str(x)"},
- {0}
- };
-
static PyObject *
wrap_richcmpfunc(PyObject *self, PyObject *args, void *wrapped, int op)
--- 2260,2263 ----
***************
*** 2499,2522 ****
RICHCMP_WRAPPER(ge, Py_GE)
- #undef RICHCMP_ENTRY
- #define RICHCMP_ENTRY(NAME, EXPR) \
- {"__" #NAME "__", (wrapperfunc)richcmp_##NAME, \
- "x.__" #NAME "__(y) <==> " EXPR}
-
- static struct wrapperbase tab_richcmp[] = {
- RICHCMP_ENTRY(lt, "x<y"),
- RICHCMP_ENTRY(le, "x<=y"),
- RICHCMP_ENTRY(eq, "x==y"),
- RICHCMP_ENTRY(ne, "x!=y"),
- RICHCMP_ENTRY(gt, "x>y"),
- RICHCMP_ENTRY(ge, "x>=y"),
- {0}
- };
-
- static struct wrapperbase tab_iter[] = {
- {"__iter__", (wrapperfunc)wrap_unaryfunc, "x.__iter__() <==> iter(x)"},
- {0}
- };
-
static PyObject *
wrap_next(PyObject *self, PyObject *args, void *wrapped)
--- 2286,2289 ----
***************
*** 2533,2542 ****
}
- static struct wrapperbase tab_next[] = {
- {"next", (wrapperfunc)wrap_next,
- "x.next() -> the next value, or raise StopIteration"},
- {0}
- };
-
static PyObject *
wrap_descr_get(PyObject *self, PyObject *args, void *wrapped)
--- 2300,2303 ----
***************
*** 2551,2560 ****
}
- static struct wrapperbase tab_descr_get[] = {
- {"__get__", (wrapperfunc)wrap_descr_get,
- "descr.__get__(obj, type) -> value"},
- {0}
- };
-
static PyObject *
wrap_descr_set(PyObject *self, PyObject *args, void *wrapped)
--- 2312,2315 ----
***************
*** 2573,2582 ****
}
- static struct wrapperbase tab_descr_set[] = {
- {"__set__", (wrapperfunc)wrap_descr_set,
- "descr.__set__(obj, value)"},
- {0}
- };
-
static PyObject *
wrap_init(PyObject *self, PyObject *args, void *wrapped)
--- 2328,2331 ----
***************
*** 2591,2601 ****
}
- static struct wrapperbase tab_init[] = {
- {"__init__", (wrapperfunc)wrap_init,
- "x.__init__(...) initializes x; "
- "see x.__class__.__doc__ for signature"},
- {0}
- };
-
static PyObject *
tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
--- 2340,2343 ----
***************
*** 2674,2816 ****
}
- static int
- add_wrappers(PyTypeObject *type, struct wrapperbase *wraps, void *wrapped)
- {
- PyObject *dict = type->tp_dict;
-
- for (; wraps->name != NULL; wraps++) {
- PyObject *descr;
- if (PyDict_GetItemString(dict, wraps->name))
- continue;
- descr = PyDescr_NewWrapper(type, wraps, wrapped);
- if (descr == NULL)
- return -1;
- if (PyDict_SetItemString(dict, wraps->name, descr) < 0)
- return -1;
- Py_DECREF(descr);
- }
- return 0;
- }
-
- /* This function is called by PyType_Ready() to populate the type's
- dictionary with method descriptors for function slots. For each
- function slot (like tp_repr) that's defined in the type, one or
- more corresponding descriptors are added in the type's tp_dict
- dictionary under the appropriate name (like __repr__). Some
- function slots cause more than one descriptor to be added (for
- example, the nb_add slot adds both __add__ and __radd__
- descriptors) and some function slots compete for the same
- descriptor (for example both sq_item and mp_subscript generate a
- __getitem__ descriptor). This only adds new descriptors and
- doesn't overwrite entries in tp_dict that were previously
- defined. The descriptors contain a reference to the C function
- they must call, so that it's safe if they are copied into a
- subtype's __dict__ and the subtype has a different C function in
- its slot -- calling the method defined by the descriptor will call
- the C function that was used to create it, rather than the C
- function present in the slot when it is called. (This is important
- because a subtype may have a C function in the slot that calls the
- method from the dictionary, and we want to avoid infinite recursion
- here.) */
-
- static int
- add_operators(PyTypeObject *type)
- {
- PySequenceMethods *sq;
- PyMappingMethods *mp;
- PyNumberMethods *nb;
-
- #undef ADD
- #define ADD(SLOT, TABLE) \
- if (SLOT) { \
- if (add_wrappers(type, TABLE, (void *)(SLOT)) < 0) \
- return -1; \
- }
-
- if ((sq = type->tp_as_sequence) != NULL) {
- ADD(sq->sq_length, tab_len);
- ADD(sq->sq_concat, tab_concat);
- ADD(sq->sq_repeat, tab_mul_int);
- ADD(sq->sq_item, tab_getitem_int);
- ADD(sq->sq_slice, tab_getslice);
- ADD(sq->sq_ass_item, tab_setitem_int);
- ADD(sq->sq_ass_slice, tab_setslice);
- ADD(sq->sq_contains, tab_contains);
- ADD(sq->sq_inplace_concat, tab_iadd);
- ADD(sq->sq_inplace_repeat, tab_imul_int);
- }
-
- if ((mp = type->tp_as_mapping) != NULL) {
- if (sq->sq_length == NULL)
- ADD(mp->mp_length, tab_len);
- ADD(mp->mp_subscript, tab_getitem);
- ADD(mp->mp_ass_subscript, tab_setitem);
- }
-
- if ((nb = type->tp_as_number) != NULL) {
- ADD(nb->nb_add, tab_add);
- ADD(nb->nb_subtract, tab_sub);
- ADD(nb->nb_multiply, tab_mul);
- ADD(nb->nb_divide, tab_div);
- ADD(nb->nb_remainder, tab_mod);
- ADD(nb->nb_divmod, tab_divmod);
- ADD(nb->nb_power, tab_pow);
- ADD(nb->nb_negative, tab_neg);
- ADD(nb->nb_positive, tab_pos);
- ADD(nb->nb_absolute, tab_abs);
- ADD(nb->nb_nonzero, tab_nonzero);
- ADD(nb->nb_invert, tab_invert);
- ADD(nb->nb_lshift, tab_lshift);
- ADD(nb->nb_rshift, tab_rshift);
- ADD(nb->nb_and, tab_and);
- ADD(nb->nb_xor, tab_xor);
- ADD(nb->nb_or, tab_or);
- ADD(nb->nb_coerce, tab_coerce);
- ADD(nb->nb_int, tab_int);
- ADD(nb->nb_long, tab_long);
- ADD(nb->nb_float, tab_float);
- ADD(nb->nb_oct, tab_oct);
- ADD(nb->nb_hex, tab_hex);
- ADD(nb->nb_inplace_add, tab_iadd);
- ADD(nb->nb_inplace_subtract, tab_isub);
- ADD(nb->nb_inplace_multiply, tab_imul);
- ADD(nb->nb_inplace_divide, tab_idiv);
- ADD(nb->nb_inplace_remainder, tab_imod);
- ADD(nb->nb_inplace_power, tab_ipow);
- ADD(nb->nb_inplace_lshift, tab_ilshift);
- ADD(nb->nb_inplace_rshift, tab_irshift);
- ADD(nb->nb_inplace_and, tab_iand);
- ADD(nb->nb_inplace_xor, tab_ixor);
- ADD(nb->nb_inplace_or, tab_ior);
- if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
- ADD(nb->nb_floor_divide, tab_floordiv);
- ADD(nb->nb_true_divide, tab_truediv);
- ADD(nb->nb_inplace_floor_divide, tab_ifloordiv);
- ADD(nb->nb_inplace_true_divide, tab_itruediv);
- }
- }
-
- ADD(type->tp_getattro, tab_getattr);
- ADD(type->tp_setattro, tab_setattr);
- ADD(type->tp_compare, tab_cmp);
- ADD(type->tp_repr, tab_repr);
- ADD(type->tp_hash, tab_hash);
- ADD(type->tp_call, tab_call);
- ADD(type->tp_str, tab_str);
- ADD(type->tp_richcompare, tab_richcmp);
- ADD(type->tp_iter, tab_iter);
- ADD(type->tp_iternext, tab_next);
- ADD(type->tp_descr_get, tab_descr_get);
- ADD(type->tp_descr_set, tab_descr_set);
- ADD(type->tp_init, tab_init);
-
- if (type->tp_new != NULL) {
- if (add_tp_new_wrapper(type) < 0)
- return -1;
- }
-
- return 0;
- }
-
/* Slot wrappers that call the corresponding __foo__ slot. See comments
below at override_slots() for more explanation. */
--- 2416,2419 ----
***************
*** 3572,3582 ****
slots (e.g. __str__ affects tp_str as well as tp_repr). */
! typedef struct {
! char *name;
! int offset;
! void *function;
! wrapperfunc wrapper;
! PyObject *name_strobj;
! } slotdef;
#undef TPSLOT
--- 3175,3179 ----
slots (e.g. __str__ affects tp_str as well as tp_repr). */
! typedef struct wrapperbase slotdef;
#undef TPSLOT
***************
*** 3585,3724 ****
#undef MPSLOT
#undef NBSLOT
#undef BINSLOT
#undef RBINSLOT
! #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \
! {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER}
! #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER) \
! {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER}
! #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER) \
! ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER)
! #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER) \
! ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER)
! #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER)
! #define BINSLOT(NAME, SLOT, FUNCTION) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l)
! #define RBINSLOT(NAME, SLOT, FUNCTION) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r)
static slotdef slotdefs[] = {
! SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry),
! SQSLOT("__add__", sq_concat, slot_sq_concat, wrap_binaryfunc),
! SQSLOT("__mul__", sq_repeat, slot_sq_repeat, wrap_intargfunc),
! SQSLOT("__rmul__", sq_repeat, slot_sq_repeat, wrap_intargfunc),
! SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item),
! SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_intintargfunc),
! SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem),
! SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem),
SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
! wrap_intintobjargproc),
! SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice),
! SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc),
SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat,
! wrap_binaryfunc),
SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat,
! wrap_intargfunc),
! MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry),
MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
! wrap_binaryfunc),
MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
! wrap_objobjargproc),
MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
! wrap_delitem),
! BINSLOT("__add__", nb_add, slot_nb_add),
! RBINSLOT("__radd__", nb_add, slot_nb_add),
! BINSLOT("__sub__", nb_subtract, slot_nb_subtract),
! RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract),
! BINSLOT("__mul__", nb_multiply, slot_nb_multiply),
! RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply),
! BINSLOT("__div__", nb_divide, slot_nb_divide),
! RBINSLOT("__rdiv__", nb_divide, slot_nb_divide),
! BINSLOT("__mod__", nb_remainder, slot_nb_remainder),
! RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder),
! BINSLOT("__divmod__", nb_divmod, slot_nb_divmod),
! RBINSLOT("__rdivmod__", nb_divmod, slot_nb_divmod),
! NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc),
! NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r),
! NBSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc),
! NBSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc),
! NBSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc),
! NBSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_unaryfunc),
! NBSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc),
! BINSLOT("__lshift__", nb_lshift, slot_nb_lshift),
! RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift),
! BINSLOT("__rshift__", nb_rshift, slot_nb_rshift),
! RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift),
! BINSLOT("__and__", nb_and, slot_nb_and),
! RBINSLOT("__rand__", nb_and, slot_nb_and),
! BINSLOT("__xor__", nb_xor, slot_nb_xor),
! RBINSLOT("__rxor__", nb_xor, slot_nb_xor),
! BINSLOT("__or__", nb_or, slot_nb_or),
! RBINSLOT("__ror__", nb_or, slot_nb_or),
! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc),
! NBSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc),
! NBSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc),
! NBSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc),
! NBSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc),
! NBSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc),
! NBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
! wrap_binaryfunc),
! NBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
! wrap_binaryfunc),
! NBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply,
! wrap_binaryfunc),
! NBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide,
! wrap_binaryfunc),
! NBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder,
! wrap_binaryfunc),
! NBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power,
! wrap_ternaryfunc),
! NBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift,
! wrap_binaryfunc),
! NBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift,
! wrap_binaryfunc),
! NBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and,
! wrap_binaryfunc),
! NBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor,
! wrap_binaryfunc),
! NBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or,
! wrap_binaryfunc),
! BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide),
! RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide),
! BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide),
! RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide),
! NBSLOT("__ifloordiv__", nb_inplace_floor_divide,
! slot_nb_inplace_floor_divide, wrap_binaryfunc),
! NBSLOT("__itruediv__", nb_inplace_true_divide,
! slot_nb_inplace_true_divide, wrap_binaryfunc),
! TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc),
! TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc),
! TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc),
! TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc),
! TPSLOT("__call__", tp_call, slot_tp_call, wrap_call),
TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
! wrap_binaryfunc),
! TPSLOT("__getattribute__", tp_getattr, NULL, NULL),
! TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL),
! TPSLOT("__getattr__", tp_getattr, NULL, NULL),
! TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr),
! TPSLOT("__setattr__", tp_setattr, NULL, NULL),
! TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr),
! TPSLOT("__delattr__", tp_setattr, NULL, NULL),
! TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt),
! TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le),
! TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq),
! TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne),
! TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt),
! TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge),
! TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc),
! TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next),
! TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get),
! TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set),
! TPSLOT("__init__", tp_init, slot_tp_init, wrap_init),
! TPSLOT("__new__", tp_new, slot_tp_new, NULL),
{NULL}
};
--- 3182,3388 ----
#undef MPSLOT
#undef NBSLOT
+ #undef UNSLOT
+ #undef IBSLOT
#undef BINSLOT
#undef RBINSLOT
! #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, DOC}
! #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER, DOC}
! #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC)
! #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC)
! #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
! #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
! "x." NAME "() <==> " DOC)
! #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
! "x." NAME "(y) <==> x" DOC "y")
! #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
! "x." NAME "(y) <==> x" DOC "y")
! #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
! ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
! "x." NAME "(y) <==> y" DOC "x")
static slotdef slotdefs[] = {
! SQSLOT("__len__", sq_length, slot_sq_length, wrap_inquiry,
! "x.__len__() <==> len(x)"),
! SQSLOT("__add__", sq_concat, slot_sq_concat, wrap_binaryfunc,
! "x.__add__(y) <==> x+y"),
! SQSLOT("__mul__", sq_repeat, slot_sq_repeat, wrap_intargfunc,
! "x.__mul__(n) <==> x*n"),
! SQSLOT("__rmul__", sq_repeat, slot_sq_repeat, wrap_intargfunc,
! "x.__rmul__(n) <==> n*x"),
! SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
! "x.__getitem__(y) <==> x[y]"),
! SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_intintargfunc,
! "x.__getslice__(i, j) <==> x[i:j]"),
! SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
! "x.__setitem__(i, y) <==> x[i]=y"),
! SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
! "x.__delitem__(y) <==> del x[y]"),
SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
! wrap_intintobjargproc,
! "x.__setslice__(i, j, y) <==> x[i:j]=y"),
! SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
! "x.__delslice__(i, j) <==> del x[i:j]"),
! SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
! "x.__contains__(y) <==> y in x"),
SQSLOT("__iadd__", sq_inplace_concat, slot_sq_inplace_concat,
! wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"),
SQSLOT("__imul__", sq_inplace_repeat, slot_sq_inplace_repeat,
! wrap_intargfunc, "x.__imul__(y) <==> x*=y"),
! MPSLOT("__len__", mp_length, slot_mp_length, wrap_inquiry,
! "x.__len__() <==> len(x)"),
MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
! wrap_binaryfunc,
! "x.__getitem__(y) <==> x[y]"),
MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
! wrap_objobjargproc,
! "x.__setitem__(i, y) <==> x[i]=y"),
MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
! wrap_delitem,
! "x.__delitem__(y) <==> del x[y]"),
! BINSLOT("__add__", nb_add, slot_nb_add,
! "+"),
! RBINSLOT("__radd__", nb_add, slot_nb_add,
! "+"),
! BINSLOT("__sub__", nb_subtract, slot_nb_subtract,
! "-"),
! RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract,
! "-"),
! BINSLOT("__mul__", nb_multiply, slot_nb_multiply,
! "*"),
! RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply,
! "*"),
! BINSLOT("__div__", nb_divide, slot_nb_divide,
! "/"),
! RBINSLOT("__rdiv__", nb_divide, slot_nb_divide,
! "/"),
! BINSLOT("__mod__", nb_remainder, slot_nb_remainder,
! "%"),
! RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder,
! "%"),
! BINSLOT("__divmod__", nb_divmod, slot_nb_divmod,
! "divmod(x, y)"),
! RBINSLOT("__rdivmod__", nb_divmod, slot_nb_divmod,
! "divmod(y, x)"),
! NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
! "x.__pow__(y[, z]) <==> pow(x, y[, z])"),
! NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r,
! "y.__rpow__(x[, z]) <==> pow(x, y[, z])"),
! UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"),
! UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"),
! UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
! "abs(x)"),
! UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_unaryfunc,
! "x != 0"),
! UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"),
! BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"),
! RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"),
! BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"),
! RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"),
! BINSLOT("__and__", nb_and, slot_nb_and, "&"),
! RBINSLOT("__rand__", nb_and, slot_nb_and, "&"),
! BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"),
! RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"),
! BINSLOT("__or__", nb_or, slot_nb_or, "|"),
! RBINSLOT("__ror__", nb_or, slot_nb_or, "|"),
! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc,
! "x.__coerce__(y) <==> coerce(x, y)"),
! UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc,
! "int(x)"),
! UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc,
! "long(x)"),
! UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
! "float(x)"),
! UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc,
! "oct(x)"),
! UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc,
! "hex(x)"),
! IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,
! wrap_binaryfunc, "+"),
! IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract,
! wrap_binaryfunc, "-"),
! IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply,
! wrap_binaryfunc, "*"),
! IBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide,
! wrap_binaryfunc, "/"),
! IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder,
! wrap_binaryfunc, "%"),
! IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power,
! wrap_ternaryfunc, "**"),
! IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift,
! wrap_binaryfunc, "<<"),
! IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift,
! wrap_binaryfunc, ">>"),
! IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and,
! wrap_binaryfunc, "&"),
! IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor,
! wrap_binaryfunc, "^"),
! IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or,
! wrap_binaryfunc, "|"),
! BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
! RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"),
! BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"),
! RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"),
! IBSLOT("__ifloordiv__", nb_inplace_floor_divide,
! slot_nb_inplace_floor_divide, wrap_binaryfunc, "//"),
! IBSLOT("__itruediv__", nb_inplace_true_divide,
! slot_nb_inplace_true_divide, wrap_binaryfunc, "/"),
! TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
! "x.__str__() <==> str(x)"),
! TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
! "x.__repr__() <==> repr(x)"),
! TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc,
! "x.__cmp__(y) <==> cmp(x,y)"),
! TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
! "x.__hash__() <==> hash(x)"),
! TPSLOT("__call__", tp_call, slot_tp_call, wrap_call,
! "x.__call__(...) <==> x(...)"),
TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
! wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"),
! TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
! TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
! TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""),
! TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
! "x.__setattr__('name', value) <==> x.name = value"),
! TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
! TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr,
! "x.__delattr__('name') <==> del x.name"),
! TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
! TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt,
! "x.__lt__(y) <==> x<y"),
! TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le,
! "x.__le__(y) <==> x<=y"),
! TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq,
! "x.__eq__(y) <==> x==y"),
! TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne,
! "x.__ne__(y) <==> x!=y"),
! TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt,
! "x.__gt__(y) <==> x>y"),
! TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge,
! "x.__ge__(y) <==> x>=y"),
! TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
! "x.__iter__() <==> iter(x)"),
! TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next,
! "x.next() -> the next value, or raise StopIteration"),
! TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
! "descr.__get__(obj[, type]) -> value"),
! TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
! "descr.__set__(obj, value)"),
! TPSLOT("__init__", tp_init, slot_tp_init, wrap_init,
! "x.__init__(...) initializes x; "
! "see x.__class__.__doc__ for signature"),
! TPSLOT("__new__", tp_new, slot_tp_new, NULL,
! ""),
{NULL}
};
***************
*** 3942,3945 ****
--- 3606,3661 ----
*ptr = generic;
}
+ }
+
+ /* This function is called by PyType_Ready() to populate the type's
+ dictionary with method descriptors for function slots. For each
+ function slot (like tp_repr) that's defined in the type, one or
+ more corresponding descriptors are added in the type's tp_dict
+ dictionary under the appropriate name (like __repr__). Some
+ function slots cause more than one descriptor to be added (for
+ example, the nb_add slot adds both __add__ and __radd__
+ descriptors) and some function slots compete for the same
+ descriptor (for example both sq_item and mp_subscript generate a
+ __getitem__ descriptor). This only adds new descriptors and
+ doesn't overwrite entries in tp_dict that were previously
+ defined. The descriptors contain a reference to the C function
+ they must call, so that it's safe if they are copied into a
+ subtype's __dict__ and the subtype has a different C function in
+ its slot -- calling the method defined by the descriptor will call
+ the C function that was used to create it, rather than the C
+ function present in the slot when it is called. (This is important
+ because a subtype may have a C function in the slot that calls the
+ method from the dictionary, and we want to avoid infinite recursion
+ here.) */
+
+ static int
+ add_operators(PyTypeObject *type)
+ {
+ PyObject *dict = type->tp_dict;
+ slotdef *p;
+ PyObject *descr;
+ void **ptr;
+
+ init_slotdefs();
+ for (p = slotdefs; p->name; p++) {
+ if (p->wrapper == NULL)
+ continue;
+ ptr = slotptr(type, p->offset);
+ if (!ptr || !*ptr)
+ continue;
+ if (PyDict_GetItem(dict, p->name_strobj))
+ continue;
+ descr = PyDescr_NewWrapper(type, p, *ptr);
+ if (descr == NULL)
+ return -1;
+ if (PyDict_SetItem(dict, p->name_strobj, descr) < 0)
+ return -1;
+ Py_DECREF(descr);
+ }
+ if (type->tp_new != NULL) {
+ if (add_tp_new_wrapper(type) < 0)
+ return -1;
+ }
+ return 0;
}