Commits

Armin Rigo committed 8fc2d6e

Kill unwrap_attr() in interp_classobj, which has no purpose any more.
Gives a simpler solution to pull request #173.

Comments (0)

Files changed (2)

pypy/module/__builtin__/interp_classobj.py

     raise operationerrfmt(space.w_TypeError, "argument %s must be %s, not %T",
                           argument, expected, w_obj)
 
-def unwrap_attr(space, w_attr):
-    try:
-        return space.str_w(w_attr)
-    except OperationError, e:
-        if not e.match(space, space.w_TypeError):
-            raise
-        return "?"    # any string different from "__dict__" & co. is fine
-        # XXX it's not clear that we have to catch the TypeError...
-
 def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict):
     if not space.isinstance_w(w_bases, space.w_tuple):
         raise_type_err(space, 'bases', 'tuple', w_bases)
         return None
 
     def descr_getattribute(self, space, w_attr):
-        if not space.isinstance_w(w_attr, space.w_str):
-            msg = "attribute name must be a string"
-            raise OperationError(space.w_TypeError, space.wrap(msg))
-        name = unwrap_attr(space, w_attr)
+        name = space.str_w(w_attr)
         if name and name[0] == "_":
             if name == "__dict__":
                 return self.w_dict
         return space.call_function(w_descr_get, w_value, space.w_None, self)
 
     def descr_setattr(self, space, w_attr, w_value):
-        if not space.isinstance_w(w_attr, space.w_str):
-            msg = "attribute name must be a string"
-            raise OperationError(space.w_TypeError, space.wrap(msg))
-        name = unwrap_attr(space, w_attr)
+        name = space.str_w(w_attr)
         if name and name[0] == "_":
             if name == "__dict__":
                 self.setdict(space, w_value)
         space.setitem(self.w_dict, w_attr, w_value)
 
     def descr_delattr(self, space, w_attr):
-        name = unwrap_attr(space, w_attr)
+        name = space.str_w(w_attr)
         if name in ("__dict__", "__name__", "__bases__"):
             raise operationerrfmt(
                 space.w_TypeError,
             return None
 
     def descr_getattribute(self, space, w_attr):
-        if not space.isinstance_w(w_attr, space.w_str):
-            msg = "attribute name must be a string"
-            raise OperationError(space.w_TypeError, space.wrap(msg))
         name = space.str_w(w_attr)
         if len(name) >= 8 and name[0] == '_':
             if name == "__dict__":
         return self.getattr(space, name)
 
     def descr_setattr(self, space, w_name, w_value):
-        if not space.isinstance_w(w_name, space.w_str):
-            msg = "attribute name must be a string"
-            raise OperationError(space.w_TypeError, space.wrap(msg))
-        name = unwrap_attr(space, w_name)
+        name = space.str_w(w_name)
         w_meth = self.getattr_from_class(space, '__setattr__')
         if name and name[0] == "_":
             if name == '__dict__':
             self.setdictvalue(space, name, w_value)
 
     def descr_delattr(self, space, w_name):
-        name = unwrap_attr(space, w_name)
+        name = space.str_w(w_name)
         if name and name[0] == "_":
             if name == '__dict__':
                 # use setdict to raise the error

pypy/module/__builtin__/test/test_classobj.py

             raises(TypeError, type(c).__getattribute__, c, [])
             raises(TypeError, type(c).__setattr__, c, [], [])
 
+    def test_attr_unicode(self):
+        class C:
+            pass
+        c = C()
+        setattr(c, u"x", 1)
+        assert getattr(c, u"x") == 1
+
+
 class AppTestOldStyleMapDict(AppTestOldstyle):
     spaceconfig = {"objspace.std.withmapdict": True}