Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: py3.5
Changeset: r93422:da0e3f790bdb
Date: 2017-12-14 19:29 +0000
http://bitbucket.org/pypy/pypy/changeset/da0e3f790bdb/

Log:    Fix handling of unencodable strings in ModuleDictStrategy

diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -6,6 +6,7 @@
 from rpython.rlib import jit, rerased, objectmodel
 
 from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import OperationError
 from pypy.objspace.std.dictmultiobject import (
     DictStrategy, ObjectDictStrategy, _never_equal_to_string,
     create_iterator_classes)
@@ -54,10 +55,21 @@
     def _getdictvalue_no_unwrapping_pure(self, version, w_dict, key):
         return self.unerase(w_dict.dstorage).get(key, None)
 
+    def try_unwrap_key(self, space, w_key):
+        if space.is_w(space.type(w_key), space.w_text):
+            try:
+                return space.text_w(w_key)
+            except OperationError as e:
+                if e.match(space, space.w_UnicodeEncodeError):
+                    return None
+                raise
+        return None
+
     def setitem(self, w_dict, w_key, w_value):
         space = self.space
-        if space.is_w(space.type(w_key), space.w_text):
-            self.setitem_str(w_dict, space.text_w(w_key), w_value)
+        key = self.try_unwrap_key(space, w_key)
+        if key is not None:
+            self.setitem_str(w_dict, key, w_value)
         else:
             self.switch_to_object_strategy(w_dict)
             w_dict.setitem(w_key, w_value)
@@ -75,8 +87,8 @@
 
     def setdefault(self, w_dict, w_key, w_default):
         space = self.space
-        if space.is_w(space.type(w_key), space.w_text):
-            key = space.text_w(w_key)
+        key = self.try_unwrap_key(space, w_key)
+        if key is not None:
             cell = self.getdictvalue_no_unwrapping(w_dict, key)
             w_result = unwrap_cell(self.space, cell)
             if w_result is not None:
@@ -90,8 +102,8 @@
     def delitem(self, w_dict, w_key):
         space = self.space
         w_key_type = space.type(w_key)
-        if space.is_w(w_key_type, space.w_text):
-            key = space.text_w(w_key)
+        key = self.try_unwrap_key(space, w_key)
+        if key is not None:
             dict_w = self.unerase(w_dict.dstorage)
             try:
                 del dict_w[key]
@@ -111,9 +123,9 @@
     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_text):
-            return self.getitem_str(w_dict, space.text_w(w_key))
-
+        key = self.try_unwrap_key(space, w_key)
+        if key is not None:
+            return self.getitem_str(w_dict, key)
         elif _never_equal_to_string(space, w_lookup_type):
             return None
         else:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to