"""This module partially implements a numpy-like dtype class. My intent is to make it easier for people to migrate to NumPy, not to reimplement NumPy, so numarray.dtype only implements a dtype "veneer" which can be used for declaring numerical arrays in a numpy-like style. Only basic usages are supported: numerical arrays simple attributes NOT supported: string and unicode arrays record arrays object arrays byteswapping and alignment info shaped numerical arrays field names >>> import numarray as na >>> import numarray.dtype Most of the numarray factory functions support a dtype parameter. I think this generally works best specified in one of the string forms but dtype instances also work. >>> x = na.arange(10, dtype='int32') >>> x = na.zeros((10,), dtype='=i4') >>> x = na.arange(10, dtype=numarray.dtype.int32) >>> x = na.array([1,2,3], dtype=x.dtype) >>> a = na.zeros((10,), dtype='q') isbuiltin defines a type as having a primitive C implementation. >>> int(a.dtype.isbuiltin) 1 isnative defines a type as being in the native system byte order. >>> int(a.dtype.isnative) 1 dtype's kind character identifies it is boolean, int, unsigned int, float, or complex: >>> a.dtype.kind 'i' dtype's char attribute fully specifies the type in native byte order and alignment. >>> a.dtype.char 'q' dtype's type attribute refers to the native numarray NumericType object. >>> a.dtype.type Int64 dtype's name attribute gives the numpy name for the type/dtype. >>> a.dtype.name 'int64' dtype's itemsize attribute gives the size of the dtype in bytes. >>> a.dtype.itemsize 8 dtype's str attribute gives a terse string specification for the dtype, including byteorder. >> a.dtype.str # byteorder char is non-portable '>> a.dtype.fields dtype's arrdescr is fairly useless in numarray: >> a.dtype.arrdescr [('', ' field array_descr --> [ field+ ] Each field is either a simple type, a tuple naming the field and defining it's type, or a tuple defining a named type which is repeated over a shape: field --> type field --> fieldname, type field --> fieldname, type, shape field --> array_descr 'i2') and ('bar', ' str fieldname --> (fullname, basicname) fullname --> str basicname --> [A-Za-z_]+[A-Za-z_0-9]* # Python identifier type --> endian_char kind bytes endian_char --> > or < or | or = > big endian < little endian | unordered = system byte order type kinds are defined by single character codes as follows: t bitfield b boolean i integer u unsigned integer f float c complex O object S string U unicode V void bytes defines the number of bytes of storage for the type bytes --> [0-9]+ """ import sys import numerictypes as _nt _numpy_descr_chars = "tbiufcOSUV" _endian_specs = { "big": ">", "little": "<", "unordered" : "|" } class dtype(object): """Partial implementation of numpy-like dtype class.""" def __new__(subclass, typestr, name=None, char=None, type=None): assert typestr[1] in _numpy_descr_chars self = object.__new__(subclass) self.arrdescr = [('', typestr)] self.byteorder = typestr[0] self.kind = typestr[1] self.itemsize = int(typestr[2:]) self.name = name self.type = type self.char = char self.fields = None return self def __repr__(self): typestr = self.byteorder + self.kind + str(self.itemsize) return "dtype('" + typestr + "')" def _get_str(self): return self.typestr str = property(_get_str, None, "") def _get_isnative(self): return ((sys.byteorder == "little" and self.byteorder == "<") or (sys.byteorder == "big" and self.byteorder == ">") or (self.byteorder == "|")) isnative = property(_get_isnative, None, "type is in native byte order.") def _get_isbuiltin(self): return self.kind in "biufc" isbuiltin = property(_get_isbuiltin, None, "is a primitive numeric type.") """ def _get_alignment(self): return self.itemsize alignment = property(_get_alignment, None, "buffer address should be a multiple of") def newbyteorder(self): neworder = {">":"<","<":">","|":"|" }[ self.byteorder ] descr = neworder + self.kind + str(self.itemsize) return self.__class__(descr) #, self.name, self.char, self.type) """ _dtypes = {} def get_dtype(d): if isinstance(d, dtype): return d else: return _dtypes[d] def _dtype(spec, name, char, type): order = _endian_specs[sys.byteorder] t = dtype(order+spec, name, char, type) _dtypes[ spec ] = t _dtypes[ "=" + spec ] = t _dtypes[ order + spec ] = t _dtypes[ name ] = t _dtypes[ char ] = t _dtypes[ type ] = t return t bool_ = _dtype("b1", "bool_", "?", _nt.Bool) bool8 = _dtype("b1", "bool8", "?", _nt.Bool) int8 = _dtype("i1", "int8", "b", _nt.Int8) uint8 = _dtype("u1", "uint8", "B", _nt.UInt8) int16 = _dtype("i2", "int16", "h", _nt.Int16) uint16 = _dtype("u2", "uint16", "H", _nt.UInt16) int32 = _dtype("i4", "int32", "i", _nt.Int32) uint32 = _dtype("u4", "uint32", "I", _nt.UInt32) int64 = _dtype("i8", "int64", "q", _nt.Int64) uint64 = _dtype("u8", "uint64", "Q", _nt.UInt64) float32 = _dtype("f4", "float32", "f", _nt.Float32) float64 = _dtype("f8", "float64", "d", _nt.Float64) complex64 = _dtype("c8", "complex64", "F", _nt.Complex32) complex128 = _dtype("c16", "complex128", "D", _nt.Complex64) def test(): import doctest, numarray.dtype return doctest.testmod(numarray.dtype)