[pypy-commit] pypy kill-multimethod: hg merge remove-remaining-smm

Manuel Jacob noreply at buildbot.pypy.org
Tue Feb 25 19:55:56 CET 2014


Author: Manuel Jacob
Branch: kill-multimethod
Changeset: r69446:99b795fd4044
Date: 2014-02-25 19:50 +0100
http://bitbucket.org/pypy/pypy/changeset/99b795fd4044/

Log:	hg merge remove-remaining-smm

diff too long, truncating to 2000 out of 2465 lines

diff --git a/lib-python/2.7/threading.py b/lib-python/2.7/threading.py
--- a/lib-python/2.7/threading.py
+++ b/lib-python/2.7/threading.py
@@ -246,7 +246,14 @@
             else:
                 # PyPy patch: use _py3k_acquire()
                 if timeout > 0:
-                    gotit = waiter._py3k_acquire(True, timeout)
+                    try:
+                        gotit = waiter._py3k_acquire(True, timeout)
+                    except OverflowError:
+                        # bah, in Python 3, acquire(True, timeout) raises
+                        # OverflowError if the timeout is too huge.  For
+                        # forward-compatibility reasons we do the same.
+                        waiter.acquire()
+                        gotit = True
                 else:
                     gotit = waiter.acquire(False)
                 if not gotit:
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -826,10 +826,9 @@
 
 
 class AppTestKeywordsToBuiltinSanity(object):
-
     def test_type(self):
         class X(object):
-            def __init__(self, **kw):
+            def __init__(myself, **kw):
                 pass
         clash = type.__call__.func_code.co_varnames[0]
 
@@ -845,7 +844,6 @@
         X(**{clash: 33})
         object.__new__(X, **{clash: 33})
 
-
     def test_dict_new(self):
         clash = dict.__new__.func_code.co_varnames[0]
 
@@ -865,4 +863,3 @@
 
         d.update(**{clash: 33})
         dict.update(d, **{clash: 33})
-
diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -14,6 +14,8 @@
     _immutable_fields_ = ['size?', 'name', 'name_position']
     # note that 'size' is not strictly immutable, because it can change
     # from -1 to the real value in the W_CTypeStruct subclass.
+    # XXX this could be improved with an elidable method get_size()
+    # that raises in case it's still -1...
 
     cast_anything = False
     is_primitive_integer = False
diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py
--- a/pypy/module/_lsprof/interp_lsprof.py
+++ b/pypy/module/_lsprof/interp_lsprof.py
@@ -159,7 +159,7 @@
                 subentry = ProfilerSubEntry(entry.frame)
                 self.calls[entry] = subentry
                 return subentry
-            return None
+            raise
 
 class ProfilerContext(object):
     def __init__(self, profobj, entry):
@@ -181,8 +181,11 @@
         entry._stop(tt, it)
         if profobj.subcalls and self.previous:
             caller = jit.promote(self.previous.entry)
-            subentry = caller._get_or_make_subentry(entry, False)
-            if subentry is not None:
+            try:
+                subentry = caller._get_or_make_subentry(entry, False)
+            except KeyError:
+                pass
+            else:
                 subentry._stop(tt, it)
 
 
@@ -308,7 +311,7 @@
                 entry = ProfilerEntry(f_code)
                 self.data[f_code] = entry
                 return entry
-            return None
+            raise
 
     @jit.elidable
     def _get_or_make_builtin_entry(self, key, make=True):
@@ -319,7 +322,7 @@
                 entry = ProfilerEntry(self.space.wrap(key))
                 self.builtin_data[key] = entry
                 return entry
-            return None
+            raise
 
     def _enter_call(self, f_code):
         # we have a superb gc, no point in freelist :)
@@ -332,8 +335,11 @@
         if context is None:
             return
         self = jit.promote(self)
-        entry = self._get_or_make_entry(f_code, False)
-        if entry is not None:
+        try:
+            entry = self._get_or_make_entry(f_code, False)
+        except KeyError:
+            pass
+        else:
             context._stop(self, entry)
         self.current_context = context.previous
 
@@ -347,8 +353,11 @@
         if context is None:
             return
         self = jit.promote(self)
-        entry = self._get_or_make_builtin_entry(key, False)
-        if entry is not None:
+        try:
+            entry = self._get_or_make_builtin_entry(key, False)
+        except KeyError:
+            pass
+        else:
             context._stop(self, entry)
         self.current_context = context.previous
 
diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py
--- a/pypy/module/cpyext/ndarrayobject.py
+++ b/pypy/module/cpyext/ndarrayobject.py
@@ -94,12 +94,12 @@
 @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
 def _PyArray_ITEMSIZE(space, w_array):
     assert isinstance(w_array, W_NDimArray)
-    return w_array.get_dtype().get_size()
+    return w_array.get_dtype().elsize
 
 @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
 def _PyArray_NBYTES(space, w_array):
     assert isinstance(w_array, W_NDimArray)
-    return w_array.get_size() * w_array.get_dtype().get_size()
+    return w_array.get_size() * w_array.get_dtype().elsize
 
 @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
 def _PyArray_TYPE(space, w_array):
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -55,7 +55,7 @@
         loop.setslice(space, shape, self, impl)
 
     def get_size(self):
-        return self.size // self.dtype.get_size()
+        return self.size // self.dtype.elsize
 
     def get_storage_size(self):
         return self.size
@@ -89,7 +89,7 @@
     def get_real(self, space, orig_array):
         strides = self.get_strides()
         backstrides = self.get_backstrides()
-        if self.dtype.is_complex_type():
+        if self.dtype.is_complex():
             dtype = self.dtype.get_float_dtype(space)
             return SliceArray(self.start, strides, backstrides,
                           self.get_shape(), self, orig_array, dtype=dtype)
@@ -103,13 +103,13 @@
     def get_imag(self, space, orig_array):
         strides = self.get_strides()
         backstrides = self.get_backstrides()
-        if self.dtype.is_complex_type():
+        if self.dtype.is_complex():
             dtype = self.dtype.get_float_dtype(space)
-            return SliceArray(self.start + dtype.get_size(), strides,
+            return SliceArray(self.start + dtype.elsize, strides,
                     backstrides, self.get_shape(), self, orig_array, dtype=dtype)
         impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides,
                              backstrides)
-        if not self.dtype.is_flexible_type():
+        if not self.dtype.is_flexible():
             impl.fill(space, self.dtype.box(0))
         return impl
 
@@ -204,7 +204,7 @@
         if space.isinstance_w(w_idx, space.w_str):
             idx = space.str_w(w_idx)
             dtype = self.dtype
-            if not dtype.is_record_type() or idx not in dtype.fields:
+            if not dtype.is_record() or idx not in dtype.fields:
                 raise OperationError(space.w_ValueError, space.wrap(
                     "field named %s not found" % idx))
             return RecordChunk(idx)
@@ -324,7 +324,7 @@
         make_sure_not_resized(strides)
         make_sure_not_resized(backstrides)
         self.shape = shape
-        self.size = support.product(shape) * dtype.get_size()
+        self.size = support.product(shape) * dtype.elsize
         self.order = order
         self.dtype = dtype
         self.strides = strides
@@ -352,7 +352,7 @@
                                          self.get_shape())
 
     def fill(self, space, box):
-        self.dtype.itemtype.fill(self.storage, self.dtype.get_size(),
+        self.dtype.itemtype.fill(self.storage, self.dtype.elsize,
                                  box, 0, self.size, 0)
 
     def set_shape(self, space, orig_array, new_shape):
@@ -425,7 +425,7 @@
         self.storage = parent.storage
         self.order = parent.order
         self.dtype = dtype
-        self.size = support.product(shape) * self.dtype.get_size()
+        self.size = support.product(shape) * self.dtype.elsize
         self.start = start
         self.orig_arr = orig_arr
 
@@ -460,12 +460,12 @@
             strides = []
             backstrides = []
             dtype = self.dtype
-            s = self.get_strides()[0] // dtype.get_size()
+            s = self.get_strides()[0] // dtype.elsize
             if self.order == 'C':
                 new_shape.reverse()
             for sh in new_shape:
-                strides.append(s * dtype.get_size())
-                backstrides.append(s * (sh - 1) * dtype.get_size())
+                strides.append(s * dtype.elsize)
+                backstrides.append(s * (sh - 1) * dtype.elsize)
                 s *= max(1, sh)
             if self.order == 'C':
                 strides.reverse()
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -70,7 +70,7 @@
         scalar = Scalar(dtype)
         if dtype.is_str_or_unicode():
             scalar.value = dtype.coerce(space, space.wrap(self.value.raw_str()))
-        elif dtype.is_record_type():
+        elif dtype.is_record():
             raise OperationError(space.w_NotImplementedError, space.wrap(
                 "viewing scalar as record not implemented"))
         else:
@@ -78,7 +78,7 @@
         return scalar
 
     def get_real(self, space, orig_array):
-        if self.dtype.is_complex_type():
+        if self.dtype.is_complex():
             scalar = Scalar(self.dtype.get_float_dtype(space))
             scalar.value = self.value.convert_real_to(scalar.dtype)
             return scalar
@@ -91,7 +91,7 @@
                 "could not broadcast input array from shape " +
                 "(%s) into shape ()" % (
                     ','.join([str(x) for x in w_arr.get_shape()],))))
-        if self.dtype.is_complex_type():
+        if self.dtype.is_complex():
             dtype = self.dtype.get_float_dtype(space)
             self.value = self.dtype.itemtype.composite(
                                w_arr.get_scalar_value().convert_to(space, dtype),
@@ -100,7 +100,7 @@
             self.value = w_arr.get_scalar_value()
 
     def get_imag(self, space, orig_array):
-        if self.dtype.is_complex_type():
+        if self.dtype.is_complex():
             scalar = Scalar(self.dtype.get_float_dtype(space))
             scalar.value = self.value.convert_imag_to(scalar.dtype)
             return scalar
@@ -110,7 +110,7 @@
 
     def set_imag(self, space, orig_array, w_val):
         #Only called on complex dtype
-        assert self.dtype.is_complex_type()
+        assert self.dtype.is_complex()
         w_arr = convert_to_array(space, w_val)
         if len(w_arr.get_shape()) > 0:
             raise OperationError(space.w_ValueError, space.wrap(
@@ -127,7 +127,7 @@
             if space.len_w(w_idx) == 0:
                 return self.get_scalar_value()
         elif space.isinstance_w(w_idx, space.w_str):
-            if self.dtype.is_record_type():
+            if self.dtype.is_record():
                 w_val = self.value.descr_getitem(space, w_idx)
                 return convert_to_array(space, w_val)
         elif space.is_none(w_idx):
@@ -148,7 +148,7 @@
             if space.len_w(w_idx) == 0:
                 return self.set_scalar_value(self.dtype.coerce(space, w_val))
         elif space.isinstance_w(w_idx, space.w_str):
-            if self.dtype.is_record_type():
+            if self.dtype.is_record():
                 return self.value.descr_setitem(space, w_idx, w_val)
         raise OperationError(space.w_IndexError,
                              space.wrap("0-d arrays can't be indexed"))
diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py
--- a/pypy/module/micronumpy/arrayimpl/sort.py
+++ b/pypy/module/micronumpy/arrayimpl/sort.py
@@ -71,10 +71,10 @@
         def __init__(self, index_stride_size, stride_size, size):
             start = 0
             dtype = interp_dtype.get_dtype_cache(space).w_longdtype
-            indexes = dtype.itemtype.malloc(size*dtype.get_size())
+            indexes = dtype.itemtype.malloc(size * dtype.elsize)
             values = alloc_raw_storage(size * stride_size,
                                             track_allocation=False)
-            Repr.__init__(self, dtype.get_size(), stride_size,
+            Repr.__init__(self, dtype.elsize, stride_size,
                           size, values, indexes, start, start)
 
         def __del__(self):
diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py
--- a/pypy/module/micronumpy/interp_arrayops.py
+++ b/pypy/module/micronumpy/interp_arrayops.py
@@ -137,14 +137,14 @@
                     "all the input array dimensions except for the "
                     "concatenation axis must match exactly"))
         a_dt = arr.get_dtype()
-        if dtype.is_record_type() and a_dt.is_record_type():
+        if dtype.is_record() and a_dt.is_record():
             # Record types must match
             for f in dtype.fields:
                 if f not in a_dt.fields or \
                              dtype.fields[f] != a_dt.fields[f]:
                     raise OperationError(space.w_TypeError,
                                space.wrap("invalid type promotion"))
-        elif dtype.is_record_type() or a_dt.is_record_type():
+        elif dtype.is_record() or a_dt.is_record():
             raise OperationError(space.w_TypeError,
                         space.wrap("invalid type promotion"))
         dtype = interp_ufuncs.find_binop_result_dtype(space, dtype,
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -16,7 +16,7 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rlib.rstring import StringBuilder
-from rpython.rlib import jit
+from rpython.rlib.objectmodel import specialize
 from pypy.module.micronumpy import constants as NPY
 
 
@@ -33,13 +33,13 @@
 long_double_size = 8
 
 
-def new_dtype_getter(name):
-    @jit.elidable
+def new_dtype_getter(num):
+    @specialize.memo()
     def _get_dtype(space):
         from pypy.module.micronumpy.interp_dtype import get_dtype_cache
-        return get_dtype_cache(space).dtypes_by_name[name]
+        return get_dtype_cache(space).dtypes_by_num[num]
 
-    def new(space, w_subtype, w_value=None):
+    def descr__new__(space, w_subtype, w_value=None):
         from pypy.module.micronumpy.interp_numarray import array
         dtype = _get_dtype(space)
         if not space.is_none(w_value):
@@ -52,7 +52,9 @@
     def descr_reduce(self, space):
         return self.reduce(space)
 
-    return func_with_new_name(new, name + "_box_new"), staticmethod(_get_dtype), func_with_new_name(descr_reduce, "descr_reduce")
+    return (func_with_new_name(descr__new__, 'descr__new__%d' % num),
+            staticmethod(_get_dtype),
+            descr_reduce)
 
 
 class Box(object):
@@ -303,15 +305,15 @@
         else:
             dtype = space.interp_w(W_Dtype,
                 space.call_function(space.gettypefor(W_Dtype), w_dtype))
-            if dtype.get_size() == 0:
+            if dtype.elsize == 0:
                 raise OperationError(space.w_TypeError, space.wrap(
                     "data-type must not be 0-sized"))
-            if dtype.get_size() != self.get_dtype(space).get_size():
+            if dtype.elsize != self.get_dtype(space).elsize:
                 raise OperationError(space.w_ValueError, space.wrap(
                     "new type not compatible with array."))
         if dtype.is_str_or_unicode():
             return dtype.coerce(space, space.wrap(self.raw_str()))
-        elif dtype.is_record_type():
+        elif dtype.is_record():
             raise OperationError(space.w_NotImplementedError, space.wrap(
                 "viewing scalar as record not implemented"))
         else:
@@ -327,7 +329,7 @@
         return space.wrap(1)
 
     def descr_get_itemsize(self, space):
-        return self.get_dtype(space).descr_get_itemsize(space)
+        return space.wrap(self.get_dtype(space).elsize)
 
     def descr_get_shape(self, space):
         return space.newtuple([])
@@ -352,6 +354,12 @@
         w_meth = space.getattr(self.descr_ravel(space), space.wrap('reshape'))
         return space.call_args(w_meth, __args__)
 
+    def descr_get_real(self, space):
+        return self.get_dtype(space).itemtype.real(self)
+
+    def descr_get_imag(self, space):
+        return self.get_dtype(space).itemtype.imag(self)
+
     w_flags = None
     def descr_get_flags(self, space):
         if self.w_flags is None:
@@ -359,7 +367,7 @@
         return self.w_flags
 
 class W_BoolBox(W_GenericBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("bool")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.BOOL)
 
 class W_NumberBox(W_GenericBox):
     pass
@@ -375,34 +383,34 @@
     pass
 
 class W_Int8Box(W_SignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("int8")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.BYTE)
 
 class W_UInt8Box(W_UnsignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("uint8")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.UBYTE)
 
 class W_Int16Box(W_SignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("int16")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.SHORT)
 
 class W_UInt16Box(W_UnsignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("uint16")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.USHORT)
 
 class W_Int32Box(W_SignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("i")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.INT)
 
 class W_UInt32Box(W_UnsignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("I")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.UINT)
+
+class W_LongBox(W_SignedIntegerBox, PrimitiveBox):
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.LONG)
+
+class W_ULongBox(W_UnsignedIntegerBox, PrimitiveBox):
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.ULONG)
 
 class W_Int64Box(W_SignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("q")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.LONGLONG)
 
 class W_UInt64Box(W_UnsignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("Q")
-
-class W_LongBox(W_SignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("l")
-
-class W_ULongBox(W_UnsignedIntegerBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("L")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.ULONGLONG)
 
 class W_InexactBox(W_NumberBox):
     pass
@@ -411,45 +419,32 @@
     pass
 
 class W_Float16Box(W_FloatingBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("float16")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.HALF)
 
 class W_Float32Box(W_FloatingBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("float32")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.FLOAT)
 
 class W_Float64Box(W_FloatingBox, PrimitiveBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("float64")
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.DOUBLE)
 
     def descr_as_integer_ratio(self, space):
         return space.call_method(self.item(space), 'as_integer_ratio')
 
 class W_ComplexFloatingBox(W_InexactBox):
-    def descr_get_real(self, space):
-        dtype = self._COMPONENTS_BOX._get_dtype(space)
-        box = self.convert_real_to(dtype)
-        assert isinstance(box, self._COMPONENTS_BOX)
-        return space.wrap(box)
-
-    def descr_get_imag(self, space):
-        dtype = self._COMPONENTS_BOX._get_dtype(space)
-        box = self.convert_imag_to(dtype)
-        assert isinstance(box, self._COMPONENTS_BOX)
-        return space.wrap(box)
+    pass
 
 class W_Complex64Box(ComplexBox, W_ComplexFloatingBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex64")
-    _COMPONENTS_BOX = W_Float32Box
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.CFLOAT)
 
 class W_Complex128Box(ComplexBox, W_ComplexFloatingBox):
-    descr__new__, _get_dtype, descr_reduce = new_dtype_getter("complex128")
-    _COMPONENTS_BOX = W_Float64Box
+    descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.CDOUBLE)
 
 if long_double_size in (8, 12, 16):
     class W_FloatLongBox(W_FloatingBox, PrimitiveBox):
-        descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.LONGDOUBLELTR)
+        descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.LONGDOUBLE)
 
     class W_ComplexLongBox(ComplexBox, W_ComplexFloatingBox):
-        descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.CLONGDOUBLELTR)
-        _COMPONENTS_BOX = W_FloatLongBox
+        descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.CLONGDOUBLE)
 
 class W_FlexibleBox(W_GenericBox):
     _attrs_ = ['arr', 'ofs', 'dtype']
@@ -635,6 +630,8 @@
     strides = GetSetProperty(W_GenericBox.descr_get_shape),
     ndim = GetSetProperty(W_GenericBox.descr_get_ndim),
     T = GetSetProperty(W_GenericBox.descr_self),
+    real = GetSetProperty(W_GenericBox.descr_get_real),
+    imag = GetSetProperty(W_GenericBox.descr_get_imag),
     flags = GetSetProperty(W_GenericBox.descr_get_flags),
 )
 
@@ -768,16 +765,12 @@
     __new__ = interp2app(W_Complex64Box.descr__new__.im_func),
     __reduce__ = interp2app(W_Complex64Box.descr_reduce),
     __complex__ = interp2app(W_GenericBox.item),
-    real = GetSetProperty(W_ComplexFloatingBox.descr_get_real),
-    imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag),
 )
 
 W_Complex128Box.typedef = TypeDef("complex128", (W_ComplexFloatingBox.typedef, W_ComplexObject.typedef),
     __module__ = "numpy",
     __new__ = interp2app(W_Complex128Box.descr__new__.im_func),
     __reduce__ = interp2app(W_Complex128Box.descr_reduce),
-    real = GetSetProperty(W_ComplexFloatingBox.descr_get_real),
-    imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag),
 )
 
 if long_double_size in (8, 12, 16):
@@ -792,8 +785,6 @@
         __new__ = interp2app(W_ComplexLongBox.descr__new__.im_func),
         __reduce__ = interp2app(W_ComplexLongBox.descr_reduce),
         __complex__ = interp2app(W_GenericBox.item),
-        real = GetSetProperty(W_ComplexFloatingBox.descr_get_real),
-        imag = GetSetProperty(W_ComplexFloatingBox.descr_get_imag),
     )
 
 W_FlexibleBox.typedef = TypeDef("flexible", W_GenericBox.typedef,
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -6,7 +6,7 @@
                                       interp_attrproperty, interp_attrproperty_w)
 from pypy.module.micronumpy import types, interp_boxes, base
 from rpython.rlib.objectmodel import specialize
-from rpython.rlib.rarithmetic import LONG_BIT, r_longlong, r_ulonglong
+from rpython.rlib.rarithmetic import r_longlong, r_ulonglong
 from rpython.rlib import jit
 from pypy.module.micronumpy.appbridge import get_appbridge_cache
 from pypy.module.micronumpy.conversion_utils import byteorder_converter
@@ -38,22 +38,19 @@
 
 class W_Dtype(W_Root):
     _immutable_fields_ = [
-        "num", "kind", "char", "w_box_type", "float_type",
-        "itemtype?", "byteorder?", "names?", "fields?", "size?",
+        "itemtype?", "num", "kind", "char", "w_box_type",
+        "byteorder?", "names?", "fields?", "elsize?", "alignment?",
         "shape?", "subdtype?", "base?",
-        "alternate_constructors", "aliases",
     ]
 
     def __init__(self, itemtype, num, kind, char, w_box_type,
-                 float_type=None, byteorder=None, names=[], fields={},
-                 size=1, shape=[], subdtype=None,
-                 alternate_constructors=[], aliases=[]):
+                 byteorder=None, names=[], fields={},
+                 elsize=None, shape=[], subdtype=None):
         self.itemtype = itemtype
         self.num = num
         self.kind = kind
         self.char = char
         self.w_box_type = w_box_type
-        self.float_type = float_type
         if byteorder is None:
             if itemtype.get_element_size() == 1:
                 byteorder = NPY.IGNORE
@@ -62,15 +59,16 @@
         self.byteorder = byteorder
         self.names = names
         self.fields = fields
-        self.size = size
+        if elsize is None:
+            elsize = itemtype.get_element_size()
+        self.elsize = elsize
+        self.alignment = itemtype.alignment
         self.shape = shape
         self.subdtype = subdtype
         if not subdtype:
             self.base = self
         else:
             self.base = subdtype.base
-        self.alternate_constructors = alternate_constructors
-        self.aliases = aliases
 
     def __repr__(self):
         if self.fields is not None:
@@ -85,100 +83,51 @@
     def box_complex(self, real, imag):
         return self.itemtype.box_complex(real, imag)
 
-    def build_and_convert(self, space, box):
-        return self.itemtype.build_and_convert(space, self, box)
-
     def coerce(self, space, w_item):
         return self.itemtype.coerce(space, self, w_item)
 
-    def is_int_type(self):
-        return (self.kind == NPY.SIGNEDLTR or self.kind == NPY.UNSIGNEDLTR or
-                self.kind == NPY.GENBOOLLTR)
+    def is_bool(self):
+        return self.kind == NPY.GENBOOLLTR
 
     def is_signed(self):
         return self.kind == NPY.SIGNEDLTR
 
-    def is_complex_type(self):
+    def is_unsigned(self):
+        return self.kind == NPY.UNSIGNEDLTR
+
+    def is_int(self):
+        return (self.kind == NPY.SIGNEDLTR or self.kind == NPY.UNSIGNEDLTR or
+                self.kind == NPY.GENBOOLLTR)
+
+    def is_float(self):
+        return self.kind == NPY.FLOATINGLTR
+
+    def is_complex(self):
         return self.kind == NPY.COMPLEXLTR
 
-    def is_float_type(self):
-        return self.kind == NPY.FLOATINGLTR or self.kind == NPY.COMPLEXLTR
-
-    def is_bool_type(self):
-        return self.kind == NPY.GENBOOLLTR
-
-    def is_record_type(self):
-        return bool(self.fields)
-
-    def is_str_type(self):
+    def is_str(self):
         return self.num == NPY.STRING
 
     def is_str_or_unicode(self):
         return self.num == NPY.STRING or self.num == NPY.UNICODE
 
-    def is_flexible_type(self):
+    def is_flexible(self):
         return self.is_str_or_unicode() or self.num == NPY.VOID
 
+    def is_record(self):
+        return bool(self.fields)
+
     def is_native(self):
         return self.byteorder in (NPY.NATIVE, NPY.NATBYTE)
 
-    def get_size(self):
-        return self.size * self.itemtype.get_element_size()
-
     def get_float_dtype(self, space):
-        assert self.kind == NPY.COMPLEXLTR
-        assert self.float_type is not None
-        dtype = get_dtype_cache(space).dtypes_by_name[self.float_type]
+        assert self.is_complex()
+        dtype = get_dtype_cache(space).component_dtypes[self.num]
         if self.byteorder == NPY.OPPBYTE:
             dtype = dtype.descr_newbyteorder(space)
+        assert dtype.is_float()
         return dtype
 
-    def descr_str(self, space):
-        if self.fields:
-            return space.str(self.descr_get_descr(space))
-        elif self.subdtype is not None:
-            return space.str(space.newtuple([
-                self.subdtype.descr_get_str(space),
-                self.descr_get_shape(space)]))
-        else:
-            if self.is_flexible_type():
-                return self.descr_get_str(space)
-            else:
-                return self.descr_get_name(space)
-
-    def descr_repr(self, space):
-        if self.fields:
-            r = self.descr_get_descr(space)
-        elif self.subdtype is not None:
-            r = space.newtuple([self.subdtype.descr_get_str(space),
-                                self.descr_get_shape(space)])
-        else:
-            if self.is_flexible_type():
-                if self.byteorder != NPY.IGNORE:
-                    byteorder = NPY.NATBYTE if self.is_native() else NPY.OPPBYTE
-                else:
-                    byteorder = ''
-                r = space.wrap(byteorder + self.char + str(self.size))
-            else:
-                r = self.descr_get_name(space)
-        return space.wrap("dtype(%s)" % space.str_w(space.repr(r)))
-
-    def descr_get_itemsize(self, space):
-        return space.wrap(self.get_size())
-
-    def descr_get_alignment(self, space):
-        return space.wrap(self.itemtype.alignment)
-
-    def descr_get_isbuiltin(self, space):
-        if self.fields is None:
-            return space.wrap(1)
-        return space.wrap(0)
-
-    def descr_get_subdtype(self, space):
-        if self.subdtype is None:
-            return space.w_None
-        return space.newtuple([space.wrap(self.subdtype), self.descr_get_shape(space)])
-
     def get_name(self):
         return self.w_box_type.name
 
@@ -186,26 +135,22 @@
         name = self.get_name()
         if name[-1] == '_':
             name = name[:-1]
-        if self.is_flexible_type():
-            return space.wrap(name + str(self.get_size() * 8))
+        if self.is_flexible() and self.elsize != 0:
+            return space.wrap(name + str(self.elsize * 8))
         return space.wrap(name)
 
     def descr_get_str(self, space):
-        size = self.get_size()
         basic = self.kind
-        if basic == NPY.UNICODELTR:
+        endian = self.byteorder
+        size = self.elsize
+        if endian == NPY.NATIVE:
+            endian = NPY.NATBYTE
+        if self.num == NPY.UNICODE:
             size >>= 2
-            endian = NPY.NATBYTE
-        elif size // (self.size or 1) <= 1:
-            endian = NPY.IGNORE
-        else:
-            endian = self.byteorder
-            if endian == NPY.NATIVE:
-                endian = NPY.NATBYTE
         return space.wrap("%s%s%s" % (endian, basic, size))
 
     def descr_get_descr(self, space):
-        if not self.is_record_type():
+        if not self.is_record():
             return space.newlist([space.newtuple([space.wrap(""),
                                                   self.descr_get_str(space)])])
         else:
@@ -213,7 +158,7 @@
             for name in self.names:
                 subdtype = self.fields[name][1]
                 subdescr = [space.wrap(name)]
-                if subdtype.is_record_type():
+                if subdtype.is_record():
                     subdescr.append(subdtype.descr_get_descr(space))
                 elif subdtype.subdtype is not None:
                     subdescr.append(subdtype.subdtype.descr_get_str(space))
@@ -224,38 +169,37 @@
                 descr.append(space.newtuple(subdescr[:]))
             return space.newlist(descr)
 
-    def descr_get_base(self, space):
-        return space.wrap(self.base)
+    def descr_get_hasobject(self, space):
+        return space.w_False
+
+    def descr_get_isbuiltin(self, space):
+        if self.fields is None:
+            return space.wrap(1)
+        return space.wrap(0)
 
     def descr_get_isnative(self, space):
         return space.wrap(self.is_native())
 
+    def descr_get_base(self, space):
+        return space.wrap(self.base)
+
+    def descr_get_subdtype(self, space):
+        if self.subdtype is None:
+            return space.w_None
+        return space.newtuple([space.wrap(self.subdtype),
+                               self.descr_get_shape(space)])
+
     def descr_get_shape(self, space):
-        w_shape = [space.wrap(dim) for dim in self.shape]
-        return space.newtuple(w_shape)
-
-    def eq(self, space, w_other):
-        w_other = space.call_function(space.gettypefor(W_Dtype), w_other)
-        if space.is_w(self, w_other):
-            return True
-        if isinstance(w_other, W_Dtype):
-            return space.eq_w(self.descr_reduce(space), w_other.descr_reduce(space))
-        return False
-
-    def descr_eq(self, space, w_other):
-        return space.wrap(self.eq(space, w_other))
-
-    def descr_ne(self, space, w_other):
-        return space.wrap(not self.eq(space, w_other))
+        return space.newtuple([space.wrap(dim) for dim in self.shape])
 
     def descr_get_fields(self, space):
         if not self.fields:
             return space.w_None
-        w_d = space.newdict()
+        w_fields = space.newdict()
         for name, (offset, subdtype) in self.fields.iteritems():
-            space.setitem(w_d, space.wrap(name),
+            space.setitem(w_fields, space.wrap(name),
                           space.newtuple([subdtype, space.wrap(offset)]))
-        return w_d
+        return w_fields
 
     def descr_get_names(self, space):
         if not self.fields:
@@ -290,8 +234,56 @@
         raise OperationError(space.w_AttributeError, space.wrap(
             "Cannot delete dtype names attribute"))
 
-    def descr_get_hasobject(self, space):
-        return space.w_False
+    def eq(self, space, w_other):
+        w_other = space.call_function(space.gettypefor(W_Dtype), w_other)
+        if space.is_w(self, w_other):
+            return True
+        if isinstance(w_other, W_Dtype):
+            return space.eq_w(self.descr_reduce(space),
+                              w_other.descr_reduce(space))
+        return False
+
+    def descr_eq(self, space, w_other):
+        return space.wrap(self.eq(space, w_other))
+
+    def descr_ne(self, space, w_other):
+        return space.wrap(not self.eq(space, w_other))
+
+    def descr_hash(self, space):
+        return space.hash(self.descr_reduce(space))
+
+    def descr_str(self, space):
+        if self.fields:
+            return space.str(self.descr_get_descr(space))
+        elif self.subdtype is not None:
+            return space.str(space.newtuple([
+                self.subdtype.descr_get_str(space),
+                self.descr_get_shape(space)]))
+        else:
+            if self.is_flexible():
+                return self.descr_get_str(space)
+            else:
+                return self.descr_get_name(space)
+
+    def descr_repr(self, space):
+        if self.fields:
+            r = self.descr_get_descr(space)
+        elif self.subdtype is not None:
+            r = space.newtuple([self.subdtype.descr_get_str(space),
+                                self.descr_get_shape(space)])
+        else:
+            if self.is_flexible():
+                if self.byteorder != NPY.IGNORE:
+                    byteorder = NPY.NATBYTE if self.is_native() else NPY.OPPBYTE
+                else:
+                    byteorder = ''
+                size = self.elsize
+                if self.num == NPY.UNICODE:
+                    size >>= 2
+                r = space.wrap(byteorder + self.char + str(size))
+            else:
+                r = self.descr_get_name(space)
+        return space.wrap("dtype(%s)" % space.str_w(space.repr(r)))
 
     def descr_getitem(self, space, w_item):
         if not self.fields:
@@ -320,41 +312,29 @@
             return space.wrap(0)
         return space.wrap(len(self.fields))
 
-    def descr_hash(self, space):
-        return space.hash(self.descr_reduce(space))
-
     def descr_reduce(self, space):
         w_class = space.type(self)
-
-        kind = self.kind
-        elemsize = self.get_size()
-        builder_args = space.newtuple([space.wrap("%s%d" % (kind, elemsize)), space.wrap(0), space.wrap(1)])
+        builder_args = space.newtuple([
+            space.wrap("%s%d" % (self.kind, self.elsize)),
+            space.wrap(0), space.wrap(1)])
 
         version = space.wrap(3)
+        endian = self.byteorder
+        if endian == NPY.NATIVE:
+            endian = NPY.NATBYTE
+        subdescr = self.descr_get_subdtype(space)
         names = self.descr_get_names(space)
         values = self.descr_get_fields(space)
-        if self.fields:
-            endian = NPY.IGNORE
-            #TODO: Implement this when subarrays are implemented
-            subdescr = space.w_None
-            size = 0
-            for key in self.fields:
-                dtype = self.fields[key][1]
-                assert isinstance(dtype, W_Dtype)
-                size += dtype.get_size()
-            w_size = space.wrap(size)
-            #TODO: Change this when alignment is implemented
-            alignment = space.wrap(1)
+        if self.is_flexible():
+            w_size = space.wrap(self.elsize)
+            alignment = space.wrap(self.alignment)
         else:
-            endian = self.byteorder
-            if endian == NPY.NATIVE:
-                endian = NPY.NATBYTE
-            subdescr = space.w_None
             w_size = space.wrap(-1)
             alignment = space.wrap(-1)
         flags = space.wrap(0)
 
-        data = space.newtuple([version, space.wrap(endian), subdescr, names, values, w_size, alignment, flags])
+        data = space.newtuple([version, space.wrap(endian), subdescr,
+                               names, values, w_size, alignment, flags])
         return space.newtuple([w_class, builder_args, data])
 
     def descr_setstate(self, space, w_data):
@@ -375,6 +355,7 @@
         w_names = space.getitem(w_data, space.wrap(3))
         w_fields = space.getitem(w_data, space.wrap(4))
         size = space.int_w(space.getitem(w_data, space.wrap(5)))
+        alignment = space.int_w(space.getitem(w_data, space.wrap(6)))
 
         if (w_names == space.w_None) != (w_fields == space.w_None):
             raise oefmt(space.w_ValueError, "inconsistent fields and names")
@@ -413,8 +394,9 @@
                 self.fields[name] = offset, dtype
             self.itemtype = types.RecordType()
 
-        if self.is_flexible_type():
-            self.size = size
+        if self.is_flexible():
+            self.elsize = size
+            self.alignment = alignment
 
     @unwrap_spec(new_order=str)
     def descr_newbyteorder(self, space, new_order=NPY.SWAP):
@@ -426,9 +408,13 @@
             elif newendian != NPY.IGNORE:
                 endian = newendian
         itemtype = self.itemtype.__class__(endian in (NPY.NATIVE, NPY.NATBYTE))
+        fields = self.fields
+        if fields is None:
+            fields = {}
         return W_Dtype(itemtype, self.num, self.kind, self.char,
-                       self.w_box_type, self.float_type, byteorder=endian,
-                       size=self.size)
+                       self.w_box_type, byteorder=endian, elsize=self.elsize,
+                       names=self.names, fields=fields,
+                       shape=self.shape, subdtype=self.subdtype)
 
 
 @specialize.arg(2)
@@ -458,11 +444,11 @@
                 raise oefmt(space.w_ValueError, "two fields with the same name")
         assert isinstance(subdtype, W_Dtype)
         fields[fldname] = (offset, subdtype)
-        offset += subdtype.get_size()
+        offset += subdtype.elsize
         names.append(fldname)
     return W_Dtype(types.RecordType(), NPY.VOID, NPY.VOIDLTR, NPY.VOIDLTR,
                    space.gettypefor(interp_boxes.W_VoidBox),
-                   names=names, fields=fields, size=offset)
+                   names=names, fields=fields, elsize=offset)
 
 
 def dtype_from_dict(space, w_dict):
@@ -501,10 +487,10 @@
             size *= dim
         if size == 1:
             return subdtype
-        size *= subdtype.get_size()
+        size *= subdtype.elsize
         return W_Dtype(types.VoidType(), NPY.VOID, NPY.VOIDLTR, NPY.VOIDLTR,
                        space.gettypefor(interp_boxes.W_VoidBox),
-                       shape=shape, subdtype=subdtype, size=size)
+                       shape=shape, subdtype=subdtype, elsize=size)
 
     if space.is_none(w_dtype):
         return cache.w_float64dtype
@@ -533,58 +519,59 @@
         w_dtype1 = space.getitem(w_dtype, space.wrap(1))
         subdtype = descr__new__(space, w_subtype, w_dtype0, w_align, w_copy)
         assert isinstance(subdtype, W_Dtype)
-        if subdtype.get_size() == 0:
+        if subdtype.elsize == 0:
             name = "%s%d" % (subdtype.kind, space.int_w(w_dtype1))
             return descr__new__(space, w_subtype, space.wrap(name), w_align, w_copy)
         return descr__new__(space, w_subtype, w_dtype0, w_align, w_copy, w_shape=w_dtype1)
     elif space.isinstance_w(w_dtype, space.w_dict):
         return dtype_from_dict(space, w_dtype)
     for dtype in cache.builtin_dtypes:
-        if w_dtype in dtype.alternate_constructors:
+        if dtype.num in cache.alternate_constructors and \
+                w_dtype in cache.alternate_constructors[dtype.num]:
             return dtype
         if w_dtype is dtype.w_box_type:
             return dtype
     if space.isinstance_w(w_dtype, space.w_type):
-        raise oefmt(space.w_NotImplementedError, "object dtype not implemented")
+        raise oefmt(space.w_NotImplementedError,
+            "cannot create dtype with type '%N'", w_dtype)
     raise oefmt(space.w_TypeError, "data type not understood")
 
 W_Dtype.typedef = TypeDef("dtype",
     __module__ = "numpy",
     __new__ = interp2app(descr__new__),
 
-    __str__= interp2app(W_Dtype.descr_str),
-    __repr__ = interp2app(W_Dtype.descr_repr),
-    __eq__ = interp2app(W_Dtype.descr_eq),
-    __ne__ = interp2app(W_Dtype.descr_ne),
-    __getitem__ = interp2app(W_Dtype.descr_getitem),
-    __len__ = interp2app(W_Dtype.descr_len),
-
-    __hash__ = interp2app(W_Dtype.descr_hash),
-    __reduce__ = interp2app(W_Dtype.descr_reduce),
-    __setstate__ = interp2app(W_Dtype.descr_setstate),
-    newbyteorder = interp2app(W_Dtype.descr_newbyteorder),
-
     type = interp_attrproperty_w("w_box_type", cls=W_Dtype),
     kind = interp_attrproperty("kind", cls=W_Dtype),
     char = interp_attrproperty("char", cls=W_Dtype),
     num = interp_attrproperty("num", cls=W_Dtype),
     byteorder = interp_attrproperty("byteorder", cls=W_Dtype),
-    itemsize = GetSetProperty(W_Dtype.descr_get_itemsize),
-    alignment = GetSetProperty(W_Dtype.descr_get_alignment),
+    itemsize = interp_attrproperty("elsize", cls=W_Dtype),
+    alignment = interp_attrproperty("alignment", cls=W_Dtype),
+
+    name = GetSetProperty(W_Dtype.descr_get_name),
+    str = GetSetProperty(W_Dtype.descr_get_str),
+    descr = GetSetProperty(W_Dtype.descr_get_descr),
+    hasobject = GetSetProperty(W_Dtype.descr_get_hasobject),
     isbuiltin = GetSetProperty(W_Dtype.descr_get_isbuiltin),
-
+    isnative = GetSetProperty(W_Dtype.descr_get_isnative),
+    base = GetSetProperty(W_Dtype.descr_get_base),
     subdtype = GetSetProperty(W_Dtype.descr_get_subdtype),
-    str = GetSetProperty(W_Dtype.descr_get_str),
-    name = GetSetProperty(W_Dtype.descr_get_name),
-    base = GetSetProperty(W_Dtype.descr_get_base),
     shape = GetSetProperty(W_Dtype.descr_get_shape),
-    isnative = GetSetProperty(W_Dtype.descr_get_isnative),
     fields = GetSetProperty(W_Dtype.descr_get_fields),
     names = GetSetProperty(W_Dtype.descr_get_names,
                            W_Dtype.descr_set_names,
                            W_Dtype.descr_del_names),
-    hasobject = GetSetProperty(W_Dtype.descr_get_hasobject),
-    descr = GetSetProperty(W_Dtype.descr_get_descr),
+
+    __eq__ = interp2app(W_Dtype.descr_eq),
+    __ne__ = interp2app(W_Dtype.descr_ne),
+    __hash__ = interp2app(W_Dtype.descr_hash),
+    __str__= interp2app(W_Dtype.descr_str),
+    __repr__ = interp2app(W_Dtype.descr_repr),
+    __getitem__ = interp2app(W_Dtype.descr_getitem),
+    __len__ = interp2app(W_Dtype.descr_len),
+    __reduce__ = interp2app(W_Dtype.descr_reduce),
+    __setstate__ = interp2app(W_Dtype.descr_setstate),
+    newbyteorder = interp2app(W_Dtype.descr_newbyteorder),
 )
 W_Dtype.typedef.acceptable_as_base_class = False
 
@@ -601,10 +588,8 @@
         except ValueError:
             raise oefmt(space.w_TypeError, "data type not understood")
     if char == NPY.CHARLTR:
-        char = NPY.STRINGLTR
-        size = 1
-
-    if char == NPY.STRINGLTR:
+        return new_string_dtype(space, 1, NPY.CHARLTR)
+    elif char == NPY.STRINGLTR:
         return new_string_dtype(space, size)
     elif char == NPY.UNICODELTR:
         return new_unicode_dtype(space, size)
@@ -613,21 +598,22 @@
     assert False
 
 
-def new_string_dtype(space, size):
+def new_string_dtype(space, size, char=NPY.STRINGLTR):
     return W_Dtype(
         types.StringType(),
-        size=size,
+        elsize=size,
         num=NPY.STRING,
         kind=NPY.STRINGLTR,
-        char=NPY.STRINGLTR,
+        char=char,
         w_box_type=space.gettypefor(interp_boxes.W_StringBox),
     )
 
 
 def new_unicode_dtype(space, size):
+    itemtype = types.UnicodeType()
     return W_Dtype(
-        types.UnicodeType(),
-        size=size,
+        itemtype,
+        elsize=size * itemtype.get_element_size(),
         num=NPY.UNICODE,
         kind=NPY.UNICODELTR,
         char=NPY.UNICODELTR,
@@ -638,7 +624,7 @@
 def new_void_dtype(space, size):
     return W_Dtype(
         types.VoidType(),
-        size=size,
+        elsize=size,
         num=NPY.VOID,
         kind=NPY.VOIDLTR,
         char=NPY.VOIDLTR,
@@ -654,8 +640,6 @@
             kind=NPY.GENBOOLLTR,
             char=NPY.BOOLLTR,
             w_box_type=space.gettypefor(interp_boxes.W_BoolBox),
-            alternate_constructors=[space.w_bool],
-            aliases=['bool', 'bool8'],
         )
         self.w_int8dtype = W_Dtype(
             types.Int8(),
@@ -663,7 +647,6 @@
             kind=NPY.SIGNEDLTR,
             char=NPY.BYTELTR,
             w_box_type=space.gettypefor(interp_boxes.W_Int8Box),
-            aliases=['byte'],
         )
         self.w_uint8dtype = W_Dtype(
             types.UInt8(),
@@ -671,7 +654,6 @@
             kind=NPY.UNSIGNEDLTR,
             char=NPY.UBYTELTR,
             w_box_type=space.gettypefor(interp_boxes.W_UInt8Box),
-            aliases=['ubyte'],
         )
         self.w_int16dtype = W_Dtype(
             types.Int16(),
@@ -679,7 +661,6 @@
             kind=NPY.SIGNEDLTR,
             char=NPY.SHORTLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Int16Box),
-            aliases=['short'],
         )
         self.w_uint16dtype = W_Dtype(
             types.UInt16(),
@@ -687,7 +668,6 @@
             kind=NPY.UNSIGNEDLTR,
             char=NPY.USHORTLTR,
             w_box_type=space.gettypefor(interp_boxes.W_UInt16Box),
-            aliases=['ushort'],
         )
         self.w_int32dtype = W_Dtype(
             types.Int32(),
@@ -709,11 +689,6 @@
             kind=NPY.SIGNEDLTR,
             char=NPY.LONGLTR,
             w_box_type=space.gettypefor(interp_boxes.W_LongBox),
-            alternate_constructors=[space.w_int,
-                                    space.gettypefor(interp_boxes.W_IntegerBox),
-                                    space.gettypefor(interp_boxes.W_SignedIntegerBox),
-                                    ],
-            aliases=['int', 'intp', 'p'],
         )
         self.w_ulongdtype = W_Dtype(
             types.ULong(),
@@ -721,9 +696,6 @@
             kind=NPY.UNSIGNEDLTR,
             char=NPY.ULONGLTR,
             w_box_type=space.gettypefor(interp_boxes.W_ULongBox),
-            alternate_constructors=[space.gettypefor(interp_boxes.W_UnsignedIntegerBox),
-                                    ],
-            aliases=['uint', 'uintp', 'P'],
         )
         self.w_int64dtype = W_Dtype(
             types.Int64(),
@@ -731,8 +703,6 @@
             kind=NPY.SIGNEDLTR,
             char=NPY.LONGLONGLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Int64Box),
-            alternate_constructors=[space.w_long],
-            aliases=['longlong'],
         )
         self.w_uint64dtype = W_Dtype(
             types.UInt64(),
@@ -740,7 +710,6 @@
             kind=NPY.UNSIGNEDLTR,
             char=NPY.ULONGLONGLTR,
             w_box_type=space.gettypefor(interp_boxes.W_UInt64Box),
-            aliases=['ulonglong'],
         )
         self.w_float32dtype = W_Dtype(
             types.Float32(),
@@ -748,7 +717,6 @@
             kind=NPY.FLOATINGLTR,
             char=NPY.FLOATLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Float32Box),
-            aliases=['single']
         )
         self.w_float64dtype = W_Dtype(
             types.Float64(),
@@ -756,11 +724,6 @@
             kind=NPY.FLOATINGLTR,
             char=NPY.DOUBLELTR,
             w_box_type=space.gettypefor(interp_boxes.W_Float64Box),
-            alternate_constructors=[space.w_float,
-                                    space.gettypefor(interp_boxes.W_NumberBox),
-                                    space.gettypefor(interp_boxes.W_FloatingBox),
-                                    ],
-            aliases=["float", "double"],
         )
         self.w_floatlongdtype = W_Dtype(
             types.FloatLong(),
@@ -768,7 +731,6 @@
             kind=NPY.FLOATINGLTR,
             char=NPY.LONGDOUBLELTR,
             w_box_type=space.gettypefor(interp_boxes.W_FloatLongBox),
-            aliases=["longdouble", "longfloat"],
         )
         self.w_complex64dtype = W_Dtype(
             types.Complex64(),
@@ -776,8 +738,6 @@
             kind=NPY.COMPLEXLTR,
             char=NPY.CFLOATLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Complex64Box),
-            aliases=['csingle'],
-            float_type=NPY.FLOATLTR,
         )
         self.w_complex128dtype = W_Dtype(
             types.Complex128(),
@@ -785,10 +745,6 @@
             kind=NPY.COMPLEXLTR,
             char=NPY.CDOUBLELTR,
             w_box_type=space.gettypefor(interp_boxes.W_Complex128Box),
-            alternate_constructors=[space.w_complex,
-                                    space.gettypefor(interp_boxes.W_ComplexFloatingBox)],
-            aliases=["complex", 'cfloat', 'cdouble'],
-            float_type=NPY.DOUBLELTR,
         )
         self.w_complexlongdtype = W_Dtype(
             types.ComplexLong(),
@@ -796,41 +752,30 @@
             kind=NPY.COMPLEXLTR,
             char=NPY.CLONGDOUBLELTR,
             w_box_type=space.gettypefor(interp_boxes.W_ComplexLongBox),
-            aliases=["clongdouble", "clongfloat"],
-            float_type=NPY.LONGDOUBLELTR,
         )
         self.w_stringdtype = W_Dtype(
             types.StringType(),
-            size=0,
+            elsize=0,
             num=NPY.STRING,
             kind=NPY.STRINGLTR,
             char=NPY.STRINGLTR,
             w_box_type=space.gettypefor(interp_boxes.W_StringBox),
-            alternate_constructors=[space.w_str,
-                                    space.gettypefor(interp_boxes.W_CharacterBox)],
-            aliases=['string', "str"],
         )
         self.w_unicodedtype = W_Dtype(
             types.UnicodeType(),
-            size=0,
+            elsize=0,
             num=NPY.UNICODE,
             kind=NPY.UNICODELTR,
             char=NPY.UNICODELTR,
             w_box_type=space.gettypefor(interp_boxes.W_UnicodeBox),
-            alternate_constructors=[space.w_unicode],
-            aliases=['unicode'],
         )
         self.w_voiddtype = W_Dtype(
             types.VoidType(),
-            size=0,
+            elsize=0,
             num=NPY.VOID,
             kind=NPY.VOIDLTR,
             char=NPY.VOIDLTR,
             w_box_type=space.gettypefor(interp_boxes.W_VoidBox),
-            #alternate_constructors=[space.w_buffer],
-            # XXX no buffer in space
-            #alternate_constructors=[space.gettypefor(interp_boxes.W_GenericBox)],
-            # XXX fix, leads to _coerce error
         )
         self.w_float16dtype = W_Dtype(
             types.Float16(),
@@ -853,10 +798,52 @@
             char=NPY.UINTPLTR,
             w_box_type=space.gettypefor(interp_boxes.W_ULongBox),
         )
+        aliases = {
+            NPY.BOOL:        ['bool', 'bool8'],
+            NPY.BYTE:        ['byte'],
+            NPY.UBYTE:       ['ubyte'],
+            NPY.SHORT:       ['short'],
+            NPY.USHORT:      ['ushort'],
+            NPY.LONG:        ['int', 'intp', 'p'],
+            NPY.ULONG:       ['uint', 'uintp', 'P'],
+            NPY.LONGLONG:    ['longlong'],
+            NPY.ULONGLONG:   ['ulonglong'],
+            NPY.FLOAT:       ['single'],
+            NPY.DOUBLE:      ['float', 'double'],
+            NPY.LONGDOUBLE:  ['longdouble', 'longfloat'],
+            NPY.CFLOAT:      ['csingle'],
+            NPY.CDOUBLE:     ['complex', 'cfloat', 'cdouble'],
+            NPY.CLONGDOUBLE: ['clongdouble', 'clongfloat'],
+            NPY.STRING:      ['string', 'str'],
+            NPY.UNICODE:     ['unicode'],
+        }
+        self.alternate_constructors = {
+            NPY.BOOL:     [space.w_bool],
+            NPY.LONG:     [space.w_int,
+                           space.gettypefor(interp_boxes.W_IntegerBox),
+                           space.gettypefor(interp_boxes.W_SignedIntegerBox)],
+            NPY.ULONG:    [space.gettypefor(interp_boxes.W_UnsignedIntegerBox)],
+            NPY.LONGLONG: [space.w_long],
+            NPY.DOUBLE:   [space.w_float,
+                           space.gettypefor(interp_boxes.W_NumberBox),
+                           space.gettypefor(interp_boxes.W_FloatingBox)],
+            NPY.CDOUBLE:  [space.w_complex,
+                           space.gettypefor(interp_boxes.W_ComplexFloatingBox)],
+            NPY.STRING:   [space.w_str,
+                           space.gettypefor(interp_boxes.W_CharacterBox)],
+            NPY.UNICODE:  [space.w_unicode],
+            NPY.VOID:     [space.gettypefor(interp_boxes.W_GenericBox)],
+                           #space.w_buffer,  # XXX no buffer in space
+        }
         float_dtypes = [self.w_float16dtype, self.w_float32dtype,
                         self.w_float64dtype, self.w_floatlongdtype]
         complex_dtypes = [self.w_complex64dtype, self.w_complex128dtype,
                           self.w_complexlongdtype]
+        self.component_dtypes = {
+            NPY.CFLOAT:      self.w_float32dtype,
+            NPY.CDOUBLE:     self.w_float64dtype,
+            NPY.CLONGDOUBLE: self.w_floatlongdtype,
+        }
         self.builtin_dtypes = [
             self.w_booldtype,
             self.w_int8dtype, self.w_uint8dtype,
@@ -869,7 +856,7 @@
             self.w_intpdtype, self.w_uintpdtype,
         ]
         self.float_dtypes_by_num_bytes = sorted(
-            (dtype.get_size(), dtype)
+            (dtype.elsize, dtype)
             for dtype in float_dtypes
         )
         self.dtypes_by_num = {}
@@ -880,14 +867,15 @@
             dtype.fields = None  # mark these as builtin
             self.dtypes_by_num[dtype.num] = dtype
             self.dtypes_by_name[dtype.get_name()] = dtype
-            for can_name in [dtype.kind + str(dtype.get_size()),
+            for can_name in [dtype.kind + str(dtype.elsize),
                              dtype.char]:
                 self.dtypes_by_name[can_name] = dtype
                 self.dtypes_by_name[NPY.NATBYTE + can_name] = dtype
                 self.dtypes_by_name[NPY.NATIVE + can_name] = dtype
                 self.dtypes_by_name[NPY.IGNORE + can_name] = dtype
-            for alias in dtype.aliases:
-                self.dtypes_by_name[alias] = dtype
+            if dtype.num in aliases:
+                for alias in aliases[dtype.num]:
+                    self.dtypes_by_name[alias] = dtype
 
         typeinfo_full = {
             'LONGLONG': self.w_int64dtype,
@@ -935,13 +923,13 @@
         for k, v in typeinfo_partial.iteritems():
             space.setitem(w_typeinfo, space.wrap(k), space.gettypefor(v))
         for k, dtype in typeinfo_full.iteritems():
-            itembits = dtype.get_size() * 8
+            itembits = dtype.elsize * 8
             items_w = [space.wrap(dtype.char),
                        space.wrap(dtype.num),
                        space.wrap(itembits),
                        space.wrap(dtype.itemtype.get_element_size())]
-            if dtype.is_int_type():
-                if dtype.kind == NPY.GENBOOLLTR:
+            if dtype.is_int():
+                if dtype.is_bool():
                     w_maxobj = space.wrap(1)
                     w_minobj = space.wrap(0)
                 elif dtype.is_signed():
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -87,8 +87,8 @@
     def descr_set_dtype(self, space, w_dtype):
         dtype = space.interp_w(interp_dtype.W_Dtype,
             space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
-        if (dtype.get_size() != self.get_dtype().get_size() or
-                dtype.is_flexible_type() or self.get_dtype().is_flexible_type()):
+        if (dtype.elsize != self.get_dtype().elsize or
+                dtype.is_flexible() or self.get_dtype().is_flexible()):
             raise OperationError(space.w_ValueError, space.wrap(
                 "new type not compatible with array."))
         self.implementation.set_dtype(space, dtype)
@@ -101,10 +101,10 @@
         return space.wrap(len(self.get_shape()))
 
     def descr_get_itemsize(self, space):
-        return space.wrap(self.get_dtype().get_size())
+        return space.wrap(self.get_dtype().elsize)
 
     def descr_get_nbytes(self, space):
-        return space.wrap(self.get_size() * self.get_dtype().get_size())
+        return space.wrap(self.get_size() * self.get_dtype().elsize)
 
     def descr_fill(self, space, w_value):
         self.fill(space, self.get_dtype().coerce(space, w_value))
@@ -220,7 +220,7 @@
     def descr_getitem(self, space, w_idx):
         if space.is_w(w_idx, space.w_Ellipsis):
             return self
-        elif isinstance(w_idx, W_NDimArray) and w_idx.get_dtype().is_bool_type() \
+        elif isinstance(w_idx, W_NDimArray) and w_idx.get_dtype().is_bool() \
                 and len(w_idx.get_shape()) > 0:
             return self.getitem_filter(space, w_idx)
         try:
@@ -235,7 +235,7 @@
         self.implementation.setitem_index(space, index_list, w_value)
 
     def descr_setitem(self, space, w_idx, w_value):
-        if isinstance(w_idx, W_NDimArray) and w_idx.get_dtype().is_bool_type() \
+        if isinstance(w_idx, W_NDimArray) and w_idx.get_dtype().is_bool() \
                 and len(w_idx.get_shape()) > 0:
             self.setitem_filter(space, w_idx, convert_to_array(space, w_value))
             return
@@ -281,7 +281,7 @@
             else:
                 s.append(separator)
                 s.append(' ')
-            if self.is_scalar() and dtype.is_str_type():
+            if self.is_scalar() and dtype.is_str():
                 s.append(dtype.itemtype.to_str(i.getitem()))
             else:
                 s.append(dtype.itemtype.str_format(i.getitem()))
@@ -344,7 +344,7 @@
 
     def descr_set_imag(self, space, w_value):
         # if possible, copy (broadcast) values into self
-        if not self.get_dtype().is_complex_type():
+        if not self.get_dtype().is_complex():
             raise OperationError(space.w_TypeError,
                     space.wrap('array does not have imaginary part to set'))
         self.implementation.set_imag(space, self, w_value)
@@ -575,10 +575,10 @@
             raise oefmt(space.w_NotImplementedError,
                         "astype(%s) not implemented yet",
                         new_dtype.get_name())
-        if new_dtype.num == NPY.STRING and new_dtype.size == 0:
+        if new_dtype.num == NPY.STRING and new_dtype.elsize == 0:
             if cur_dtype.num == NPY.STRING:
                 new_dtype = interp_dtype.variable_dtype(space,
-                    'S' + str(cur_dtype.size))
+                    'S' + str(cur_dtype.elsize))
         impl = self.implementation
         if isinstance(impl, scalar.Scalar):
             return W_NDimArray.new_scalar(space, new_dtype, impl.value)
@@ -689,7 +689,7 @@
     @unwrap_spec(decimals=int)
     def descr_round(self, space, decimals=0, w_out=None):
         if space.is_none(w_out):
-            if self.get_dtype().is_bool_type():
+            if self.get_dtype().is_bool():
                 #numpy promotes bool.round() to float16. Go figure.
                 w_out = W_NDimArray.from_shape(space, self.get_shape(),
                        interp_dtype.get_dtype_cache(space).w_float16dtype)
@@ -700,7 +700,7 @@
                 "return arrays must be of ArrayType"))
         out = interp_dtype.dtype_agreement(space, [self], self.get_shape(),
                                            w_out)
-        if out.get_dtype().is_bool_type() and self.get_dtype().is_bool_type():
+        if out.get_dtype().is_bool() and self.get_dtype().is_bool():
             calc_dtype = interp_dtype.get_dtype_cache(space).w_longdtype
         else:
             calc_dtype = out.get_dtype()
@@ -781,8 +781,8 @@
                                                                    w_dtype))
         else:
             dtype = self.get_dtype()
-        old_itemsize = self.get_dtype().get_size()
-        new_itemsize = dtype.get_size()
+        old_itemsize = self.get_dtype().elsize
+        new_itemsize = dtype.elsize
         impl = self.implementation
         if new_itemsize == 0:
             raise OperationError(space.w_TypeError, space.wrap(
@@ -1093,7 +1093,7 @@
             raise OperationError(space.w_TypeError, space.wrap(
                 "only integer arrays with one element "
                 "can be converted to an index"))
-        if not self.get_dtype().is_int_type() or self.get_dtype().is_bool_type():
+        if not self.get_dtype().is_int() or self.get_dtype().is_bool():
             raise OperationError(space.w_TypeError, space.wrap(
                 "only integer arrays with one element "
                 "can be converted to an index"))
@@ -1188,7 +1188,7 @@
         if not shape:
             raise OperationError(space.w_TypeError, space.wrap(
                 "numpy scalars from buffers not supported yet"))
-        totalsize = support.product(shape) * dtype.get_size()
+        totalsize = support.product(shape) * dtype.elsize
         if totalsize+offset > buf.getlength():
             raise OperationError(space.w_TypeError, space.wrap(
                 "buffer is too small for requested array"))
@@ -1448,9 +1448,10 @@
     # scalars and strings w/o __array__ method
     isstr = space.isinstance_w(w_object, space.w_str)
     if not issequence_w(space, w_object) or isstr:
-        if dtype is None or (dtype.is_str_or_unicode() and dtype.get_size() < 1):
-            dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object)
-        return W_NDimArray.new_scalar(space, dtype, w_object)
+        if dtype is None or dtype.char != NPY.CHARLTR:
+            if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1):
+                dtype = interp_ufuncs.find_dtype_for_scalar(space, w_object)
+            return W_NDimArray.new_scalar(space, dtype, w_object)
 
     if space.is_none(w_order):
         order = 'C'
@@ -1478,14 +1479,14 @@
 
     # not an array or incorrect dtype
     shape, elems_w = find_shape_and_elems(space, w_object, dtype)
-    if dtype is None or (dtype.is_str_or_unicode() and dtype.get_size() < 1):
+    if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1):
         for w_elem in elems_w:
             if isinstance(w_elem, W_NDimArray) and w_elem.is_scalar():
                 w_elem = w_elem.get_scalar_value()
             dtype = interp_ufuncs.find_dtype_for_scalar(space, w_elem, dtype)
         if dtype is None:
             dtype = interp_dtype.get_dtype_cache(space).w_float64dtype
-        elif dtype.is_str_or_unicode() and dtype.get_size() < 1:
+        elif dtype.is_str_or_unicode() and dtype.elsize < 1:
             # promote S0 -> S1, U0 -> U1
             dtype = interp_dtype.variable_dtype(space, dtype.char + '1')
 
@@ -1501,7 +1502,7 @@
 def zeros(space, w_shape, w_dtype=None, w_order=None):
     dtype = space.interp_w(interp_dtype.W_Dtype,
         space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
-    if dtype.is_str_or_unicode() and dtype.get_size() < 1:
+    if dtype.is_str_or_unicode() and dtype.elsize < 1:
         dtype = interp_dtype.variable_dtype(space, dtype.char + '1')
     shape = _find_shape(space, w_shape, dtype)
     return W_NDimArray.from_shape(space, shape, dtype=dtype)
@@ -1514,24 +1515,30 @@
     else:
         dtype = space.interp_w(interp_dtype.W_Dtype,
             space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
-        if dtype.is_str_or_unicode() and dtype.get_size() < 1:
+        if dtype.is_str_or_unicode() and dtype.elsize < 1:
             dtype = interp_dtype.variable_dtype(space, dtype.char + '1')
     return W_NDimArray.from_shape(space, w_a.get_shape(), dtype=dtype,
                                   w_instance=w_a if subok else None)
 
-def _reconstruct(space, w_subtype, w_shape, w_dtype):
-    return descr_new_array(space, w_subtype, w_shape, w_dtype)
-
 def build_scalar(space, w_dtype, w_state):
     from rpython.rtyper.lltypesystem import rffi, lltype
-
-    assert isinstance(w_dtype, interp_dtype.W_Dtype)
-
+    if not isinstance(w_dtype, interp_dtype.W_Dtype):
+        raise oefmt(space.w_TypeError,
+                    "argument 1 must be numpy.dtype, not %T", w_dtype)
+    if w_dtype.elsize == 0:
+        raise oefmt(space.w_ValueError, "itemsize cannot be zero")
+    if not space.isinstance_w(w_state, space.w_str):
+        raise oefmt(space.w_TypeError, "initializing object must be a string")
+    if space.len_w(w_state) != w_dtype.elsize:
+        raise oefmt(space.w_ValueError, "initialization string is too small")
     state = rffi.str2charp(space.str_w(w_state))
     box = w_dtype.itemtype.box_raw_data(state)
     lltype.free(state, flavor="raw")
     return box
 
+def _reconstruct(space, w_subtype, w_shape, w_dtype):
+    return descr_new_array(space, w_subtype, w_shape, w_dtype)
+
 
 W_FlatIterator.typedef = TypeDef("flatiter",
     __module__ = "numpy",
diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py
--- a/pypy/module/micronumpy/interp_support.py
+++ b/pypy/module/micronumpy/interp_support.py
@@ -59,7 +59,7 @@
     return space.wrap(a)
 
 def _fromstring_bin(space, s, count, length, dtype):
-    itemsize = dtype.get_size()
+    itemsize = dtype.elsize
     assert itemsize >= 0
     if count == -1:
         count = length / itemsize
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -168,7 +168,7 @@
                 "supported for binary functions"))
         assert isinstance(self, W_Ufunc2)
         obj = convert_to_array(space, w_obj)
-        if obj.get_dtype().is_flexible_type():
+        if obj.get_dtype().is_flexible():
             raise OperationError(space.w_TypeError,
                       space.wrap('cannot perform reduce with flexible type'))
         obj_shape = obj.get_shape()
@@ -287,12 +287,12 @@
                 out = None
         w_obj = convert_to_array(space, w_obj)
         dtype = w_obj.get_dtype()
-        if dtype.is_flexible_type():
+        if dtype.is_flexible():
             raise OperationError(space.w_TypeError,
                       space.wrap('Not implemented for this type'))
-        if (self.int_only and not dtype.is_int_type() or
-                not self.allow_bool and dtype.is_bool_type() or
-                not self.allow_complex and dtype.is_complex_type()):
+        if (self.int_only and not dtype.is_int() or
+                not self.allow_bool and dtype.is_bool() or
+                not self.allow_complex and dtype.is_complex()):
             raise OperationError(space.w_TypeError, space.wrap(
                 "ufunc %s not supported for the input type" % self.name))
         calc_dtype = find_unaryop_result_dtype(space,
@@ -311,7 +311,7 @@
             res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
         else:
             res_dtype = calc_dtype
-            if self.complex_to_float and calc_dtype.is_complex_type():
+            if self.complex_to_float and calc_dtype.is_complex():
                 if calc_dtype.num == NPY.CFLOAT:
                     res_dtype = interp_dtype.get_dtype_cache(space).w_float32dtype
                 else:
@@ -351,11 +351,11 @@
             self.done_func = None
 
     def are_common_types(self, dtype1, dtype2):
-        if dtype1.is_complex_type() and dtype2.is_complex_type():
-            return True
-        elif not (dtype1.is_complex_type() or dtype2.is_complex_type()) and \
-                (dtype1.is_int_type() and dtype2.is_int_type() or dtype1.is_float_type() and dtype2.is_float_type()) and \
-                not (dtype1.is_bool_type() or dtype2.is_bool_type()):
+        if dtype1.is_bool() or dtype2.is_bool():
+            return False
+        if (dtype1.is_int() and dtype2.is_int() or
+                dtype1.is_float() and dtype2.is_float() or
+                dtype1.is_complex() and dtype2.is_complex()):
             return True
         return False
 
@@ -370,13 +370,13 @@
         w_rhs = convert_to_array(space, w_rhs)
         w_ldtype = w_lhs.get_dtype()
         w_rdtype = w_rhs.get_dtype()
-        if w_ldtype.is_str_type() and w_rdtype.is_str_type() and \
+        if w_ldtype.is_str() and w_rdtype.is_str() and \
                 self.comparison_func:
             pass
-        elif (w_ldtype.is_str_type() or w_rdtype.is_str_type()) and \
+        elif (w_ldtype.is_str() or w_rdtype.is_str()) and \
                 self.comparison_func and w_out is None:
             return space.wrap(False)
-        elif w_ldtype.is_flexible_type() or w_rdtype.is_flexible_type():
+        elif w_ldtype.is_flexible() or w_rdtype.is_flexible():
             if self.comparison_func:
                 if self.name == 'equal' or self.name == 'not_equal':
                     res = w_ldtype.eq(space, w_rdtype)
@@ -399,13 +399,13 @@
             w_ldtype, w_rdtype,
             promote_to_float=self.promote_to_float,
             promote_bools=self.promote_bools)
-        if (self.int_only and (not w_ldtype.is_int_type() or
-                               not w_rdtype.is_int_type() or
-                               not calc_dtype.is_int_type()) or
-                not self.allow_bool and (w_ldtype.is_bool_type() or
-                                         w_rdtype.is_bool_type()) or
-                not self.allow_complex and (w_ldtype.is_complex_type() or
-                                            w_rdtype.is_complex_type())):
+        if (self.int_only and (not w_ldtype.is_int() or
+                               not w_rdtype.is_int() or
+                               not calc_dtype.is_int()) or
+                not self.allow_bool and (w_ldtype.is_bool() or
+                                         w_rdtype.is_bool()) or
+                not self.allow_complex and (w_ldtype.is_complex() or
+                                            w_rdtype.is_complex())):
             raise OperationError(space.w_TypeError, space.wrap(
                 "ufunc '%s' not supported for the input types" % self.name))
         if space.is_none(w_out):
@@ -467,7 +467,7 @@
         return interp_dtype.get_dtype_cache(space).w_int8dtype
 
     # Everything numeric promotes to complex
-    if dt2.is_complex_type() or dt1.is_complex_type():
+    if dt2.is_complex() or dt1.is_complex():
         if dt2.num == NPY.HALF:
             dt1, dt2 = dt2, dt1
         if dt2.num == NPY.CFLOAT:
@@ -488,7 +488,7 @@
     if promote_to_float:
         return find_unaryop_result_dtype(space, dt2, promote_to_float=True)
     # If they're the same kind, choose the greater one.
-    if dt1.kind == dt2.kind and not dt2.is_flexible_type():
+    if dt1.kind == dt2.kind and not dt2.is_flexible():
         if dt2.num == NPY.HALF:
             return dt1
         return dt2
@@ -513,13 +513,13 @@
     elif dt2.num == NPY.ULONGLONG or (LONG_BIT == 64 and dt2.num == NPY.ULONG):
         # UInt64 + signed = Float64
         dtypenum = NPY.DOUBLE
-    elif dt2.is_flexible_type():
+    elif dt2.is_flexible():
         # For those operations that get here (concatenate, stack),
         # flexible types take precedence over numeric type
-        if dt2.is_record_type():
+        if dt2.is_record():
             return dt2
         if dt1.is_str_or_unicode():
-            if dt2.get_size() >= dt1.get_size():
+            if dt2.elsize >= dt1.elsize:
                 return dt2
             return dt1
         return dt2
@@ -542,10 +542,10 @@
         promote_bools=False, promote_to_largest=False):
     if promote_to_largest:
         if dt.kind == NPY.GENBOOLLTR or dt.kind == NPY.SIGNEDLTR:
-            if dt.get_size() * 8 < LONG_BIT:
+            if dt.elsize * 8 < LONG_BIT:
                 return interp_dtype.get_dtype_cache(space).w_longdtype
         elif dt.kind == NPY.UNSIGNEDLTR:
-            if dt.get_size() * 8 < LONG_BIT:
+            if dt.elsize * 8 < LONG_BIT:
                 return interp_dtype.get_dtype_cache(space).w_ulongdtype
         else:
             assert dt.kind == NPY.FLOATINGLTR or dt.kind == NPY.COMPLEXLTR
@@ -596,7 +596,7 @@
             return interp_dtype.variable_dtype(space,
                                                'S%d' % space.len_w(w_obj))
         elif current_guess.num == NPY.STRING:
-            if current_guess.get_size() < space.len_w(w_obj):
+            if current_guess.elsize < space.len_w(w_obj):
                 return interp_dtype.variable_dtype(space,
                                                    'S%d' % space.len_w(w_obj))
         return current_guess
diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -174,7 +174,7 @@
     def __init__(self, array):
         self.array = array
         self.offset = 0
-        self.skip = array.dtype.get_size()
+        self.skip = array.dtype.elsize
         self.size = array.size
 
     def setitem(self, elem):
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -459,7 +459,7 @@
     builder = StringBuilder()
     iter = arr.create_iter()
     w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order='C')
-    itemsize = arr.get_dtype().get_size()
+    itemsize = arr.get_dtype().elsize
     res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
                                w_res_str.implementation.get_storage_as_int(space))
     while not iter.done():
diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -69,7 +69,7 @@
     return True
 
 def find_shape_and_elems(space, w_iterable, dtype):
-    is_rec_type = dtype is not None and dtype.is_record_type()
+    is_rec_type = dtype is not None and dtype.is_record()
     if is_rec_type and is_single_elem(space, w_iterable, is_rec_type):
         return [], [w_iterable]
     if isinstance(w_iterable, W_NDimArray) and w_iterable.is_scalar():
diff --git a/pypy/module/micronumpy/support.py b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -28,8 +28,8 @@
         shape_rev.reverse()
     for sh in shape_rev:
         slimit = max(sh, 1)
-        strides.append(s * dtype.get_size())
-        backstrides.append(s * (slimit - 1) * dtype.get_size())
+        strides.append(s * dtype.elsize)
+        backstrides.append(s * (slimit - 1) * dtype.elsize)
         s *= slimit
     if order == 'C':
         strides.reverse()
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -58,6 +58,7 @@
 
         assert dtype('int8').num == 1
         assert dtype('int8').name == 'int8'
+        assert dtype('void').name == 'void'
         assert dtype(int).fields is None
         assert dtype(int).names is None
         assert dtype(int).hasobject is False
@@ -371,6 +372,7 @@
                 raises(TypeError, hash, d)
 
     def test_pickle(self):
+        import numpy as np
         from numpypy import array, dtype
         from cPickle import loads, dumps
         a = array([1,2,3])
@@ -379,6 +381,9 @@
         else:
             assert a.dtype.__reduce__() == (dtype, ('i4', 0, 1), (3, '<', None, None, None, -1, -1, 0))
         assert loads(dumps(a.dtype)) == a.dtype
+        assert np.dtype('bool').__reduce__() == (dtype, ('b1', 0, 1), (3, '|', None, None, None, -1, -1, 0))
+        assert np.dtype('|V16').__reduce__() == (dtype, ('V16', 0, 1), (3, '|', None, None, None, 16, 1, 0))
+        assert np.dtype(('<f8', 2)).__reduce__() == (dtype, ('V16', 0, 1), (3, '|', (dtype('float64'), (2,)), None, None, 16, 1, 0))
 
     def test_newbyteorder(self):
         import numpypy as np
@@ -423,6 +428,20 @@
             s2 = np.array(123, dtype=dt2).byteswap().tostring()
             assert s1 == s2
 
+        d = np.dtype([('', '<i8')]).newbyteorder()
+        assert d.shape == ()
+        assert d.names == ('f0',)
+        #assert d.fields['f0'] == ('>i8', 0)
+        assert d.subdtype is None
+        #assert d.descr == [('f0', '>i8')]
+        #assert str(d) == "[('f0', '>i8')]"
+        d = np.dtype(('<i8', 2)).newbyteorder()
+        assert d.shape == (2,)
+        assert d.names is None
+        assert d.fields is None
+        assert d.descr == [('', '|V16')]
+        #assert str(d) == "('>i8', (2,))"
+
     def test_object(self):
         import numpy as np
         import sys
@@ -433,7 +452,7 @@
                 assert np.dtype(o).str == '|O8'
             else:
                 exc = raises(NotImplementedError, "np.dtype(o)")
-                assert exc.value[0] == 'object dtype not implemented'
+                assert exc.value[0] == "cannot create dtype with type '%s'" % o.__name__
 
 class AppTestTypes(BaseAppTestDtypes):
     def test_abstract_types(self):
@@ -855,6 +874,7 @@
         raises(TypeError, lambda: float64(3) & 1)
 
     def test_alternate_constructs(self):
+        import numpy as np
         from numpypy import dtype
         nnp = self.non_native_prefix
         byteorder = self.native_prefix
@@ -870,6 +890,12 @@
         assert dtype('<S5').newbyteorder('=').byteorder == '|'
         assert dtype('void').byteorder == '|'
         assert dtype((int, 2)).byteorder == '|'
+        assert dtype(np.generic).str == '|V0'
+        d = dtype(np.character)
+        assert d.num == 18
+        assert d.char == 'S'
+        assert d.kind == 'S'
+        assert d.str == '|S0'
 
     def test_dtype_str(self):
         from numpypy import dtype
@@ -1034,12 +1060,19 @@
             assert isinstance(u, unicode)
 
     def test_character_dtype(self):
+        import numpy as np
         from numpypy import array, character
         x = array([["A", "B"], ["C", "D"]], character)
         assert (x == [["A", "B"], ["C", "D"]]).all()
+        d = np.dtype('c')
+        assert d.num == 18
+        assert d.char == 'c'
+        assert d.kind == 'S'
+        assert d.str == '|S1'
 
 class AppTestRecordDtypes(BaseNumpyAppTest):
     spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
+
     def test_create(self):
         from numpypy import dtype, void
 
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -14,15 +14,9 @@
         def malloc(size):
             return None
 
-        @staticmethod
-        def get_element_size():
-            return 1
-
     def __init__(self):
         self.base = self
-
-    def get_size(self):
-        return 1
+        self.elsize = 1
 
 
 def create_slice(space, a, chunks):
@@ -779,6 +773,23 @@
         a[()] = 4
         assert a == 4
 
+    def test_build_scalar(self):
+        from numpy import dtype
+        try:
+            from numpy.core.multiarray import scalar
+        except ImportError:
+            from numpy import scalar
+        exc = raises(TypeError, scalar, int, 2)
+        assert exc.value[0] == 'argument 1 must be numpy.dtype, not type'
+        exc = raises(ValueError, scalar, dtype('void'), 'abc')
+        assert exc.value[0] == 'itemsize cannot be zero'
+        exc = raises(TypeError, scalar, dtype(float), 2.5)
+        assert exc.value[0] == 'initializing object must be a string'
+        exc = raises(ValueError, scalar, dtype(float), 'abc')
+        assert exc.value[0] == 'initialization string is too small'
+        a = scalar(dtype('<f8'), dtype('<f8').type(2.5).tostring())
+        assert a == 2.5
+
     def test_len(self):
         from numpypy import array
         a = array(range(5))
@@ -1629,6 +1640,12 @@
 
     def test_realimag_views(self):
         from numpypy import arange, array
+        a = array(1.5)
+        assert a.real == 1.5
+        assert a.imag == 0.0
+        a = array([1.5, 2.5])


More information about the pypy-commit mailing list