diff options
author | Guido van Rossum <guido@python.org> | 2001-08-29 15:47:46 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-08-29 15:47:46 (GMT) |
commit | bef1417f9f31fdf0f7b7bdb458c1c1f17c5cfada (patch) | |
tree | 23a3648e6c25e55c0d1b1df836f0a29623b94155 /Objects/floatobject.c | |
parent | e705ef1bced126819d7568b1d4e0ac6944b987e0 (diff) | |
download | cpython-bef1417f9f31fdf0f7b7bdb458c1c1f17c5cfada.zip cpython-bef1417f9f31fdf0f7b7bdb458c1c1f17c5cfada.tar.gz cpython-bef1417f9f31fdf0f7b7bdb458c1c1f17c5cfada.tar.bz2 |
Make int, long and float subclassable.
This uses a slightly wimpy and wasteful approach, but it works. :-)
Diffstat (limited to 'Objects/floatobject.c')
-rw-r--r-- | Objects/floatobject.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 69aede4..295f47e 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -626,13 +626,17 @@ float_float(PyObject *v) } +staticforward PyObject * +float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + static PyObject * float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *x = Py_False; /* Integer zero */ static char *kwlist[] = {"x", 0}; - assert(type == &PyFloat_Type); + if (type != &PyFloat_Type) + return float_subtype_new(type, args, kwds); /* Wimp out */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) return NULL; if (PyString_Check(x)) @@ -640,6 +644,29 @@ float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return PyNumber_Float(x); } +/* 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\ \n\ @@ -708,7 +735,8 @@ PyTypeObject PyFloat_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | + Py_TPFLAGS_BASETYPE, /* tp_flags */ float_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -750,7 +778,7 @@ PyFloat_Fini(void) for (i = 0, p = &list->objects[0]; i < N_FLOATOBJECTS; i++, p++) { - if (PyFloat_Check(p) && p->ob_refcnt != 0) + if (p->ob_type == &PyFloat_Type && p->ob_refcnt != 0) frem++; } next = list->next; @@ -760,7 +788,8 @@ PyFloat_Fini(void) for (i = 0, p = &list->objects[0]; i < N_FLOATOBJECTS; i++, p++) { - if (!PyFloat_Check(p) || p->ob_refcnt == 0) { + if (p->ob_type != &PyFloat_Type || + p->ob_refcnt == 0) { p->ob_type = (struct _typeobject *) free_list; free_list = p; @@ -792,7 +821,8 @@ PyFloat_Fini(void) for (i = 0, p = &list->objects[0]; i < N_FLOATOBJECTS; i++, p++) { - if (PyFloat_Check(p) && p->ob_refcnt != 0) { + if (p->ob_type == &PyFloat_Type && + p->ob_refcnt != 0) { char buf[100]; PyFloat_AsString(buf, p); fprintf(stderr, |