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 "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

View File

@ -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

View File

@ -63,7 +63,7 @@ PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *,
#define METH_CLASS 0x0010
#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
method, "__contains__" for example, to coexist with a defined
slot like sq_contains. */

View File

@ -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;

View File

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

View File

@ -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)

View File

@ -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)

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
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;

View File

@ -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);

View File

@ -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 &&

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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,15 +786,7 @@ 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);
return adjust_tp_compare(c);
}
/* We only get here if one of the following is true:
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
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(PyType_Check(base));
dict = ((PyTypeObject *)base)->tp_dict;
assert(dict && PyDict_Check(dict));
descr = PyDict_GetItem(dict, name);
if (descr != NULL)
@ -1554,20 +1536,7 @@ 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;
}
return x->ob_type->tp_call != NULL;
}
/* 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.
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)");
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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(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,41 +4421,35 @@ 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) {
PyObject *res = PyEval_CallObject(func, NULL);
if (func == Py_None) {
Py_DECREF(func);
if (res == NULL)
return -1;
if (PyLong_Check(res))
h = PyLong_Type.tp_hash(res);
else
h = PyInt_AsLong(res);
Py_DECREF(res);
func = NULL;
}
else {
if (func == NULL) {
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;
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)
return -1;
if (PyLong_Check(res))
h = PyLong_Type.tp_hash(res);
else
h = PyInt_AsLong(res);
Py_DECREF(res);
if (h == -1 && !PyErr_Occurred())
h = -2;
return h;
}
static PyObject *
@ -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);

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\
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

View File

@ -3409,14 +3409,8 @@ 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 *
@ -3428,13 +3422,8 @@ 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

View File

@ -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
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.
@ -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?
---------------------------