Author: andrewjlawrence
Branch: winmultiprocessing
Changeset: r96596:ff7e3469b931
Date: 2019-05-11 19:14 +0100
http://bitbucket.org/pypy/pypy/changeset/ff7e3469b931/
Log: Merged in latest changes from py3.6
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -10,10 +10,6 @@
32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1
10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0
9c4588d731b7fe0b08669bd732c2b676cb0a8233 release-2.5.1
-fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0
-fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0
-e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0
-e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0
295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0
f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1
850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0
@@ -24,17 +20,10 @@
b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1
80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2
40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2
-40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2
c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3
7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1
-68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0
-68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0
77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0
-050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1
-050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1
0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1
-4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1
-4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1
d7724c0a5700b895a47de44074cdf5fd659a988f RevDB-pypy2.7-v5.4.1
aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0
e90317857d27917bf840caf675832292ee070510 RevDB-pypy2.7-v5.6.1
@@ -45,33 +34,20 @@
2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1
c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0
a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0
-03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0
d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0
-03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0
84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0
0e7ea4fe15e82d5124e805e2e4a37cae1a402d4b release-pypy2.7-v5.10.0
-a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0
-a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0
-0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0
-0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0
09f9160b643e3f02ccb8c843b2fbb4e5cbf54082 release-pypy3.5-v5.10.0
3f6eaa010fce78cc7973bdc1dfdb95970f08fed2 release-pypy3.5-v5.10.1
ab0b9caf307db6592905a80b8faffd69b39005b8 release-pypy2.7-v6.0.0
fdd60ed87e941677e8ea11acf9f1819466521bf2 release-pypy3.5-v6.0.0
9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0
1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0
-dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0
-9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0
c8805ee6d7846ca2722b106eeaa2f128c699aba3 release-pypy2.7-v7.0.0
-1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0
928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0
-dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0
fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0
990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0
-bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0
-bb0d05b190b9c579f0c889a368636e14f6205bab release-pypy3.6-v7.1.0
-6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0
-6fd188f8f903b7555920adf7d5e7fe21db1bd593 release-pypy3.6-v7.1.0
-7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0
-7a2e437acfceafe2665b23b1394dc6c66add3b89 release-pypy3.6-v7.1.0
de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0
+784b254d669919c872a505b807db8462b6140973 release-pypy3.6-v7.1.1
+8cdda8b8cdb8ff29d9e620cccd6c5edd2f2a23ec release-pypy2.7-v7.1.1
+
diff --git a/lib-python/3/pdb.py b/lib-python/3/pdb.py
--- a/lib-python/3/pdb.py
+++ b/lib-python/3/pdb.py
@@ -341,8 +341,14 @@
def interaction(self, frame, traceback):
# Restore the previous signal handler at the Pdb prompt.
if Pdb._previous_sigint_handler:
- signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
- Pdb._previous_sigint_handler = None
+ try:
+ signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
+ Pdb._previous_sigint_handler = None
+ except ValueError:
+ # ValueError happens when we're in a non-main thread,
+ # if we already invoked pdb in the same program from the
+ # main thread. (PyPy fix)
+ pass
if self.setup(frame, traceback):
# no interaction desired at this time (happens if .pdbrc contains
# a command like "continue")
diff --git a/lib_pypy/_blake2/impl/blake2b.o b/lib_pypy/_blake2/impl/blake2b.o
deleted file mode 100644
index
0957bfc2e8b188b193b9eee3808641a638e0a2f7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
[cut]
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -95,7 +95,9 @@
There are a few extra implications from the difference in the GC. Most
notably, if an object has a ``__del__``, the ``__del__`` is never called more
than once in PyPy; but CPython will call the same ``__del__`` several times
-if the object is resurrected and dies again. The ``__del__`` methods are
+if the object is resurrected and dies again (at least it is reliably so in
+older CPythons; newer CPythons try to call destructors not more than once,
+but there are counter-examples). The ``__del__`` methods are
called in "the right" order if they are on objects pointing to each
other, as in CPython, but unlike CPython, if there is a dead cycle of
objects referencing each other, their ``__del__`` methods are called anyway;
diff --git a/pypy/doc/index-of-release-notes.rst
b/pypy/doc/index-of-release-notes.rst
--- a/pypy/doc/index-of-release-notes.rst
+++ b/pypy/doc/index-of-release-notes.rst
@@ -6,6 +6,7 @@
.. toctree::
+ release-v7.1.1.rst
release-v7.1.0.rst
release-v7.0.0.rst
release-v6.0.0.rst
diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst
--- a/pypy/doc/index-of-whatsnew.rst
+++ b/pypy/doc/index-of-whatsnew.rst
@@ -7,6 +7,7 @@
.. toctree::
whatsnew-head.rst
+ whatsnew-pypy2-7.1.0.rst
whatsnew-pypy2-7.0.0.rst
whatsnew-pypy2-6.0.0.rst
whatsnew-pypy2-5.10.0.rst
diff --git a/pypy/doc/release-v7.1.1.rst b/pypy/doc/release-v7.1.1.rst
--- a/pypy/doc/release-v7.1.1.rst
+++ b/pypy/doc/release-v7.1.1.rst
@@ -68,10 +68,14 @@
Changelog
=========
-Changes shared across versions
-* improve performance of ``u''.append``
+Changes shared across versions:
+
+* Improve performance of ``u''.append``
+
* Prevent a crash in ``zlib`` when flushing a closed stream
-* Fix a few corener cases when encountering unicode values above 0x110000
+
+* Fix a few corner cases when encountering unicode values above 0x110000
+
* Teach the JIT how to handle very large constant lists, sets, or dicts
* Fix building on ARM32 (issue 2984_)
* Fix a bug in register assignment in ARM32
@@ -81,9 +85,9 @@
* Fix memoryviews of ctype structures with padding, (cpython issue 32780_)
* CFFI updated to as-yet-unreleased 1.12.3
-Python 3.6 only
+Python 3.6 only:
-* On win32, override some ``errno.E*`` values that were added to MSVC in v2010
+* Override some ``errno.E*`` values that were added to MSVC in v2010
so that ``errno.E* == errno.WSAE*`` as in CPython
* Do the same optimization that CPython does for ``(1, 2, 3, *a)`` (but at the
AST level)
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -16,3 +16,12 @@
.. branch: datetime_api_27
Add ``DateTime_FromTimestamp`` and ``Date_FromTimestamp``
+
+.. branch: issue2968
+
+Fix segfault in cpyext_tp_new_tupl
+
+.. branch: semlock-deadlock
+
+Test and reduce the probability of a deadlock when acquiring a semaphore by
+moving global state changes closer to the actual aquire.
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -180,14 +180,17 @@
too_many_args = False
# put the special w_firstarg into the scope, if it exists
+ upfront = 0
+ args_w = self.arguments_w
if w_firstarg is not None:
- upfront = 1
if co_argcount > 0:
scope_w[0] = w_firstarg
- else:
- upfront = 0
+ upfront = 1
+ else:
+ # ugh, this is a call to a method 'def meth(*args)', maybe
+ # (see test_issue2996_*). Fall-back solution...
+ args_w = [w_firstarg] + args_w
- args_w = self.arguments_w
num_args = len(args_w)
avail = num_args + upfront
@@ -210,11 +213,8 @@
# collect extra positional arguments into the *vararg
if signature.has_vararg():
args_left = co_argcount - upfront
- if args_left < 0: # check required by rpython
- starargs_w = [w_firstarg]
- if num_args:
- starargs_w = starargs_w + args_w
- elif num_args > args_left:
+ assert args_left >= 0 # check required by rpython
+ if num_args > args_left:
starargs_w = args_w[args_left:]
else:
starargs_w = []
diff --git a/pypy/interpreter/astcompiler/codegen.py
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -509,8 +509,7 @@
return
self.update_position(asrt.lineno)
end = self.new_block()
- if self.compile_info.optimize != 0:
- self.emit_jump(ops.JUMP_IF_NOT_DEBUG, end)
+ self.emit_jump(ops.JUMP_IF_NOT_DEBUG, end)
asrt.test.accept_jump_if(self, True, end)
self.emit_op_name(ops.LOAD_GLOBAL, self.names, "AssertionError")
if asrt.msg:
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -58,8 +58,9 @@
assert argcount >= 0 # annotator hint
assert kwonlyargcount >= 0
argnames = list(varnames[:argcount])
- if argcount < len(varnames):
+ if kwonlyargcount > 0:
kwonlyargs = list(varnames[argcount:argcount + kwonlyargcount])
+ argcount += kwonlyargcount
else:
kwonlyargs = None
if code.co_flags & CO_VARARGS:
@@ -68,7 +69,7 @@
else:
varargname = None
if code.co_flags & CO_VARKEYWORDS:
- kwargname = code.co_varnames[argcount + kwonlyargcount]
+ kwargname = code.co_varnames[argcount]
else:
kwargname = None
return Signature(argnames, varargname, kwargname, kwonlyargs)
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
@@ -923,3 +923,18 @@
def test(**kwargs):
return kwargs
assert test(**q) == {"foo": "bar"}
+
+ def test_issue2996_1(self): """
+ class Class:
+ def method(*args, a_parameter=None, **kwargs):
+ pass
+ Class().method(**{'a_parameter': 4})
+ """
+
+ def test_issue2996_2(self): """
+ class Foo:
+ def methhh(*args, offset=42):
+ return args, offset
+ foo = Foo()
+ assert foo.methhh(**{}) == ((foo,), 42)
+ """
diff --git a/pypy/interpreter/test/test_compiler.py
b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -824,6 +824,13 @@
sig = cpython_code_signature(co)
assert sig == Signature(['a', 'b'], None, 'kwargs', ['m', 'n'])
+ # a variant with varargname, which was buggy before issue2996
+ snippet = 'def f(*args, offset=42): pass'
+ containing_co = self.compiler.compile(snippet, '<string>', 'single', 0)
+ co = find_func(containing_co)
+ sig = cpython_code_signature(co)
+ assert sig == Signature([], 'args', None, ['offset'])
+
class AppTestCompiler(object):
diff --git a/pypy/interpreter/test/test_zpy.py
b/pypy/interpreter/test/test_zpy.py
--- a/pypy/interpreter/test/test_zpy.py
+++ b/pypy/interpreter/test/test_zpy.py
@@ -84,7 +84,28 @@
# test 3 : additionnal pypy parameters
output = run(sys.executable, pypypath, '-S', "-O", tmpfilepath, "hello")
assert output.splitlines()[-1] == str([tmpfilepath,'hello'])
-
+
+def test_optimize_removes_assert():
+ tmpfilepath = str(udir.join("test_assert.py"))
+ tmpfile = file(tmpfilepath, "w")
+ tmpfile.write("""
+try:
+ assert 0
+except AssertionError:
+ print("AssertionError")
+else:
+ print("nothing")
+""")
+ tmpfile.close()
+
+ # no optimization: crashes
+ output = run(sys.executable, pypypath, '-S', tmpfilepath)
+ assert "AssertionError" in output
+
+ # optimization: just works
+ output = run(sys.executable, pypypath, '-SO', tmpfilepath)
+ assert "nothing" in output
+
TB_NORMALIZATION_CHK= """
class K(object):
diff --git a/pypy/interpreter/unicodehelper.py
b/pypy/interpreter/unicodehelper.py
--- a/pypy/interpreter/unicodehelper.py
+++ b/pypy/interpreter/unicodehelper.py
@@ -1400,7 +1400,7 @@
s, pos, pos + 4)
result.append(r)
continue
- elif ch >= 0x110000:
+ elif r_uint(ch) >= 0x110000:
r, pos, rettype = errorhandler(errors, public_encoding_name,
"codepoint not in range(0x110000)",
s, pos, len(s))
diff --git a/pypy/module/_codecs/interp_codecs.py
b/pypy/module/_codecs/interp_codecs.py
--- a/pypy/module/_codecs/interp_codecs.py
+++ b/pypy/module/_codecs/interp_codecs.py
@@ -575,14 +575,7 @@
if encoding is None:
encoding = space.sys.defaultencoding
w_encoder = space.getitem(lookup_codec(space, encoding), space.newint(0))
- w_retval = _call_codec(space, w_encoder, w_obj, "encoding", encoding,
errors)
- if not space.isinstance_w(w_retval, space.w_bytes):
- raise oefmt(space.w_TypeError,
- "'%s' encoder returned '%T' instead of 'bytes'; "
- "use codecs.encode() to encode to arbitrary types",
- encoding,
- w_retval)
- return w_retval
+ return _call_codec(space, w_encoder, w_obj, "encoding", encoding, errors)
@unwrap_spec(errors='text_or_none')
def readbuffer_encode(space, w_data, errors='strict'):
@@ -604,14 +597,7 @@
if encoding is None:
encoding = space.sys.defaultencoding
w_decoder = space.getitem(lookup_codec(space, encoding), space.newint(1))
- w_retval = _call_codec(space, w_decoder, w_obj, "decoding", encoding,
errors)
- if not isinstance(w_retval, W_UnicodeObject):
- raise oefmt(space.w_TypeError,
- "'%s' decoder returned '%T' instead of 'str'; "
- "use codecs.decode() to decode to arbitrary types",
- encoding,
- w_retval)
- return w_retval
+ return _call_codec(space, w_decoder, w_obj, "decoding", encoding, errors)
@unwrap_spec(errors='text')
def register_error(space, errors, w_handler):
@@ -842,7 +828,7 @@
if not 0 <= x <= 0x10FFFF:
raise oefmt(space.w_TypeError,
"character mapping must be in range(0x110000)")
- return rutf8.unichr_as_utf8(x)
+ return rutf8.unichr_as_utf8(x, allow_surrogates=True)
elif space.is_w(w_ch, space.w_None):
# Charmap may return None
return errorchar
@@ -972,9 +958,17 @@
unicode_name_handler)
if first_escape_error_char is not None:
+ # Here, 'first_escape_error_char' is a single string character.
+ # Careful, it might be >= '\x80'. If it is, it would made an
+ # invalid utf-8 string when pasted directory in it.
+ if ' ' <= first_escape_error_char < '\x7f':
+ msg = "invalid escape sequence '\\%s'" % (first_escape_error_char,)
+ else:
+ msg = "invalid escape sequence: '\\' followed by %s" % (
+ space.text_w(space.repr(
+ space.newbytes(first_escape_error_char))),)
space.warn(
- space.newtext("invalid escape sequence '\\%s'"
- % str(first_escape_error_char)),
+ space.newtext(msg),
space.w_DeprecationWarning
)
return space.newtuple([space.newutf8(result, lgt), space.newint(u_len)])
diff --git a/pypy/module/_codecs/test/test_codecs.py
b/pypy/module/_codecs/test/test_codecs.py
--- a/pypy/module/_codecs/test/test_codecs.py
+++ b/pypy/module/_codecs/test/test_codecs.py
@@ -125,6 +125,7 @@
assert (charmap_decode(b"\x00\x01\x02", "strict",
{0: u'\U0010FFFF', 1: u'b', 2: u'c'}) ==
(u"\U0010FFFFbc", 3))
+ assert charmap_decode(b'\xff', "strict", {0xff: 0xd800}) ==
(u'\ud800', 1)
def test_escape_decode(self):
from _codecs import unicode_escape_decode as decode
@@ -1386,7 +1387,7 @@
"foo\udca5bar")
assert ("foo\udca5bar".encode("iso-8859-3", "surrogateescape") ==
b"foo\xa5bar")
-
+
def test_warn_escape_decode(self):
import warnings
import codecs
@@ -1394,10 +1395,37 @@
with warnings.catch_warnings(record=True) as l:
warnings.simplefilter("always")
codecs.unicode_escape_decode(b'\\A')
- codecs.unicode_escape_decode(b"\\A")
+ codecs.unicode_escape_decode(b"\\" + b"\xff")
assert len(l) == 2
assert isinstance(l[0].message, DeprecationWarning)
+ assert isinstance(l[1].message, DeprecationWarning)
+ def test_invalid_type_errors(self):
+ # hex is not a text encoding. it works via the codecs functions, but
+ # not the methods
+ import codecs
+ res = codecs.decode(b"aabb", "hex")
+ assert res == b"\xaa\xbb"
+ res = codecs.decode(u"aabb", "hex")
+ assert res == b"\xaa\xbb"
+ res = codecs.encode(b"\xaa\xbb", "hex")
+ assert res == b"aabb"
+ raises(LookupError, u"abc".encode, "hex")
+ def test_non_text_codec(self):
+ import _codecs
+ def search_function(encoding):
+ def f(input, errors="strict"):
+ return 52, len(input)
+ if encoding == 'test.mynontextenc':
+ return (f, f, None, None)
+ return None
+ _codecs.register(search_function)
+ res = _codecs.encode(u"abc", "test.mynontextenc")
+ assert res == 52
+ res = _codecs.decode(b"abc", "test.mynontextenc")
+ assert res == 52
+ raises(TypeError, u"abc".encode, "test.mynontextenc")
+ raises(TypeError, b"abc".decode, "test.mynontextenc")
diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -105,16 +105,10 @@
# desired, all in one pass.
seennl = self.seennl
- # If, up to now, newlines are consistently \n, do a quick check
- # for the \r
- only_lf = False
- if seennl == SEEN_LF or seennl == 0:
- only_lf = (output.find('\r') < 0)
-
- if only_lf:
- # If not already seen, quick scan for a possible "\n" character.
+ if output.find('\r') < 0:
+ # If no \r, quick scan for a possible "\n" character.
# (there's nothing else to be done, even when in translation mode)
- if seennl == 0 and output.find('\n') >= 0:
+ if output.find('\n') >= 0:
seennl |= SEEN_LF
# Finished: we have scanned for newlines, and none of them
# need translating.
diff --git a/pypy/module/_io/test/test_textio.py
b/pypy/module/_io/test/test_textio.py
--- a/pypy/module/_io/test/test_textio.py
+++ b/pypy/module/_io/test/test_textio.py
@@ -566,3 +566,13 @@
_check(dec)
dec = _io.IncrementalNewlineDecoder(None, translate=True)
_check(dec)
+
+ def test_newlines2(self):
+ import _io, codecs
+ inner_decoder = codecs.getincrementaldecoder("utf-8")()
+ decoder = _io.IncrementalNewlineDecoder(inner_decoder, translate=True)
+ msg = b"abc\r\n\n\r\r\n\n"
+ decoded = ''
+ for ch in msg:
+ decoded += decoder.decode(bytes([ch]))
+ assert set(decoder.newlines) == {"\r", "\n", "\r\n"}
diff --git a/pypy/module/_multiprocessing/interp_semaphore.py
b/pypy/module/_multiprocessing/interp_semaphore.py
--- a/pypy/module/_multiprocessing/interp_semaphore.py
+++ b/pypy/module/_multiprocessing/interp_semaphore.py
@@ -48,7 +48,8 @@
eci = ExternalCompilationInfo(
includes = ['sys/time.h',
'limits.h',
- 'semaphore.h'],
+ 'semaphore.h',
+ ],
libraries = libraries,
)
@@ -269,6 +270,8 @@
res = rwin32.WaitForSingleObject(self.handle, 0)
if res != rwin32.WAIT_TIMEOUT:
+ self.last_tid = rthread.get_ident()
+ self.count += 1
return True
msecs = full_msecs
@@ -301,6 +304,8 @@
# handle result
if res != rwin32.WAIT_TIMEOUT:
+ self.last_tid = rthread.get_ident()
+ self.count += 1
return True
return False
@@ -379,8 +384,9 @@
elif e.errno in (errno.EAGAIN, errno.ETIMEDOUT):
return False
raise
- _check_signals(space)
-
+ _check_signals(space)
+ self.last_tid = rthread.get_ident()
+ self.count += 1
return True
finally:
if deadline:
@@ -449,6 +455,7 @@
self.count = 0
self.maxvalue = maxvalue
self.register_finalizer(space)
+ self.last_tid = -1
self.name = name
def name_get(self, space):
@@ -495,15 +502,15 @@
if self.kind == RECURSIVE_MUTEX and self._ismine():
self.count += 1
return space.w_True
-
try:
+ # sets self.last_tid and increments self.count
+ # those steps need to be as close as possible to
+ # acquiring the semlock for self._ismine() to support
+ # multiple threads
got = semlock_acquire(self, space, block, w_timeout)
except OSError as e:
raise wrap_oserror(space, e)
-
if got:
- self.last_tid = rthread.get_ident()
- self.count += 1
return space.w_True
else:
return space.w_False
@@ -520,10 +527,10 @@
try:
semlock_release(self, space)
+ self.count -= 1
except OSError as e:
raise wrap_oserror(space, e)
- self.count -= 1
def after_fork(self):
self.count = 0
diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py
b/pypy/module/_multiprocessing/test/test_semaphore.py
--- a/pypy/module/_multiprocessing/test/test_semaphore.py
+++ b/pypy/module/_multiprocessing/test/test_semaphore.py
@@ -18,6 +18,7 @@
def setup_class(cls):
cls.w_SEMAPHORE = cls.space.wrap(SEMAPHORE)
cls.w_RECURSIVE = cls.space.wrap(RECURSIVE_MUTEX)
+ cls.w_runappdirect = cls.space.wrap(cls.runappdirect)
@py.test.mark.skipif("sys.platform == 'win32'")
def test_sem_unlink(self):
@@ -138,3 +139,25 @@
from _multiprocessing import SemLock
sem = SemLock(self.SEMAPHORE, 1, 1, '/mp-123', unlink=True)
assert sem._count() == 0
+
+ def test_in_threads(self):
+ from _multiprocessing import SemLock
+ from threading import Thread
+ from time import sleep
+ l = SemLock(0, 1, 1, "6", unlink=True)
+ if self.runappdirect:
+ def f(id):
+ for i in range(10000):
+ pass
+ else:
+ def f(id):
+ for i in range(1000):
+ # reduce the probability of thread switching
+ # at exactly the wrong time in semlock_acquire
+ for j in range(10):
+ pass
+ threads = [Thread(None, f, args=(i,)) for i in range(2)]
+ [t.start() for t in threads]
+ # if the RLock calls to sem_wait and sem_post do not match,
+ # one of the threads will block and the call to join will fail
+ [t.join() for t in threads]
diff --git a/pypy/module/_pypyjson/interp_decoder.py
b/pypy/module/_pypyjson/interp_decoder.py
--- a/pypy/module/_pypyjson/interp_decoder.py
+++ b/pypy/module/_pypyjson/interp_decoder.py
@@ -366,10 +366,14 @@
hexdigits = self.getslice(start, i)
try:
val = int(hexdigits, 16)
- if sys.maxunicode > 65535 and 0xd800 <= val <= 0xdfff:
- # surrogate pair
- if self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u':
- val = self.decode_surrogate_pair(i, val)
+ if (0xd800 <= val <= 0xdbff and
+ self.ll_chars[i] == '\\' and self.ll_chars[i+1] == 'u'):
+ hexdigits = self.getslice(i+2, i+6)
+ lowsurr = int(hexdigits, 16)
+ if 0xdc00 <= lowsurr <= 0xdfff:
+ # decode surrogate pair
+ val = 0x10000 + (((val - 0xd800) << 10) |
+ (lowsurr - 0xdc00))
i += 6
except ValueError:
raise DecoderError("Invalid \uXXXX escape (char %d)", i-1)
@@ -380,15 +384,6 @@
builder.append(utf8_ch)
return i
- def decode_surrogate_pair(self, i, highsurr):
- """ uppon enter the following must hold:
- chars[i] == "\\" and chars[i+1] == "u"
- """
- i += 2
- hexdigits = self.getslice(i, i+4)
- lowsurr = int(hexdigits, 16) # the possible ValueError is caugth by
the caller
- return 0x10000 + (((highsurr - 0xd800) << 10) | (lowsurr - 0xdc00))
-
def decode_key(self, i):
""" returns a wrapped unicode """
from rpython.rlib.rarithmetic import intmask
diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py
b/pypy/module/_pypyjson/test/test__pypyjson.py
--- a/pypy/module/_pypyjson/test/test__pypyjson.py
+++ b/pypy/module/_pypyjson/test/test__pypyjson.py
@@ -198,6 +198,17 @@
res = _pypyjson.loads('"z\\ud834\\udd20x"')
assert res == expected
+ def test_unicode_not_a_surrogate_pair(self):
+ import _pypyjson
+ res = _pypyjson.loads('"z\\ud800\\ud800x"')
+ assert list(res) == [u'z', u'\ud800', u'\ud800', u'x']
+ res = _pypyjson.loads('"z\\udbff\\uffffx"')
+ assert list(res) == [u'z', u'\udbff', u'\uffff', u'x']
+ res = _pypyjson.loads('"z\\ud800\\ud834\\udd20x"')
+ assert res == u'z\ud800\U0001d120x'
+ res = _pypyjson.loads('"z\\udc00\\udc00x"')
+ assert list(res) == [u'z', u'\udc00', u'\udc00', u'x']
+
def test_lone_surrogate(self):
import _pypyjson
json = '{"a":"\\uD83D"}'
diff --git a/pypy/module/_rawffi/interp_rawffi.py
b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -452,8 +452,13 @@
elif c == 'c':
return space.newbytes(func(add_arg, argdesc, ll_type))
elif c == 'u':
- return space.newutf8(rutf8.unichr_as_utf8(
- r_uint(ord(func(add_arg, argdesc, ll_type)))), 1)
+ code = ord(func(add_arg, argdesc, ll_type))
+ try:
+ return space.newutf8(rutf8.unichr_as_utf8(
+ r_uint(code), allow_surrogates=True), 1)
+ except rutf8.OutOfRange:
+ raise oefmt(space.w_ValueError,
+ "unicode character %d out of range", code)
elif c == 'f' or c == 'd' or c == 'g':
return space.newfloat(float(func(add_arg, argdesc, ll_type)))
else:
diff --git a/pypy/module/_rawffi/test/test__rawffi.py
b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -348,6 +348,21 @@
arg2.free()
a.free()
+ def test_unicode_array(self):
+ import _rawffi
+ A = _rawffi.Array('u')
+ a = A(6, u'\u1234')
+ assert a[0] == u'\u1234'
+ a[0] = u'\U00012345'
+ assert a[0] == u'\U00012345'
+ a[0] = u'\ud800'
+ assert a[0] == u'\ud800'
+ B = _rawffi.Array('i')
+ b = B.fromaddress(a.itemaddress(0), 1)
+ b[0] = 0xffffffff
+ raises(ValueError, "a[0]")
+ a.free()
+
def test_returning_unicode(self):
import _rawffi
A = _rawffi.Array('u')
diff --git a/pypy/module/array/interp_array.py
b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -94,8 +94,8 @@
lgt = min(arr1.len, arr2.len)
for i in range(lgt):
arr_eq_driver.jit_merge_point(comp_func=comp_op)
- w_elem1 = arr1.w_getitem(space, i)
- w_elem2 = arr2.w_getitem(space, i)
+ w_elem1 = arr1.w_getitem(space, i, integer_instead_of_char=True)
+ w_elem2 = arr2.w_getitem(space, i, integer_instead_of_char=True)
if comp_op == EQ:
res = space.eq_w(w_elem1, w_elem2)
if not res:
@@ -1142,10 +1142,11 @@
else:
self.fromsequence(w_iterable)
- def w_getitem(self, space, idx):
+ def w_getitem(self, space, idx, integer_instead_of_char=False):
item = self.get_buffer()[idx]
keepalive_until_here(self)
- if mytype.typecode in 'bBhHil':
+ if mytype.typecode in 'bBhHil' or (
+ integer_instead_of_char and mytype.typecode in 'cu'):
item = rffi.cast(lltype.Signed, item)
return space.newint(item)
if mytype.typecode in 'ILqQ':
@@ -1158,7 +1159,7 @@
elif mytype.typecode == 'u':
code = r_uint(ord(item))
try:
- item = rutf8.unichr_as_utf8(code)
+ item = rutf8.unichr_as_utf8(code, allow_surrogates=True)
except rutf8.OutOfRange:
raise oefmt(space.w_ValueError,
"cannot operate on this array('u') because it contains"
diff --git a/pypy/module/array/test/test_array.py
b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -892,14 +892,21 @@
assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])"
assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])"
+ def test_array_of_chars_equality(self):
+ input_bytes = '\x01\x63a\x00!'
+ a = self.array('c', input_bytes)
+ b = self.array('c', input_bytes)
+ b.byteswap()
+ assert a == b
+
def test_unicode_outofrange(self):
input_unicode = u'\x01\u263a\x00\ufeff'
a = self.array('u', input_unicode)
b = self.array('u', input_unicode)
b.byteswap()
assert b[2] == u'\u0000'
- raises(ValueError, "b[1]") # doesn't work
- e = raises(ValueError, "a != b") # doesn't work
+ assert a != b
+ e = raises(ValueError, "b[0]") # doesn't work
assert str(e.value) == (
"cannot operate on this array('u') because it contains"
" character U+1000000 not in range [U+0000; U+10ffff]"
@@ -910,6 +917,10 @@
assert a.tounicode() == input_unicode
raises(ValueError, b.tounicode) # doesn't work
+ def test_unicode_surrogate(self):
+ a = self.array('u', u'\ud800')
+ assert a[0] == u'\ud800'
+
def test_weakref(self):
import weakref
a = self.array('u', 'Hi!')
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -639,16 +639,18 @@
'PyThread_ReInitTLS', 'PyThread_init_thread',
'PyThread_start_new_thread',
- 'PyStructSequence_InitType', 'PyStructSequence_New',
- 'PyStructSequence_UnnamedField',
+ 'PyStructSequence_InitType', 'PyStructSequence_InitType2',
+ 'PyStructSequence_New', 'PyStructSequence_UnnamedField',
'PyFunction_Type', 'PyMethod_Type', 'PyRange_Type', 'PyTraceBack_Type',
- 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_InteractiveFlag', 'Py_InspectFlag',
+ 'Py_DebugFlag', 'Py_VerboseFlag', 'Py_QuietFlag',
+ 'Py_InteractiveFlag', 'Py_InspectFlag',
'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag',
'Py_UseClassExceptionsFlag',
- 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag',
'Py_IgnoreEnvironmentFlag',
- 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag',
'Py_NoUserSiteDirectory',
- '_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag',
'_Py_PackageContext',
+ 'Py_FrozenFlag', 'Py_IgnoreEnvironmentFlag',
+ 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory',
+ 'Py_UnbufferedStdioFlag', 'Py_HashRandomizationFlag', 'Py_IsolatedFlag',
+ '_Py_PackageContext',
'PyOS_InputHook',
'PyMem_RawMalloc', 'PyMem_RawCalloc', 'PyMem_RawRealloc', 'PyMem_RawFree',
@@ -664,6 +666,8 @@
'PyObject_Init', 'PyObject_InitVar',
'PyTuple_New', '_Py_Dealloc',
]
+if sys.platform == "win32":
+ SYMBOLS_C.append('Py_LegacyWindowsStdioFlag')
TYPES = {}
FORWARD_DECLS = []
INIT_FUNCTIONS = []
diff --git a/pypy/module/cpyext/include/pythonrun.h
b/pypy/module/cpyext/include/pythonrun.h
--- a/pypy/module/cpyext/include/pythonrun.h
+++ b/pypy/module/cpyext/include/pythonrun.h
@@ -9,6 +9,7 @@
PyAPI_FUNC(void) Py_FatalError(const char *msg);
/* taken from Python-3.2.3/Include/pydebug.h */
+/* Note: they are always 0 for now, expect Py_DebugFlag which is always 1 */
PyAPI_DATA(int) Py_DebugFlag;
PyAPI_DATA(int) Py_VerboseFlag;
PyAPI_DATA(int) Py_QuietFlag;
@@ -20,11 +21,17 @@
PyAPI_DATA(int) Py_UseClassExceptionsFlag;
PyAPI_DATA(int) Py_FrozenFlag;
PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
-PyAPI_DATA(int) Py_DivisionWarningFlag;
PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
PyAPI_DATA(int) Py_NoUserSiteDirectory;
PyAPI_DATA(int) Py_UnbufferedStdioFlag;
PyAPI_DATA(int) Py_HashRandomizationFlag;
+PyAPI_DATA(int) Py_IsolatedFlag;
+
+#ifdef MS_WINDOWS
+PyAPI_DATA(int) Py_LegacyWindowsStdioFlag;
+#endif
+
+#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s))
typedef struct {
diff --git a/pypy/module/cpyext/include/structseq.h
b/pypy/module/cpyext/include/structseq.h
--- a/pypy/module/cpyext/include/structseq.h
+++ b/pypy/module/cpyext/include/structseq.h
@@ -24,6 +24,9 @@
PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type,
PyStructSequence_Desc *desc);
+PyAPI_FUNC(int) PyStructSequence_InitType2(PyTypeObject *type,
+ PyStructSequence_Desc *desc);
+
PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type);
typedef struct {
diff --git a/pypy/module/cpyext/src/missing.c b/pypy/module/cpyext/src/missing.c
--- a/pypy/module/cpyext/src/missing.c
+++ b/pypy/module/cpyext/src/missing.c
@@ -10,6 +10,7 @@
int Py_DebugFlag = 1;
int Py_VerboseFlag = 0;
+int Py_QuietFlag = 0;
int Py_InteractiveFlag = 0;
int Py_InspectFlag = 0;
int Py_OptimizeFlag = 0;
@@ -17,15 +18,17 @@
int Py_BytesWarningFlag = 0;
int Py_UseClassExceptionsFlag = 0;
int Py_FrozenFlag = 0;
-int Py_TabcheckFlag = 0;
-int Py_UnicodeFlag = 0;
int Py_IgnoreEnvironmentFlag = 0;
-int Py_DivisionWarningFlag = 0;
int Py_DontWriteBytecodeFlag = 0;
int Py_NoUserSiteDirectory = 0;
-int _Py_QnewFlag = 0;
-int Py_Py3kWarningFlag = 0;
+int Py_UnbufferedStdioFlag = 0;
int Py_HashRandomizationFlag = 0;
+int Py_IsolatedFlag = 0;
+
+#ifdef MS_WINDOWS
+int Py_LegacyWindowsStdioFlag = 0;
+#endif
+
const char *Py_FileSystemDefaultEncoding; /* filled when cpyext is imported */
void _Py_setfilesystemdefaultencoding(const char *enc) {
diff --git a/pypy/module/cpyext/src/structseq.c
b/pypy/module/cpyext/src/structseq.c
--- a/pypy/module/cpyext/src/structseq.c
+++ b/pypy/module/cpyext/src/structseq.c
@@ -315,8 +315,8 @@
structseq_new, /* tp_new */
};
-void
-PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
+int
+PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)
{
PyObject *dict;
PyMemberDef* members;
@@ -342,8 +342,10 @@
type->tp_doc = desc->doc;
members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1);
- if (members == NULL)
- return;
+ if (members == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
for (i = k = 0; i < n_members; ++i) {
if (desc->fields[i].name == PyStructSequence_UnnamedField)
@@ -361,22 +363,33 @@
type->tp_members = members;
if (PyType_Ready(type) < 0)
- return;
+ return -1;
Py_INCREF(type);
dict = type->tp_dict;
-#define SET_DICT_FROM_INT(key, value) \
+#define SET_DICT_FROM_SIZE(key, value) \
do { \
- PyObject *v = PyLong_FromLong((long) value); \
- if (v != NULL) { \
- PyDict_SetItemString(dict, key, v); \
+ PyObject *v = PyLong_FromSsize_t(value); \
+ if (v == NULL) \
+ return -1; \
+ if (PyDict_SetItemString(dict, key, v) < 0) { \
Py_DECREF(v); \
+ return -1; \
} \
+ Py_DECREF(v); \
} while (0)
- SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
- SET_DICT_FROM_INT(real_length_key, n_members);
- SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
+ SET_DICT_FROM_SIZE(visible_length_key, desc->n_in_sequence);
+ SET_DICT_FROM_SIZE(real_length_key, n_members);
+ SET_DICT_FROM_SIZE(unnamed_fields_key, n_unnamed_members);
+
+ return 0;
+}
+
+void
+PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
+{
+ (void)PyStructSequence_InitType2(type, desc);
}
PyTypeObject*
diff --git a/pypy/module/zlib/interp_zlib.py b/pypy/module/zlib/interp_zlib.py
--- a/pypy/module/zlib/interp_zlib.py
+++ b/pypy/module/zlib/interp_zlib.py
@@ -344,8 +344,7 @@
raise oefmt(space.w_ValueError,
"length must be greater than zero")
if not self.stream:
- raise zlib_error(space,
- "compressor object already flushed")
+ return space.newbytes('')
data = self.unconsumed_tail
try:
self.lock()
diff --git a/pypy/module/zlib/test/test_zlib.py
b/pypy/module/zlib/test/test_zlib.py
--- a/pypy/module/zlib/test/test_zlib.py
+++ b/pypy/module/zlib/test/test_zlib.py
@@ -421,4 +421,5 @@
dco = zlib.decompressobj()
dco.decompress(x)
dco.flush()
- raises(self.zlib.error, dco.flush)
+ # multiple flush calls should not raise
+ dco.flush()
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -326,7 +326,8 @@
space = self.space
if do_unicode:
cp = rutf8.codepoint_at_pos(self.fmt, self.fmtpos - 1)
- w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp)), 1)
+ w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp),
+ allow_surrogates=True), 1)
else:
cp = ord(self.fmt[self.fmtpos - 1])
w_s = space.newbytes(chr(cp))
@@ -478,7 +479,8 @@
n = space.int_w(w_value)
if do_unicode:
try:
- c = rutf8.unichr_as_utf8(r_uint(n))
+ c = rutf8.unichr_as_utf8(r_uint(n),
+ allow_surrogates=True)
except rutf8.OutOfRange:
raise oefmt(space.w_OverflowError,
"unicode character code out of range")
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -357,9 +357,11 @@
if recursive:
spec = self._build_string(spec_start, end, level)
w_rendered = self.space.format(w_obj, self.wrap(spec))
- unwrapper = "utf8_w" if self.is_unicode else "bytes_w"
- to_interp = getattr(self.space, unwrapper)
- return to_interp(w_rendered)
+ if self.is_unicode:
+ w_rendered = self.space.unicode_from_object(w_rendered)
+ return self.space.utf8_w(w_rendered)
+ else:
+ return self.space.bytes_w(w_rendered)
def formatter_parser(self):
self.parser_list_w = []
diff --git a/pypy/objspace/std/test/test_newformat.py
b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -245,6 +245,7 @@
def test_simple(self):
assert format(self.i(2)) == "2"
assert isinstance(format(self.i(2), ""), str)
+ assert isinstance(self.i(2).__format__(""), str)
def test_invalid(self):
raises(ValueError, format, self.i(8), "s")
@@ -491,3 +492,9 @@
excinfo = raises(ValueError, "{:j}".format, x(1))
print(excinfo.value)
assert str(excinfo.value) == "Unknown format code j for object of type
'x'"
+
+ def test_format_char(self):
+ import sys
+ assert '{0:c}'.format(42) == '*'
+ assert '{0:c}'.format(1234) == '\u04d2'
+ raises(OverflowError, '{0:c}'.format, -1)
diff --git a/pypy/objspace/std/test/test_stringformat.py
b/pypy/objspace/std/test/test_stringformat.py
--- a/pypy/objspace/std/test/test_stringformat.py
+++ b/pypy/objspace/std/test/test_stringformat.py
@@ -215,6 +215,7 @@
def test_format_wrong_char(self):
raises(ValueError, 'a%Zb'.__mod__, ((23,),))
+ raises(ValueError, u'a%\ud800b'.__mod__, ((23,),))
def test_incomplete_format(self):
raises(ValueError, '%'.__mod__, ((23,),))
@@ -234,6 +235,8 @@
raises(TypeError, '%c'.__mod__, ("",))
raises(TypeError, '%c'.__mod__, (['c'],))
raises(TypeError, '%c'.__mod__, b'A')
+ surrogate = 0xd800
+ assert '%c' % surrogate == '\ud800'
def test___int__index__(self):
class MyInt(object):
diff --git a/pypy/objspace/std/test/test_unicodeobject.py
b/pypy/objspace/std/test/test_unicodeobject.py
--- a/pypy/objspace/std/test/test_unicodeobject.py
+++ b/pypy/objspace/std/test/test_unicodeobject.py
@@ -728,6 +728,7 @@
raises(TypeError, 'hello'.translate)
raises(ValueError, "\xff".translate, {0xff: sys.maxunicode+1})
+ raises(TypeError, u'x'.translate, {ord('x'):0x110000})
def test_maketrans(self):
assert 'abababc' == 'abababc'.translate({'b': '<i>'})
@@ -1179,8 +1180,7 @@
def test_format_repeat(self):
assert format(u"abc", u"z<5") == u"abczz"
assert format(u"abc", u"\u2007<5") == u"abc\u2007\u2007"
- #CPython2 raises UnicodeEncodeError
- assert format(123, u"\u2007<5") == u"123\u2007\u2007"
+ assert format(123, "\u2007<5") == "123\u2007\u2007"
def test_formatting_unicode__repr__(self):
# Printable character
diff --git a/pypy/objspace/std/unicodeobject.py
b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -1235,7 +1235,14 @@
a.pos, a.pos + 1)
assert False, "always raises"
return space.newbytes(utf8)
- return encode(space, w_obj, encoding, errors)
+ w_retval = encode(space, w_obj, encoding, errors)
+ if not space.isinstance_w(w_retval, space.w_bytes):
+ raise oefmt(space.w_TypeError,
+ "'%s' encoder returned '%T' instead of 'bytes'; "
+ "use codecs.encode() to encode to arbitrary types",
+ encoding,
+ w_retval)
+ return w_retval
def decode_object(space, w_obj, encoding, errors=None):
@@ -1250,7 +1257,14 @@
lgt = unicodehelper.check_utf8_or_raise(space, s)
return space.newutf8(s, lgt)
from pypy.module._codecs.interp_codecs import decode
- return decode(space, w_obj, encoding, errors)
+ w_retval = decode(space, w_obj, encoding, errors)
+ if not isinstance(w_retval, W_UnicodeObject):
+ raise oefmt(space.w_TypeError,
+ "'%s' decoder returned '%T' instead of 'str'; "
+ "use codecs.decode() to decode to arbitrary types",
+ encoding,
+ w_retval)
+ return w_retval
def unicode_from_object(space, w_obj):
if space.is_w(space.type(w_obj), space.w_unicode):
diff --git a/pypy/tool/build_cffi_imports.py b/pypy/tool/build_cffi_imports.py
--- a/pypy/tool/build_cffi_imports.py
+++ b/pypy/tool/build_cffi_imports.py
@@ -7,6 +7,8 @@
cffi_build_scripts = {
+ "_blake2": "_blake2/_blake2_build.py",
+ "_ssl": "_ssl_build.py",
"sqlite3": "_sqlite3_build.py",
"audioop": "_audioop_build.py",
"tk": "_tkinter/tklib_build.py",
@@ -17,8 +19,6 @@
"resource": "_resource_build.py" if sys.platform != "win32" else None,
"lzma": "_lzma_build.py",
"_decimal": "_decimal_build.py",
- "_ssl": "_ssl_build.py",
- "_blake2": "_blake2/_blake2_build.py",
"_sha3": "_sha3/_sha3_build.py",
"xx": None, # for testing: 'None' should be completely ignored
}
@@ -154,7 +154,7 @@
status, stdout, stderr = run_subprocess(str(pypy_c), ['-m',
'ensurepip'])
failures = []
- for key, module in sorted(cffi_build_scripts.items()):
+ for key, module in cffi_build_scripts.items():
if only and key not in only:
print("* SKIPPING", key, '(not specified in --only)')
continue
diff --git a/pypy/tool/release/force-builds.py
b/pypy/tool/release/force-builds.py
--- a/pypy/tool/release/force-builds.py
+++ b/pypy/tool/release/force-builds.py
@@ -8,8 +8,13 @@
modified by PyPy team
"""
+from __future__ import absolute_import, division, print_function
-import os, sys, urllib, subprocess
+import os, sys, subprocess
+try:
+ from urllib2 import quote
+except ImportError:
+ from urllib.request import quote
from twisted.internet import reactor, defer
from twisted.python import log
@@ -29,10 +34,10 @@
'pypy-c-jit-macosx-x86-64',
'pypy-c-jit-win-x86-32',
'pypy-c-jit-linux-s390x',
- 'build-pypy-c-jit-linux-armhf-raspbian',
- 'build-pypy-c-jit-linux-armel',
+# 'build-pypy-c-jit-linux-armhf-raspbian',
+# 'build-pypy-c-jit-linux-armel',
'rpython-linux-x86-32',
- 'rpython-linux-x86-64'
+ 'rpython-linux-x86-64',
'rpython-win-x86-32'
]
@@ -54,7 +59,7 @@
log.err(err, "Build force failure")
for builder in BUILDERS:
- print 'Forcing', builder, '...'
+ print('Forcing', builder, '...')
url = "http://" + server + "/builders/" + builder + "/force"
args = [
('username', user),
@@ -63,15 +68,15 @@
('submit', 'Force Build'),
('branch', branch),
('comments', "Forced by command line script")]
- url = url + '?' + '&'.join([k + '=' + urllib.quote(v) for (k, v) in
args])
+ url = url + '?' + '&'.join([k + '=' + quote(v) for (k, v) in args])
requests.append(
- lock.run(client.getPage, url,
followRedirect=False).addErrback(ebList))
+ lock.run(client.getPage, url.encode('utf-8'),
followRedirect=False).addErrback(ebList))
d = defer.gatherResults(requests)
d.addErrback(log.err)
d.addCallback(lambda ign: reactor.stop())
reactor.run()
- print 'See http://buildbot.pypy.org/summary after a while'
+ print('See http://buildbot.pypy.org/summary after a while')
if __name__ == '__main__':
log.startLogging(sys.stdout)
@@ -86,6 +91,6 @@
try:
subprocess.check_call(['hg','id','-r', options.branch])
except subprocess.CalledProcessError:
- print 'branch', options.branch, 'could not be found in local
repository'
+ print('branch', options.branch, 'could not be found in local
repository')
sys.exit(-1)
main(options.branch, options.server, user=options.user)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit