Bug#771148: (pre-upload) unblock: pypy/2.4.0+dfsg-2
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please consider unblocking the follow upload for package pypy:
There is an FTBFS (#771137) with the current gcc in sid (that I only
noticed when preparing this request), so we should definitely do an
upload, fixing that.
There have been a few issues reported in PyPy 2.4, fixed post-release,
that are probably worth cherry-picking into jessie. They haven't been
reported in Debian's BTS, but even subtle interpreter bugs tend to be
important.
The one that caught my attention was a segfault, if one runs the hy test
suite. See http://thread.gmane.org/gmane.comp.python.pypy/13039
These also appear interesting:
* https://bitbucket.org/pypy/pypy/issue/1902 (one of the two test-cases
has been fixed)
* https://bitbucket.org/pypy/pypy/issue/1872 (although we don't provide
have a packaged numpypy in Debian, yet)
* https://bitbucket.org/pypy/pypy/issue/1887
I am proposing the following:
diff --git a/debian/changelog b/debian/changelog
index 541f13e..67f6e59 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+pypy (2.4.0+dfsg-2) UNRELEASED; urgency=medium
+
+ * Patch trackgcroot-new-ops: Fix FTBFS with gcc 4.9.2, expect some new
+ operations. (Closes: #771137)
+ * Cherry-pick upstream patches for:
+ - ast-segfault: an AST compiler crash.
+ - io-double-rewind: EINVAL in raw io.
+ - streamio-ext-seek: Avoid an crash when fds are unexpectedly seeked.
+ - ndarray-swapaxes-segfault: Description: Fix a segfault when doing a noop
+ swapaxes.
+
+ -- Stefano Rivera <stefanor@debian.org> Thu, 25 Sep 2014 19:56:34 -0700
+
pypy (2.4.0+dfsg-1) unstable; urgency=medium
* New upstream release.
diff --git a/debian/patches/ast-segfault b/debian/patches/ast-segfault
new file mode 100644
index 0000000..2df75e1
--- /dev/null
+++ b/debian/patches/ast-segfault
@@ -0,0 +1,52 @@
+Description: Fix a crash in the AST compiler
+Origin: Upstream, https://bitbucket.org/pypy/pypy/commits/75ab5316ff3f
+ https://bitbucket.org/pypy/pypy/commits/27aa8184f00f
+Author: Armin Rigo <arigo@tunes.org>
+
+diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py
+--- a/pypy/module/_ast/test/test_ast.py
++++ b/pypy/module/_ast/test/test_ast.py
+@@ -425,3 +425,8 @@
+ str_node2 = copy.deepcopy(str_node)
+ dict_res = str_node2.__dict__
+ assert dict_res == {'n':2, 'lineno':2}
++
++ def test_bug_null_in_objspace_type(self):
++ import ast
++ code = ast.Expression(lineno=1, col_offset=1, body=ast.ListComp(lineno=1, col_offset=1, elt=ast.Call(lineno=1, col_offset=1, func=ast.Name(lineno=1, col_offset=1, id='str', ctx=ast.Load(lineno=1, col_offset=1)), args=[ast.Name(lineno=1, col_offset=1, id='x', ctx=ast.Load(lineno=1, col_offset=1))], keywords=[]), generators=[ast.comprehension(lineno=1, col_offset=1, target=ast.Name(lineno=1, col_offset=1, id='x', ctx=ast.Store(lineno=1, col_offset=1)), iter=ast.List(lineno=1, col_offset=1, elts=[ast.Num(lineno=1, col_offset=1, n=23)], ctx=ast.Load(lineno=1, col_offset=1, )), ifs=[])]))
++ compile(code, '<template>', 'eval')
+
+diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
+--- a/pypy/interpreter/astcompiler/ast.py
++++ b/pypy/interpreter/astcompiler/ast.py
+@@ -22,9 +22,11 @@
+
+ def get_field(space, w_node, name, optional):
+ w_obj = w_node.getdictvalue(space, name)
+- if w_obj is None and not optional:
+- raise oefmt(space.w_TypeError,
++ if w_obj is None:
++ if not optional:
++ raise oefmt(space.w_TypeError,
+ "required field \"%s\" missing from %T", name, w_node)
++ w_obj = space.w_None
+ return w_obj
+
+
+diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
+--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
++++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
+@@ -405,9 +405,11 @@
+
+ def get_field(space, w_node, name, optional):
+ w_obj = w_node.getdictvalue(space, name)
+- if w_obj is None and not optional:
+- raise oefmt(space.w_TypeError,
++ if w_obj is None:
++ if not optional:
++ raise oefmt(space.w_TypeError,
+ "required field \"%s\" missing from %T", name, w_node)
++ w_obj = space.w_None
+ return w_obj
+
+
diff --git a/debian/patches/io-double-rewind b/debian/patches/io-double-rewind
new file mode 100644
index 0000000..e034889
--- /dev/null
+++ b/debian/patches/io-double-rewind
@@ -0,0 +1,36 @@
+Description: Fix a buffer flush thinko that rewound the raw stream twice
+ Causes EINVALs to be thrown.
+Bug-Upstream: https://bitbucket.org/pypy/pypy/issue/1902
+Origin: upstream, https://bitbucket.org/pypy/pypy/commits/60d682352d46
+Author: Philip Jenvey <pjenvey@underboss.org>
+
+--- a/pypy/module/_io/interp_bufferedio.py
++++ b/pypy/module/_io/interp_bufferedio.py
+@@ -812,11 +812,6 @@
+ self._check_closed(space, "flush of closed file")
+ with self.lock:
+ self._flush_and_rewind_unlocked(space)
+- if self.readable:
+- # Rewind the raw stream so that its position corresponds to
+- # the current logical position.
+- self._raw_seek(space, -self._raw_offset(), 1)
+- self._reader_reset_buf()
+
+ def _flush_and_rewind_unlocked(self, space):
+ self._writer_flush_unlocked(space)
+--- a/pypy/module/_io/test/test_io.py
++++ b/pypy/module/_io/test/test_io.py
+@@ -352,3 +352,13 @@
+ assert mod == 'io'
+ else:
+ assert mod == '_io'
++
++ def test_issue1902(self):
++ import _io
++ with _io.open(self.tmpfile, 'w+b', 4096) as f:
++ f.write(b'\xff' * 13569)
++ f.flush()
++ f.seek(0, 0)
++ f.read(1)
++ f.seek(-1, 1)
++ f.write(b'')
diff --git a/debian/patches/ndarray-swapaxes-segfault b/debian/patches/ndarray-swapaxes-segfault
new file mode 100644
index 0000000..fa32496
--- /dev/null
+++ b/debian/patches/ndarray-swapaxes-segfault
@@ -0,0 +1,29 @@
+Description: Fix a segfault when doing a noop swapaxes
+Author: Brian Kearns <bdkearns@gmail.com>
+Bug-Upstream: https://bitbucket.org/pypy/pypy/issue/1872
+Origin: upstream, https://bitbucket.org/pypy/pypy/commits/8faa11984f7a
+
+--- a/pypy/module/micronumpy/ndarray.py
++++ b/pypy/module/micronumpy/ndarray.py
+@@ -407,7 +407,7 @@
+ --------
+ numpy.swapaxes : equivalent function
+ """
+- if self.is_scalar():
++ if axis1 == axis2 or len(self.get_shape()) <= 1:
+ return self
+ return self.implementation.swapaxes(space, self, axis1, axis2)
+
+--- a/pypy/module/micronumpy/test/test_ndarray.py
++++ b/pypy/module/micronumpy/test/test_ndarray.py
+@@ -2020,6 +2020,10 @@
+
+ def test_swapaxes(self):
+ from numpypy import array
++ x = array([])
++ assert x.swapaxes(0, 2) is x
++ x = array([[1, 2]])
++ assert x.swapaxes(0, 0) is x
+ # testcases from numpy docstring
+ x = array([[1, 2, 3]])
+ assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all()
diff --git a/debian/patches/series b/debian/patches/series
index 66eae25..9dd096a 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -12,6 +12,11 @@ test_fsync-eatmydata
test_termios
fpic-archs
sandbox-access
+trackgcroot-new-ops
+ast-segfault
+io-double-rewind
+streamio-ext-seek
+ndarray-swapaxes-segfault
# from python2.7
ctypes-arm
diff --git a/debian/patches/streamio-ext-seek b/debian/patches/streamio-ext-seek
new file mode 100644
index 0000000..70e526a
--- /dev/null
+++ b/debian/patches/streamio-ext-seek
@@ -0,0 +1,64 @@
+Description: Avoid crashing with an AssertionError when fds are unexpectedly seeked
+Author: Armin Rigo <arigo@tunes.org>
+Bug-Upstream: https://bitbucket.org/pypy/pypy/issue/1887
+Origin: upstream, https://bitbucket.org/pypy/pypy/commits/80f6a6e5c89c
+
+--- a/rpython/rlib/streamio.py
++++ b/rpython/rlib/streamio.py
+@@ -557,13 +557,27 @@
+
+ def tell(self):
+ tellpos = self.do_tell() # This may fail
++ # Best-effort: to avoid extra system calls to tell() all the
++ # time, and a more complicated logic in this class, we can
++ # only assume that nobody changed the underlying file
++ # descriptor position while we have buffered data. If they
++ # do, we might get bogus results here (and the following
++ # read() will still return the data cached at the old
++ # position). Just make sure that we don't fail an assert.
+ offset = len(self.buf) - self.pos
+- assert tellpos >= offset #, (locals(), self.__dict__)
++ if tellpos < offset:
++ # bug! someone changed the fd position under our feet,
++ # and moved it at or very close to the beginning of the
++ # file, so that we have more buffered data than the
++ # current offset.
++ self.buf = ""
++ self.pos = 0
++ offset = 0
+ return tellpos - offset
+
+ def seek(self, offset, whence):
+- # This may fail on the do_seek() or do_tell() call.
+- # But it won't call either on a relative forward seek.
++ # This may fail on the do_seek() or on the tell() call.
++ # But it won't depend on either on a relative forward seek.
+ # Nor on a seek to the very end.
+ if whence == 0 or whence == 1:
+ currentsize = len(self.buf) - self.pos
+--- a/rpython/rlib/test/test_streamio.py
++++ b/rpython/rlib/test/test_streamio.py
+@@ -1119,6 +1119,23 @@
+ assert x.read() == 'abc123456'
+ x.close()
+
++ def test_seek_changed_underlying_position(self):
++ tfn = str(udir.join('seek_changed_underlying_position'))
++ fo = streamio.open_file_as_stream # shorthand
++ x = fo(tfn, 'w')
++ x.write('abc123')
++ x.close()
++
++ x = fo(tfn, 'r')
++ fd = x.try_to_find_file_descriptor()
++ assert fd >= 0
++ got = x.read(1)
++ assert got == 'a'
++ assert x.tell() == 1
++ os.lseek(fd, 0, 0)
++ assert x.tell() == 0 # detected in this case. not always.
++ # the point of the test is that we don't crash in an assert.
++
+
+ # Speed test
+
diff --git a/debian/patches/trackgcroot-new-ops b/debian/patches/trackgcroot-new-ops
new file mode 100644
index 0000000..dd3a688
--- /dev/null
+++ b/debian/patches/trackgcroot-new-ops
@@ -0,0 +1,26 @@
+Description: Expect cmovnb and jnb
+ Fixes an FTBFS since gcc 4.9.2, which is emmiting new operations
+Author: Stefano Rivera <stefanor@debian.org>
+Forwarded: https://bitbucket.org/pypy/pypy/commits/c1abec418acf30bb04891c3249bc12cbe8f48d4a
+Bug-Debian: https://bugs.debian.org/771137
+Last-Update: 2014-11-26
+
+--- a/rpython/translator/c/gcc/trackgcroot.py
++++ b/rpython/translator/c/gcc/trackgcroot.py
+@@ -590,7 +590,7 @@
+
+ # The various cmov* operations
+ for name in '''
+- e ne g ge l le a ae b be p np s ns o no
++ e ne g ge l le a ae b be nb p np s ns o no
+ '''.split():
+ locals()['visit_cmov' + name] = binary_insn
+ locals()['visit_cmov' + name + 'l'] = binary_insn
+@@ -837,6 +837,7 @@
+ visit_jb = conditional_jump
+ visit_jbe = conditional_jump
+ visit_jp = conditional_jump
++ visit_jnb = conditional_jump
+ visit_jnp = conditional_jump
+ visit_js = conditional_jump
+ visit_jns = conditional_jump
Thanks,
SR
unblock pypy/2.4.0+dfsg-2
Reply to: