[pypy-commit] pypy remove-remaining-smm: hg merge default

Manuel Jacob noreply at buildbot.pypy.org
Tue Feb 25 03:47:35 CET 2014


Author: Manuel Jacob
Branch: remove-remaining-smm
Changeset: r69380:d708c09fcb34
Date: 2014-02-25 03:46 +0100
http://bitbucket.org/pypy/pypy/changeset/d708c09fcb34/

Log:	hg merge default

diff too long, truncating to 2000 out of 2756 lines

diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -27,7 +27,7 @@
 
 class UMathModule(MixedModule):
     appleveldefs = {}
-    interpleveldefs = {}
+    interpleveldefs = {'FLOATING_POINT_SUPPORT': 'space.wrap(1)'}
     # ufuncs
     for exposed, impl in [
         ("absolute", "absolute"),
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
@@ -1,7 +1,6 @@
 from pypy.module.micronumpy.arrayimpl import base
 from pypy.module.micronumpy.base import W_NDimArray, convert_to_array
 from pypy.module.micronumpy import support
-from pypy.module.micronumpy.interp_boxes import W_GenericBox
 from pypy.interpreter.error import OperationError
 
 class ScalarIterator(base.BaseArrayIterator):
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
@@ -10,9 +10,9 @@
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.rarithmetic import widen
 from rpython.rlib.objectmodel import specialize
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, oefmt
 from pypy.module.micronumpy.base import W_NDimArray
-from pypy.module.micronumpy import interp_dtype, types
+from pypy.module.micronumpy import interp_dtype, types, constants as NPY
 from pypy.module.micronumpy.iter import AxisIterator
 
 INT_SIZE = rffi.sizeof(lltype.Signed)
@@ -175,9 +175,9 @@
             return cache._lookup(tp)(arr, space, w_axis,
                                      itemtype.get_element_size())
     # XXX this should probably be changed
-    raise OperationError(space.w_NotImplementedError,
-           space.wrap("sorting of non-numeric types " + \
-                  "'%s' is not implemented" % arr.dtype.get_name(), ))
+    raise oefmt(space.w_NotImplementedError,
+                "sorting of non-numeric types '%s' is not implemented",
+                arr.dtype.get_name())
 
 all_types = (types.all_float_types + types.all_complex_types +
              types.all_int_types)
@@ -310,17 +310,17 @@
 def sort_array(arr, space, w_axis, w_order):
     cache = space.fromcache(SortCache) # that populates SortClasses
     itemtype = arr.dtype.itemtype
-    if not arr.dtype.is_native():
-        raise OperationError(space.w_NotImplementedError,
-           space.wrap("sorting of non-native btyeorder not supported yet"))
+    if arr.dtype.byteorder == NPY.OPPBYTE:
+        raise oefmt(space.w_NotImplementedError,
+                    "sorting of non-native byteorder not supported yet")
     for tp in all_types:
         if isinstance(itemtype, tp[0]):
             return cache._lookup(tp)(arr, space, w_axis,
                                      itemtype.get_element_size())
     # XXX this should probably be changed
-    raise OperationError(space.w_NotImplementedError,
-           space.wrap("sorting of non-numeric types " + \
-                  "'%s' is not implemented" % arr.dtype.get_name(), ))
+    raise oefmt(space.w_NotImplementedError,
+                "sorting of non-numeric types '%s' is not implemented",
+                arr.dtype.get_name())
 
 all_types = (types.all_float_types + types.all_complex_types +
              types.all_int_types)
diff --git a/pypy/module/micronumpy/bench/dot.py b/pypy/module/micronumpy/bench/dot.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/bench/dot.py
@@ -0,0 +1,28 @@
+import time
+
+try:
+    import numpypy
+except ImportError:
+    pass
+
+import numpy
+
+def get_matrix():
+    import random
+    n = 502
+    x = numpy.zeros((n,n), dtype=numpy.float64)
+    for i in range(n):
+        for j in range(n):
+            x[i][j] = random.random()
+    return x
+
+def main():
+    x = get_matrix()
+    y = get_matrix()
+    a = time.time()
+    #z = numpy.dot(x, y)  # uses numpy possibly-blas-lib dot
+    z = numpy.core.multiarray.dot(x, y)  # uses strictly numpy C dot
+    b = time.time()
+    print '%.2f seconds' % (b-a)
+
+main()
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -75,6 +75,7 @@
     def __init__(self):
         """NOT_RPYTHON"""
         self.fromcache = InternalSpaceCache(self).getorbuild
+        self.w_Ellipsis = special.Ellipsis(self)
         self.w_NotImplemented = special.NotImplemented(self)
 
     def _freeze_(self):
@@ -217,7 +218,7 @@
         return w_type.lookup(name)
 
     def gettypefor(self, w_obj):
-        return None
+        return W_TypeObject(w_obj.typedef.name)
 
     def call_function(self, tp, w_dtype):
         return w_dtype
diff --git a/pypy/module/micronumpy/constants.py b/pypy/module/micronumpy/constants.py
--- a/pypy/module/micronumpy/constants.py
+++ b/pypy/module/micronumpy/constants.py
@@ -1,88 +1,88 @@
-NPY_BOOL = 0
-NPY_BYTE = 1
-NPY_UBYTE = 2
-NPY_SHORT = 3
-NPY_USHORT = 4
-NPY_INT = 5
-NPY_UINT = 6
-NPY_LONG = 7
-NPY_ULONG = 8
-NPY_LONGLONG = 9
-NPY_ULONGLONG = 10
-NPY_FLOAT = 11
-NPY_DOUBLE = 12
-NPY_LONGDOUBLE = 13
-NPY_CFLOAT = 14
-NPY_CDOUBLE = 15
-NPY_CLONGDOUBLE = 16
-NPY_OBJECT = 17
-NPY_STRING = 18
-NPY_UNICODE = 19
-NPY_VOID = 20
-NPY_DATETIME = 21
-NPY_TIMEDELTA = 22
-NPY_HALF = 23
-NPY_NTYPES = 24
-NPY_NOTYPE = 25
-NPY_CHAR = 26
-NPY_USERDEF = 256
+BOOL = 0
+BYTE = 1
+UBYTE = 2
+SHORT = 3
+USHORT = 4
+INT = 5
+UINT = 6
+LONG = 7
+ULONG = 8
+LONGLONG = 9
+ULONGLONG = 10
+FLOAT = 11
+DOUBLE = 12
+LONGDOUBLE = 13
+CFLOAT = 14
+CDOUBLE = 15
+CLONGDOUBLE = 16
+OBJECT = 17
+STRING = 18
+UNICODE = 19
+VOID = 20
+DATETIME = 21
+TIMEDELTA = 22
+HALF = 23
+NTYPES = 24
+NOTYPE = 25
+CHAR = 26
+USERDEF = 256
 
-NPY_BOOLLTR = '?'
-NPY_BYTELTR = 'b'
-NPY_UBYTELTR = 'B'
-NPY_SHORTLTR = 'h'
-NPY_USHORTLTR = 'H'
-NPY_INTLTR = 'i'
-NPY_UINTLTR = 'I'
-NPY_LONGLTR = 'l'
-NPY_ULONGLTR = 'L'
-NPY_LONGLONGLTR = 'q'
-NPY_ULONGLONGLTR = 'Q'
-NPY_HALFLTR = 'e'
-NPY_FLOATLTR = 'f'
-NPY_DOUBLELTR = 'd'
-NPY_LONGDOUBLELTR = 'g'
-NPY_CFLOATLTR = 'F'
-NPY_CDOUBLELTR = 'D'
-NPY_CLONGDOUBLELTR = 'G'
-NPY_OBJECTLTR = 'O'
-NPY_STRINGLTR = 'S'
-NPY_STRINGLTR2 = 'a'
-NPY_UNICODELTR = 'U'
-NPY_VOIDLTR = 'V'
-NPY_DATETIMELTR = 'M'
-NPY_TIMEDELTALTR = 'm'
-NPY_CHARLTR = 'c'
+BOOLLTR = '?'
+BYTELTR = 'b'
+UBYTELTR = 'B'
+SHORTLTR = 'h'
+USHORTLTR = 'H'
+INTLTR = 'i'
+UINTLTR = 'I'
+LONGLTR = 'l'
+ULONGLTR = 'L'
+LONGLONGLTR = 'q'
+ULONGLONGLTR = 'Q'
+HALFLTR = 'e'
+FLOATLTR = 'f'
+DOUBLELTR = 'd'
+LONGDOUBLELTR = 'g'
+CFLOATLTR = 'F'
+CDOUBLELTR = 'D'
+CLONGDOUBLELTR = 'G'
+OBJECTLTR = 'O'
+STRINGLTR = 'S'
+STRINGLTR2 = 'a'
+UNICODELTR = 'U'
+VOIDLTR = 'V'
+DATETIMELTR = 'M'
+TIMEDELTALTR = 'm'
+CHARLTR = 'c'
 
-NPY_INTPLTR = 'p'
-NPY_UINTPLTR = 'P'
+INTPLTR = 'p'
+UINTPLTR = 'P'
 
-NPY_GENBOOLLTR ='b'
-NPY_SIGNEDLTR = 'i'
-NPY_UNSIGNEDLTR = 'u'
-NPY_FLOATINGLTR = 'f'
-NPY_COMPLEXLTR = 'c'
+GENBOOLLTR ='b'
+SIGNEDLTR = 'i'
+UNSIGNEDLTR = 'u'
+FLOATINGLTR = 'f'
+COMPLEXLTR = 'c'
 
-NPY_ANYORDER = -1
-NPY_CORDER = 0
-NPY_FORTRANORDER = 1
-NPY_KEEPORDER = 2
+ANYORDER = -1
+CORDER = 0
+FORTRANORDER = 1
+KEEPORDER = 2
 
-NPY_CLIP = 0
-NPY_WRAP = 1
-NPY_RAISE = 2
+CLIP = 0
+WRAP = 1
+RAISE = 2
 
-NPY_LITTLE = '<'
-NPY_BIG = '>'
-NPY_NATIVE = '='
-NPY_SWAP = 's'
-NPY_IGNORE = '|'
+LITTLE = '<'
+BIG = '>'
+NATIVE = '='
+SWAP = 's'
+IGNORE = '|'
 
 import sys
 if sys.byteorder == 'big':
-    NPY_NATBYTE = NPY_BIG
-    NPY_OPPBYTE = NPY_LITTLE
+    NATBYTE = BIG
+    OPPBYTE = LITTLE
 else:
-    NPY_NATBYTE = NPY_LITTLE
-    NPY_OPPBYTE = NPY_BIG
+    NATBYTE = LITTLE
+    OPPBYTE = BIG
 del sys
diff --git a/pypy/module/micronumpy/conversion_utils.py b/pypy/module/micronumpy/conversion_utils.py
--- a/pypy/module/micronumpy/conversion_utils.py
+++ b/pypy/module/micronumpy/conversion_utils.py
@@ -1,21 +1,21 @@
 from pypy.interpreter.error import OperationError
-from pypy.module.micronumpy.constants import *
+from pypy.module.micronumpy import constants as NPY
 
 
 def byteorder_converter(space, new_order):
     endian = new_order[0]
-    if endian not in (NPY_BIG, NPY_LITTLE, NPY_NATIVE, NPY_IGNORE, NPY_SWAP):
+    if endian not in (NPY.BIG, NPY.LITTLE, NPY.NATIVE, NPY.IGNORE, NPY.SWAP):
         ch = endian
         if ch in ('b', 'B'):
-            endian = NPY_BIG
+            endian = NPY.BIG
         elif ch in ('l', 'L'):
-            endian = NPY_LITTLE
+            endian = NPY.LITTLE
         elif ch in ('n', 'N'):
-            endian = NPY_NATIVE
+            endian = NPY.NATIVE
         elif ch in ('i', 'I'):
-            endian = NPY_IGNORE
+            endian = NPY.IGNORE
         elif ch in ('s', 'S'):
-            endian = NPY_SWAP
+            endian = NPY.SWAP
         else:
             raise OperationError(space.w_ValueError, space.wrap(
                 "%s is an unrecognized byteorder" % new_order))
@@ -24,18 +24,18 @@
 
 def clipmode_converter(space, w_mode):
     if space.is_none(w_mode):
-        return NPY_RAISE
+        return NPY.RAISE
     if space.isinstance_w(w_mode, space.w_str):
         mode = space.str_w(w_mode)
         if mode.startswith('C') or mode.startswith('c'):
-            return NPY_CLIP
+            return NPY.CLIP
         if mode.startswith('W') or mode.startswith('w'):
-            return NPY_WRAP
+            return NPY.WRAP
         if mode.startswith('R') or mode.startswith('r'):
-            return NPY_RAISE
+            return NPY.RAISE
     elif space.isinstance_w(w_mode, space.w_int):
         mode = space.int_w(w_mode)
-        if NPY_CLIP <= mode <= NPY_RAISE:
+        if NPY.CLIP <= mode <= NPY.RAISE:
             return mode
     raise OperationError(space.w_TypeError,
                          space.wrap("clipmode not understood"))
@@ -46,19 +46,19 @@
         return default
     if not space.isinstance_w(w_order, space.w_str):
         if space.is_true(w_order):
-            return NPY_FORTRANORDER
+            return NPY.FORTRANORDER
         else:
-            return NPY_CORDER
+            return NPY.CORDER
     else:
         order = space.str_w(w_order)
         if order.startswith('C') or order.startswith('c'):
-            return NPY_CORDER
+            return NPY.CORDER
         elif order.startswith('F') or order.startswith('f'):
-            return NPY_FORTRANORDER
+            return NPY.FORTRANORDER
         elif order.startswith('A') or order.startswith('a'):
-            return NPY_ANYORDER
+            return NPY.ANYORDER
         elif order.startswith('K') or order.startswith('k'):
-            return NPY_KEEPORDER
+            return NPY.KEEPORDER
         else:
             raise OperationError(space.w_TypeError, space.wrap(
                 "order not understood"))
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
@@ -6,7 +6,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.module.micronumpy.conversion_utils import clipmode_converter
-from pypy.module.micronumpy.constants import *
+from pypy.module.micronumpy import constants as NPY
 
 def where(space, w_arr, w_x=None, w_y=None):
     """where(condition, [x, y])
@@ -238,12 +238,12 @@
         index = index_w(space, idx)
 
         if index < 0 or index >= arr.get_size():
-            if mode == NPY_RAISE:
+            if mode == NPY.RAISE:
                 raise OperationError(space.w_IndexError, space.wrap(
                     "index %d is out of bounds for axis 0 with size %d" % (index, arr.get_size())))
-            elif mode == NPY_WRAP:
+            elif mode == NPY.WRAP:
                 index = index % arr.get_size()
-            elif mode == NPY_CLIP:
+            elif mode == NPY.CLIP:
                 if index < 0:
                     index = 0
                 else:
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,8 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rlib.rstring import StringBuilder
-from pypy.module.micronumpy.constants import *
+from rpython.rlib import jit
+from pypy.module.micronumpy import constants as NPY
 
 
 MIXIN_32 = (W_IntObject.typedef,) if LONG_BIT == 32 else ()
@@ -33,6 +34,7 @@
 
 
 def new_dtype_getter(name):
+    @jit.elidable
     def _get_dtype(space):
         from pypy.module.micronumpy.interp_dtype import get_dtype_cache
         return get_dtype_cache(space).dtypes_by_name[name]
@@ -443,10 +445,10 @@
 
 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.LONGDOUBLELTR)
 
     class W_ComplexLongBox(ComplexBox, W_ComplexFloatingBox):
-        descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY_CLONGDOUBLELTR)
+        descr__new__, _get_dtype, descr_reduce = new_dtype_getter(NPY.CLONGDOUBLELTR)
         _COMPONENTS_BOX = W_FloatLongBox
 
 class W_FlexibleBox(W_GenericBox):
@@ -471,10 +473,10 @@
         elif space.isinstance_w(w_item, space.w_int):
             indx = space.int_w(w_item)
             try:
-                item = self.dtype.fieldnames[indx]
+                item = self.dtype.names[indx]
             except IndexError:
                 if indx < 0:
-                    indx += len(self.dtype.fieldnames)
+                    indx += len(self.dtype.names)
                 raise OperationError(space.w_IndexError, space.wrap(
                     "invalid index (%d)" % indx))
         else:
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
@@ -7,11 +7,10 @@
 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.rtyper.lltypesystem import rffi
 from rpython.rlib import jit
 from pypy.module.micronumpy.appbridge import get_appbridge_cache
 from pypy.module.micronumpy.conversion_utils import byteorder_converter
-from pypy.module.micronumpy.constants import *
+from pypy.module.micronumpy import constants as NPY
 
 
 def decode_w_dtype(space, w_dtype):
@@ -38,34 +37,40 @@
 
 
 class W_Dtype(W_Root):
-    _immutable_fields_ = ["itemtype?", "num", "kind", "name?", "char",
-                          "w_box_type", "byteorder", "size?", "float_type",
-                          "fields?", "fieldnames?", "shape", "subdtype", "base"]
+    _immutable_fields_ = [
+        "num", "kind", "char", "w_box_type", "float_type",
+        "itemtype?", "byteorder?", "names?", "fields?", "size?",
+        "shape?", "subdtype?", "base?",
+        "alternate_constructors", "aliases",
+    ]
 
-    def __init__(self, itemtype, num, kind, name, char, w_box_type, byteorder=NPY_NATIVE,
-                 size=1, alternate_constructors=[], aliases=[], float_type=None,
-                 fields=None, fieldnames=None, shape=[], subdtype=None):
+    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=[]):
         self.itemtype = itemtype
         self.num = num
         self.kind = kind
-        self.name = name
         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
+            else:
+                byteorder = NPY.NATIVE
         self.byteorder = byteorder
+        self.names = names
+        self.fields = fields
         self.size = size
-        self.alternate_constructors = alternate_constructors
-        self.aliases = aliases
-        self.float_type = float_type
-        self.fields = fields
-        if fieldnames is None:
-            fieldnames = []
-        self.fieldnames = fieldnames
-        self.shape = list(shape)
+        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:
@@ -87,54 +92,76 @@
         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)
+        return (self.kind == NPY.SIGNEDLTR or self.kind == NPY.UNSIGNEDLTR or
+                self.kind == NPY.GENBOOLLTR)
 
     def is_signed(self):
-        return self.kind == NPY_SIGNEDLTR
+        return self.kind == NPY.SIGNEDLTR
 
     def is_complex_type(self):
-        return self.kind == NPY_COMPLEXLTR
+        return self.kind == NPY.COMPLEXLTR
 
     def is_float_type(self):
-        return self.kind == NPY_FLOATINGLTR or self.kind == NPY_COMPLEXLTR
+        return self.kind == NPY.FLOATINGLTR or self.kind == NPY.COMPLEXLTR
 
     def is_bool_type(self):
-        return self.kind == NPY_GENBOOLLTR
+        return self.kind == NPY.GENBOOLLTR
 
     def is_record_type(self):
-        return self.fields is not None
+        return bool(self.fields)
 
     def is_str_type(self):
-        return self.num == NPY_STRING
+        return self.num == NPY.STRING
 
     def is_str_or_unicode(self):
-        return (self.num == NPY_STRING or self.num == NPY_UNICODE)
+        return self.num == NPY.STRING or self.num == NPY.UNICODE
 
     def is_flexible_type(self):
-        return (self.is_str_or_unicode() or self.is_record_type())
+        return self.is_str_or_unicode() or self.num == NPY.VOID
 
     def is_native(self):
-        return self.byteorder in (NPY_NATIVE, NPY_NATBYTE)
+        return self.byteorder in (NPY.NATIVE, NPY.NATBYTE)
 
     def get_size(self):
         return self.size * self.itemtype.get_element_size()
 
-    def get_name(self):
-        if self.char == 'S':
-            return '|S' + str(self.get_size())
-        return self.name
-
     def get_float_dtype(self, space):
-        assert self.kind == NPY_COMPLEXLTR
+        assert self.kind == NPY.COMPLEXLTR
         assert self.float_type is not None
-        return get_dtype_cache(space).dtypes_by_name[self.byteorder + self.float_type]
+        dtype = get_dtype_cache(space).dtypes_by_name[self.float_type]
+        if self.byteorder == NPY.OPPBYTE:
+            dtype = dtype.descr_newbyteorder(space)
+        return dtype
 
     def descr_str(self, space):
-        return space.wrap(self.get_name())
+        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):
-        return space.wrap("dtype('%s')" % self.get_name())
+        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())
@@ -142,23 +169,39 @@
     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
+
+    def descr_get_name(self, space):
+        name = self.get_name()
+        if name[-1] == '_':
+            name = name[:-1]
+        if self.is_flexible_type():
+            return space.wrap(name + str(self.get_size() * 8))
+        return space.wrap(name)
+
     def descr_get_str(self, space):
         size = self.get_size()
         basic = self.kind
-        if basic == NPY_UNICODELTR:
+        if basic == NPY.UNICODELTR:
             size >>= 2
-            endian = NPY_NATBYTE
+            endian = NPY.NATBYTE
         elif size // (self.size or 1) <= 1:
-            endian = NPY_IGNORE
+            endian = NPY.IGNORE
         else:
             endian = self.byteorder
-            if endian == NPY_NATIVE:
-                endian = NPY_NATBYTE
+            if endian == NPY.NATIVE:
+                endian = NPY.NATBYTE
         return space.wrap("%s%s%s" % (endian, basic, size))
 
     def descr_get_descr(self, space):
@@ -167,7 +210,7 @@
                                                   self.descr_get_str(space)])])
         else:
             descr = []
-            for name in self.fieldnames:
+            for name in self.names:
                 subdtype = self.fields[name][1]
                 subdescr = [space.wrap(name)]
                 if subdtype.is_record_type():
@@ -206,56 +249,42 @@
         return space.wrap(not self.eq(space, w_other))
 
     def descr_get_fields(self, space):
-        if self.fields is None:
+        if not self.fields:
             return space.w_None
         w_d = space.newdict()
         for name, (offset, subdtype) in self.fields.iteritems():
-            space.setitem(w_d, space.wrap(name), space.newtuple([subdtype,
-                                                                 space.wrap(offset)]))
+            space.setitem(w_d, space.wrap(name),
+                          space.newtuple([subdtype, space.wrap(offset)]))
         return w_d
 
-    def descr_set_fields(self, space, w_fields):
-        if w_fields == space.w_None:
-            self.fields = None
-        else:
-            self.fields = {}
-            size = 0
-            for key in space.listview(w_fields):
-                value = space.getitem(w_fields, key)
-
-                dtype = space.getitem(value, space.wrap(0))
-                assert isinstance(dtype, W_Dtype)
-
-                offset = space.int_w(space.getitem(value, space.wrap(1)))
-                self.fields[space.str_w(key)] = offset, dtype
-
-                size += dtype.get_size()
-
-            self.itemtype = types.RecordType()
-            self.size = size
-            self.name = "void" + str(8 * self.get_size())
-
     def descr_get_names(self, space):
-        if len(self.fieldnames) == 0:
+        if not self.fields:
             return space.w_None
-        return space.newtuple([space.wrap(name) for name in self.fieldnames])
+        return space.newtuple([space.wrap(name) for name in self.names])
 
     def descr_set_names(self, space, w_names):
-        fieldnames = []
-        if w_names != space.w_None:
-            iter = space.iter(w_names)
-            while True:
-                try:
-                    name = space.str_w(space.next(iter))
-                except OperationError, e:
-                    if not e.match(space, space.w_StopIteration):
-                        raise
-                    break
-                if name in fieldnames:
-                    raise OperationError(space.w_ValueError, space.wrap(
-                        "Duplicate field names given."))
-                fieldnames.append(name)
-        self.fieldnames = fieldnames
+        if not self.fields:
+            raise oefmt(space.w_ValueError, "there are no fields defined")
+        if not space.issequence_w(w_names) or \
+                space.len_w(w_names) != len(self.names):
+            raise oefmt(space.w_ValueError,
+                        "must replace all names at once "
+                        "with a sequence of length %d",
+                        len(self.names))
+        names = []
+        for w_name in space.fixedview(w_names):
+            if not space.isinstance_w(w_name, space.w_str):
+                raise oefmt(space.w_ValueError,
+                            "item #%d of names is of type %T and not string",
+                            len(names), w_name)
+            names.append(space.str_w(w_name))
+        fields = {}
+        for i in range(len(self.names)):
+            if names[i] in fields:
+                raise oefmt(space.w_ValueError, "Duplicate field names given.")
+            fields[names[i]] = self.fields[self.names[i]]
+        self.fields = fields
+        self.names = names
 
     def descr_del_names(self, space):
         raise OperationError(space.w_AttributeError, space.wrap(
@@ -265,15 +294,15 @@
         return space.w_False
 
     def descr_getitem(self, space, w_item):
-        if self.fields is None:
-            raise OperationError(space.w_KeyError, space.wrap(
-                "There are no fields in dtype %s." % self.name))
+        if not self.fields:
+            raise oefmt(space.w_KeyError, "There are no fields in dtype %s.",
+                        self.get_name())
         if space.isinstance_w(w_item, space.w_basestring):
             item = space.str_w(w_item)
         elif space.isinstance_w(w_item, space.w_int):
             indx = space.int_w(w_item)
             try:
-                item = self.fieldnames[indx]
+                item = self.names[indx]
             except IndexError:
                 raise OperationError(space.w_IndexError, space.wrap(
                     "Field index %d out of range." % indx))
@@ -287,7 +316,7 @@
                 "Field named '%s' not found." % item))
 
     def descr_len(self, space):
-        if self.fields is None:
+        if not self.fields:
             return space.wrap(0)
         return space.wrap(len(self.fields))
 
@@ -305,7 +334,7 @@
         names = self.descr_get_names(space)
         values = self.descr_get_fields(space)
         if self.fields:
-            endian = NPY_IGNORE
+            endian = NPY.IGNORE
             #TODO: Implement this when subarrays are implemented
             subdescr = space.w_None
             size = 0
@@ -318,8 +347,8 @@
             alignment = space.wrap(1)
         else:
             endian = self.byteorder
-            if endian == NPY_NATIVE:
-                endian = NPY_NATBYTE
+            if endian == NPY.NATIVE:
+                endian = NPY.NATBYTE
             subdescr = space.w_None
             w_size = space.wrap(-1)
             alignment = space.wrap(-1)
@@ -329,32 +358,77 @@
         return space.newtuple([w_class, builder_args, data])
 
     def descr_setstate(self, space, w_data):
-        if space.int_w(space.getitem(w_data, space.wrap(0))) != 3:
-            raise OperationError(space.w_NotImplementedError, space.wrap("Pickling protocol version not supported"))
+        if self.fields is None:  # if builtin dtype
+            return space.w_None
+
+        version = space.int_w(space.getitem(w_data, space.wrap(0)))
+        if version != 3:
+            raise oefmt(space.w_ValueError,
+                        "can't handle version %d of numpy.dtype pickle",
+                        version)
 
         endian = space.str_w(space.getitem(w_data, space.wrap(1)))
-        if endian == NPY_NATBYTE:
-            endian = NPY_NATIVE
+        if endian == NPY.NATBYTE:
+            endian = NPY.NATIVE
+
+        w_subarray = space.getitem(w_data, space.wrap(2))
+        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)))
+
+        if (w_names == space.w_None) != (w_fields == space.w_None):
+            raise oefmt(space.w_ValueError, "inconsistent fields and names")
+
         self.byteorder = endian
+        self.shape = []
+        self.subdtype = None
+        self.base = self
 
-        fieldnames = space.getitem(w_data, space.wrap(3))
-        self.descr_set_names(space, fieldnames)
+        if w_subarray != space.w_None:
+            if not space.isinstance_w(w_subarray, space.w_tuple) or \
+                    space.len_w(w_subarray) != 2:
+                raise oefmt(space.w_ValueError,
+                            "incorrect subarray in __setstate__")
+            subdtype, w_shape = space.fixedview(w_subarray)
+            assert isinstance(subdtype, W_Dtype)
+            if not base.issequence_w(space, w_shape):
+                self.shape = [space.int_w(w_shape)]
+            else:
+                self.shape = [space.int_w(w_s) for w_s in space.fixedview(w_shape)]
+            self.subdtype = subdtype
+            self.base = subdtype.base
 
-        fields = space.getitem(w_data, space.wrap(4))
-        self.descr_set_fields(space, fields)
+        if w_names != space.w_None:
+            self.names = []
+            self.fields = {}
+            for w_name in space.fixedview(w_names):
+                name = space.str_w(w_name)
+                value = space.getitem(w_fields, w_name)
+
+                dtype = space.getitem(value, space.wrap(0))
+                assert isinstance(dtype, W_Dtype)
+                offset = space.int_w(space.getitem(value, space.wrap(1)))
+
+                self.names.append(name)
+                self.fields[name] = offset, dtype
+            self.itemtype = types.RecordType()
+
+        if self.is_flexible_type():
+            self.size = size
 
     @unwrap_spec(new_order=str)
-    def descr_newbyteorder(self, space, new_order=NPY_SWAP):
+    def descr_newbyteorder(self, space, new_order=NPY.SWAP):
         newendian = byteorder_converter(space, new_order)
         endian = self.byteorder
-        if endian != NPY_IGNORE:
-            if newendian == NPY_SWAP:
-                endian = NPY_OPPBYTE if self.is_native() else NPY_NATBYTE
-            elif newendian != NPY_IGNORE:
+        if endian != NPY.IGNORE:
+            if newendian == NPY.SWAP:
+                endian = NPY.OPPBYTE if self.is_native() else NPY.NATBYTE
+            elif newendian != NPY.IGNORE:
                 endian = newendian
-        itemtype = self.itemtype.__class__(endian in (NPY_NATIVE, NPY_NATBYTE))
-        return W_Dtype(itemtype, self.num, self.kind, self.name, self.char,
-                       self.w_box_type, endian, size=self.size)
+        itemtype = self.itemtype.__class__(endian in (NPY.NATIVE, NPY.NATBYTE))
+        return W_Dtype(itemtype, self.num, self.kind, self.char,
+                       self.w_box_type, self.float_type, byteorder=endian,
+                       size=self.size)
 
 
 @specialize.arg(2)
@@ -362,7 +436,7 @@
     lst_w = space.listview(w_lst)
     fields = {}
     offset = 0
-    fieldnames = []
+    names = []
     for i in range(len(lst_w)):
         w_elem = lst_w[i]
         if simple:
@@ -385,12 +459,10 @@
         assert isinstance(subdtype, W_Dtype)
         fields[fldname] = (offset, subdtype)
         offset += subdtype.get_size()
-        fieldnames.append(fldname)
-    itemtype = types.RecordType()
-    return W_Dtype(itemtype, NPY_VOID, NPY_VOIDLTR,
-                   "void" + str(8 * offset * itemtype.get_element_size()),
-                   NPY_VOIDLTR, space.gettypefor(interp_boxes.W_VoidBox),
-                   fields=fields, fieldnames=fieldnames, size=offset)
+        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)
 
 
 def dtype_from_dict(space, w_dict):
@@ -429,11 +501,10 @@
             size *= dim
         if size == 1:
             return subdtype
-        return W_Dtype(types.VoidType(), NPY_VOID, NPY_VOIDLTR,
-                       "void" + str(8 * subdtype.get_size() * size),
-                       NPY_VOIDLTR, space.gettypefor(interp_boxes.W_VoidBox),
-                       shape=shape, subdtype=subdtype,
-                       size=subdtype.get_size() * size)
+        size *= subdtype.get_size()
+        return W_Dtype(types.VoidType(), NPY.VOID, NPY.VOIDLTR, NPY.VOIDLTR,
+                       space.gettypefor(interp_boxes.W_VoidBox),
+                       shape=shape, subdtype=subdtype, size=size)
 
     if space.is_none(w_dtype):
         return cache.w_float64dtype
@@ -443,10 +514,15 @@
         name = space.str_w(w_dtype)
         if ',' in name:
             return dtype_from_spec(space, w_dtype)
+        cname = name[1:] if name[0] == NPY.OPPBYTE else name
         try:
-            return cache.dtypes_by_name[name]
+            dtype = cache.dtypes_by_name[cname]
         except KeyError:
             pass
+        else:
+            if name[0] == NPY.OPPBYTE:
+                dtype = dtype.descr_newbyteorder(space)
+            return dtype
         if name[0] in 'VSUc' or name[0] in '<>=|' and name[1] in 'VSUc':
             return variable_dtype(space, name)
         raise oefmt(space.w_TypeError, 'data type "%s" not understood', name)
@@ -495,10 +571,11 @@
     byteorder = interp_attrproperty("byteorder", cls=W_Dtype),
     itemsize = GetSetProperty(W_Dtype.descr_get_itemsize),
     alignment = GetSetProperty(W_Dtype.descr_get_alignment),
+    isbuiltin = GetSetProperty(W_Dtype.descr_get_isbuiltin),
 
     subdtype = GetSetProperty(W_Dtype.descr_get_subdtype),
     str = GetSetProperty(W_Dtype.descr_get_str),
-    name = interp_attrproperty("name", cls=W_Dtype),
+    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),
@@ -522,57 +599,50 @@
         try:
             size = int(name[1:])
         except ValueError:
-            raise OperationError(space.w_TypeError, space.wrap("data type not understood"))
-    if char == NPY_CHARLTR:
-        char = NPY_STRINGLTR
+            raise oefmt(space.w_TypeError, "data type not understood")
+    if char == NPY.CHARLTR:
+        char = NPY.STRINGLTR
         size = 1
 
-    if char == NPY_STRINGLTR:
-        itemtype = types.StringType()
-        basename = 'string'
-        num = NPY_STRING
-        w_box_type = space.gettypefor(interp_boxes.W_StringBox)
-    elif char == NPY_VOIDLTR:
-        itemtype = types.VoidType()
-        basename = 'void'
-        num = NPY_VOID
-        w_box_type = space.gettypefor(interp_boxes.W_VoidBox)
-    elif char == NPY_UNICODELTR:
-        itemtype = types.UnicodeType()
-        basename = 'unicode'
-        num = NPY_UNICODE
-        w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox)
-    else:
-        assert False
-
-    return W_Dtype(itemtype, num, char,
-                   basename + str(8 * size * itemtype.get_element_size()),
-                   char, w_box_type, size=size)
+    if char == NPY.STRINGLTR:
+        return new_string_dtype(space, size)
+    elif char == NPY.UNICODELTR:
+        return new_unicode_dtype(space, size)
+    elif char == NPY.VOIDLTR:
+        return new_void_dtype(space, size)
+    assert False
 
 
 def new_string_dtype(space, size):
-    itemtype = types.StringType()
     return W_Dtype(
-        itemtype,
+        types.StringType(),
         size=size,
-        num=NPY_STRING,
-        kind=NPY_STRINGLTR,
-        name='string' + str(8 * size * itemtype.get_element_size()),
-        char=NPY_STRINGLTR,
-        w_box_type = space.gettypefor(interp_boxes.W_StringBox),
+        num=NPY.STRING,
+        kind=NPY.STRINGLTR,
+        char=NPY.STRINGLTR,
+        w_box_type=space.gettypefor(interp_boxes.W_StringBox),
     )
 
 
 def new_unicode_dtype(space, size):
-    itemtype = types.UnicodeType()
     return W_Dtype(
-        itemtype,
+        types.UnicodeType(),
         size=size,
-        num=NPY_UNICODE,
-        kind=NPY_UNICODELTR,
-        name='unicode' + str(8 * size * itemtype.get_element_size()),
-        char=NPY_UNICODELTR,
-        w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox),
+        num=NPY.UNICODE,
+        kind=NPY.UNICODELTR,
+        char=NPY.UNICODELTR,
+        w_box_type=space.gettypefor(interp_boxes.W_UnicodeBox),
+    )
+
+
+def new_void_dtype(space, size):
+    return W_Dtype(
+        types.VoidType(),
+        size=size,
+        num=NPY.VOID,
+        kind=NPY.VOIDLTR,
+        char=NPY.VOIDLTR,
+        w_box_type=space.gettypefor(interp_boxes.W_VoidBox),
     )
 
 
@@ -580,125 +650,112 @@
     def __init__(self, space):
         self.w_booldtype = W_Dtype(
             types.Bool(),
-            num=NPY_BOOL,
-            kind=NPY_GENBOOLLTR,
-            name="bool",
-            char=NPY_BOOLLTR,
+            num=NPY.BOOL,
+            kind=NPY.GENBOOLLTR,
+            char=NPY.BOOLLTR,
             w_box_type=space.gettypefor(interp_boxes.W_BoolBox),
             alternate_constructors=[space.w_bool],
-            aliases=['bool8'],
+            aliases=['bool', 'bool8'],
         )
         self.w_int8dtype = W_Dtype(
             types.Int8(),
-            num=NPY_BYTE,
-            kind=NPY_SIGNEDLTR,
-            name="int8",
-            char=NPY_BYTELTR,
+            num=NPY.BYTE,
+            kind=NPY.SIGNEDLTR,
+            char=NPY.BYTELTR,
             w_box_type=space.gettypefor(interp_boxes.W_Int8Box),
             aliases=['byte'],
         )
         self.w_uint8dtype = W_Dtype(
             types.UInt8(),
-            num=NPY_UBYTE,
-            kind=NPY_UNSIGNEDLTR,
-            name="uint8",
-            char=NPY_UBYTELTR,
+            num=NPY.UBYTE,
+            kind=NPY.UNSIGNEDLTR,
+            char=NPY.UBYTELTR,
             w_box_type=space.gettypefor(interp_boxes.W_UInt8Box),
             aliases=['ubyte'],
         )
         self.w_int16dtype = W_Dtype(
             types.Int16(),
-            num=NPY_SHORT,
-            kind=NPY_SIGNEDLTR,
-            name="int16",
-            char=NPY_SHORTLTR,
+            num=NPY.SHORT,
+            kind=NPY.SIGNEDLTR,
+            char=NPY.SHORTLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Int16Box),
             aliases=['short'],
         )
         self.w_uint16dtype = W_Dtype(
             types.UInt16(),
-            num=NPY_USHORT,
-            kind=NPY_UNSIGNEDLTR,
-            name="uint16",
-            char=NPY_USHORTLTR,
+            num=NPY.USHORT,
+            kind=NPY.UNSIGNEDLTR,
+            char=NPY.USHORTLTR,
             w_box_type=space.gettypefor(interp_boxes.W_UInt16Box),
             aliases=['ushort'],
         )
         self.w_int32dtype = W_Dtype(
             types.Int32(),
-            num=NPY_INT,
-            kind=NPY_SIGNEDLTR,
-            name="int32",
-            char=NPY_INTLTR,
+            num=NPY.INT,
+            kind=NPY.SIGNEDLTR,
+            char=NPY.INTLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Int32Box),
         )
         self.w_uint32dtype = W_Dtype(
             types.UInt32(),
-            num=NPY_UINT,
-            kind=NPY_UNSIGNEDLTR,
-            name="uint32",
-            char=NPY_UINTLTR,
+            num=NPY.UINT,
+            kind=NPY.UNSIGNEDLTR,
+            char=NPY.UINTLTR,
             w_box_type=space.gettypefor(interp_boxes.W_UInt32Box),
         )
         self.w_longdtype = W_Dtype(
             types.Long(),
-            num=NPY_LONG,
-            kind=NPY_SIGNEDLTR,
-            name="int%d" % LONG_BIT,
-            char=NPY_LONGLTR,
+            num=NPY.LONG,
+            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'],
+            aliases=['int', 'intp', 'p'],
         )
         self.w_ulongdtype = W_Dtype(
             types.ULong(),
-            num=NPY_ULONG,
-            kind=NPY_UNSIGNEDLTR,
-            name="uint%d" % LONG_BIT,
-            char=NPY_ULONGLTR,
+            num=NPY.ULONG,
+            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'],
+            aliases=['uint', 'uintp', 'P'],
         )
         self.w_int64dtype = W_Dtype(
             types.Int64(),
-            num=NPY_LONGLONG,
-            kind=NPY_SIGNEDLTR,
-            name="int64",
-            char=NPY_LONGLONGLTR,
+            num=NPY.LONGLONG,
+            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(),
-            num=NPY_ULONGLONG,
-            kind=NPY_UNSIGNEDLTR,
-            name="uint64",
-            char=NPY_ULONGLONGLTR,
+            num=NPY.ULONGLONG,
+            kind=NPY.UNSIGNEDLTR,
+            char=NPY.ULONGLONGLTR,
             w_box_type=space.gettypefor(interp_boxes.W_UInt64Box),
             aliases=['ulonglong'],
         )
         self.w_float32dtype = W_Dtype(
             types.Float32(),
-            num=NPY_FLOAT,
-            kind=NPY_FLOATINGLTR,
-            name="float32",
-            char=NPY_FLOATLTR,
+            num=NPY.FLOAT,
+            kind=NPY.FLOATINGLTR,
+            char=NPY.FLOATLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Float32Box),
             aliases=['single']
         )
         self.w_float64dtype = W_Dtype(
             types.Float64(),
-            num=NPY_DOUBLE,
-            kind=NPY_FLOATINGLTR,
-            name="float64",
-            char=NPY_DOUBLELTR,
-            w_box_type = space.gettypefor(interp_boxes.W_Float64Box),
+            num=NPY.DOUBLE,
+            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),
@@ -707,75 +764,69 @@
         )
         self.w_floatlongdtype = W_Dtype(
             types.FloatLong(),
-            num=NPY_LONGDOUBLE,
-            kind=NPY_FLOATINGLTR,
-            name="float%d" % (interp_boxes.long_double_size * 8),
-            char=NPY_LONGDOUBLELTR,
+            num=NPY.LONGDOUBLE,
+            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(),
-            num=NPY_CFLOAT,
-            kind=NPY_COMPLEXLTR,
-            name="complex64",
-            char=NPY_CFLOATLTR,
-            w_box_type = space.gettypefor(interp_boxes.W_Complex64Box),
+            num=NPY.CFLOAT,
+            kind=NPY.COMPLEXLTR,
+            char=NPY.CFLOATLTR,
+            w_box_type=space.gettypefor(interp_boxes.W_Complex64Box),
             aliases=['csingle'],
-            float_type=NPY_FLOATLTR,
+            float_type=NPY.FLOATLTR,
         )
         self.w_complex128dtype = W_Dtype(
             types.Complex128(),
-            num=NPY_CDOUBLE,
-            kind=NPY_COMPLEXLTR,
-            name="complex128",
-            char=NPY_CDOUBLELTR,
-            w_box_type = space.gettypefor(interp_boxes.W_Complex128Box),
+            num=NPY.CDOUBLE,
+            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,
+            float_type=NPY.DOUBLELTR,
         )
         self.w_complexlongdtype = W_Dtype(
             types.ComplexLong(),
-            num=NPY_CLONGDOUBLE,
-            kind=NPY_COMPLEXLTR,
-            name="complex%d" % (interp_boxes.long_double_size * 16),
-            char=NPY_CLONGDOUBLELTR,
-            w_box_type = space.gettypefor(interp_boxes.W_ComplexLongBox),
+            num=NPY.CLONGDOUBLE,
+            kind=NPY.COMPLEXLTR,
+            char=NPY.CLONGDOUBLELTR,
+            w_box_type=space.gettypefor(interp_boxes.W_ComplexLongBox),
             aliases=["clongdouble", "clongfloat"],
-            float_type=NPY_LONGDOUBLELTR,
+            float_type=NPY.LONGDOUBLELTR,
         )
         self.w_stringdtype = W_Dtype(
             types.StringType(),
             size=0,
-            num=NPY_STRING,
-            kind=NPY_STRINGLTR,
-            name='string',
-            char=NPY_STRINGLTR,
-            w_box_type = space.gettypefor(interp_boxes.W_StringBox),
+            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=["str"],
+            aliases=['string', "str"],
         )
         self.w_unicodedtype = W_Dtype(
             types.UnicodeType(),
             size=0,
-            num=NPY_UNICODE,
-            kind=NPY_UNICODELTR,
-            name='unicode',
-            char=NPY_UNICODELTR,
-            w_box_type = space.gettypefor(interp_boxes.W_UnicodeBox),
+            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,
-            num=NPY_VOID,
-            kind=NPY_VOIDLTR,
-            name='void',
-            char=NPY_VOIDLTR,
-            w_box_type = space.gettypefor(interp_boxes.W_VoidBox),
+            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)],
@@ -783,27 +834,24 @@
         )
         self.w_float16dtype = W_Dtype(
             types.Float16(),
-            num=NPY_HALF,
-            kind=NPY_FLOATINGLTR,
-            name="float16",
-            char=NPY_HALFLTR,
+            num=NPY.HALF,
+            kind=NPY.FLOATINGLTR,
+            char=NPY.HALFLTR,
             w_box_type=space.gettypefor(interp_boxes.W_Float16Box),
         )
         self.w_intpdtype = W_Dtype(
             types.Long(),
-            num=NPY_LONG,
-            kind=NPY_SIGNEDLTR,
-            name='intp',
-            char=NPY_INTPLTR,
-            w_box_type = space.gettypefor(interp_boxes.W_LongBox),
+            num=NPY.LONG,
+            kind=NPY.SIGNEDLTR,
+            char=NPY.INTPLTR,
+            w_box_type=space.gettypefor(interp_boxes.W_LongBox),
         )
         self.w_uintpdtype = W_Dtype(
             types.ULong(),
-            num=NPY_ULONG,
-            kind=NPY_UNSIGNEDLTR,
-            name='uintp',
-            char=NPY_UINTPLTR,
-            w_box_type = space.gettypefor(interp_boxes.W_ULongBox),
+            num=NPY.ULONG,
+            kind=NPY.UNSIGNEDLTR,
+            char=NPY.UINTPLTR,
+            w_box_type=space.gettypefor(interp_boxes.W_ULongBox),
         )
         float_dtypes = [self.w_float16dtype, self.w_float32dtype,
                         self.w_float64dtype, self.w_floatlongdtype]
@@ -829,20 +877,15 @@
         # we reverse, so the stuff with lower numbers override stuff with
         # higher numbers
         for dtype in reversed(self.builtin_dtypes):
+            dtype.fields = None  # mark these as builtin
             self.dtypes_by_num[dtype.num] = dtype
-            self.dtypes_by_name[dtype.name] = dtype
+            self.dtypes_by_name[dtype.get_name()] = dtype
             for can_name in [dtype.kind + str(dtype.get_size()),
                              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
-                new_name = NPY_OPPBYTE + can_name
-                itemtype = type(dtype.itemtype)(False)
-                self.dtypes_by_name[new_name] = W_Dtype(
-                    itemtype, dtype.num, dtype.kind, new_name, dtype.char,
-                    dtype.w_box_type, byteorder=NPY_OPPBYTE,
-                    float_type=dtype.float_type)
+                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
 
@@ -898,7 +941,7 @@
                        space.wrap(itembits),
                        space.wrap(dtype.itemtype.get_element_size())]
             if dtype.is_int_type():
-                if dtype.kind == NPY_GENBOOLLTR:
+                if dtype.kind == NPY.GENBOOLLTR:
                     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
@@ -23,7 +23,7 @@
 from pypy.module.micronumpy.arrayimpl.base import BaseArrayImplementation
 from pypy.module.micronumpy.conversion_utils import order_converter, multi_axis_converter
 from pypy.module.micronumpy import support
-from pypy.module.micronumpy.constants import *
+from pypy.module.micronumpy import constants as NPY
 
 def _find_shape(space, w_size, dtype):
     if space.is_none(w_size):
@@ -110,8 +110,8 @@
         self.fill(space, self.get_dtype().coerce(space, w_value))
 
     def descr_tostring(self, space, w_order=None):
-        order = order_converter(space, w_order, NPY_CORDER)
-        if order == NPY_FORTRANORDER:
+        order = order_converter(space, w_order, NPY.CORDER)
+        if order == NPY.FORTRANORDER:
             raise OperationError(space.w_NotImplementedError, space.wrap(
                 "unsupported value for order"))
         return space.wrap(loop.tostring(space, self))
@@ -218,7 +218,9 @@
                                prefix)
 
     def descr_getitem(self, space, w_idx):
-        if isinstance(w_idx, W_NDimArray) and w_idx.get_dtype().is_bool_type() \
+        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() \
                 and len(w_idx.get_shape()) > 0:
             return self.getitem_filter(space, w_idx)
         try:
@@ -320,8 +322,8 @@
         return self.implementation.get_scalar_value()
 
     def descr_copy(self, space, w_order=None):
-        order = order_converter(space, w_order, NPY_KEEPORDER)
-        if order == NPY_FORTRANORDER:
+        order = order_converter(space, w_order, NPY.KEEPORDER)
+        if order == NPY.FORTRANORDER:
             raise OperationError(space.w_NotImplementedError, space.wrap(
                 "unsupported value for order"))
         copy = self.implementation.copy(space)
@@ -375,7 +377,7 @@
         numpy.reshape : equivalent function
         """
         args_w, kw_w = __args__.unpack()
-        order = NPY_CORDER
+        order = NPY.CORDER
         if kw_w:
             if "order" in kw_w:
                 order = order_converter(space, kw_w["order"], order)
@@ -383,10 +385,10 @@
             if kw_w:
                 raise OperationError(space.w_TypeError, space.wrap(
                     "reshape() got unexpected keyword argument(s)"))
-        if order == NPY_KEEPORDER:
+        if order == NPY.KEEPORDER:
             raise OperationError(space.w_ValueError, space.wrap(
                 "order 'K' is not permitted for reshaping"))
-        if order != NPY_CORDER and order != NPY_ANYORDER:
+        if order != NPY.CORDER and order != NPY.ANYORDER:
             raise OperationError(space.w_NotImplementedError, space.wrap(
                 "unsupported value for order"))
         if len(args_w) == 1:
@@ -561,7 +563,7 @@
         # by converting nonnative byte order.
         if self.is_scalar():
             return space.wrap(0)
-        dtype = self.get_dtype().descr_newbyteorder(space, NPY_NATIVE)
+        dtype = self.get_dtype().descr_newbyteorder(space, NPY.NATIVE)
         contig = self.implementation.astype(space, dtype)
         return contig.argsort(space, w_axis)
 
@@ -569,9 +571,14 @@
         cur_dtype = self.get_dtype()
         new_dtype = space.interp_w(interp_dtype.W_Dtype,
             space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
-        if new_dtype.shape:
+        if new_dtype.num == NPY.VOID:
             raise oefmt(space.w_NotImplementedError,
-                "%s.astype(%s) not implemented yet", cur_dtype.name, new_dtype.name)
+                        "astype(%s) not implemented yet",
+                        new_dtype.get_name())
+        if new_dtype.num == NPY.STRING and new_dtype.size == 0:
+            if cur_dtype.num == NPY.STRING:
+                new_dtype = interp_dtype.variable_dtype(space,
+                    'S' + str(cur_dtype.size))
         impl = self.implementation
         if isinstance(impl, scalar.Scalar):
             return W_NDimArray.new_scalar(space, new_dtype, impl.value)
@@ -662,7 +669,7 @@
             "getfield not implemented yet"))
 
     @unwrap_spec(new_order=str)
-    def descr_newbyteorder(self, space, new_order=NPY_SWAP):
+    def descr_newbyteorder(self, space, new_order=NPY.SWAP):
         return self.descr_view(space,
             self.get_dtype().descr_newbyteorder(space, new_order))
 
@@ -1023,7 +1030,7 @@
             except AttributeError:
                 raise oefmt(space.w_NotImplementedError,
                             '%s not implemented for %s',
-                            op_name, self.get_dtype().name)
+                            op_name, self.get_dtype().get_name())
             return space.wrap(res)
         return func_with_new_name(impl, "reduce_arg%s_impl" % op_name)
 
@@ -1138,7 +1145,7 @@
                  "__setstate__ called with len(args[1])==%d, not 5 or 4" % lens))
         shape = space.getitem(w_state, space.wrap(base_index))
         dtype = space.getitem(w_state, space.wrap(base_index+1))
-        isfortran = space.getitem(w_state, space.wrap(base_index+2))
+        #isfortran = space.getitem(w_state, space.wrap(base_index+2))
         storage = space.getitem(w_state, space.wrap(base_index+3))
         if not isinstance(dtype, interp_dtype.W_Dtype):
             raise OperationError(space.w_ValueError, space.wrap(
@@ -1192,8 +1199,8 @@
                                                   w_base=w_buffer,
                                                   writable=buf.is_writable())
 
-    order = order_converter(space, w_order, NPY_CORDER)
-    if order == NPY_CORDER:
+    order = order_converter(space, w_order, NPY.CORDER)
+    if order == NPY.CORDER:
         order = 'C'
     else:
         order = 'F'
@@ -1230,7 +1237,8 @@
 
 app_take = applevel(r"""
     def take(a, indices, axis, out, mode):
-        assert mode == 'raise'
+        if mode != 'raise':
+            raise NotImplementedError("mode != raise not implemented")
         if axis is None:
             from numpy import array
             indices = array(indices)
@@ -1440,7 +1448,7 @@
     # 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():
+        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)
 
@@ -1493,6 +1501,8 @@
 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:
+        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)
 
@@ -1504,6 +1514,8 @@
     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:
+            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)
 
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
@@ -9,7 +9,7 @@
 from pypy.module.micronumpy.interp_support import unwrap_axis_arg
 from pypy.module.micronumpy.strides import shape_agreement
 from pypy.module.micronumpy.base import convert_to_array, W_NDimArray
-from pypy.module.micronumpy.constants import *
+from pypy.module.micronumpy import constants as NPY
 
 def done_if_true(dtype, val):
     return dtype.itemtype.bool(val)
@@ -312,7 +312,7 @@
         else:
             res_dtype = calc_dtype
             if self.complex_to_float and calc_dtype.is_complex_type():
-                if calc_dtype.name == 'complex64':
+                if calc_dtype.num == NPY.CFLOAT:
                     res_dtype = interp_dtype.get_dtype_cache(space).w_float32dtype
                 else:
                     res_dtype = interp_dtype.get_dtype_cache(space).w_float64dtype
@@ -386,8 +386,9 @@
                     return space.w_NotImplemented
             else:
                 raise oefmt(space.w_TypeError,
-                    'unsupported operand dtypes %s and %s for "%s"',
-                    w_rdtype.name, w_ldtype.name, self.name)
+                            'unsupported operand dtypes %s and %s for "%s"',
+                            w_rdtype.get_name(), w_ldtype.get_name(),
+                            self.name)
 
         if self.are_common_types(w_ldtype, w_rdtype):
             if not w_lhs.is_scalar() and w_rhs.is_scalar():
@@ -462,24 +463,24 @@
     if dt1.num > dt2.num:
         dt1, dt2 = dt2, dt1
     # Some operations promote op(bool, bool) to return int8, rather than bool
-    if promote_bools and (dt1.kind == dt2.kind == NPY_GENBOOLLTR):
+    if promote_bools and (dt1.kind == dt2.kind == NPY.GENBOOLLTR):
         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.num == NPY_HALF:
+        if dt2.num == NPY.HALF:
             dt1, dt2 = dt2, dt1
-        if dt2.num == NPY_CFLOAT:
-            if dt1.num == NPY_DOUBLE:
+        if dt2.num == NPY.CFLOAT:
+            if dt1.num == NPY.DOUBLE:
                 return interp_dtype.get_dtype_cache(space).w_complex128dtype
-            elif dt1.num == NPY_LONGDOUBLE:
+            elif dt1.num == NPY.LONGDOUBLE:
                 return interp_dtype.get_dtype_cache(space).w_complexlongdtype
             return interp_dtype.get_dtype_cache(space).w_complex64dtype
-        elif dt2.num == NPY_CDOUBLE:
-            if dt1.num == NPY_LONGDOUBLE:
+        elif dt2.num == NPY.CDOUBLE:
+            if dt1.num == NPY.LONGDOUBLE:
                 return interp_dtype.get_dtype_cache(space).w_complexlongdtype
             return interp_dtype.get_dtype_cache(space).w_complex128dtype
-        elif dt2.num == NPY_CLONGDOUBLE:
+        elif dt2.num == NPY.CLONGDOUBLE:
             return interp_dtype.get_dtype_cache(space).w_complexlongdtype
         else:
             raise OperationError(space.w_TypeError, space.wrap("Unsupported types"))
@@ -488,30 +489,30 @@
         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 dt2.num == NPY_HALF:
+        if dt2.num == NPY.HALF:
             return dt1
         return dt2
 
     # Everything promotes to float, and bool promotes to everything.
-    if dt2.kind == NPY_FLOATINGLTR or dt1.kind == NPY_GENBOOLLTR:
-        if dt2.num == NPY_HALF and dt1.itemtype.get_element_size() == 2:
+    if dt2.kind == NPY.FLOATINGLTR or dt1.kind == NPY.GENBOOLLTR:
+        if dt2.num == NPY.HALF and dt1.itemtype.get_element_size() == 2:
             return interp_dtype.get_dtype_cache(space).w_float32dtype
-        if dt2.num == NPY_HALF and dt1.itemtype.get_element_size() >= 4:
+        if dt2.num == NPY.HALF and dt1.itemtype.get_element_size() >= 4:
             return interp_dtype.get_dtype_cache(space).w_float64dtype
-        if dt2.num == NPY_FLOAT and dt1.itemtype.get_element_size() >= 4:
+        if dt2.num == NPY.FLOAT and dt1.itemtype.get_element_size() >= 4:
             return interp_dtype.get_dtype_cache(space).w_float64dtype
         return dt2
 
     # for now this means mixing signed and unsigned
-    if dt2.kind == NPY_SIGNEDLTR:
+    if dt2.kind == NPY.SIGNEDLTR:
         # if dt2 has a greater number of bytes, then just go with it
         if dt1.itemtype.get_element_size() < dt2.itemtype.get_element_size():
             return dt2
         # we need to promote both dtypes
         dtypenum = dt2.num + 2
-    elif dt2.num == NPY_ULONGLONG or (LONG_BIT == 64 and dt2.num == NPY_ULONG):
+    elif dt2.num == NPY.ULONGLONG or (LONG_BIT == 64 and dt2.num == NPY.ULONG):
         # UInt64 + signed = Float64
-        dtypenum = NPY_DOUBLE
+        dtypenum = NPY.DOUBLE
     elif dt2.is_flexible_type():
         # For those operations that get here (concatenate, stack),
         # flexible types take precedence over numeric type
@@ -528,7 +529,7 @@
     newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum]
 
     if (newdtype.itemtype.get_element_size() > dt2.itemtype.get_element_size() or
-            newdtype.kind == NPY_FLOATINGLTR):
+            newdtype.kind == NPY.FLOATINGLTR):
         return newdtype
     else:
         # we only promoted to long on 32-bit or to longlong on 64-bit
@@ -540,24 +541,24 @@
 def find_unaryop_result_dtype(space, dt, promote_to_float=False,
         promote_bools=False, promote_to_largest=False):
     if promote_to_largest:
-        if dt.kind == NPY_GENBOOLLTR or dt.kind == NPY_SIGNEDLTR:
+        if dt.kind == NPY.GENBOOLLTR or dt.kind == NPY.SIGNEDLTR:
             if dt.get_size() * 8 < LONG_BIT:
                 return interp_dtype.get_dtype_cache(space).w_longdtype
-        elif dt.kind == NPY_UNSIGNEDLTR:
+        elif dt.kind == NPY.UNSIGNEDLTR:
             if dt.get_size() * 8 < LONG_BIT:
                 return interp_dtype.get_dtype_cache(space).w_ulongdtype
         else:
-            assert dt.kind == NPY_FLOATINGLTR or dt.kind == NPY_COMPLEXLTR
+            assert dt.kind == NPY.FLOATINGLTR or dt.kind == NPY.COMPLEXLTR
         return dt
-    if promote_bools and (dt.kind == NPY_GENBOOLLTR):
+    if promote_bools and (dt.kind == NPY.GENBOOLLTR):
         return interp_dtype.get_dtype_cache(space).w_int8dtype
     if promote_to_float:
-        if dt.kind == NPY_FLOATINGLTR or dt.kind == NPY_COMPLEXLTR:
+        if dt.kind == NPY.FLOATINGLTR or dt.kind == NPY.COMPLEXLTR:
             return dt
-        if dt.num >= NPY_INT:
+        if dt.num >= NPY.INT:
             return interp_dtype.get_dtype_cache(space).w_float64dtype
         for bytes, dtype in interp_dtype.get_dtype_cache(space).float_dtypes_by_num_bytes:
-            if (dtype.kind == NPY_FLOATINGLTR and
+            if (dtype.kind == NPY.FLOATINGLTR and
                 dtype.itemtype.get_element_size() > dt.itemtype.get_element_size()):
                 return dtype
     return dt
@@ -594,7 +595,7 @@
         if current_guess is None:
             return interp_dtype.variable_dtype(space,
                                                'S%d' % space.len_w(w_obj))
-        elif current_guess.num == NPY_STRING:
+        elif current_guess.num == NPY.STRING:
             if current_guess.get_size() < space.len_w(w_obj):
                 return interp_dtype.variable_dtype(space,
                                                    'S%d' % space.len_w(w_obj))
@@ -612,7 +613,7 @@
         except AttributeError:
             raise oefmt(space.w_NotImplementedError,
                         "%s not implemented for %s",
-                        ufunc_name, dtype.name)
+                        ufunc_name, dtype.get_name())
     if argcount == 1:
         def impl(res_dtype, value):
             res = get_op(res_dtype)(value)
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
@@ -11,7 +11,7 @@
 from pypy.module.micronumpy.base import W_NDimArray
 from pypy.module.micronumpy.iter import PureShapeIterator
 from pypy.module.micronumpy.support import index_w
-from pypy.module.micronumpy.constants import *
+from pypy.module.micronumpy import constants as NPY
 
 call2_driver = jit.JitDriver(name='numpy_call2',
                              greens = ['shapelen', 'func', 'calc_dtype',
@@ -90,19 +90,11 @@
         obj_iter.next()
     return out
 
-setslice_driver1 = jit.JitDriver(name='numpy_setslice1',
-                                greens = ['shapelen', 'dtype'],
-                                reds = 'auto')
-setslice_driver2 = jit.JitDriver(name='numpy_setslice2',
+setslice_driver = jit.JitDriver(name='numpy_setslice',
                                 greens = ['shapelen', 'dtype'],
                                 reds = 'auto')
 
 def setslice(space, shape, target, source):
-    if target.dtype.is_str_or_unicode():
-        return setslice_build_and_convert(space, shape, target, source)
-    return setslice_to(space, shape, target, source)
-
-def setslice_to(space, shape, target, source):
     # note that unlike everything else, target and source here are
     # array implementations, not arrays
     target_iter = target.create_iter(shape)
@@ -110,22 +102,11 @@
     dtype = target.dtype
     shapelen = len(shape)
     while not target_iter.done():
-        setslice_driver1.jit_merge_point(shapelen=shapelen, dtype=dtype)
-        target_iter.setitem(source_iter.getitem().convert_to(space, dtype))
-        target_iter.next()
-        source_iter.next()
-    return target
-
-def setslice_build_and_convert(space, shape, target, source):
-    # note that unlike everything else, target and source here are
-    # array implementations, not arrays
-    target_iter = target.create_iter(shape)
-    source_iter = source.create_iter(shape)
-    dtype = target.dtype
-    shapelen = len(shape)
-    while not target_iter.done():
-        setslice_driver2.jit_merge_point(shapelen=shapelen, dtype=dtype)
-        target_iter.setitem(dtype.build_and_convert(space, source_iter.getitem()))
+        setslice_driver.jit_merge_point(shapelen=shapelen, dtype=dtype)
+        if dtype.is_str_or_unicode():
+            target_iter.setitem(dtype.coerce(space, source_iter.getitem()))
+        else:
+            target_iter.setitem(source_iter.getitem().convert_to(space, dtype))
         target_iter.next()
         source_iter.next()
     return target
@@ -434,43 +415,21 @@
         ri.next()
     return res
 
-flatiter_setitem_driver1 = jit.JitDriver(name = 'numpy_flatiter_setitem1',
-                                        greens = ['dtype'],
-                                        reds = 'auto')
-
-flatiter_setitem_driver2 = jit.JitDriver(name = 'numpy_flatiter_setitem2',
+flatiter_setitem_driver = jit.JitDriver(name = 'numpy_flatiter_setitem',
                                         greens = ['dtype'],
                                         reds = 'auto')
 
 def flatiter_setitem(space, arr, val, start, step, length):
     dtype = arr.get_dtype()
-    if dtype.is_str_or_unicode():
-        return flatiter_setitem_build_and_convert(space, arr, val, start, step, length)
-    return flatiter_setitem_to(space, arr, val, start, step, length)
-
-def flatiter_setitem_to(space, arr, val, start, step, length):
-    dtype = arr.get_dtype()
     arr_iter = arr.create_iter()
     val_iter = val.create_iter()
     arr_iter.next_skip_x(start)
     while length > 0:
-        flatiter_setitem_driver1.jit_merge_point(dtype=dtype)
-        arr_iter.setitem(val_iter.getitem().convert_to(space, dtype))
-        # need to repeat i_nput values until all assignments are done
-        arr_iter.next_skip_x(step)
-        length -= 1
-        val_iter.next()
-        # WTF numpy?
-        val_iter.reset()
-
-def flatiter_setitem_build_and_convert(space, arr, val, start, step, length):
-    dtype = arr.get_dtype()
-    arr_iter = arr.create_iter()
-    val_iter = val.create_iter()
-    arr_iter.next_skip_x(start)
-    while length > 0:
-        flatiter_setitem_driver2.jit_merge_point(dtype=dtype)
-        arr_iter.setitem(dtype.build_and_convert(space, val_iter.getitem()))
+        flatiter_setitem_driver.jit_merge_point(dtype=dtype)
+        if dtype.is_str_or_unicode():
+            arr_iter.setitem(dtype.coerce(space, val_iter.getitem()))
+        else:
+            arr_iter.setitem(val_iter.getitem().convert_to(space, dtype))
         # need to repeat i_nput values until all assignments are done
         arr_iter.next_skip_x(step)
         length -= 1
@@ -597,13 +556,13 @@
                                       mode=mode)
         index = index_w(space, arr_iter.getitem())
         if index < 0 or index >= len(iterators):
-            if mode == NPY_RAISE:
+            if mode == NPY.RAISE:
                 raise OperationError(space.w_ValueError, space.wrap(
                     "invalid entry in choice array"))
-            elif mode == NPY_WRAP:
+            elif mode == NPY.WRAP:
                 index = index % (len(iterators))
             else:
-                assert mode == NPY_CLIP
+                assert mode == NPY.CLIP
                 if index < 0:
                     index = 0
                 else:
diff --git a/pypy/module/micronumpy/test/test_appbridge.py b/pypy/module/micronumpy/test/test_appbridge.py
--- a/pypy/module/micronumpy/test/test_appbridge.py
+++ b/pypy/module/micronumpy/test/test_appbridge.py
@@ -1,5 +1,6 @@
 from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
 
+
 class AppTestAppBridge(BaseNumpyAppTest):
     def test_array_methods(self):
         import numpy as np
diff --git a/pypy/module/micronumpy/test/test_arrayops.py b/pypy/module/micronumpy/test/test_arrayops.py
--- a/pypy/module/micronumpy/test/test_arrayops.py
+++ b/pypy/module/micronumpy/test/test_arrayops.py
@@ -1,5 +1,5 @@
+from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
 
-from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
 
 class AppTestNumSupport(BaseNumpyAppTest):
     def test_where(self):
diff --git a/pypy/module/micronumpy/test/test_base.py b/pypy/module/micronumpy/test/test_base.py
--- a/pypy/module/micronumpy/test/test_base.py
+++ b/pypy/module/micronumpy/test/test_base.py
@@ -1,5 +1,6 @@
-from pypy.module.micronumpy.interp_dtype import NPY_NATBYTE, NPY_OPPBYTE
 from pypy.conftest import option
+from pypy.module.micronumpy import constants as NPY
+
 
 class BaseNumpyAppTest(object):
     spaceconfig = dict(usemodules=['micronumpy'])
@@ -23,5 +24,5 @@
             import sys
             sys.modules['numpypy'] = numpy
             """)
-        cls.w_non_native_prefix = cls.space.wrap(NPY_OPPBYTE)
-        cls.w_native_prefix = cls.space.wrap(NPY_NATBYTE)
+        cls.w_non_native_prefix = cls.space.wrap(NPY.OPPBYTE)
+        cls.w_native_prefix = cls.space.wrap(NPY.NATBYTE)
diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py
--- a/pypy/module/micronumpy/test/test_compile.py
+++ b/pypy/module/micronumpy/test/test_compile.py
@@ -1,4 +1,3 @@
-
 import py
 from pypy.module.micronumpy.compile import (numpy_compile, Assignment,
     ArrayConstant, FloatConstant, Operator, Variable, RangeConstant, Execute,
diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py
--- a/pypy/module/micronumpy/test/test_complex.py
+++ b/pypy/module/micronumpy/test/test_complex.py
@@ -61,6 +61,7 @@
             '%r and %r are not sufficiently close, %g > %g' %\
             (a, b, absolute_error, max(abs_err, rel_err*abs(a))))
 
+
 def parse_testfile(fname):
     """Parse a file with test values
 
@@ -85,6 +86,7 @@
                    flags
                   )
 
+
 class AppTestUfuncs(BaseNumpyAppTest):
     def setup_class(cls):
         import os
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
@@ -1,4 +1,3 @@
-import py, sys
 from pypy.conftest import option
 from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
 from pypy.interpreter.gateway import interp2app
@@ -41,6 +40,7 @@
 
     def test_dtype_basic(self):
         from numpypy import dtype
+        import sys
 
         d = dtype('?')
         assert d.num == 0
@@ -48,7 +48,13 @@
         assert dtype(d) is d
         assert dtype('bool') is d
         assert dtype('|b1') is d
+        b = '>' if sys.byteorder == 'little' else '<'
+        assert dtype(b + 'i4') is not dtype(b + 'i4')
         assert repr(type(d)) == "<type 'numpy.dtype'>"
+        exc = raises(ValueError, "d.names = []")
+        assert exc.value[0] == "there are no fields defined"
+        exc = raises(ValueError, "d.names = None")
+        assert exc.value[0] == "there are no fields defined"
 
         assert dtype('int8').num == 1
         assert dtype('int8').name == 'int8'
@@ -59,13 +65,10 @@
 
         assert dtype(None) is dtype(float)
 
-        e = dtype('int8')
-        exc = raises(KeyError, "e[2]")
-        assert exc.value.message == "There are no fields in dtype int8."
-        exc = raises(KeyError, "e['z']")
-        assert exc.value.message == "There are no fields in dtype int8."
-        exc = raises(KeyError, "e[None]")
-        assert exc.value.message == "There are no fields in dtype int8."
+        for d in [dtype('<c8'), dtype('>i4')]:
+            for key in ["d[2]", "d['z']", "d[None]"]:
+                exc = raises(KeyError, key)
+                assert exc.value[0] == "There are no fields in dtype %s." % str(d)
 
         exc = raises(TypeError, dtype, (1, 2))
         assert exc.value[0] == 'data type not understood'
@@ -154,13 +157,48 @@
         a = array(range(5), long)
         assert a.dtype is dtype(long)
 
+    def test_isbuiltin(self):
+        import numpy as np
+        import sys
+        assert np.dtype('?').isbuiltin == 1
+        assert np.dtype(int).newbyteorder().isbuiltin == 0
+        assert np.dtype(np.dtype(int)).isbuiltin == 1


More information about the pypy-commit mailing list