[Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.87,2.88 intobject.c,2.65,2.66 longobject.c,1.92,1.93
Guido van Rossum
gvanrossum@users.sourceforge.net
Wed, 29 Aug 2001 08:47:49 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv32398
Modified Files:
floatobject.c intobject.c longobject.c
Log Message:
Make int, long and float subclassable.
This uses a slightly wimpy and wasteful approach, but it works. :-)
Index: floatobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v
retrieving revision 2.87
retrieving revision 2.88
diff -C2 -d -r2.87 -r2.88
*** floatobject.c 2001/08/23 22:31:37 2.87
--- floatobject.c 2001/08/29 15:47:46 2.88
***************
*** 627,630 ****
--- 627,633 ----
+ staticforward PyObject *
+ float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
static PyObject *
float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
***************
*** 633,637 ****
static char *kwlist[] = {"x", 0};
! assert(type == &PyFloat_Type);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
return NULL;
--- 636,641 ----
static char *kwlist[] = {"x", 0};
! if (type != &PyFloat_Type)
! return float_subtype_new(type, args, kwds); /* Wimp out */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
return NULL;
***************
*** 641,644 ****
--- 645,671 ----
}
+ /* Wimpy, slow approach to tp_new calls for subtypes of float:
+ first create a regular float from whatever arguments we got,
+ then allocate a subtype instance and initialize its ob_fval
+ from the regular float. The regular float is then thrown away.
+ */
+ static PyObject *
+ float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ PyObject *tmp, *new;
+
+ assert(PyType_IsSubtype(type, &PyFloat_Type));
+ tmp = float_new(&PyFloat_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyFloat_Check(tmp));
+ new = type->tp_alloc(type, 0);;
+ if (new == NULL)
+ return NULL;
+ ((PyFloatObject *)new)->ob_fval = ((PyFloatObject *)tmp)->ob_fval;
+ Py_DECREF(tmp);
+ return new;
+ }
+
static char float_doc[] =
"float(x) -> floating point number\n\
***************
*** 709,713 ****
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
float_doc, /* tp_doc */
0, /* tp_traverse */
--- 736,741 ----
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
! Py_TPFLAGS_BASETYPE, /* tp_flags */
float_doc, /* tp_doc */
0, /* tp_traverse */
***************
*** 751,755 ****
i < N_FLOATOBJECTS;
i++, p++) {
! if (PyFloat_Check(p) && p->ob_refcnt != 0)
frem++;
}
--- 779,783 ----
i < N_FLOATOBJECTS;
i++, p++) {
! if (p->ob_type == &PyFloat_Type && p->ob_refcnt != 0)
frem++;
}
***************
*** 761,765 ****
i < N_FLOATOBJECTS;
i++, p++) {
! if (!PyFloat_Check(p) || p->ob_refcnt == 0) {
p->ob_type = (struct _typeobject *)
free_list;
--- 789,794 ----
i < N_FLOATOBJECTS;
i++, p++) {
! if (p->ob_type != &PyFloat_Type ||
! p->ob_refcnt == 0) {
p->ob_type = (struct _typeobject *)
free_list;
***************
*** 793,797 ****
i < N_FLOATOBJECTS;
i++, p++) {
! if (PyFloat_Check(p) && p->ob_refcnt != 0) {
char buf[100];
PyFloat_AsString(buf, p);
--- 822,827 ----
i < N_FLOATOBJECTS;
i++, p++) {
! if (p->ob_type == &PyFloat_Type &&
! p->ob_refcnt != 0) {
char buf[100];
PyFloat_AsString(buf, p);
Index: intobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v
retrieving revision 2.65
retrieving revision 2.66
diff -C2 -d -r2.65 -r2.66
*** intobject.c 2001/08/23 21:32:40 2.65
--- intobject.c 2001/08/29 15:47:46 2.66
***************
*** 135,140 ****
int_dealloc(PyIntObject *v)
{
! v->ob_type = (struct _typeobject *)free_list;
! free_list = v;
}
--- 135,144 ----
int_dealloc(PyIntObject *v)
{
! if (v->ob_type == &PyInt_Type) {
! v->ob_type = (struct _typeobject *)free_list;
! free_list = v;
! }
! else
! v->ob_type->tp_free((PyObject *)v);
}
***************
*** 784,787 ****
--- 788,794 ----
}
+ staticforward PyObject *
+ int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
static PyObject *
int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
***************
*** 791,795 ****
static char *kwlist[] = {"x", "base", 0};
! assert(type == &PyInt_Type);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
&x, &base))
--- 798,803 ----
static char *kwlist[] = {"x", "base", 0};
! if (type != &PyInt_Type)
! return int_subtype_new(type, args, kwds); /* Wimp out */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
&x, &base))
***************
*** 812,815 ****
--- 820,846 ----
}
+ /* Wimpy, slow approach to tp_new calls for subtypes of int:
+ first create a regular int from whatever arguments we got,
+ then allocate a subtype instance and initialize its ob_ival
+ from the regular int. The regular int is then thrown away.
+ */
+ static PyObject *
+ int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ PyObject *tmp, *new;
+
+ assert(PyType_IsSubtype(type, &PyInt_Type));
+ tmp = int_new(&PyInt_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyInt_Check(tmp));
+ new = type->tp_alloc(type, 0);;
+ if (new == NULL)
+ return NULL;
+ ((PyIntObject *)new)->ob_ival = ((PyIntObject *)tmp)->ob_ival;
+ Py_DECREF(tmp);
+ return new;
+ }
+
static char int_doc[] =
"int(x[, base]) -> integer\n\
***************
*** 883,887 ****
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
int_doc, /* tp_doc */
0, /* tp_traverse */
--- 914,919 ----
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
! Py_TPFLAGS_BASETYPE, /* tp_flags */
int_doc, /* tp_doc */
0, /* tp_traverse */
***************
*** 935,939 ****
i < N_INTOBJECTS;
i++, p++) {
! if (PyInt_Check(p) && p->ob_refcnt != 0)
irem++;
}
--- 967,971 ----
i < N_INTOBJECTS;
i++, p++) {
! if (p->ob_type == &PyInt_Type && p->ob_refcnt != 0)
irem++;
}
***************
*** 945,949 ****
i < N_INTOBJECTS;
i++, p++) {
! if (!PyInt_Check(p) || p->ob_refcnt == 0) {
p->ob_type = (struct _typeobject *)
free_list;
--- 977,982 ----
i < N_INTOBJECTS;
i++, p++) {
! if (p->ob_type != &PyInt_Type ||
! p->ob_refcnt == 0) {
p->ob_type = (struct _typeobject *)
free_list;
***************
*** 987,991 ****
i < N_INTOBJECTS;
i++, p++) {
! if (PyInt_Check(p) && p->ob_refcnt != 0)
fprintf(stderr,
"# <int at %p, refcnt=%d, val=%ld>\n",
--- 1020,1024 ----
i < N_INTOBJECTS;
i++, p++) {
! if (p->ob_type == &PyInt_Type && p->ob_refcnt != 0)
fprintf(stderr,
"# <int at %p, refcnt=%d, val=%ld>\n",
Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.92
retrieving revision 1.93
diff -C2 -d -r1.92 -r1.93
*** longobject.c 2001/08/17 18:39:25 1.92
--- longobject.c 2001/08/29 15:47:46 1.93
***************
*** 2039,2042 ****
--- 2039,2044 ----
return long_format(v, 16, 1);
}
+ staticforward PyObject *
+ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static PyObject *
***************
*** 2047,2051 ****
static char *kwlist[] = {"x", "base", 0};
! assert(type == &PyLong_Type);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
&x, &base))
--- 2049,2054 ----
static char *kwlist[] = {"x", "base", 0};
! if (type != &PyLong_Type)
! return long_subtype_new(type, args, kwds); /* Wimp out */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
&x, &base))
***************
*** 2070,2073 ****
--- 2073,2106 ----
}
+ /* Wimpy, slow approach to tp_new calls for subtypes of long:
+ first create a regular long from whatever arguments we got,
+ then allocate a subtype instance and initialize it from
+ the regular long. The regular long is then thrown away.
+ */
+ static PyObject *
+ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+ {
+ PyLongObject *tmp, *new;
+ int i, n;
+
+ assert(PyType_IsSubtype(type, &PyLong_Type));
+ tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyLong_Check(tmp));
+ n = tmp->ob_size;
+ if (n < 0)
+ n = -n;
+ new = (PyLongObject *)type->tp_alloc(type, n);
+ if (new == NULL)
+ return NULL;
+ assert(PyLong_Check(new));
+ new->ob_size = type->ob_size;
+ for (i = 0; i < n; i++)
+ new->ob_digit[i] = tmp->ob_digit[i];
+ Py_DECREF(tmp);
+ return (PyObject *)new;
+ }
+
static char long_doc[] =
"long(x[, base]) -> integer\n\
***************
*** 2141,2145 ****
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
long_doc, /* tp_doc */
0, /* tp_traverse */
--- 2174,2179 ----
0, /* tp_setattro */
0, /* tp_as_buffer */
! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
! Py_TPFLAGS_BASETYPE, /* tp_flags */
long_doc, /* tp_doc */
0, /* tp_traverse */