[pypy-svn] pypy default: A test and fix for someone doing f(**{u'\u1234': 5}).

arigo commits-noreply at bitbucket.org
Tue Feb 8 10:50:50 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r41696:62ccd916df24
Date: 2011-02-08 10:50 +0100
http://bitbucket.org/pypy/pypy/changeset/62ccd916df24/

Log:	A test and fix for someone doing f(**{u'\u1234': 5}). CPython's
	tests don't expect to get the UnicodeEncodeError here. Actually
	CPython has a different behavior, but see comment.

diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -196,10 +196,15 @@
             try:
                 key = space.str_w(w_key)
             except OperationError, e:
-                if not e.match(space, space.w_TypeError):
-                    raise
-                raise OperationError(space.w_TypeError,
-                                     space.wrap("keywords must be strings"))
+                if e.match(space, space.w_TypeError):
+                    raise OperationError(
+                        space.w_TypeError,
+                        space.wrap("keywords must be strings"))
+                if e.match(space, space.w_UnicodeEncodeError):
+                    raise OperationError(
+                        space.w_TypeError,
+                        space.wrap("keyword cannot be encoded to ascii"))
+                raise
             if self.keywords and key in self.keywords:
                 raise operationerrfmt(self.space.w_TypeError,
                                       "got multiple values "

diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py
--- a/pypy/interpreter/test/test_argument.py
+++ b/pypy/interpreter/test/test_argument.py
@@ -124,6 +124,7 @@
 
     w_TypeError = TypeError
     w_AttributeError = AttributeError
+    w_UnicodeEncodeError = UnicodeEncodeError
     w_dict = dict
 
 class TestArgumentsNormal(object):
@@ -474,6 +475,35 @@
         assert w_args == (1, )
         assert not w_kwds
 
+    def test_argument_unicode(self):
+        space = DummySpace()
+        w_starstar = space.wrap({u'abc': 5})
+        args = Arguments(space, [], w_starstararg=w_starstar)
+        l = [None]
+        args._match_signature(None, l, Signature(['abc']))
+        assert len(l) == 1
+        assert l[0] == space.wrap(5)
+        #
+        def str_w(w):
+            try:
+                return str(w)
+            except UnicodeEncodeError:
+                raise OperationError(space.w_UnicodeEncodeError,
+                                     space.wrap("oups"))
+        space.str_w = str_w
+        w_starstar = space.wrap({u'\u1234': 5})
+        err = py.test.raises(OperationError, Arguments,
+                             space, [], w_starstararg=w_starstar)
+        # Check that we get a TypeError.  On CPython it is because of
+        # "no argument called '?'".  On PyPy we get a TypeError too, but
+        # earlier: "keyword cannot be encoded to ascii".  The
+        # difference, besides the error message, is only apparent if the
+        # receiver also takes a **arg.  Then CPython passes the
+        # non-ascii unicode unmodified, whereas PyPy complains.  We will
+        # not care until someone has a use case for that.
+        assert not err.value.match(space, space.w_UnicodeEncodeError)
+        assert     err.value.match(space, space.w_TypeError)
+
 class TestErrorHandling(object):
     def test_missing_args(self):
         # got_nargs, nkwds, expected_nargs, has_vararg, has_kwarg,


More information about the Pypy-commit mailing list