[Numpy-svn] r3493 - trunk/numpy/core/src
numpy-svn at scipy.org
numpy-svn at scipy.org
Thu Jan 4 20:30:05 EST 2007
Author: oliphant
Date: 2007-01-04 19:29:57 -0600 (Thu, 04 Jan 2007)
New Revision: 3493
Modified:
trunk/numpy/core/src/scalartypes.inc.src
Log:
Make it so that array scalars can be sub-classed.
Modified: trunk/numpy/core/src/scalartypes.inc.src
===================================================================
--- trunk/numpy/core/src/scalartypes.inc.src 2007-01-03 14:15:17 UTC (rev 3492)
+++ trunk/numpy/core/src/scalartypes.inc.src 2007-01-05 01:29:57 UTC (rev 3493)
@@ -1708,12 +1708,11 @@
#define _WORK(num) \
if (type->tp_bases && (PyTuple_GET_SIZE(type->tp_bases)==2)) { \
PyTypeObject *sup; \
- PyObject *ret; \
/* We are inheriting from a Python type as well so \
give it first dibs on conversion */ \
sup = (PyTypeObject *)PyTuple_GET_ITEM(type->tp_bases, num); \
- ret = sup->tp_new(type, args, kwds); \
- if (ret) return ret; \
+ robj = sup->tp_new(type, args, kwds); \
+ if (robj != NULL) goto finish; \
if (PyTuple_GET_SIZE(args)!=1) return NULL; \
PyErr_Clear(); \
/* now do default conversion */ \
@@ -1723,7 +1722,7 @@
#define _WORKz _WORK(0)
#define _WORK0
-/**begin repeat
+/**begin repeat1
#name=byte, short, int, long, longlong, ubyte, ushort, uint, ulong, ulonglong, float, double, longdouble, cfloat, cdouble, clongdouble, string, unicode, object#
#TYPE=BYTE, SHORT, INT, LONG, LONGLONG, UBYTE, USHORT, UINT, ULONG, ULONGLONG, FLOAT, DOUBLE, LONGDOUBLE, CFLOAT, CDOUBLE, CLONGDOUBLE, STRING, UNICODE, OBJECT#
#work=0,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,z,z,1#
@@ -1733,33 +1732,64 @@
@name at _arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *obj=NULL;
+ PyObject *robj;
PyObject *arr;
- PyArray_Descr *typecode;
+ PyArray_Descr *typecode=NULL;
+ int itemsize;
+ void *dest, *src;
_WORK at work@
if (!PyArg_ParseTuple(args, "|O", &obj)) return NULL;
typecode = PyArray_DescrFromType(PyArray_ at TYPE@);
+ Py_INCREF(typecode);
if (obj == NULL) {
#if @default@ == 0
char *mem;
- PyObject *obj;
mem = malloc(sizeof(@name@));
memset(mem, 0, sizeof(@name@));
- obj = PyArray_Scalar(mem, typecode, NULL);
+ robj = PyArray_Scalar(mem, typecode, NULL);
free(mem);
- return obj;
#elif @default@ == 1
- return PyArray_Scalar(NULL, typecode, NULL);
+ robj = PyArray_Scalar(NULL, typecode, NULL);
#elif @default@ == 2
- PyObject *obj = Py_None;
- return PyArray_Scalar(&obj, typecode, NULL);
+ obj = Py_None;
+ robj = PyArray_Scalar(&obj, typecode, NULL);
#endif
+ goto finish;
}
arr = PyArray_FromAny(obj, typecode, 0, 0, FORCECAST, NULL);
- return PyArray_Return((PyArrayObject *)arr);
+ robj = PyArray_Return((PyArrayObject *)arr);
+
+ finish:
+ if (robj->ob_type == type) return robj;
+ /* Need to allocate new type and copy data-area over */
+ if (type->tp_itemsize) {
+ itemsize = PyString_GET_SIZE(robj);
+ }
+ else itemsize = 0;
+ obj = type->tp_alloc(type, itemsize);
+ if (obj == NULL) {Py_DECREF(robj); return NULL;}
+ if (typecode==NULL)
+ typecode = PyArray_DescrFromType(PyArray_ at TYPE@);
+ dest = scalar_value(obj, typecode);
+ src = scalar_value(robj, typecode);
+ Py_DECREF(typecode);
+#if @default@ == 0
+ *((npy_ at name@ *)dest) = *((npy_ at name@ *)src);
+#elif @default@ == 1
+ if (itemsize == 0) {
+ itemsize = ((PyUnicodeObject *)robj)->length << 2;
+ }
+ memcpy(dest, src, itemsize);
+#elif @default@ == 2
+ memcpy(dest, src, sizeof(void *));
+ Py_INCREF(*((PyObject **)dest));
+#endif
+ Py_DECREF(robj);
+ return obj;
}
/**end repeat**/
@@ -2524,6 +2554,17 @@
return typenum;
}
+static PyArray_Descr *
+_descr_from_subtype(PyObject *type)
+{
+ PyObject *mro;
+ mro = ((PyTypeObject *)type)->tp_mro;
+ if (PyTuple_GET_SIZE(mro) < 2) {
+ return PyArray_DescrFromType(PyArray_OBJECT);
+ }
+ return PyArray_DescrFromTypeObject(PyTuple_GET_ITEM(mro, 1));
+}
+
/*New reference */
/*OBJECT_API
*/
@@ -2563,33 +2604,31 @@
}
/* Otherwise --- type is a sub-type of an array scalar
- currently only VOID allows it -- use it as the type-object.
- This is for non-registered data-type objects.
+ not corresponding to a registered data-type object.
+ */
+
+ /* Do special thing for VOID sub-types
*/
- /* look for a dtypedescr attribute */
- if (!PyType_IsSubtype((PyTypeObject *)type, &PyVoidArrType_Type)) {
- PyErr_SetString(PyExc_TypeError,
- "data type cannot be determined from "
- "type object");
- return NULL;
- }
- new = PyArray_DescrNewFromType(PyArray_VOID);
+ if (PyType_IsSubtype((PyTypeObject *)type, &PyVoidArrType_Type)) {
+ new = PyArray_DescrNewFromType(PyArray_VOID);
- conv = _arraydescr_fromobj(type);
- if (conv) {
- new->fields = conv->fields;
- Py_INCREF(new->fields);
- new->names = conv->names;
- Py_INCREF(new->names);
- new->elsize = conv->elsize;
- new->subarray = conv->subarray;
- conv->subarray = NULL;
- Py_DECREF(conv);
+ conv = _arraydescr_fromobj(type);
+ if (conv) {
+ new->fields = conv->fields;
+ Py_INCREF(new->fields);
+ new->names = conv->names;
+ Py_INCREF(new->names);
+ new->elsize = conv->elsize;
+ new->subarray = conv->subarray;
+ conv->subarray = NULL;
+ Py_DECREF(conv);
+ }
+ Py_XDECREF(new->typeobj);
+ new->typeobj = (PyTypeObject *)type;
+ Py_INCREF(type);
+ return new;
}
- Py_XDECREF(new->typeobj);
- new->typeobj = (PyTypeObject *)type;
- Py_INCREF(type);
- return new;
+ return _descr_from_subtype(type);
}
/*OBJECT_API
More information about the Numpy-svn
mailing list