[pypy-commit] pypy default: issue1101: Even if only string keys are allowed in type dicts,

amauryfa noreply at buildbot.pypy.org
Sat Mar 31 11:28:28 CEST 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r54105:c07e2a2ba2f8
Date: 2012-03-31 11:27 +0200
http://bitbucket.org/pypy/pypy/changeset/c07e2a2ba2f8/

Log:	issue1101: Even if only string keys are allowed in type dicts, it
	should be possible to fetch with a unicode key:
	str.__dict__[u'decode']

diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -20,7 +20,17 @@
     def getitem(self, w_dict, w_key):
         space = self.space
         w_lookup_type = space.type(w_key)
-        if space.is_w(w_lookup_type, space.w_str):
+        if (space.is_w(w_lookup_type, space.w_str) or  # Most common path first
+            space.abstract_issubclass_w(w_lookup_type, space.w_str)):
+            return self.getitem_str(w_dict, space.str_w(w_key))
+        elif space.abstract_issubclass_w(w_lookup_type, space.w_unicode):
+            try:
+                w_key = space.str(w_key)
+            except OperationError, e:
+                if not e.match(space, space.w_UnicodeEncodeError):
+                    raise
+                # non-ascii unicode is never equal to a byte string
+                return None
             return self.getitem_str(w_dict, space.str_w(w_key))
         else:
             return None
diff --git a/pypy/objspace/std/test/test_dictproxy.py b/pypy/objspace/std/test/test_dictproxy.py
--- a/pypy/objspace/std/test/test_dictproxy.py
+++ b/pypy/objspace/std/test/test_dictproxy.py
@@ -25,6 +25,16 @@
         key, value = NotEmpty.__dict__.popitem()
         assert (key == 'a' and value == 1) or (key == 'b' and value == 4)
 
+    def test_dictproxy_getitem(self):
+        class NotEmpty(object):
+            a = 1
+        assert 'a' in NotEmpty.__dict__
+        class substr(str): pass
+        assert substr('a') in NotEmpty.__dict__
+        assert u'a' in NotEmpty.__dict__
+        assert NotEmpty.__dict__[u'a'] == 1
+        assert u'\xe9' not in NotEmpty.__dict__
+
     def test_dictproxyeq(self):
         class a(object):
             pass


More information about the pypy-commit mailing list