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:
Guido van Rossum 2006-08-17 05:42:55 +00:00
parent d033ddf4dc
commit 50e9fb9e2d
22 changed files with 325 additions and 2543 deletions

View File

@ -7,14 +7,6 @@
#include "patchlevel.h" #include "patchlevel.h"
#include "pyconfig.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> #include <limits.h>
#ifndef UCHAR_MAX #ifndef UCHAR_MAX

View File

@ -1,5 +1,4 @@
/* Former class object interface -- now only (un)bound methods are here */
/* Class object interface */
/* Revealing some structures (not for general use) */ /* Revealing some structures (not for general use) */
@ -9,24 +8,6 @@
extern "C" { extern "C" {
#endif #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 { typedef struct {
PyObject_HEAD PyObject_HEAD
PyObject *im_func; /* The callable object implementing the method */ PyObject *im_func; /* The callable object implementing the method */
@ -35,34 +16,16 @@ typedef struct {
PyObject *im_weakreflist; /* List of weak references */ PyObject *im_weakreflist; /* List of weak references */
} PyMethodObject; } 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) #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_New(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Class(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* /* Macros for direct access to these values. Type checks are *not*
done, so use with care. */ done, so use with care. */
#define PyMethod_GET_FUNCTION(meth) \ #define PyMethod_GET_FUNCTION(meth) \
@ -72,9 +35,6 @@ PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name);
#define PyMethod_GET_CLASS(meth) \ #define PyMethod_GET_CLASS(meth) \
(((PyMethodObject *)meth) -> im_class) (((PyMethodObject *)meth) -> im_class)
PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -63,7 +63,7 @@ PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *,
#define METH_CLASS 0x0010 #define METH_CLASS 0x0010
#define METH_STATIC 0x0020 #define METH_STATIC 0x0020
/* METH_COEXIST allows a method to be entered eventhough a slot has /* METH_COEXIST allows a method to be entered even though a slot has
already filled the entry. When defined, the flag allows a separate already filled the entry. When defined, the flag allows a separate
method, "__contains__" for example, to coexist with a defined method, "__contains__" for example, to coexist with a defined
slot like sq_contains. */ slot like sq_contains. */

View File

@ -147,7 +147,7 @@ typedef int (*visitproc)(PyObject *, void *);
typedef int (*traverseproc)(PyObject *, visitproc, void *); typedef int (*traverseproc)(PyObject *, visitproc, void *);
typedef struct { typedef struct {
/* Number implementations should check *both* /* Number implementations must check *both*
arguments for proper type and implement the necessary conversions arguments for proper type and implement the necessary conversions
in the slot functions themselves. */ in the slot functions themselves. */
@ -173,7 +173,7 @@ typedef struct {
unaryfunc nb_float; unaryfunc nb_float;
unaryfunc nb_oct; unaryfunc nb_oct;
unaryfunc nb_hex; unaryfunc nb_hex;
/* Added in release 2.0 */
binaryfunc nb_inplace_add; binaryfunc nb_inplace_add;
binaryfunc nb_inplace_subtract; binaryfunc nb_inplace_subtract;
binaryfunc nb_inplace_multiply; binaryfunc nb_inplace_multiply;
@ -185,13 +185,11 @@ typedef struct {
binaryfunc nb_inplace_xor; binaryfunc nb_inplace_xor;
binaryfunc nb_inplace_or; binaryfunc nb_inplace_or;
/* Added in release 2.2 */
binaryfunc nb_floor_divide; binaryfunc nb_floor_divide;
binaryfunc nb_true_divide; binaryfunc nb_true_divide;
binaryfunc nb_inplace_floor_divide; binaryfunc nb_inplace_floor_divide;
binaryfunc nb_inplace_true_divide; binaryfunc nb_inplace_true_divide;
/* Added in release 2.5 */
lenfunc nb_index; lenfunc nb_index;
} PyNumberMethods; } PyNumberMethods;
@ -204,7 +202,7 @@ typedef struct {
ssizeobjargproc sq_ass_item; ssizeobjargproc sq_ass_item;
ssizessizeobjargproc sq_ass_slice; ssizessizeobjargproc sq_ass_slice;
objobjproc sq_contains; objobjproc sq_contains;
/* Added in release 2.0 */
binaryfunc sq_inplace_concat; binaryfunc sq_inplace_concat;
ssizeargfunc sq_inplace_repeat; ssizeargfunc sq_inplace_repeat;
} PySequenceMethods; } PySequenceMethods;
@ -292,7 +290,6 @@ typedef struct _typeobject {
/* weak reference enabler */ /* weak reference enabler */
Py_ssize_t tp_weaklistoffset; Py_ssize_t tp_weaklistoffset;
/* Added in release 2.2 */
/* Iterators */ /* Iterators */
getiterfunc tp_iter; getiterfunc tp_iter;
iternextfunc tp_iternext; iternextfunc tp_iternext;

View File

@ -67,9 +67,11 @@ typedef struct PyMemberDef {
converting to None. */ converting to None. */
#ifdef HAVE_LONG_LONG #ifdef HAVE_LONG_LONG
#define T_LONGLONG 17 #define T_LONGLONG 17
#define T_ULONGLONG 18 #define T_ULONGLONG 18
#endif /* HAVE_LONG_LONG */ #endif /* HAVE_LONG_LONG */
#define T_NONE 19 /* Value is always None */
/* Flags */ /* Flags */
#define READONLY 1 #define READONLY 1
#define RO READONLY /* Shorthand */ #define RO READONLY /* Shorthand */

View File

@ -3363,19 +3363,19 @@ static PyMethodDef _functions[] = {
{NULL, NULL} {NULL, NULL}
}; };
#if PY_VERSION_HEX < 0x02030000
DL_EXPORT(void) init_sre(void)
#else
PyMODINIT_FUNC init_sre(void) PyMODINIT_FUNC init_sre(void)
#endif
{ {
PyObject* m; PyObject* m;
PyObject* d; PyObject* d;
PyObject* x; PyObject* x;
/* Patch object types */ /* Initialize object types */
Pattern_Type.ob_type = Match_Type.ob_type = if (PyType_Ready(&Pattern_Type) < 0)
Scanner_Type.ob_type = &PyType_Type; return;
if (PyType_Ready(&Match_Type) < 0)
return;
if (PyType_Ready(&Scanner_Type) < 0)
return;
m = Py_InitModule("_" SRE_MODULE, _functions); m = Py_InitModule("_" SRE_MODULE, _functions);
if (m == NULL) if (m == NULL)

View File

@ -2112,7 +2112,8 @@ initarray(void)
{ {
PyObject *m; PyObject *m;
Arraytype.ob_type = &PyType_Type; if (PyType_Ready(&Arraytype) < 0)
return;
PyArrayIter_Type.ob_type = &PyType_Type; PyArrayIter_Type.ob_type = &PyType_Type;
m = Py_InitModule3("array", a_methods, module_doc); m = Py_InitModule3("array", a_methods, module_doc);
if (m == NULL) if (m == NULL)

View File

@ -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 static int
save_global(Picklerobject *self, PyObject *args, PyObject *name) save_global(Picklerobject *self, PyObject *args, PyObject *name)
@ -2420,20 +2278,6 @@ save(Picklerobject *self, PyObject *args, int pers_save)
} }
break; 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': case 'f':
if (type == &PyFunction_Type) { if (type == &PyFunction_Type) {
res = save_global(self, args, NULL); res = save_global(self, args, NULL);
@ -3594,57 +3438,6 @@ load_dict(Unpicklerobject *self)
return 0; 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 static int
load_obj(Unpicklerobject *self) load_obj(Unpicklerobject *self)
@ -3655,10 +3448,6 @@ load_obj(Unpicklerobject *self)
if ((i = marker(self)) < 0) return -1; if ((i = marker(self)) < 0) return -1;
if (!( tup=Pdata_popTuple(self->stack, i+1))) return -1; if (!( tup=Pdata_popTuple(self->stack, i+1))) return -1;
PDATA_POP(self->stack, class); PDATA_POP(self->stack, class);
if (class) {
obj = Instance_New(class, tup);
Py_DECREF(class);
}
Py_DECREF(tup); Py_DECREF(tup);
if (! obj) return -1; if (! obj) return -1;
@ -3694,8 +3483,8 @@ load_inst(Unpicklerobject *self)
if (! class) return -1; if (! class) return -1;
if ((tup=Pdata_popTuple(self->stack, i))) { if ((tup=Pdata_popTuple(self->stack, i))) {
obj = Instance_New(class, tup); PyErr_SetString(UnpicklingError, "it's dead, Jim");
Py_DECREF(tup); return -1;
} }
Py_DECREF(class); Py_DECREF(class);
@ -4388,10 +4177,6 @@ load_reduce(Unpicklerobject *self)
PDATA_POP(self->stack, arg_tup); PDATA_POP(self->stack, arg_tup);
if (! arg_tup) return -1; if (! arg_tup) return -1;
PDATA_POP(self->stack, callable); PDATA_POP(self->stack, callable);
if (callable) {
ob = Instance_New(callable, arg_tup);
Py_DECREF(callable);
}
Py_DECREF(arg_tup); Py_DECREF(arg_tup);
if (! ob) return -1; if (! ob) return -1;

View File

@ -66,12 +66,10 @@ static PyObject *delstr = NULL;
#define DEBUG_STATS (1<<0) /* print collection statistics */ #define DEBUG_STATS (1<<0) /* print collection statistics */
#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */ #define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable 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_OBJECTS (1<<4) /* print other objects */
#define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */ #define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
#define DEBUG_LEAK DEBUG_COLLECTABLE | \ #define DEBUG_LEAK DEBUG_COLLECTABLE | \
DEBUG_UNCOLLECTABLE | \ DEBUG_UNCOLLECTABLE | \
DEBUG_INSTANCES | \
DEBUG_OBJECTS | \ DEBUG_OBJECTS | \
DEBUG_SAVEALL DEBUG_SAVEALL
static int debug; static int debug;
@ -410,13 +408,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
static int static int
has_finalizer(PyObject *op) has_finalizer(PyObject *op)
{ {
if (PyInstance_Check(op)) { if (PyGen_CheckExact(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))
return PyGen_NeedsFinalizing((PyGenObject *)op); return PyGen_NeedsFinalizing((PyGenObject *)op);
else else
return 0; return 0;
@ -632,27 +624,10 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
return num_freed; 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 static void
debug_cycle(char *msg, PyObject *op) debug_cycle(char *msg, PyObject *op)
{ {
if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) { if (debug & DEBUG_OBJECTS) {
debug_instance(msg, (PyInstanceObject *)op);
}
else if (debug & DEBUG_OBJECTS) {
PySys_WriteStderr("gc: %.100s <%.100s %p>\n", PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
msg, op->ob_type->tp_name, op); 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_STATS - Print statistics during collection.\n"
" DEBUG_COLLECTABLE - Print collectable objects found.\n" " DEBUG_COLLECTABLE - Print collectable objects found.\n"
" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable 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_OBJECTS - Print objects other than instances.\n"
" DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n" " DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n"
" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n"); " DEBUG_LEAK - Debug leaking programs (everything but STATS).\n");
@ -1244,7 +1218,6 @@ initgc(void)
ADD_INT(DEBUG_STATS); ADD_INT(DEBUG_STATS);
ADD_INT(DEBUG_COLLECTABLE); ADD_INT(DEBUG_COLLECTABLE);
ADD_INT(DEBUG_UNCOLLECTABLE); ADD_INT(DEBUG_UNCOLLECTABLE);
ADD_INT(DEBUG_INSTANCES);
ADD_INT(DEBUG_OBJECTS); ADD_INT(DEBUG_OBJECTS);
ADD_INT(DEBUG_SAVEALL); ADD_INT(DEBUG_SAVEALL);
ADD_INT(DEBUG_LEAK); ADD_INT(DEBUG_LEAK);

View File

@ -1000,8 +1000,6 @@ PyNumber_Float(PyObject *o)
int int
PySequence_Check(PyObject *s) PySequence_Check(PyObject *s)
{ {
if (s && PyInstance_Check(s))
return PyObject_HasAttrString(s, "__getitem__");
return s != NULL && s->ob_type->tp_as_sequence && return s != NULL && s->ob_type->tp_as_sequence &&
s->ob_type->tp_as_sequence->sq_item != NULL; s->ob_type->tp_as_sequence->sq_item != NULL;
} }
@ -1586,9 +1584,6 @@ PySequence_Index(PyObject *s, PyObject *o)
int int
PyMapping_Check(PyObject *o) PyMapping_Check(PyObject *o)
{ {
if (o && PyInstance_Check(o))
return PyObject_HasAttrString(o, "__getitem__");
return o && o->ob_type->tp_as_mapping && return o && o->ob_type->tp_as_mapping &&
o->ob_type->tp_as_mapping->mp_subscript && o->ob_type->tp_as_mapping->mp_subscript &&
!(o->ob_type->tp_as_sequence && !(o->ob_type->tp_as_sequence &&

View File

@ -379,13 +379,6 @@ bytes_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value)
return 0; return 0;
} }
static long
bytes_nohash(PyObject *self)
{
PyErr_SetString(PyExc_TypeError, "bytes objects are unhashable");
return -1;
}
static int static int
bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds) bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds)
{ {
@ -833,7 +826,7 @@ PyTypeObject PyBytes_Type = {
0, /* tp_as_number */ 0, /* tp_as_number */
&bytes_as_sequence, /* tp_as_sequence */ &bytes_as_sequence, /* tp_as_sequence */
&bytes_as_mapping, /* tp_as_mapping */ &bytes_as_mapping, /* tp_as_mapping */
bytes_nohash, /* tp_hash */ 0, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
(reprfunc)bytes_str, /* tp_str */ (reprfunc)bytes_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */

File diff suppressed because it is too large Load Diff

View File

@ -2006,13 +2006,6 @@ dict_init(PyObject *self, PyObject *args, PyObject *kwds)
return dict_update_common(self, args, kwds, "dict"); 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 * static PyObject *
dict_iter(dictobject *dict) dict_iter(dictobject *dict)
{ {
@ -2045,7 +2038,7 @@ PyTypeObject PyDict_Type = {
0, /* tp_as_number */ 0, /* tp_as_number */
&dict_as_sequence, /* tp_as_sequence */ &dict_as_sequence, /* tp_as_sequence */
&dict_as_mapping, /* tp_as_mapping */ &dict_as_mapping, /* tp_as_mapping */
dict_nohash, /* tp_hash */ 0, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
0, /* tp_str */ 0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */

View File

@ -2381,13 +2381,6 @@ list_init(PyListObject *self, PyObject *args, PyObject *kw)
return 0; 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_iter(PyObject *seq);
static PyObject *list_reversed(PyListObject* seq, PyObject* unused); static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
@ -2655,7 +2648,7 @@ PyTypeObject PyList_Type = {
0, /* tp_as_number */ 0, /* tp_as_number */
&list_as_sequence, /* tp_as_sequence */ &list_as_sequence, /* tp_as_sequence */
&list_as_mapping, /* tp_as_mapping */ &list_as_mapping, /* tp_as_mapping */
list_nohash, /* tp_hash */ 0, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
0, /* tp_str */ 0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */

View File

@ -2,6 +2,7 @@
/* Generic object operations; and implementation of None (NoObject) */ /* Generic object operations; and implementation of None (NoObject) */
#include "Python.h" #include "Python.h"
#include "sliceobject.h" /* For PyEllipsis_Type */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -663,10 +664,6 @@ try_3way_compare(PyObject *v, PyObject *w)
which has the same return conventions as this function. */ which has the same return conventions as this function. */
f = v->ob_type->tp_compare; 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 both have the same (non-NULL) tp_compare, use it. */
if (f != NULL && f == w->ob_type->tp_compare) { if (f != NULL && f == w->ob_type->tp_compare) {
@ -789,15 +786,7 @@ do_cmp(PyObject *v, PyObject *w)
if (v->ob_type == w->ob_type if (v->ob_type == w->ob_type
&& (f = v->ob_type->tp_compare) != NULL) { && (f = v->ob_type->tp_compare) != NULL) {
c = (*f)(v, w); c = (*f)(v, w);
if (PyInstance_Check(v)) { return adjust_tp_compare(c);
/* 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: /* We only get here if one of the following is true:
a) v and w have different types a) v and w have different types
@ -911,7 +900,7 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op)
/* If the types are equal, and not old-style instances, try to /* If the types are equal, and not old-style instances, try to
get out cheap (don't bother with coercions etc.). */ 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; cmpfunc fcmp;
richcmpfunc frich = RICHCOMPARE(v->ob_type); richcmpfunc frich = RICHCOMPARE(v->ob_type);
/* If the type has richcmp, try it first. try_rich_compare /* If the type has richcmp, try it first. try_rich_compare
@ -1063,10 +1052,7 @@ PyObject_Hash(PyObject *v)
PyTypeObject *tp = v->ob_type; PyTypeObject *tp = v->ob_type;
if (tp->tp_hash != NULL) if (tp->tp_hash != NULL)
return (*tp->tp_hash)(v); return (*tp->tp_hash)(v);
if (tp->tp_compare == NULL && RICHCOMPARE(tp) == NULL) { /* Otherwise, the object can't be hashed */
return _Py_HashPointer(v); /* Use address as hash value */
}
/* If there's a cmp but no hash defined, the object can't be hashed */
PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
v->ob_type->tp_name); v->ob_type->tp_name);
return -1; return -1;
@ -1303,12 +1289,8 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
n = PyTuple_GET_SIZE(mro); n = PyTuple_GET_SIZE(mro);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
base = PyTuple_GET_ITEM(mro, i); base = PyTuple_GET_ITEM(mro, i);
if (PyClass_Check(base)) assert(PyType_Check(base));
dict = ((PyClassObject *)base)->cl_dict; dict = ((PyTypeObject *)base)->tp_dict;
else {
assert(PyType_Check(base));
dict = ((PyTypeObject *)base)->tp_dict;
}
assert(dict && PyDict_Check(dict)); assert(dict && PyDict_Check(dict));
descr = PyDict_GetItem(dict, name); descr = PyDict_GetItem(dict, name);
if (descr != NULL) if (descr != NULL)
@ -1554,20 +1536,7 @@ PyCallable_Check(PyObject *x)
{ {
if (x == NULL) if (x == NULL)
return 0; return 0;
if (PyInstance_Check(x)) { return x->ob_type->tp_call != NULL;
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. /* Helper for PyObject_Dir.
@ -1701,7 +1670,7 @@ PyObject_Dir(PyObject *arg)
/* Elif some form of type or class, grab its dict and its bases. /* Elif some form of type or class, grab its dict and its bases.
We deliberately don't suck up its __class__, as methods belonging We deliberately don't suck up its __class__, as methods belonging
to the metaclass would probably be more confusing than helpful. */ 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(); masterdict = PyDict_New();
if (masterdict == NULL) if (masterdict == NULL)
goto error; goto error;
@ -1886,6 +1855,9 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyNone_Type) < 0) if (PyType_Ready(&PyNone_Type) < 0)
Py_FatalError("Can't initialize type(None)"); 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) if (PyType_Ready(&PyNotImplemented_Type) < 0)
Py_FatalError("Can't initialize type(NotImplemented)"); Py_FatalError("Can't initialize type(NotImplemented)");
} }

View File

@ -718,13 +718,6 @@ frozenset_hash(PyObject *self)
return hash; return hash;
} }
static long
set_nohash(PyObject *self)
{
PyErr_SetString(PyExc_TypeError, "set objects are unhashable");
return -1;
}
/***** Set iterator type ***********************************************/ /***** Set iterator type ***********************************************/
typedef struct { typedef struct {
@ -1813,7 +1806,7 @@ PyTypeObject PySet_Type = {
&set_as_number, /* tp_as_number */ &set_as_number, /* tp_as_number */
&set_as_sequence, /* tp_as_sequence */ &set_as_sequence, /* tp_as_sequence */
0, /* tp_as_mapping */ 0, /* tp_as_mapping */
set_nohash, /* tp_hash */ 0, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
0, /* tp_str */ 0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */

View File

@ -3982,6 +3982,8 @@ PyDoc_STRVAR(string_doc,
Return a nice string representation of the object.\n\ Return a nice string representation of the object.\n\
If the argument is a string, the return value is the same object."); If the argument is a string, the return value is the same object.");
static PyObject *str_iter(PyObject *seq);
PyTypeObject PyString_Type = { PyTypeObject PyString_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
@ -4009,7 +4011,7 @@ PyTypeObject PyString_Type = {
0, /* tp_clear */ 0, /* tp_clear */
(richcmpfunc)string_richcompare, /* tp_richcompare */ (richcmpfunc)string_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */ 0, /* tp_weaklistoffset */
0, /* tp_iter */ str_iter, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
string_methods, /* tp_methods */ string_methods, /* tp_methods */
0, /* tp_members */ 0, /* tp_members */
@ -4984,3 +4986,120 @@ void _Py_ReleaseInternedStrings(void)
Py_DECREF(interned); Py_DECREF(interned);
interned = NULL; 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;
}

View File

@ -214,7 +214,7 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context)
} }
for (i = 0; i < PyTuple_GET_SIZE(value); i++) { for (i = 0; i < PyTuple_GET_SIZE(value); i++) {
ob = PyTuple_GET_ITEM(value, i); ob = PyTuple_GET_ITEM(value, i);
if (!PyClass_Check(ob) && !PyType_Check(ob)) { if (!PyType_Check(ob)) {
PyErr_Format( PyErr_Format(
PyExc_TypeError, PyExc_TypeError,
"%s.__bases__ must be tuple of old- or new-style classes, not '%s'", "%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; 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 Method resolution order algorithm C3 described in
"A Monotonic Superclass Linearization for Dylan", "A Monotonic Superclass Linearization for Dylan",
@ -1229,11 +1188,7 @@ mro_implementation(PyTypeObject *type)
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
PyObject *base = PyTuple_GET_ITEM(bases, i); PyObject *base = PyTuple_GET_ITEM(bases, i);
PyObject *parentMRO; PyObject *parentMRO;
if (PyType_Check(base)) parentMRO = PySequence_List(((PyTypeObject*)base)->tp_mro);
parentMRO = PySequence_List(
((PyTypeObject*)base)->tp_mro);
else
parentMRO = classic_mro(base);
if (parentMRO == NULL) { if (parentMRO == NULL) {
Py_DECREF(to_merge); Py_DECREF(to_merge);
return NULL; return NULL;
@ -1315,9 +1270,7 @@ mro_internal(PyTypeObject *type)
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
PyTypeObject *t; PyTypeObject *t;
cls = PyTuple_GET_ITEM(tuple, i); cls = PyTuple_GET_ITEM(tuple, i);
if (PyClass_Check(cls)) if (!PyType_Check(cls)) {
continue;
else if (!PyType_Check(cls)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"mro() returned a non-class ('%.500s')", "mro() returned a non-class ('%.500s')",
cls->ob_type->tp_name); cls->ob_type->tp_name);
@ -1356,8 +1309,6 @@ best_base(PyObject *bases)
winner = NULL; winner = NULL;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
base_proto = PyTuple_GET_ITEM(bases, i); base_proto = PyTuple_GET_ITEM(bases, i);
if (PyClass_Check(base_proto))
continue;
if (!PyType_Check(base_proto)) { if (!PyType_Check(base_proto)) {
PyErr_SetString( PyErr_SetString(
PyExc_TypeError, PyExc_TypeError,
@ -1636,8 +1587,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
for (i = 0; i < nbases; i++) { for (i = 0; i < nbases; i++) {
tmp = PyTuple_GET_ITEM(bases, i); tmp = PyTuple_GET_ITEM(bases, i);
tmptype = tmp->ob_type; tmptype = tmp->ob_type;
if (tmptype == &PyClass_Type)
continue; /* Special case classic classes */
if (PyType_IsSubtype(winner, tmptype)) if (PyType_IsSubtype(winner, tmptype))
continue; continue;
if (PyType_IsSubtype(tmptype, winner)) { if (PyType_IsSubtype(tmptype, winner)) {
@ -1793,14 +1742,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
tmp = PyTuple_GET_ITEM(bases, i); tmp = PyTuple_GET_ITEM(bases, i);
if (tmp == (PyObject *)base) if (tmp == (PyObject *)base)
continue; /* Skip primary 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)); assert(PyType_Check(tmp));
tmptype = (PyTypeObject *)tmp; tmptype = (PyTypeObject *)tmp;
if (may_add_dict && !add_dict && if (may_add_dict && !add_dict &&
@ -2006,12 +1947,8 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
n = PyTuple_GET_SIZE(mro); n = PyTuple_GET_SIZE(mro);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
base = PyTuple_GET_ITEM(mro, i); base = PyTuple_GET_ITEM(mro, i);
if (PyClass_Check(base)) assert(PyType_Check(base));
dict = ((PyClassObject *)base)->cl_dict; dict = ((PyTypeObject *)base)->tp_dict;
else {
assert(PyType_Check(base));
dict = ((PyTypeObject *)base)->tp_dict;
}
assert(dict && PyDict_Check(dict)); assert(dict && PyDict_Check(dict));
res = PyDict_GetItem(dict, name); res = PyDict_GetItem(dict, name);
if (res != NULL) if (res != NULL)
@ -2364,12 +2301,6 @@ object_str(PyObject *self)
return f(self); return f(self);
} }
static long
object_hash(PyObject *self)
{
return _Py_HashPointer(self);
}
static PyObject * static PyObject *
object_get_class(PyObject *self, void *closure) object_get_class(PyObject *self, void *closure)
{ {
@ -2762,7 +2693,7 @@ PyTypeObject PyBaseObject_Type = {
0, /* tp_as_number */ 0, /* tp_as_number */
0, /* tp_as_sequence */ 0, /* tp_as_sequence */
0, /* tp_as_mapping */ 0, /* tp_as_mapping */
object_hash, /* tp_hash */ (hashfunc)_Py_HashPointer, /* tp_hash */
0, /* tp_call */ 0, /* tp_call */
object_str, /* tp_str */ object_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */ 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 static int
add_methods(PyTypeObject *type, PyMethodDef *meth) add_methods(PyTypeObject *type, PyMethodDef *meth)
@ -3118,7 +3049,7 @@ PyType_Ready(PyTypeObject *type)
*/ */
/* Initialize the base class */ /* Initialize the base class */
if (base && base->tp_dict == NULL) { if (base != NULL && base->tp_dict == NULL) {
if (PyType_Ready(base) < 0) if (PyType_Ready(base) < 0)
goto error; goto error;
} }
@ -4490,41 +4421,35 @@ static long
slot_tp_hash(PyObject *self) slot_tp_hash(PyObject *self)
{ {
PyObject *func; PyObject *func;
static PyObject *hash_str, *eq_str, *cmp_str; static PyObject *hash_str;
long h; long h;
func = lookup_method(self, "__hash__", &hash_str); func = lookup_method(self, "__hash__", &hash_str);
if (func != NULL) { if (func == Py_None) {
PyObject *res = PyEval_CallObject(func, NULL);
Py_DECREF(func); Py_DECREF(func);
if (res == NULL) func = NULL;
return -1;
if (PyLong_Check(res))
h = PyLong_Type.tp_hash(res);
else
h = PyInt_AsLong(res);
Py_DECREF(res);
} }
else {
if (func == NULL) {
PyErr_Clear(); PyErr_Clear();
func = lookup_method(self, "__eq__", &eq_str); PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'",
if (func == NULL) { self->ob_type->tp_name);
PyErr_Clear(); return -1;
func = lookup_method(self, "__cmp__", &cmp_str); }
}
if (func != NULL) { PyObject *res = PyEval_CallObject(func, NULL);
PyErr_Format(PyExc_TypeError, "unhashable type: '%.200s'", Py_DECREF(func);
self->ob_type->tp_name); if (res == NULL)
Py_DECREF(func); return -1;
return -1; if (PyLong_Check(res))
} h = PyLong_Type.tp_hash(res);
PyErr_Clear(); else
h = _Py_HashPointer((void *)self); h = PyInt_AsLong(res);
} Py_DECREF(res);
if (h == -1 && !PyErr_Occurred()) if (h == -1 && !PyErr_Occurred())
h = -2; h = -2;
return h; return h;
} }
static PyObject * static PyObject *
@ -5579,8 +5504,6 @@ super_getattro(PyObject *self, PyObject *name)
tmp = PyTuple_GET_ITEM(mro, i); tmp = PyTuple_GET_ITEM(mro, i);
if (PyType_Check(tmp)) if (PyType_Check(tmp))
dict = ((PyTypeObject *)tmp)->tp_dict; dict = ((PyTypeObject *)tmp)->tp_dict;
else if (PyClass_Check(tmp))
dict = ((PyClassObject *)tmp)->cl_dict;
else else
continue; continue;
res = PyDict_GetItem(dict, name); res = PyDict_GetItem(dict, name);

View File

@ -7848,6 +7848,8 @@ Create a new Unicode object from the given encoded string.\n\
encoding defaults to the current default string encoding.\n\ encoding defaults to the current default string encoding.\n\
errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'."); errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.");
static PyObject *unicode_iter(PyObject *seq);
PyTypeObject PyUnicode_Type = { PyTypeObject PyUnicode_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, /* ob_size */ 0, /* ob_size */
@ -7876,7 +7878,7 @@ PyTypeObject PyUnicode_Type = {
0, /* tp_clear */ 0, /* tp_clear */
0, /* tp_richcompare */ 0, /* tp_richcompare */
0, /* tp_weaklistoffset */ 0, /* tp_weaklistoffset */
0, /* tp_iter */ unicode_iter, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
unicode_methods, /* tp_methods */ unicode_methods, /* tp_methods */
0, /* tp_members */ 0, /* tp_members */
@ -7961,6 +7963,124 @@ _PyUnicode_Fini(void)
unicode_freelist_size = 0; 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -3409,14 +3409,8 @@ PyEval_GetFuncName(PyObject *func)
return PyString_AsString(((PyFunctionObject*)func)->func_name); return PyString_AsString(((PyFunctionObject*)func)->func_name);
else if (PyCFunction_Check(func)) else if (PyCFunction_Check(func))
return ((PyCFunctionObject*)func)->m_ml->ml_name; return ((PyCFunctionObject*)func)->m_ml->ml_name;
else if (PyClass_Check(func)) else
return PyString_AsString(((PyClassObject*)func)->cl_name);
else if (PyInstance_Check(func)) {
return PyString_AsString(
((PyInstanceObject*)func)->in_class->cl_name);
} else {
return func->ob_type->tp_name; return func->ob_type->tp_name;
}
} }
const char * const char *
@ -3428,13 +3422,8 @@ PyEval_GetFuncDesc(PyObject *func)
return "()"; return "()";
else if (PyCFunction_Check(func)) else if (PyCFunction_Check(func))
return "()"; return "()";
else if (PyClass_Check(func)) else
return " constructor";
else if (PyInstance_Check(func)) {
return " instance";
} else {
return " object"; return " object";
}
} }
static void static void

View File

@ -126,6 +126,10 @@ PyMember_GetOne(const char *addr, PyMemberDef *l)
v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr); v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
break; break;
#endif /* HAVE_LONG_LONG */ #endif /* HAVE_LONG_LONG */
case T_NONE:
v = Py_None;
Py_INCREF(v);
break;
default: default:
PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
v = NULL; v = NULL;

10
README
View File

@ -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. 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. 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? What's new in this release?
--------------------------- ---------------------------