Author: Brian Kearns <[email protected]>
Branch: 
Changeset: r69002:991a7649add9
Date: 2014-01-29 16:44 -0500
http://bitbucket.org/pypy/pypy/changeset/991a7649add9/

Log:    allow setting dtype.names attribute

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
@@ -207,7 +207,7 @@
                                                                  
space.wrap(offset)]))
         return w_d
 
-    def set_fields(self, space, w_fields):
+    def descr_set_fields(self, space, w_fields):
         if w_fields == space.w_None:
             self.fields = None
         else:
@@ -233,19 +233,26 @@
             return space.w_None
         return space.newtuple([space.wrap(name) for name in self.fieldnames])
 
-    def set_names(self, space, w_names):
-        self.fieldnames = []
-        if w_names == space.w_None:
-            return
-        else:
+    def descr_set_names(self, space, w_names):
+        fieldnames = []
+        if w_names != space.w_None:
             iter = space.iter(w_names)
             while True:
                 try:
-                    self.fieldnames.append(space.str_w(space.next(iter)))
+                    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
+
+    def descr_del_names(self, space):
+        raise OperationError(space.w_AttributeError, space.wrap(
+            "Cannot delete dtype names attribute"))
 
     def descr_get_hasobject(self, space):
         return space.w_False
@@ -321,10 +328,10 @@
         self.byteorder = endian
 
         fieldnames = space.getitem(w_data, space.wrap(3))
-        self.set_names(space, fieldnames)
+        self.descr_set_names(space, fieldnames)
 
         fields = space.getitem(w_data, space.wrap(4))
-        self.set_fields(space, fields)
+        self.descr_set_fields(space, fields)
 
     @unwrap_spec(new_order=str)
     def descr_newbyteorder(self, space, new_order=NPY_SWAP):
@@ -468,7 +475,9 @@
     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),
+    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),
 )
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
@@ -948,6 +948,13 @@
         assert d.type is void
         assert d.char == 'V'
         assert d.names == ("x", "y", "z", "value")
+        d.names = ('a', 'b', 'c', 'd')
+        assert d.names == ('a', 'b', 'c', 'd')
+        exc = raises(ValueError, "d.names = ('a', 'b', 'c', 'c')")
+        assert exc.value[0] == "Duplicate field names given."
+        exc = raises(AttributeError, 'del d.names')
+        assert exc.value[0] == "Cannot delete dtype names attribute"
+        assert d.names == ('a', 'b', 'c', 'd')
         raises(KeyError, 'd["xyz"]')
         raises(KeyError, 'd.fields["xyz"]')
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to