Completely get rid of PyClass and PyInstance.
(classobject.[ch] aren't empty yet because they also define PyMethod.) This breaks lots of stuff, notably cPickle. But it's a step in the right direction. I'll clean it up later. (Also a few unrelated changes, e.g. T_NONE to define a "struct member" that is always None, and simplification of __hash__ -- these are unfinished.)
This commit is contained in:
parent
d033ddf4dc
commit
50e9fb9e2d
|
@ -7,14 +7,6 @@
|
|||
#include "patchlevel.h"
|
||||
#include "pyconfig.h"
|
||||
|
||||
/* Cyclic gc is always enabled, starting with release 2.3a1. Supply the
|
||||
* old symbol for the benefit of extension modules written before then
|
||||
* that may be conditionalizing on it. The core doesn't use it anymore.
|
||||
*/
|
||||
#ifndef WITH_CYCLE_GC
|
||||
#define WITH_CYCLE_GC 1
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef UCHAR_MAX
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
/* Class object interface */
|
||||
/* Former class object interface -- now only (un)bound methods are here */
|
||||
|
||||
/* Revealing some structures (not for general use) */
|
||||
|
||||
|
@ -9,24 +8,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *cl_bases; /* A tuple of class objects */
|
||||
PyObject *cl_dict; /* A dictionary */
|
||||
PyObject *cl_name; /* A string */
|
||||
/* The following three are functions or NULL */
|
||||
PyObject *cl_getattr;
|
||||
PyObject *cl_setattr;
|
||||
PyObject *cl_delattr;
|
||||
} PyClassObject;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyClassObject *in_class; /* The class object */
|
||||
PyObject *in_dict; /* A dictionary */
|
||||
PyObject *in_weakreflist; /* List of weak references */
|
||||
} PyInstanceObject;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *im_func; /* The callable object implementing the method */
|
||||
|
@ -35,34 +16,16 @@ typedef struct {
|
|||
PyObject *im_weakreflist; /* List of weak references */
|
||||
} PyMethodObject;
|
||||
|
||||
PyAPI_DATA(PyTypeObject) PyClass_Type, PyInstance_Type, PyMethod_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyMethod_Type;
|
||||
|
||||
#define PyClass_Check(op) ((op)->ob_type == &PyClass_Type)
|
||||
#define PyInstance_Check(op) ((op)->ob_type == &PyInstance_Type)
|
||||
#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type)
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyClass_New(PyObject *, PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyInstance_New(PyObject *, PyObject *,
|
||||
PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyInstance_NewRaw(PyObject *, PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *);
|
||||
|
||||
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
|
||||
PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *);
|
||||
|
||||
/* Look up attribute with name (a string) on instance object pinst, using
|
||||
* only the instance and base class dicts. If a descriptor is found in
|
||||
* a class dict, the descriptor is returned without calling it.
|
||||
* Returns NULL if nothing found, else a borrowed reference to the
|
||||
* value associated with name in the dict in which name was found.
|
||||
* The point of this routine is that it never calls arbitrary Python
|
||||
* code, so is always "safe": all it does is dict lookups. The function
|
||||
* can't fail, never sets an exception, and NULL is not an error (it just
|
||||
* means "not found").
|
||||
*/
|
||||
PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name);
|
||||
|
||||
/* Macros for direct access to these values. Type checks are *not*
|
||||
done, so use with care. */
|
||||
#define PyMethod_GET_FUNCTION(meth) \
|
||||
|
@ -72,9 +35,6 @@ PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name);
|
|||
#define PyMethod_GET_CLASS(meth) \
|
||||
(((PyMethodObject *)meth) -> im_class)
|
||||
|
||||
PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -147,7 +147,7 @@ typedef int (*visitproc)(PyObject *, void *);
|
|||
typedef int (*traverseproc)(PyObject *, visitproc, void *);
|
||||
|
||||
typedef struct {
|
||||
/* Number implementations should check *both*
|
||||
/* Number implementations must check *both*
|
||||
arguments for proper type and implement the necessary conversions
|
||||
in the slot functions themselves. */
|
||||
|
||||
|
@ -173,7 +173,7 @@ typedef struct {
|
|||
unaryfunc nb_float;
|
||||
unaryfunc nb_oct;
|
||||
unaryfunc nb_hex;
|
||||
/* Added in release 2.0 */
|
||||
|
||||
binaryfunc nb_inplace_add;
|
||||
binaryfunc nb_inplace_subtract;
|
||||
binaryfunc nb_inplace_multiply;
|
||||
|
@ -185,13 +185,11 @@ typedef struct {
|
|||
binaryfunc nb_inplace_xor;
|
||||
binaryfunc nb_inplace_or;
|
||||
|
||||
/* Added in release 2.2 */
|
||||
binaryfunc nb_floor_divide;
|
||||
binaryfunc nb_true_divide;
|
||||
binaryfunc nb_inplace_floor_divide;
|
||||
binaryfunc nb_inplace_true_divide;
|
||||
|
||||
/* Added in release 2.5 */
|
||||
lenfunc nb_index;
|
||||
} PyNumberMethods;
|
||||
|
||||
|
@ -204,7 +202,7 @@ typedef struct {
|
|||
ssizeobjargproc sq_ass_item;
|
||||
ssizessizeobjargproc sq_ass_slice;
|
||||
objobjproc sq_contains;
|
||||
/* Added in release 2.0 */
|
||||
|
||||
binaryfunc sq_inplace_concat;
|
||||
ssizeargfunc sq_inplace_repeat;
|
||||
} PySequenceMethods;
|
||||
|
@ -292,7 +290,6 @@ typedef struct _typeobject {
|
|||
/* weak reference enabler */
|
||||
Py_ssize_t tp_weaklistoffset;
|
||||
|
||||
/* Added in release 2.2 */
|
||||
/* Iterators */
|
||||
getiterfunc tp_iter;
|
||||
iternextfunc tp_iternext;
|
||||
|
|
|
@ -70,6 +70,8 @@ typedef struct PyMemberDef {
|
|||
#define T_ULONGLONG 18
|
||||
#endif /* HAVE_LONG_LONG */
|
||||
|
||||
#define T_NONE 19 /* Value is always None */
|
||||
|
||||
/* Flags */
|
||||
#define READONLY 1
|
||||
#define RO READONLY /* Shorthand */
|
||||
|
|
|
@ -3363,19 +3363,19 @@ static PyMethodDef _functions[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#if PY_VERSION_HEX < 0x02030000
|
||||
DL_EXPORT(void) init_sre(void)
|
||||
#else
|
||||
PyMODINIT_FUNC init_sre(void)
|
||||
#endif
|
||||
{
|
||||
PyObject* m;
|
||||
PyObject* d;
|
||||
PyObject* x;
|
||||
|
||||
/* Patch object types */
|
||||
Pattern_Type.ob_type = Match_Type.ob_type =
|
||||
Scanner_Type.ob_type = &PyType_Type;
|
||||
/* Initialize object types */
|
||||
if (PyType_Ready(&Pattern_Type) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&Match_Type) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&Scanner_Type) < 0)
|
||||
return;
|
||||
|
||||
m = Py_InitModule("_" SRE_MODULE, _functions);
|
||||
if (m == NULL)
|
||||
|
|
|
@ -2112,7 +2112,8 @@ initarray(void)
|
|||
{
|
||||
PyObject *m;
|
||||
|
||||
Arraytype.ob_type = &PyType_Type;
|
||||
if (PyType_Ready(&Arraytype) < 0)
|
||||
return;
|
||||
PyArrayIter_Type.ob_type = &PyType_Type;
|
||||
m = Py_InitModule3("array", a_methods, module_doc);
|
||||
if (m == NULL)
|
||||
|
|
|
@ -1786,148 +1786,6 @@ save_dict(Picklerobject *self, PyObject *args)
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
save_inst(Picklerobject *self, PyObject *args)
|
||||
{
|
||||
PyObject *class = 0, *module = 0, *name = 0, *state = 0,
|
||||
*getinitargs_func = 0, *getstate_func = 0, *class_args = 0;
|
||||
char *module_str, *name_str;
|
||||
int module_size, name_size, res = -1;
|
||||
|
||||
static char inst = INST, obj = OBJ, build = BUILD;
|
||||
|
||||
if (self->fast && !fast_save_enter(self, args))
|
||||
goto finally;
|
||||
|
||||
if (self->write_func(self, &MARKv, 1) < 0)
|
||||
goto finally;
|
||||
|
||||
if (!( class = PyObject_GetAttr(args, __class___str)))
|
||||
goto finally;
|
||||
|
||||
if (self->bin) {
|
||||
if (save(self, class, 0) < 0)
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if ((getinitargs_func = PyObject_GetAttr(args, __getinitargs___str))) {
|
||||
PyObject *element = 0;
|
||||
int i, len;
|
||||
|
||||
if (!( class_args =
|
||||
PyObject_Call(getinitargs_func, empty_tuple, NULL)))
|
||||
goto finally;
|
||||
|
||||
if ((len = PyObject_Size(class_args)) < 0)
|
||||
goto finally;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!( element = PySequence_GetItem(class_args, i)))
|
||||
goto finally;
|
||||
|
||||
if (save(self, element, 0) < 0) {
|
||||
Py_DECREF(element);
|
||||
goto finally;
|
||||
}
|
||||
|
||||
Py_DECREF(element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
PyErr_Clear();
|
||||
else
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if (!self->bin) {
|
||||
if (!( name = ((PyClassObject *)class)->cl_name )) {
|
||||
PyErr_SetString(PicklingError, "class has no name");
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if (!( module = whichmodule(class, name)))
|
||||
goto finally;
|
||||
|
||||
|
||||
if ((module_size = PyString_Size(module)) < 0 ||
|
||||
(name_size = PyString_Size(name)) < 0)
|
||||
goto finally;
|
||||
|
||||
module_str = PyString_AS_STRING((PyStringObject *)module);
|
||||
name_str = PyString_AS_STRING((PyStringObject *)name);
|
||||
|
||||
if (self->write_func(self, &inst, 1) < 0)
|
||||
goto finally;
|
||||
|
||||
if (self->write_func(self, module_str, module_size) < 0)
|
||||
goto finally;
|
||||
|
||||
if (self->write_func(self, "\n", 1) < 0)
|
||||
goto finally;
|
||||
|
||||
if (self->write_func(self, name_str, name_size) < 0)
|
||||
goto finally;
|
||||
|
||||
if (self->write_func(self, "\n", 1) < 0)
|
||||
goto finally;
|
||||
}
|
||||
else if (self->write_func(self, &obj, 1) < 0) {
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) {
|
||||
state = PyObject_Call(getstate_func, empty_tuple, NULL);
|
||||
if (!state)
|
||||
goto finally;
|
||||
}
|
||||
else {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
PyErr_Clear();
|
||||
else
|
||||
goto finally;
|
||||
|
||||
if (!( state = PyObject_GetAttr(args, __dict___str))) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
PyErr_Clear();
|
||||
else
|
||||
goto finally;
|
||||
res = 0;
|
||||
goto finally;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PyDict_Check(state)) {
|
||||
if (put2(self, args) < 0)
|
||||
goto finally;
|
||||
}
|
||||
else {
|
||||
if (put(self, args) < 0)
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if (save(self, state, 0) < 0)
|
||||
goto finally;
|
||||
|
||||
if (self->write_func(self, &build, 1) < 0)
|
||||
goto finally;
|
||||
|
||||
res = 0;
|
||||
|
||||
finally:
|
||||
if (self->fast && !fast_save_leave(self, args))
|
||||
res = -1;
|
||||
|
||||
Py_XDECREF(module);
|
||||
Py_XDECREF(class);
|
||||
Py_XDECREF(state);
|
||||
Py_XDECREF(getinitargs_func);
|
||||
Py_XDECREF(getstate_func);
|
||||
Py_XDECREF(class_args);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
save_global(Picklerobject *self, PyObject *args, PyObject *name)
|
||||
|
@ -2420,20 +2278,6 @@ save(Picklerobject *self, PyObject *args, int pers_save)
|
|||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if (type == &PyInstance_Type) {
|
||||
res = save_inst(self, args);
|
||||
goto finally;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (type == &PyClass_Type) {
|
||||
res = save_global(self, args, NULL);
|
||||
goto finally;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (type == &PyFunction_Type) {
|
||||
res = save_global(self, args, NULL);
|
||||
|
@ -3594,57 +3438,6 @@ load_dict(Unpicklerobject *self)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Instance_New(PyObject *cls, PyObject *args)
|
||||
{
|
||||
PyObject *r = 0;
|
||||
|
||||
if (PyClass_Check(cls)) {
|
||||
int l;
|
||||
|
||||
if ((l=PyObject_Size(args)) < 0) goto err;
|
||||
if (!( l )) {
|
||||
PyObject *__getinitargs__;
|
||||
|
||||
__getinitargs__ = PyObject_GetAttr(cls,
|
||||
__getinitargs___str);
|
||||
if (!__getinitargs__) {
|
||||
/* We have a class with no __getinitargs__,
|
||||
so bypass usual construction */
|
||||
PyObject *inst;
|
||||
|
||||
PyErr_Clear();
|
||||
if (!( inst=PyInstance_NewRaw(cls, NULL)))
|
||||
goto err;
|
||||
return inst;
|
||||
}
|
||||
Py_DECREF(__getinitargs__);
|
||||
}
|
||||
|
||||
if ((r=PyInstance_New(cls, args, NULL))) return r;
|
||||
else goto err;
|
||||
}
|
||||
|
||||
if ((r=PyObject_CallObject(cls, args))) return r;
|
||||
|
||||
err:
|
||||
{
|
||||
PyObject *tp, *v, *tb, *tmp_value;
|
||||
|
||||
PyErr_Fetch(&tp, &v, &tb);
|
||||
tmp_value = v;
|
||||
/* NULL occurs when there was a KeyboardInterrupt */
|
||||
if (tmp_value == NULL)
|
||||
tmp_value = Py_None;
|
||||
if ((r = PyTuple_Pack(3, tmp_value, cls, args))) {
|
||||
Py_XDECREF(v);
|
||||
v=r;
|
||||
}
|
||||
PyErr_Restore(tp,v,tb);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_obj(Unpicklerobject *self)
|
||||
|
@ -3655,10 +3448,6 @@ load_obj(Unpicklerobject *self)
|
|||
if ((i = marker(self)) < 0) return -1;
|
||||
if (!( tup=Pdata_popTuple(self->stack, i+1))) return -1;
|
||||
PDATA_POP(self->stack, class);
|
||||
if (class) {
|
||||
obj = Instance_New(class, tup);
|
||||
Py_DECREF(class);
|
||||
}
|
||||
Py_DECREF(tup);
|
||||
|
||||
if (! obj) return -1;
|
||||
|
@ -3694,8 +3483,8 @@ load_inst(Unpicklerobject *self)
|
|||
if (! class) return -1;
|
||||
|
||||
if ((tup=Pdata_popTuple(self->stack, i))) {
|
||||
obj = Instance_New(class, tup);
|
||||
Py_DECREF(tup);
|
||||
PyErr_SetString(UnpicklingError, "it's dead, Jim");
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(class);
|
||||
|
||||
|
@ -4388,10 +4177,6 @@ load_reduce(Unpicklerobject *self)
|
|||
PDATA_POP(self->stack, arg_tup);
|
||||
if (! arg_tup) return -1;
|
||||
PDATA_POP(self->stack, callable);
|
||||
if (callable) {
|
||||
ob = Instance_New(callable, arg_tup);
|
||||
Py_DECREF(callable);
|
||||
}
|
||||
Py_DECREF(arg_tup);
|
||||
|
||||
if (! ob) return -1;
|
||||
|
|
|
@ -66,12 +66,10 @@ static PyObject *delstr = NULL;
|
|||
#define DEBUG_STATS (1<<0) /* print collection statistics */
|
||||
#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
|
||||
#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
|
||||
#define DEBUG_INSTANCES (1<<3) /* print instances */
|
||||
#define DEBUG_OBJECTS (1<<4) /* print other objects */
|
||||
#define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
|
||||
#define DEBUG_LEAK DEBUG_COLLECTABLE | \
|
||||
DEBUG_UNCOLLECTABLE | \
|
||||
DEBUG_INSTANCES | \
|
||||
DEBUG_OBJECTS | \
|
||||
DEBUG_SAVEALL
|
||||
static int debug;
|
||||
|
@ -410,13 +408,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
|
|||
static int
|
||||
has_finalizer(PyObject *op)
|
||||
{
|
||||
if (PyInstance_Check(op)) {
|
||||
assert(delstr != NULL);
|
||||
return _PyInstance_Lookup(op, delstr) != NULL;
|
||||
}
|
||||
else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
|
||||
return op->ob_type->tp_del != NULL;
|
||||
else if (PyGen_CheckExact(op))
|
||||
if (PyGen_CheckExact(op))
|
||||
return PyGen_NeedsFinalizing((PyGenObject *)op);
|
||||
else
|
||||
return 0;
|
||||
|
@ -632,27 +624,10 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
|
|||
return num_freed;
|
||||
}
|
||||
|
||||
static void
|
||||
debug_instance(char *msg, PyInstanceObject *inst)
|
||||
{
|
||||
char *cname;
|
||||
/* simple version of instance_repr */
|
||||
PyObject *classname = inst->in_class->cl_name;
|
||||
if (classname != NULL && PyString_Check(classname))
|
||||
cname = PyString_AsString(classname);
|
||||
else
|
||||
cname = "?";
|
||||
PySys_WriteStderr("gc: %.100s <%.100s instance at %p>\n",
|
||||
msg, cname, inst);
|
||||
}
|
||||
|
||||
static void
|
||||
debug_cycle(char *msg, PyObject *op)
|
||||
{
|
||||
if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) {
|
||||
debug_instance(msg, (PyInstanceObject *)op);
|
||||
}
|
||||
else if (debug & DEBUG_OBJECTS) {
|
||||
if (debug & DEBUG_OBJECTS) {
|
||||
PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
|
||||
msg, op->ob_type->tp_name, op);
|
||||
}
|
||||
|
@ -983,7 +958,6 @@ PyDoc_STRVAR(gc_set_debug__doc__,
|
|||
" DEBUG_STATS - Print statistics during collection.\n"
|
||||
" DEBUG_COLLECTABLE - Print collectable objects found.\n"
|
||||
" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n"
|
||||
" DEBUG_INSTANCES - Print instance objects.\n"
|
||||
" DEBUG_OBJECTS - Print objects other than instances.\n"
|
||||
" DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n"
|
||||
" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n");
|
||||
|
@ -1244,7 +1218,6 @@ initgc(void)
|
|||
ADD_INT(DEBUG_STATS);
|
||||
ADD_INT(DEBUG_COLLECTABLE);
|
||||
ADD_INT(DEBUG_UNCOLLECTABLE);
|
||||
ADD_INT(DEBUG_INSTANCES);
|
||||
ADD_INT(DEBUG_OBJECTS);
|
||||
ADD_INT(DEBUG_SAVEALL);
|
||||
ADD_INT(DEBUG_LEAK);
|
||||
|
|
|
@ -1000,8 +1000,6 @@ PyNumber_Float(PyObject *o)
|
|||
int
|
||||
PySequence_Check(PyObject *s)
|
||||
{
|
||||
if (s && PyInstance_Check(s))
|
||||
return PyObject_HasAttrString(s, "__getitem__");
|
||||
return s != NULL && s->ob_type->tp_as_sequence &&
|
||||
s->ob_type->tp_as_sequence->sq_item != NULL;
|
||||
}
|
||||
|
@ -1586,9 +1584,6 @@ PySequence_Index(PyObject *s, PyObject *o)
|
|||
int
|
||||
PyMapping_Check(PyObject *o)
|
||||
{
|
||||
if (o && PyInstance_Check(o))
|
||||
return PyObject_HasAttrString(o, "__getitem__");
|
||||
|
||||
return o && o->ob_type->tp_as_mapping &&
|
||||
o->ob_type->tp_as_mapping->mp_subscript &&
|
||||
!(o->ob_type->tp_as_sequence &&
|
||||
|
|
|
@ -379,13 +379,6 @@ bytes_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static long
|
||||
bytes_nohash(PyObject *self)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "bytes objects are unhashable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
@ -833,7 +826,7 @@ PyTypeObject PyBytes_Type = {
|
|||
0, /* tp_as_number */
|
||||
&bytes_as_sequence, /* tp_as_sequence */
|
||||
&bytes_as_mapping, /* tp_as_mapping */
|
||||
bytes_nohash, /* tp_hash */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
(reprfunc)bytes_str, /* tp_str */
|
||||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2006,13 +2006,6 @@ dict_init(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return dict_update_common(self, args, kwds, "dict");
|
||||
}
|
||||
|
||||
static long
|
||||
dict_nohash(PyObject *self)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "dict objects are unhashable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
dict_iter(dictobject *dict)
|
||||
{
|
||||
|
@ -2045,7 +2038,7 @@ PyTypeObject PyDict_Type = {
|
|||
0, /* tp_as_number */
|
||||
&dict_as_sequence, /* tp_as_sequence */
|
||||
&dict_as_mapping, /* tp_as_mapping */
|
||||
dict_nohash, /* tp_hash */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
|
|
|
@ -2381,13 +2381,6 @@ list_init(PyListObject *self, PyObject *args, PyObject *kw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static long
|
||||
list_nohash(PyObject *self)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "list objects are unhashable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static PyObject *list_iter(PyObject *seq);
|
||||
static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
|
||||
|
||||
|
@ -2655,7 +2648,7 @@ PyTypeObject PyList_Type = {
|
|||
0, /* tp_as_number */
|
||||
&list_as_sequence, /* tp_as_sequence */
|
||||
&list_as_mapping, /* tp_as_mapping */
|
||||
list_nohash, /* tp_hash */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* Generic object operations; and implementation of None (NoObject) */
|
||||
|
||||
#include "Python.h"
|
||||
#include "sliceobject.h" /* For PyEllipsis_Type */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -663,10 +664,6 @@ try_3way_compare(PyObject *v, PyObject *w)
|
|||
which has the same return conventions as this function. */
|
||||
|
||||
f = v->ob_type->tp_compare;
|
||||
if (PyInstance_Check(v))
|
||||
return (*f)(v, w);
|
||||
if (PyInstance_Check(w))
|
||||
return (*w->ob_type->tp_compare)(v, w);
|
||||
|
||||
/* If both have the same (non-NULL) tp_compare, use it. */
|
||||
if (f != NULL && f == w->ob_type->tp_compare) {
|
||||
|
@ -789,14 +786,6 @@ do_cmp(PyObject *v, PyObject *w)
|
|||
if (v->ob_type == w->ob_type
|
||||
&& (f = v->ob_type->tp_compare) != NULL) {
|
||||
c = (*f)(v, w);
|
||||
if (PyInstance_Check(v)) {
|
||||
/* Instance tp_compare has a different signature.
|
||||
But if it returns undefined we fall through. */
|
||||
if (c != 2)
|
||||
return c;
|
||||
/* Else fall through to try_rich_to_3way_compare() */
|
||||
}
|
||||
else
|
||||
return adjust_tp_compare(c);
|
||||
}
|
||||
/* We only get here if one of the following is true:
|
||||
|
@ -911,7 +900,7 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op)
|
|||
|
||||
/* If the types are equal, and not old-style instances, try to
|
||||
get out cheap (don't bother with coercions etc.). */
|
||||
if (v->ob_type == w->ob_type && !PyInstance_Check(v)) {
|
||||
if (v->ob_type == w->ob_type) {
|
||||
cmpfunc fcmp;
|
||||
richcmpfunc frich = RICHCOMPARE(v->ob_type);
|
||||
/* If the type has richcmp, try it first. try_rich_compare
|
||||
|
@ -1063,10 +1052,7 @@ PyObject_Hash(PyObject *v)
|
|||
PyTypeObject *tp = v->ob_type;
|
||||
if (tp->tp_hash != NULL)
|
||||
return (*tp->tp_hash)(v);
|
||||
if (tp->tp_compare == NULL && RICHCOMPARE(tp) == NULL) {
|
||||
return _Py_HashPointer(v); /* Use address as hash value */
|
||||
}
|
||||
/* If there's a cmp but no hash defined, the object can't be hashed */
|
||||
/* Otherwise, the object can't be hashed */
|
||||
PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
|
||||
v->ob_type->tp_name);
|
||||
return -1;
|
||||
|
@ -1303,12 +1289,8 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
|
|||
n = PyTuple_GET_SIZE(mro);
|
||||
for (i = 0; i < n; i++) {
|
||||
base = PyTuple_GET_ITEM(mro, i);
|
||||
if (PyClass_Check(base))
|
||||
dict = ((PyClassObject *)base)->cl_dict;
|
||||
else {
|
||||
assert(PyType_Check(base));
|
||||
dict = ((PyTypeObject *)base)->tp_dict;
|
||||
}
|
||||
assert(dict && PyDict_Check(dict));
|
||||
descr = PyDict_GetItem(dict, name);
|
||||
if (descr != NULL)
|
||||
|
@ -1554,21 +1536,8 @@ PyCallable_Check(PyObject *x)
|
|||
{
|
||||
if (x == NULL)
|
||||
return 0;
|
||||
if (PyInstance_Check(x)) {
|
||||
PyObject *call = PyObject_GetAttrString(x, "__call__");
|
||||
if (call == NULL) {
|
||||
PyErr_Clear();
|
||||
return 0;
|
||||
}
|
||||
/* Could test recursively but don't, for fear of endless
|
||||
recursion if some joker sets self.__call__ = self */
|
||||
Py_DECREF(call);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return x->ob_type->tp_call != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for PyObject_Dir.
|
||||
Merge the __dict__ of aclass into dict, and recursively also all
|
||||
|
@ -1701,7 +1670,7 @@ PyObject_Dir(PyObject *arg)
|
|||
/* Elif some form of type or class, grab its dict and its bases.
|
||||
We deliberately don't suck up its __class__, as methods belonging
|
||||
to the metaclass would probably be more confusing than helpful. */
|
||||
else if (PyType_Check(arg) || PyClass_Check(arg)) {
|
||||
else if (PyType_Check(arg)) {
|
||||
masterdict = PyDict_New();
|
||||
if (masterdict == NULL)
|
||||
goto error;
|
||||
|
@ -1886,6 +1855,9 @@ _Py_ReadyTypes(void)
|
|||
if (PyType_Ready(&PyNone_Type) < 0)
|
||||
Py_FatalError("Can't initialize type(None)");
|
||||
|
||||
if (PyType_Ready(Py_Ellipsis->ob_type) < 0)
|
||||
Py_FatalError("Can't initialize type(Ellipsis)");
|
||||
|
||||
if (PyType_Ready(&PyNotImplemented_Type) < 0)
|
||||
Py_FatalError("Can't initialize type(NotImplemented)");
|
||||
}
|
||||
|
|
|
@ -718,13 +718,6 @@ frozenset_hash(PyObject *self)
|
|||
return hash;
|
||||
}
|
||||
|
||||
static long
|
||||
set_nohash(PyObject *self)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "set objects are unhashable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/***** Set iterator type ***********************************************/
|
||||
|
||||
typedef struct {
|
||||
|
@ -1813,7 +1806,7 @@ PyTypeObject PySet_Type = {
|
|||
&set_as_number, /* tp_as_number */
|
||||
&set_as_sequence, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
set_nohash, /* tp_hash */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
|
|
|
@ -3982,6 +3982,8 @@ PyDoc_STRVAR(string_doc,
|
|||
Return a nice string representation of the object.\n\
|
||||
If the argument is a string, the return value is the same object.");
|
||||
|
||||
static PyObject *str_iter(PyObject *seq);
|
||||
|
||||
PyTypeObject PyString_Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0,
|
||||
|
@ -4009,7 +4011,7 @@ PyTypeObject PyString_Type = {
|
|||
0, /* tp_clear */
|
||||
(richcmpfunc)string_richcompare, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
str_iter, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
string_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
|
@ -4984,3 +4986,120 @@ void _Py_ReleaseInternedStrings(void)
|
|||
Py_DECREF(interned);
|
||||
interned = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*********************** Str Iterator ****************************/
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
long it_index;
|
||||
PyStringObject *it_seq; /* Set to NULL when iterator is exhausted */
|
||||
} striterobject;
|
||||
|
||||
static void
|
||||
striter_dealloc(striterobject *it)
|
||||
{
|
||||
_PyObject_GC_UNTRACK(it);
|
||||
Py_XDECREF(it->it_seq);
|
||||
PyObject_GC_Del(it);
|
||||
}
|
||||
|
||||
static int
|
||||
striter_traverse(striterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(it->it_seq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
striter_next(striterobject *it)
|
||||
{
|
||||
PyStringObject *seq;
|
||||
PyObject *item;
|
||||
|
||||
assert(it != NULL);
|
||||
seq = it->it_seq;
|
||||
if (seq == NULL)
|
||||
return NULL;
|
||||
assert(PyString_Check(seq));
|
||||
|
||||
if (it->it_index < PyString_GET_SIZE(seq)) {
|
||||
item = PyString_FromStringAndSize(PyString_AS_STRING(seq)+it->it_index, 1);
|
||||
if (item != NULL)
|
||||
++it->it_index;
|
||||
return item;
|
||||
}
|
||||
|
||||
Py_DECREF(seq);
|
||||
it->it_seq = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
striter_len(striterobject *it)
|
||||
{
|
||||
Py_ssize_t len = 0;
|
||||
if (it->it_seq)
|
||||
len = PyString_GET_SIZE(it->it_seq) - it->it_index;
|
||||
return PyInt_FromSsize_t(len);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
|
||||
|
||||
static PyMethodDef striter_methods[] = {
|
||||
{"__length_hint__", (PyCFunction)striter_len, METH_NOARGS, length_hint_doc},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
PyTypeObject PyStringIter_Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0, /* ob_size */
|
||||
"striterator", /* tp_name */
|
||||
sizeof(striterobject), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
(destructor)striter_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
|
||||
0, /* tp_doc */
|
||||
(traverseproc)striter_traverse, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
PyObject_SelfIter, /* tp_iter */
|
||||
(iternextfunc)striter_next, /* tp_iternext */
|
||||
striter_methods, /* tp_methods */
|
||||
0,
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
str_iter(PyObject *seq)
|
||||
{
|
||||
striterobject *it;
|
||||
|
||||
if (!PyString_Check(seq)) {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
it = PyObject_GC_New(striterobject, &PyStringIter_Type);
|
||||
if (it == NULL)
|
||||
return NULL;
|
||||
it->it_index = 0;
|
||||
Py_INCREF(seq);
|
||||
it->it_seq = (PyStringObject *)seq;
|
||||
_PyObject_GC_TRACK(it);
|
||||
return (PyObject *)it;
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context)
|
|||
}
|
||||
for (i = 0; i < PyTuple_GET_SIZE(value); i++) {
|
||||
ob = PyTuple_GET_ITEM(value, i);
|
||||
if (!PyClass_Check(ob) && !PyType_Check(ob)) {
|
||||
if (!PyType_Check(ob)) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"%s.__bases__ must be tuple of old- or new-style classes, not '%s'",
|
||||
|
@ -957,47 +957,6 @@ call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
fill_classic_mro(PyObject *mro, PyObject *cls)
|
||||
{
|
||||
PyObject *bases, *base;
|
||||
Py_ssize_t i, n;
|
||||
|
||||
assert(PyList_Check(mro));
|
||||
assert(PyClass_Check(cls));
|
||||
i = PySequence_Contains(mro, cls);
|
||||
if (i < 0)
|
||||
return -1;
|
||||
if (!i) {
|
||||
if (PyList_Append(mro, cls) < 0)
|
||||
return -1;
|
||||
}
|
||||
bases = ((PyClassObject *)cls)->cl_bases;
|
||||
assert(bases && PyTuple_Check(bases));
|
||||
n = PyTuple_GET_SIZE(bases);
|
||||
for (i = 0; i < n; i++) {
|
||||
base = PyTuple_GET_ITEM(bases, i);
|
||||
if (fill_classic_mro(mro, base) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
classic_mro(PyObject *cls)
|
||||
{
|
||||
PyObject *mro;
|
||||
|
||||
assert(PyClass_Check(cls));
|
||||
mro = PyList_New(0);
|
||||
if (mro != NULL) {
|
||||
if (fill_classic_mro(mro, cls) == 0)
|
||||
return mro;
|
||||
Py_DECREF(mro);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
Method resolution order algorithm C3 described in
|
||||
"A Monotonic Superclass Linearization for Dylan",
|
||||
|
@ -1229,11 +1188,7 @@ mro_implementation(PyTypeObject *type)
|
|||
for (i = 0; i < n; i++) {
|
||||
PyObject *base = PyTuple_GET_ITEM(bases, i);
|
||||
PyObject *parentMRO;
|
||||
if (PyType_Check(base))
|
||||
parentMRO = PySequence_List(
|
||||
((PyTypeObject*)base)->tp_mro);
|
||||
else
|
||||
parentMRO = classic_mro(base);
|
||||
parentMRO = PySequence_List(((PyTypeObject*)base)->tp_mro);
|
||||
if (parentMRO == NULL) {
|
||||
Py_DECREF(to_merge);
|
||||
return NULL;
|
||||
|
@ -1315,9 +1270,7 @@ mro_internal(PyTypeObject *type)
|
|||
for (i = 0; i < len; i++) {
|
||||
PyTypeObject *t;
|
||||
cls = PyTuple_GET_ITEM(tuple, i);
|
||||
if (PyClass_Check(cls))
|
||||
continue;
|
||||
else if (!PyType_Check(cls)) {
|
||||
if (!PyType_Check(cls)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"mro() returned a non-class ('%.500s')",
|
||||
cls->ob_type->tp_name);
|
||||
|
@ -1356,8 +1309,6 @@ best_base(PyObject *bases)
|
|||
winner = NULL;
|
||||
for (i = 0; i < n; i++) {
|
||||
base_proto = PyTuple_GET_ITEM(bases, i);
|
||||
if (PyClass_Check(base_proto))
|
||||
continue;
|
||||
if (!PyType_Check(base_proto)) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
|
@ -1636,8 +1587,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
|||
for (i = 0; i < nbases; i++) {
|
||||
tmp = PyTuple_GET_ITEM(bases, i);
|
||||
tmptype = tmp->ob_type;
|
||||
if (tmptype == &PyClass_Type)
|
||||
continue; /* Special case classic classes */
|
||||
if (PyType_IsSubtype(winner, tmptype))
|
||||
continue;
|
||||
if (PyType_IsSubtype(tmptype, winner)) {
|
||||
|
@ -1793,14 +1742,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
|||
tmp = PyTuple_GET_ITEM(bases, i);
|
||||
if (tmp == (PyObject *)base)
|
||||
continue; /* Skip primary base */
|
||||
if (PyClass_Check(tmp)) {
|
||||
/* Classic base class provides both */
|
||||
if (may_add_dict && !add_dict)
|
||||
add_dict++;
|
||||
if (may_add_weak && !add_weak)
|
||||
add_weak++;
|
||||
break;
|
||||
}
|
||||
assert(PyType_Check(tmp));
|
||||
tmptype = (PyTypeObject *)tmp;
|
||||
if (may_add_dict && !add_dict &&
|
||||
|
@ -2006,12 +1947,8 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
|
|||
n = PyTuple_GET_SIZE(mro);
|
||||
for (i = 0; i < n; i++) {
|
||||
base = PyTuple_GET_ITEM(mro, i);
|
||||
if (PyClass_Check(base))
|
||||
dict = ((PyClassObject *)base)->cl_dict;
|
||||
else {
|
||||
assert(PyType_Check(base));
|
||||
dict = ((PyTypeObject *)base)->tp_dict;
|
||||
}
|
||||
assert(dict && PyDict_Check(dict));
|
||||
res = PyDict_GetItem(dict, name);
|
||||
if (res != NULL)
|
||||
|
@ -2364,12 +2301,6 @@ object_str(PyObject *self)
|
|||
return f(self);
|
||||
}
|
||||
|
||||
static long
|
||||
object_hash(PyObject *self)
|
||||
{
|
||||
return _Py_HashPointer(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
object_get_class(PyObject *self, void *closure)
|
||||
{
|
||||
|
@ -2762,7 +2693,7 @@ PyTypeObject PyBaseObject_Type = {
|
|||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
object_hash, /* tp_hash */
|
||||
(hashfunc)_Py_HashPointer, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
object_str, /* tp_str */
|
||||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
|
@ -2791,7 +2722,7 @@ PyTypeObject PyBaseObject_Type = {
|
|||
};
|
||||
|
||||
|
||||
/* Initialize the __dict__ in a type object */
|
||||
/* Add the methods from tp_methods to the __dict__ in a type object */
|
||||
|
||||
static int
|
||||
add_methods(PyTypeObject *type, PyMethodDef *meth)
|
||||
|
@ -3118,7 +3049,7 @@ PyType_Ready(PyTypeObject *type)
|
|||
*/
|
||||
|
||||
/* Initialize the base class */
|
||||
if (base && base->tp_dict == NULL) {
|
||||
if (base != NULL && base->tp_dict == NULL) {
|
||||
if (PyType_Ready(base) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
@ -4490,12 +4421,23 @@ static long
|
|||
slot_tp_hash(PyObject *self)
|
||||
{
|
||||
PyObject *func;
|
||||
static PyObject *hash_str, *eq_str, *cmp_str;
|
||||
static PyObject *hash_str;
|
||||
long h;
|
||||
|
||||
func = lookup_method(self, "__hash__", &hash_str);
|
||||
|
||||
if (func != NULL) {
|
||||
if (func == Py_None) {
|
||||
Py_DECREF(func);
|
||||
func = NULL;
|
||||
}
|
||||
|
||||
if (func == NULL) {
|
||||
PyErr_Clear();
|
||||
PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
|
||||
self->ob_type->tp_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyObject *res = PyEval_CallObject(func, NULL);
|
||||
Py_DECREF(func);
|
||||
if (res == NULL)
|
||||
|
@ -4505,23 +4447,6 @@ slot_tp_hash(PyObject *self)
|
|||
else
|
||||
h = PyInt_AsLong(res);
|
||||
Py_DECREF(res);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
func = lookup_method(self, "__eq__", &eq_str);
|
||||
if (func == NULL) {
|
||||
PyErr_Clear();
|
||||
func = lookup_method(self, "__cmp__", &cmp_str);
|
||||
}
|
||||
if (func != NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
|
||||
self->ob_type->tp_name);
|
||||
Py_DECREF(func);
|
||||
return -1;
|
||||
}
|
||||
PyErr_Clear();
|
||||
h = _Py_HashPointer((void *)self);
|
||||
}
|
||||
if (h == -1 && !PyErr_Occurred())
|
||||
h = -2;
|
||||
return h;
|
||||
|
@ -5579,8 +5504,6 @@ super_getattro(PyObject *self, PyObject *name)
|
|||
tmp = PyTuple_GET_ITEM(mro, i);
|
||||
if (PyType_Check(tmp))
|
||||
dict = ((PyTypeObject *)tmp)->tp_dict;
|
||||
else if (PyClass_Check(tmp))
|
||||
dict = ((PyClassObject *)tmp)->cl_dict;
|
||||
else
|
||||
continue;
|
||||
res = PyDict_GetItem(dict, name);
|
||||
|
|
|
@ -7848,6 +7848,8 @@ Create a new Unicode object from the given encoded string.\n\
|
|||
encoding defaults to the current default string encoding.\n\
|
||||
errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.");
|
||||
|
||||
static PyObject *unicode_iter(PyObject *seq);
|
||||
|
||||
PyTypeObject PyUnicode_Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0, /* ob_size */
|
||||
|
@ -7876,7 +7878,7 @@ PyTypeObject PyUnicode_Type = {
|
|||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
unicode_iter, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
unicode_methods, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
|
@ -7961,6 +7963,124 @@ _PyUnicode_Fini(void)
|
|||
unicode_freelist_size = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************* Unicode Iterator **************************/
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
long it_index;
|
||||
PyUnicodeObject *it_seq; /* Set to NULL when iterator is exhausted */
|
||||
} unicodeiterobject;
|
||||
|
||||
static void
|
||||
unicodeiter_dealloc(unicodeiterobject *it)
|
||||
{
|
||||
_PyObject_GC_UNTRACK(it);
|
||||
Py_XDECREF(it->it_seq);
|
||||
PyObject_GC_Del(it);
|
||||
}
|
||||
|
||||
static int
|
||||
unicodeiter_traverse(unicodeiterobject *it, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(it->it_seq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
unicodeiter_next(unicodeiterobject *it)
|
||||
{
|
||||
PyUnicodeObject *seq;
|
||||
PyObject *item;
|
||||
|
||||
assert(it != NULL);
|
||||
seq = it->it_seq;
|
||||
if (seq == NULL)
|
||||
return NULL;
|
||||
assert(PyUnicode_Check(seq));
|
||||
|
||||
if (it->it_index < PyUnicode_GET_SIZE(seq)) {
|
||||
item = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(seq)+it->it_index, 1);
|
||||
if (item != NULL)
|
||||
++it->it_index;
|
||||
return item;
|
||||
}
|
||||
|
||||
Py_DECREF(seq);
|
||||
it->it_seq = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
unicodeiter_len(unicodeiterobject *it)
|
||||
{
|
||||
Py_ssize_t len = 0;
|
||||
if (it->it_seq)
|
||||
len = PyUnicode_GET_SIZE(it->it_seq) - it->it_index;
|
||||
return PyInt_FromSsize_t(len);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
|
||||
|
||||
static PyMethodDef unicodeiter_methods[] = {
|
||||
{"__length_hint__", (PyCFunction)unicodeiter_len, METH_NOARGS, length_hint_doc},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
PyTypeObject PyUnicodeIter_Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0, /* ob_size */
|
||||
"unicodeiterator", /* tp_name */
|
||||
sizeof(unicodeiterobject), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
/* methods */
|
||||
(destructor)unicodeiter_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
PyObject_GenericGetAttr, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
|
||||
0, /* tp_doc */
|
||||
(traverseproc)unicodeiter_traverse, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
PyObject_SelfIter, /* tp_iter */
|
||||
(iternextfunc)unicodeiter_next, /* tp_iternext */
|
||||
unicodeiter_methods, /* tp_methods */
|
||||
0,
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
unicode_iter(PyObject *seq)
|
||||
{
|
||||
unicodeiterobject *it;
|
||||
|
||||
if (!PyUnicode_Check(seq)) {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
it = PyObject_GC_New(unicodeiterobject, &PyUnicodeIter_Type);
|
||||
if (it == NULL)
|
||||
return NULL;
|
||||
it->it_index = 0;
|
||||
Py_INCREF(seq);
|
||||
it->it_seq = (PyUnicodeObject *)seq;
|
||||
_PyObject_GC_TRACK(it);
|
||||
return (PyObject *)it;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -3409,15 +3409,9 @@ PyEval_GetFuncName(PyObject *func)
|
|||
return PyString_AsString(((PyFunctionObject*)func)->func_name);
|
||||
else if (PyCFunction_Check(func))
|
||||
return ((PyCFunctionObject*)func)->m_ml->ml_name;
|
||||
else if (PyClass_Check(func))
|
||||
return PyString_AsString(((PyClassObject*)func)->cl_name);
|
||||
else if (PyInstance_Check(func)) {
|
||||
return PyString_AsString(
|
||||
((PyInstanceObject*)func)->in_class->cl_name);
|
||||
} else {
|
||||
else
|
||||
return func->ob_type->tp_name;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
PyEval_GetFuncDesc(PyObject *func)
|
||||
|
@ -3428,14 +3422,9 @@ PyEval_GetFuncDesc(PyObject *func)
|
|||
return "()";
|
||||
else if (PyCFunction_Check(func))
|
||||
return "()";
|
||||
else if (PyClass_Check(func))
|
||||
return " constructor";
|
||||
else if (PyInstance_Check(func)) {
|
||||
return " instance";
|
||||
} else {
|
||||
else
|
||||
return " object";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
err_args(PyObject *func, int flags, int nargs)
|
||||
|
|
|
@ -126,6 +126,10 @@ PyMember_GetOne(const char *addr, PyMemberDef *l)
|
|||
v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG */
|
||||
case T_NONE:
|
||||
v = Py_None;
|
||||
Py_INCREF(v);
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
|
||||
v = NULL;
|
||||
|
|
10
README
10
README
|
@ -1,4 +1,4 @@
|
|||
This is Python 3000 -- unversioned (branched off 2.5 pre alpha 1)
|
||||
This is Python 3000 -- unversioned (branched off 2.5 in various beta stages)
|
||||
=================================================================
|
||||
|
||||
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation.
|
||||
|
@ -30,6 +30,14 @@ All trademarks referenced herein are property of their respective
|
|||
holders.
|
||||
|
||||
|
||||
Python 3000 disclaimer
|
||||
----------------------
|
||||
|
||||
This README hasn't been updated for Python 3000 yet. If you see
|
||||
anything that should clearly be deleted, let me know (guido@python.org)
|
||||
or submit a patch to the Python 3000 category in SourceForge.
|
||||
|
||||
|
||||
What's new in this release?
|
||||
---------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue