Author: mattip <[email protected]>
Branch: dtypes-compatability
Changeset: r78557:8937dc4116db
Date: 2015-07-15 22:19 +0300
http://bitbucket.org/pypy/pypy/changeset/8937dc4116db/

Log:    hack at dict-based vs. list-based repr(dtype) for compatibility, fix
        union dtypes, fix translation

diff --git a/pypy/module/micronumpy/descriptor.py 
b/pypy/module/micronumpy/descriptor.py
--- a/pypy/module/micronumpy/descriptor.py
+++ b/pypy/module/micronumpy/descriptor.py
@@ -182,14 +182,27 @@
             name = name[:-1]
         return name
 
-    def descr_get_name(self, space):
-        name = self.get_name()
+    def descr_get_name(self, space, quote=False):
+        if quote:
+            name = "'" + self.get_name() + "'"
+        else:
+            name = self.get_name()
         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):
-        return space.wrap(self.get_str())
+    def descr_get_str(self, space, ignore='|', simple=True):
+        if not simple and self.fields and len(self.fields) > 0:
+            return self.descr_get_descr(space)
+        total = 0
+        for s in self.shape:
+            total += s
+        if not simple and total > 0:
+            return space.newtuple(
+                [space.wrap(self.subdtype.get_str(ignore='')), 
+                 space.newtuple([space.wrap(s) for s in self.shape]),
+                ])
+        return space.wrap(self.get_str(ignore=ignore))
 
     def get_str(self, ignore='|'):
         basic = self.kind
@@ -203,11 +216,14 @@
             size >>= 2
         return "%s%s%s" % (endian, basic, size)
 
-    def descr_get_descr(self, space, style='descr'):
+    def descr_get_descr(self, space, style='descr', force_dict=False):
+        simple = False
+        if style == 'descr':
+            simple = True
         if not self.is_record():
             return space.newlist([space.newtuple([space.wrap(""),
-                                                  self.descr_get_str(space)])])
-        elif self.alignment >= 0 and style != 'descr':
+                                                  self.descr_get_str(space, 
simple=simple)])])
+        elif (self.alignment > 1 and style != 'descr') or force_dict:
             # we need to force a sorting order for the keys,
             # so return a string instead of a dict. Also, numpy formats
             # the lists without spaces between elements, so we cannot simply
@@ -217,6 +233,9 @@
             offsets = "'offsets':["
             titles = "'titles':["
             use_titles = False
+            show_offsets = False
+            offsets_n = []
+            total = 0
             for name, title in self.names:
                 offset, subdtype = self.fields[name]
                 if subdtype.is_record():
@@ -232,20 +251,37 @@
                 titles += "'" + str(title) + "',"
                 if title is not None:
                     use_titles = True
+                if total != offset:
+                    show_offsets = True
+                total += subdtype.elsize
+                # make sure offsets_n is sorted
+                i = 0
+                for i in range(len(offsets_n)):
+                    if offset < offsets_n[i]:
+                        break
+                offsets_n.insert(i, offset)
+            total = 0
+            for i in range(len(offsets_n)):
+                if offsets_n[i] != self.alignment * i:
+                    show_offsets = True
             formats = formats[:-1] + ']'
             offsets = offsets[:-1] + ']'
             names = names[:-1] + ']'
             titles = titles[:-1] + ']'
-            if style == 'str':
+            if self.alignment < 2:
+                suffix = "}"
+            elif style == 'str':
                 suffix = ", 'aligned':True}"
             elif style == 'substr':
                 suffix = '}'
             else:
                 suffix = "}, align=True"
-            if use_titles: 
+            if use_titles and not show_offsets: 
+                return self.descr_get_descr(space, style='descr')
+            elif use_titles:
                 return space.wrap('{' + names + ', ' + formats + ', ' +
-                            offsets + ', ' + "'itemsize':" + str(self.elsize) +
-                            titles + ', ' + suffix)
+                            offsets + ', ' + titles + ", 'itemsize':" + 
+                            str(self.elsize) + suffix)
             else:
                 return space.wrap('{' + names + ', ' + formats + ', ' +
                             offsets + ', ' + "'itemsize':" + str(self.elsize) +
@@ -253,18 +289,31 @@
             
         else:
             descr = []
+            total = 0
             for name, title in self.names:
-                subdtype = self.fields[name][1]
-                subdescr = [space.wrap(name)]
+                offset, subdtype = self.fields[name]
+                show_offsets = False
+                if total != offset:
+                    # whoops, need to use other format
+                    return self.descr_get_descr(space, style=style, 
force_dict=True)
+                total += subdtype.elsize
+                ignore = '|'
+                if title:
+                    subdescr = [space.newtuple([space.wrap(title), 
space.wrap(name)])]
+                    ignore = ''
+                else:
+                    subdescr = [space.wrap(name)]
                 if subdtype.is_record():
                     subdescr.append(subdtype.descr_get_descr(space, style))
                 elif subdtype.subdtype is not None:
-                    subdescr.append(subdtype.subdtype.descr_get_str(space))
+                    subdescr.append(subdtype.subdtype.descr_get_str(space, 
simple=False))
                 else:
-                    subdescr.append(subdtype.descr_get_str(space))
+                    subdescr.append(subdtype.descr_get_str(space, 
ignore=ignore, simple=False))
                 if subdtype.shape != []:
                     subdescr.append(subdtype.descr_get_shape(space))
                 descr.append(space.newtuple(subdescr[:]))
+            if self.alignment >= 0:
+                return 
space.wrap(space.str_w(space.repr(space.newlist(descr))) + ', align=True')      
           
             return space.newlist(descr)
 
     def descr_get_hasobject(self, space):
@@ -457,9 +506,11 @@
                 size = self.elsize
                 if self.num == NPY.UNICODE:
                     size >>= 2
-                r = space.wrap(byteorder + self.char + str(size))
+                r = space.wrap("'" + byteorder + self.char + str(size) + "'")
             else:
-                r = self.descr_get_name(space)
+                r = self.descr_get_name(space, quote=True)
+        if space.isinstance_w(r, space.w_str):
+            return space.wrap("dtype(%s)" % space.str_w(r))
         return space.wrap("dtype(%s)" % space.str_w(space.repr(r)))
 
     def descr_getitem(self, space, w_item):
@@ -626,6 +677,7 @@
     fldnames = [''] * len(lst_w)
     subdtypes = [None] * len(lst_w)
     titles = [None] * len(lst_w)
+    total = 0
     for i in range(len(lst_w)):
         w_elem = lst_w[i]
         if simple:
@@ -675,6 +727,15 @@
             if  i + 1 < len(offsets) and offsets[i + 1] == 0:
                 offsets[i+1] = offsets[i] + subdtype.elsize
         subdtypes[i] = subdtype
+        if use_supplied_offsets:
+            sz = subdtype.elsize
+        else:
+            sz = max(maxalign, subdtype.elsize)
+        if offsets[i] + sz > total:
+            total = offsets[i] + sz
+    # padding?
+    if alignment >= 0 and total % maxalign:
+        total = total // maxalign * maxalign + maxalign
     names = []
     for i in range(len(subdtypes)):
         subdtype = subdtypes[i]
@@ -683,7 +744,7 @@
             subdtype.alignment = maxalign
         if fldnames[i] in fields:
             raise oefmt(space.w_ValueError, "two fields with the same name")
-        if maxalign > 1 and offsets[i] % maxalign:
+        if maxalign > 1 and offsets[i] % subdtype.alignment:
             raise oefmt(space.w_ValueError, "offset %d for NumPy dtype with "
                     "fields is not divisible by the field alignment %d "
                     "with align=True", offsets[i], maxalign)
@@ -693,7 +754,6 @@
                 raise oefmt(space.w_ValueError, "two fields with the same 
name")
             fields[titles[i]] = offsets[i], subdtype
         names.append((fldnames[i], titles[i]))
-    total = offsets[-1] + max(maxalign, fields[names[-1][0]][1].elsize)
     if itemsize > 1:
         if total > itemsize:
             raise oefmt(space.w_ValueError,
@@ -878,10 +938,6 @@
     shape_w = space.fixedview(w_shape)
     if len(shape_w) < 1:
         return None
-    if len(shape_w) == 1:
-        if (not space.isinstance_w(shape_w[0], space.w_int) and
-            not space.isinstance_w(shape_w[0], space.w_long)):
-            return None
     shape = []
     for w_dim in shape_w:
         try:
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
@@ -1439,7 +1439,8 @@
                     "'offsets':[0,2], "
                     "'titles':['Red pixel','Blue pixel'], "
                     "'itemsize':4})")
-
+        if 'datetime64' not in dir(np):
+            skip('datetime dtype not available')
         dt = np.dtype([('a', '<M8[D]'), ('b', '<m8[us]')])
         assert repr(dt) == (
                     "dtype([('a', '<M8[D]'), ('b', '<m8[us]')])")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to