Author: Matti Picus <[email protected]>
Branch: release-pypy2.7-v7.x
Changeset: r98253:1c36a847ec09
Date: 2019-12-08 09:00 +0200
http://bitbucket.org/pypy/pypy/changeset/1c36a847ec09/
Log: merge default into release branch
diff --git a/lib_pypy/_cffi_ssl/_stdssl/error.py
b/lib_pypy/_cffi_ssl/_stdssl/error.py
--- a/lib_pypy/_cffi_ssl/_stdssl/error.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/error.py
@@ -27,13 +27,14 @@
if self.strerror and isinstance(self.strerror, str):
return self.strerror
return str(self.args)
-# these are expected on socket as well
-socket.sslerror = SSLError
-for v in [ 'SSL_ERROR_ZERO_RETURN', 'SSL_ERROR_WANT_READ',
- 'SSL_ERROR_WANT_WRITE', 'SSL_ERROR_WANT_X509_LOOKUP', 'SSL_ERROR_SYSCALL',
- 'SSL_ERROR_SSL', 'SSL_ERROR_WANT_CONNECT', 'SSL_ERROR_EOF',
- 'SSL_ERROR_INVALID_ERROR_CODE' ]:
- setattr(socket, v, locals()[v])
+# these are expected on socket in python2 as well
+if sys.version_info[0] < 3:
+ socket.sslerror = SSLError
+ for v in [ 'SSL_ERROR_ZERO_RETURN', 'SSL_ERROR_WANT_READ',
+ 'SSL_ERROR_WANT_WRITE', 'SSL_ERROR_WANT_X509_LOOKUP',
'SSL_ERROR_SYSCALL',
+ 'SSL_ERROR_SSL', 'SSL_ERROR_WANT_CONNECT', 'SSL_ERROR_EOF',
+ 'SSL_ERROR_INVALID_ERROR_CODE' ]:
+ setattr(socket, v, locals()[v])
class SSLZeroReturnError(SSLError):
""" SSL/TLS session closed cleanly. """
diff --git a/lib_pypy/_curses_build.py b/lib_pypy/_curses_build.py
--- a/lib_pypy/_curses_build.py
+++ b/lib_pypy/_curses_build.py
@@ -28,13 +28,25 @@
# error message
raise e_last
-def find_curses_include_dirs():
- if os.path.exists('/usr/include/ncurses'):
- return ['/usr/include/ncurses']
- if os.path.exists('/usr/include/ncursesw'):
- return ['/usr/include/ncursesw']
- return []
+def find_curses_dir_and_name():
+ for base in ('/usr', '/usr/local'):
+ if os.path.exists(os.path.join(base, 'include', 'ncursesw')):
+ return base, 'ncursesw'
+ if os.path.exists(os.path.join(base, 'include', 'ncurses')):
+ return base, 'ncurses'
+ return '', None
+base, name = find_curses_dir_and_name()
+if base:
+ include_dirs = [os.path.join(base, 'include', name)]
+ library_dirs = [os.path.join(base, 'lib')]
+ libs = [name, name.replace('ncurses', 'panel')]
+else:
+ include_dirs = []
+ library_dirs = []
+ libs = [find_library(['ncursesw', 'ncurses']),
+ find_library(['panelw', 'panel']),
+ ]
ffi = FFI()
ffi.set_source("_curses_cffi", """
@@ -83,9 +95,10 @@
void _m_getsyx(int *yx) {
getsyx(yx[0], yx[1]);
}
-""", libraries=[find_library(['ncurses', 'ncursesw']),
- find_library(['panel', 'panelw'])],
- include_dirs=find_curses_include_dirs())
+""", libraries=libs,
+ library_dirs = library_dirs,
+ include_dirs=include_dirs,
+)
ffi.cdef("""
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -60,12 +60,9 @@
Install build-time dependencies
-------------------------------
(**Note**: for some hints on how to translate the Python interpreter under
-Windows, see the `windows document`_ . For hints on how to cross-compile in
-a chroot using scratchbox2, see the `arm document`_ in the
-`RPython documentation`_)
+Windows, see the `windows document`_ .
.. _`windows document`: windows.html
-.. _`arm document`: http://rpython.readthedocs.org/en/latest/arm.html
.. _`RPython documentation`: http://rpython.readthedocs.org
The host Python needs to have CFFI installed. If translating on PyPy, CFFI is
@@ -88,9 +85,6 @@
pyexpat
libexpat1
-_ssl
- libssl
-
_vmprof
libunwind (optional, loaded dynamically at runtime)
@@ -104,6 +98,9 @@
sqlite3
libsqlite3
+_ssl, _hashlib
+ libssl
+
curses
libncurses-dev (for PyPy2)
libncursesw-dev (for PyPy3)
@@ -115,11 +112,12 @@
tk-dev
lzma (PyPy3 only)
- liblzma
+ liblzma or libxz, version 5 and up
-To run untranslated tests, you need the Boehm garbage collector libgc.
+To run untranslated tests, you need the Boehm garbage collector libgc, version
+7.4 and up
-On recent Debian and Ubuntu (16.04 onwards), this is the command to install
+On Debian and Ubuntu (16.04 onwards), this is the command to install
all build-time dependencies::
apt-get install gcc make libffi-dev pkg-config zlib1g-dev libbz2-dev \
@@ -127,18 +125,11 @@
tk-dev libgc-dev python-cffi \
liblzma-dev libncursesw5-dev # these two only needed on PyPy3
-On older Debian and Ubuntu (12.04-14.04)::
-
- apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \
- libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \
- tk-dev libgc-dev python-cffi \
- liblzma-dev libncursesw-dev # these two only needed on PyPy3
-
On Fedora::
dnf install gcc make libffi-devel pkgconfig zlib-devel bzip2-devel \
sqlite-devel ncurses-devel expat-devel openssl-devel tk-devel \
- gdbm-devel python-cffi\
+ gdbm-devel python-cffi gc-devel\
xz-devel # For lzma on PyPy3.
On SLES11::
diff --git a/pypy/doc/release-v7.3.0.rst b/pypy/doc/release-v7.3.0.rst
--- a/pypy/doc/release-v7.3.0.rst
+++ b/pypy/doc/release-v7.3.0.rst
@@ -18,6 +18,12 @@
building third party packages for python, so this release changes the ABI tag
for PyPy.
+Based on the great work done in `portable-pypy`_, the linux downloads we
+provide are now built on top of the `manylinux2010`_ CentOS6 docker image.
+The tarballs include the needed shared objects to run on any platform that
+supports manylinux2010 wheels, which should include all supported versions of
+debian- and RedHat-based distributions (including Ubuntu, CentOS, and Fedora).
+
The `CFFI`_ backend has been updated to version 1.13.1. We recommend using CFFI
rather than c-extensions to interact with C.
@@ -57,6 +63,8 @@
.. _`CFFI`: http://cffi.readthedocs.io
.. _`cppyy`: https://cppyy.readthedocs.io
.. _`available as wheels`: https://github.com/antocuni/pypy-wheels
+.. _`portable-pypy`: https://github.com/squeaky-pl/portable-pypy
+.. _`manylinux2010`: https://github.com/pypa/manylinux
What is PyPy?
=============
@@ -124,6 +132,7 @@
* Check for overflow in ctypes array creation
* Better support and report MSVC versions used to compile on windows
* Allow any kind of buffer in socket.setsockopt(), like CPython (`issue 3114`_)
+* Fix importing a module with unicode in ``sys.path`` (`issue 3112`_)
C-API (cpyext) and c-extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -166,6 +175,8 @@
it. (`issue 3096`_)
* Remove incorrect clobbering of the ``locals`` after running ``exec()``
* Adds encoding, decoding codepages on win32
+* Remove socket error attributes from ``_ssl`` (`issue 3119`_)
+* Add missing ``os.getgrouplist`` (part of `issue 2375`_)
Python 3.6 C-API
~~~~~~~~~~~~~~~~
@@ -182,6 +193,7 @@
.. _`manylinux2010`: fix broken link
.. _`macports pypy`:
https://github.com/macports/macports-ports/blob/master/lang/pypy/files/darwin.py.diff
+.. _`issue 2375`: https://bitbucket.com/pypy/pypy/issues/2375
.. _`issue 2389`: https://bitbucket.com/pypy/pypy/issues/2389
.. _`issue 2687`: https://bitbucket.com/pypy/pypy/issues/2687
.. _`issue 2970`: https://bitbucket.com/pypy/pypy/issues/2970
@@ -198,8 +210,10 @@
.. _`issue 3100`: https://bitbucket.com/pypy/pypy/issues/3100
.. _`issue 3108`: https://bitbucket.com/pypy/pypy/issues/3108
.. _`issue 3109`: https://bitbucket.com/pypy/pypy/issues/3109
+.. _`issue 3112`: https://bitbucket.com/pypy/pypy/issues/3112
.. _`issue 3114`: https://bitbucket.com/pypy/pypy/issues/3114
.. _`issue 3117`: https://bitbucket.com/pypy/pypy/issues/3117
+.. _`issue 3119`: https://bitbucket.com/pypy/pypy/issues/3119
.. _`issue 3120`: https://bitbucket.com/pypy/pypy/issues/3120
.. _13312: https://bugs.python.org/issue13312
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
@@ -5,4 +5,6 @@
.. this is a revision shortly after release-pypy-7.3.0
.. startrev: dbbbae99135f
+.. branch: backport-decode_timeval_ns-py3.7
+Backport ``rtime.decode_timeval_ns`` from py3.7 to rpython
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -155,7 +155,7 @@
the `get_externals.py` utility to checkout the proper branch for your platform
and PyPy version.
-.. _subrepository: https://bitbucket.org/pypy/external
+.. _subrepository: https://bitbucket.org/pypy/externals
Using the mingw compiler
------------------------
diff --git a/pypy/interpreter/test/test_generator.py
b/pypy/interpreter/test/apptest_generator.py
copy from pypy/interpreter/test/test_generator.py
copy to pypy/interpreter/test/apptest_generator.py
--- a/pypy/interpreter/test/test_generator.py
+++ b/pypy/interpreter/test/apptest_generator.py
@@ -1,322 +1,311 @@
-class AppTestGenerator:
+from pytest import raises, skip
- def test_generator(self):
- def f():
+def test_generator():
+ def f():
+ yield 1
+ assert f().next() == 1
+
+def test_generator2():
+ def f():
+ yield 1
+ g = f()
+ assert g.next() == 1
+ with raises(StopIteration):
+ g.next()
+
+def test_attributes():
+ def f():
+ yield 1
+ assert g.gi_running
+ g = f()
+ assert g.gi_code is f.__code__
+ assert g.__name__ == 'f'
+ assert g.gi_frame is not None
+ assert not g.gi_running
+ g.next()
+ assert not g.gi_running
+ with raises(StopIteration):
+ g.next()
+ assert not g.gi_running
+ assert g.gi_frame is None
+ assert g.gi_code is f.__code__
+ assert g.__name__ == 'f'
+
+def test_generator3():
+ def f():
+ yield 1
+ g = f()
+ assert list(g) == [1]
+
+def test_generator4():
+ def f():
+ yield 1
+ g = f()
+ assert [x for x in g] == [1]
+
+def test_generator5():
+ def f():
+ v = (yield)
+ yield v
+ g = f()
+ g.next()
+ assert g.send(42) == 42
+
+def test_throw1():
+ def f():
+ yield 2
+ g = f()
+ # two arguments version
+ with raises(NameError):
+ g.throw(NameError, "Error")
+
+def test_throw2():
+ def f():
+ yield 2
+ g = f()
+ # single argument version
+ with raises(NameError):
+ g.throw(NameError("Error"))
+
+def test_throw3():
+ def f():
+ try:
yield 1
- assert f().next() == 1
+ yield 2
+ except NameError:
+ yield 3
+ g = f()
+ assert g.next() == 1
+ assert g.throw(NameError("Error")) == 3
+ with raises(StopIteration):
+ g.next()
- def test_generator2(self):
- def f():
+def test_throw4():
+ def f():
+ try:
yield 1
- g = f()
- assert g.next() == 1
- raises(StopIteration, g.next)
+ v = (yield 2)
+ except NameError:
+ yield 3
+ g = f()
+ assert g.next() == 1
+ assert g.next() == 2
+ assert g.throw(NameError("Error")) == 3
+ with raises(StopIteration):
+ g.next()
- def test_attributes(self):
- def f():
+def test_throw5():
+ def f():
+ try:
yield 1
- assert g.gi_running
- g = f()
- assert g.gi_code is f.__code__
- assert g.__name__ == 'f'
- assert g.gi_frame is not None
- assert not g.gi_running
+ except Exception:
+ x = 3
+ try:
+ yield x
+ except Exception:
+ pass
+ g = f()
+ g.next()
+ # String exceptions are not allowed anymore
+ with raises(TypeError):
+ g.throw("Error")
+ assert g.throw(Exception) == 3
+ with raises(StopIteration):
+ g.throw(Exception)
+
+def test_throw6():
+ def f():
+ yield 2
+ g = f()
+ with raises(NameError):
+ g.throw(NameError, "Error", None)
+
+
+def test_throw_fail():
+ def f():
+ yield 1
+ g = f()
+ with raises(TypeError):
+ g.throw(NameError("Error"), "error")
+
+def test_throw_fail2():
+ def f():
+ yield 1
+ g = f()
+ with raises(TypeError):
+ g.throw(list())
+
+def test_throw_fail3():
+ def f():
+ yield 1
+ g = f()
+ with raises(TypeError):
+ g.throw(NameError("Error"), None, "not tb object")
+
+def test_throw_finishes_generator():
+ def f():
+ yield 1
+ g = f()
+ assert g.gi_frame is not None
+ with raises(ValueError):
+ g.throw(ValueError)
+ assert g.gi_frame is None
+
+def test_throw_bug():
+ def f():
+ try:
+ x.throw(IndexError) # => "generator already executing"
+ except ValueError:
+ yield 1
+ x = f()
+ res = list(x)
+ assert res == [1]
+
+def test_throw_on_finished_generator():
+ def f():
+ yield 1
+ g = f()
+ res = g.next()
+ assert res == 1
+ with raises(StopIteration):
g.next()
- assert not g.gi_running
- raises(StopIteration, g.next)
- assert not g.gi_running
- assert g.gi_frame is None
- assert g.gi_code is f.__code__
- assert g.__name__ == 'f'
+ with raises(NameError):
+ g.throw(NameError)
- def test_generator3(self):
- def f():
+def test_close():
+ def f():
+ yield 1
+ g = f()
+ assert g.close() is None
+
+def test_close2():
+ def f():
+ try:
yield 1
- g = f()
- assert list(g) == [1]
+ except GeneratorExit:
+ raise StopIteration
+ g = f()
+ g.next()
+ assert g.close() is None
- def test_generator4(self):
- def f():
+def test_close3():
+ def f():
+ try:
yield 1
- g = f()
- assert [x for x in g] == [1]
+ except GeneratorExit:
+ raise NameError
+ g = f()
+ g.next()
+ with raises(NameError):
+ g.close()
- def test_generator5(self):
- d = {}
- exec """if 1:
- def f():
- v = (yield )
- yield v
- g = f()
- g.next()
- """ in d
- g = d['g']
- assert g.send(42) == 42
+def test_close_fail():
+ def f():
+ try:
+ yield 1
+ except GeneratorExit:
+ yield 2
+ g = f()
+ g.next()
+ with raises(RuntimeError):
+ g.close()
- def test_throw1(self):
- def f():
- yield 2
- g = f()
- # two arguments version
- raises(NameError, g.throw, NameError, "Error")
+def test_close_on_collect():
+ import gc
+ def f():
+ try:
+ yield
+ finally:
+ f.x = 42
+ g = f()
+ g.next()
+ del g
+ gc.collect()
+ assert f.x == 42
- def test_throw2(self):
- def f():
- yield 2
- g = f()
- # single argument version
- raises(NameError, g.throw, NameError("Error"))
+def test_generator_raises_typeerror():
+ def f():
+ yield 1
+ g = f()
+ with raises(TypeError):
+ g.send() # one argument required
+ with raises(TypeError):
+ g.send(1) # not started, must send None
- def test_throw3(self):
- def f():
- try:
- yield 1
- yield 2
- except:
- yield 3
- g = f()
- assert g.next() == 1
- assert g.throw(NameError("Error")) == 3
- raises(StopIteration, g.next)
+def test_generator_explicit_stopiteration():
+ def f():
+ yield 1
+ raise StopIteration
+ g = f()
+ assert [x for x in g] == [1]
- def test_throw4(self):
- d = {}
- exec """if 1:
- def f():
- try:
- yield 1
- v = (yield 2)
- except:
- yield 3
- g = f()
- """ in d
- g = d['g']
- assert g.next() == 1
- assert g.next() == 2
- assert g.throw(NameError("Error")) == 3
- raises(StopIteration, g.next)
+def test_generator_propagate_stopiteration():
+ def f():
+ it = iter([1])
+ while 1:
+ yield it.next()
+ g = f()
+ assert [x for x in g] == [1]
- def test_throw5(self):
- def f():
- try:
- yield 1
- except:
- x = 3
- try:
- yield x
- except:
- pass
- g = f()
- g.next()
- # String exceptions are not allowed anymore
- raises(TypeError, g.throw, "Error")
- assert g.throw(Exception) == 3
- raises(StopIteration, g.throw, Exception)
+def test_generator_restart():
+ def g():
+ i = me.next()
+ yield i
+ me = g()
+ with raises(ValueError):
+ me.next()
- def test_throw6(self):
- def f():
- yield 2
- g = f()
- raises(NameError, g.throw, NameError, "Error", None)
+def test_generator_expression():
+ exec "res = sum(i*i for i in range(5))"
+ assert res == 30
+def test_generator_expression_2():
+ def f():
+ total = sum(i for i in [x for x in z])
+ return total, x
+ z = [1, 2, 7]
+ assert f() == (10, 7)
- def test_throw_fail(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.throw, NameError("Error"), "error")
+def test_repr():
+ def myFunc():
+ yield 1
+ g = myFunc()
+ r = repr(g)
+ assert r.startswith("<generator object myFunc at 0x")
+ assert list(g) == [1]
+ assert repr(g) == r
- def test_throw_fail2(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.throw, list())
+def test_unpackiterable_gen():
+ g = (i * i for i in range(-5, 3))
+ assert set(g) == set([0, 1, 4, 9, 16, 25])
+ assert set(g) == set()
+ assert set(i for i in range(0)) == set()
- def test_throw_fail3(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.throw, NameError("Error"), None, "not tb object")
+def test_explicit_stop_iteration_unpackiterable():
+ def f():
+ yield 1
+ raise StopIteration
+ assert tuple(f()) == (1,)
- def test_throw_finishes_generator(self):
- def f():
- yield 1
- g = f()
- assert g.gi_frame is not None
- raises(ValueError, g.throw, ValueError)
- assert g.gi_frame is None
+def test_exception_is_cleared_by_yield():
+ def f():
+ try:
+ foobar
+ except NameError:
+ yield 5
+ raise # should raise "no active exception to re-raise"
+ gen = f()
+ next(gen) # --> 5
+ try:
+ next(gen)
+ except TypeError:
+ pass
- def test_throw_bug(self):
- def f():
- try:
- x.throw(IndexError) # => "generator already executing"
- except ValueError:
- yield 1
- x = f()
- res = list(x)
- assert res == [1]
-
- def test_throw_on_finished_generator(self):
- def f():
- yield 1
- g = f()
- res = g.next()
- assert res == 1
- raises(StopIteration, g.next)
- raises(NameError, g.throw, NameError)
-
- def test_close(self):
- def f():
- yield 1
- g = f()
- assert g.close() is None
-
- def test_close2(self):
- def f():
- try:
- yield 1
- except GeneratorExit:
- raise StopIteration
- g = f()
- g.next()
- assert g.close() is None
-
- def test_close3(self):
- def f():
- try:
- yield 1
- except GeneratorExit:
- raise NameError
- g = f()
- g.next()
- raises(NameError, g.close)
-
- def test_close_fail(self):
- def f():
- try:
- yield 1
- except GeneratorExit:
- yield 2
- g = f()
- g.next()
- raises(RuntimeError, g.close)
-
- def test_close_on_collect(self):
- ## we need to exec it, else it won't run on python2.4
- d = {}
- exec """
- def f():
- try:
- yield
- finally:
- f.x = 42
- """.strip() in d
-
- g = d['f']()
- g.next()
- del g
- import gc
- gc.collect()
- assert d['f'].x == 42
-
- def test_generator_raises_typeerror(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.send) # one argument required
- raises(TypeError, g.send, 1) # not started, must send None
-
- def test_generator_explicit_stopiteration(self):
- def f():
- yield 1
- raise StopIteration
- g = f()
- assert [x for x in g] == [1]
-
- def test_generator_propagate_stopiteration(self):
- def f():
- it = iter([1])
- while 1: yield it.next()
- g = f()
- assert [x for x in g] == [1]
-
- def test_generator_restart(self):
- def g():
- i = me.next()
- yield i
- me = g()
- raises(ValueError, me.next)
-
- def test_generator_expression(self):
- exec "res = sum(i*i for i in range(5))"
- assert res == 30
-
- def test_generator_expression_2(self):
- d = {}
- exec """
-def f():
- total = sum(i for i in [x for x in z])
- return total, x
-z = [1, 2, 7]
-res = f()
-""" in d
- assert d['res'] == (10, 7)
-
- def test_repr(self):
- def myFunc():
- yield 1
- g = myFunc()
- r = repr(g)
- assert r.startswith("<generator object myFunc at 0x")
- assert list(g) == [1]
- assert repr(g) == r
-
- def test_unpackiterable_gen(self):
- g = (i*i for i in range(-5, 3))
- assert set(g) == set([0, 1, 4, 9, 16, 25])
- assert set(g) == set()
- assert set(i for i in range(0)) == set()
-
- def test_explicit_stop_iteration_unpackiterable(self):
- def f():
- yield 1
- raise StopIteration
- assert tuple(f()) == (1,)
-
- def test_exception_is_cleared_by_yield(self):
- def f():
- try:
- foobar
- except NameError:
- yield 5
- raise # should raise "no active exception to re-raise"
- gen = f()
- next(gen) # --> 5
- try:
- next(gen)
- except TypeError:
- pass
-
- def test_multiple_invalid_sends(self):
- def mygen():
- yield 42
- g = mygen()
- raises(TypeError, g.send, 2)
- raises(TypeError, g.send, 2)
-
-
-def test_should_not_inline(space):
- from pypy.interpreter.generator import should_not_inline
- w_co = space.appexec([], '''():
- def g(x):
- yield x + 5
- return g.__code__
- ''')
- assert should_not_inline(w_co) == False
- w_co = space.appexec([], '''():
- def g(x):
- yield x + 5
- yield x + 6
- return g.__code__
- ''')
- assert should_not_inline(w_co) == True
+def test_multiple_invalid_sends():
+ def mygen():
+ yield 42
+ g = mygen()
+ with raises(TypeError):
+ g.send(2)
+ with raises(TypeError):
+ g.send(2)
diff --git a/pypy/interpreter/test/test_generator.py
b/pypy/interpreter/test/test_generator.py
--- a/pypy/interpreter/test/test_generator.py
+++ b/pypy/interpreter/test/test_generator.py
@@ -1,310 +1,3 @@
-class AppTestGenerator:
-
- def test_generator(self):
- def f():
- yield 1
- assert f().next() == 1
-
- def test_generator2(self):
- def f():
- yield 1
- g = f()
- assert g.next() == 1
- raises(StopIteration, g.next)
-
- def test_attributes(self):
- def f():
- yield 1
- assert g.gi_running
- g = f()
- assert g.gi_code is f.__code__
- assert g.__name__ == 'f'
- assert g.gi_frame is not None
- assert not g.gi_running
- g.next()
- assert not g.gi_running
- raises(StopIteration, g.next)
- assert not g.gi_running
- assert g.gi_frame is None
- assert g.gi_code is f.__code__
- assert g.__name__ == 'f'
-
- def test_generator3(self):
- def f():
- yield 1
- g = f()
- assert list(g) == [1]
-
- def test_generator4(self):
- def f():
- yield 1
- g = f()
- assert [x for x in g] == [1]
-
- def test_generator5(self):
- d = {}
- exec """if 1:
- def f():
- v = (yield )
- yield v
- g = f()
- g.next()
- """ in d
- g = d['g']
- assert g.send(42) == 42
-
- def test_throw1(self):
- def f():
- yield 2
- g = f()
- # two arguments version
- raises(NameError, g.throw, NameError, "Error")
-
- def test_throw2(self):
- def f():
- yield 2
- g = f()
- # single argument version
- raises(NameError, g.throw, NameError("Error"))
-
- def test_throw3(self):
- def f():
- try:
- yield 1
- yield 2
- except:
- yield 3
- g = f()
- assert g.next() == 1
- assert g.throw(NameError("Error")) == 3
- raises(StopIteration, g.next)
-
- def test_throw4(self):
- d = {}
- exec """if 1:
- def f():
- try:
- yield 1
- v = (yield 2)
- except:
- yield 3
- g = f()
- """ in d
- g = d['g']
- assert g.next() == 1
- assert g.next() == 2
- assert g.throw(NameError("Error")) == 3
- raises(StopIteration, g.next)
-
- def test_throw5(self):
- def f():
- try:
- yield 1
- except:
- x = 3
- try:
- yield x
- except:
- pass
- g = f()
- g.next()
- # String exceptions are not allowed anymore
- raises(TypeError, g.throw, "Error")
- assert g.throw(Exception) == 3
- raises(StopIteration, g.throw, Exception)
-
- def test_throw6(self):
- def f():
- yield 2
- g = f()
- raises(NameError, g.throw, NameError, "Error", None)
-
-
- def test_throw_fail(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.throw, NameError("Error"), "error")
-
- def test_throw_fail2(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.throw, list())
-
- def test_throw_fail3(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.throw, NameError("Error"), None, "not tb object")
-
- def test_throw_finishes_generator(self):
- def f():
- yield 1
- g = f()
- assert g.gi_frame is not None
- raises(ValueError, g.throw, ValueError)
- assert g.gi_frame is None
-
- def test_throw_bug(self):
- def f():
- try:
- x.throw(IndexError) # => "generator already executing"
- except ValueError:
- yield 1
- x = f()
- res = list(x)
- assert res == [1]
-
- def test_throw_on_finished_generator(self):
- def f():
- yield 1
- g = f()
- res = g.next()
- assert res == 1
- raises(StopIteration, g.next)
- raises(NameError, g.throw, NameError)
-
- def test_close(self):
- def f():
- yield 1
- g = f()
- assert g.close() is None
-
- def test_close2(self):
- def f():
- try:
- yield 1
- except GeneratorExit:
- raise StopIteration
- g = f()
- g.next()
- assert g.close() is None
-
- def test_close3(self):
- def f():
- try:
- yield 1
- except GeneratorExit:
- raise NameError
- g = f()
- g.next()
- raises(NameError, g.close)
-
- def test_close_fail(self):
- def f():
- try:
- yield 1
- except GeneratorExit:
- yield 2
- g = f()
- g.next()
- raises(RuntimeError, g.close)
-
- def test_close_on_collect(self):
- ## we need to exec it, else it won't run on python2.4
- d = {}
- exec """
- def f():
- try:
- yield
- finally:
- f.x = 42
- """.strip() in d
-
- g = d['f']()
- g.next()
- del g
- import gc
- gc.collect()
- assert d['f'].x == 42
-
- def test_generator_raises_typeerror(self):
- def f():
- yield 1
- g = f()
- raises(TypeError, g.send) # one argument required
- raises(TypeError, g.send, 1) # not started, must send None
-
- def test_generator_explicit_stopiteration(self):
- def f():
- yield 1
- raise StopIteration
- g = f()
- assert [x for x in g] == [1]
-
- def test_generator_propagate_stopiteration(self):
- def f():
- it = iter([1])
- while 1: yield it.next()
- g = f()
- assert [x for x in g] == [1]
-
- def test_generator_restart(self):
- def g():
- i = me.next()
- yield i
- me = g()
- raises(ValueError, me.next)
-
- def test_generator_expression(self):
- exec "res = sum(i*i for i in range(5))"
- assert res == 30
-
- def test_generator_expression_2(self):
- d = {}
- exec """
-def f():
- total = sum(i for i in [x for x in z])
- return total, x
-z = [1, 2, 7]
-res = f()
-""" in d
- assert d['res'] == (10, 7)
-
- def test_repr(self):
- def myFunc():
- yield 1
- g = myFunc()
- r = repr(g)
- assert r.startswith("<generator object myFunc at 0x")
- assert list(g) == [1]
- assert repr(g) == r
-
- def test_unpackiterable_gen(self):
- g = (i*i for i in range(-5, 3))
- assert set(g) == set([0, 1, 4, 9, 16, 25])
- assert set(g) == set()
- assert set(i for i in range(0)) == set()
-
- def test_explicit_stop_iteration_unpackiterable(self):
- def f():
- yield 1
- raise StopIteration
- assert tuple(f()) == (1,)
-
- def test_exception_is_cleared_by_yield(self):
- def f():
- try:
- foobar
- except NameError:
- yield 5
- raise # should raise "no active exception to re-raise"
- gen = f()
- next(gen) # --> 5
- try:
- next(gen)
- except TypeError:
- pass
-
- def test_multiple_invalid_sends(self):
- def mygen():
- yield 42
- g = mygen()
- raises(TypeError, g.send, 2)
- raises(TypeError, g.send, 2)
-
-
def test_should_not_inline(space):
from pypy.interpreter.generator import should_not_inline
w_co = space.appexec([], '''():
diff --git a/pypy/module/_hashlib/__init__.py b/pypy/module/_hashlib/__init__.py
deleted file mode 100644
diff --git a/pypy/module/_hashlib/interp_hashlib.py
b/pypy/module/_hashlib/interp_hashlib.py
deleted file mode 100644
--- a/pypy/module/_hashlib/interp_hashlib.py
+++ /dev/null
@@ -1,204 +0,0 @@
-from __future__ import with_statement
-
-from rpython.rlib import rgc, ropenssl
-from rpython.rlib.objectmodel import we_are_translated
-from rpython.rlib.rstring import StringBuilder
-from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.tool.sourcetools import func_renamer
-
-from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.gateway import unwrap_spec, interp2app, WrappedDefault
-from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from pypy.module.thread.os_lock import Lock
-
-
-algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
-
-def hash_name_mapper_callback(obj_name, userdata):
- if not obj_name:
- return
- # Ignore aliased names, they pollute the list and OpenSSL appears
- # to have a its own definition of alias as the resulting list
- # still contains duplicate and alternate names for several
- # algorithms.
- if rffi.cast(lltype.Signed, obj_name[0].c_alias):
- return
- name = rffi.charp2str(obj_name[0].c_name)
- global_name_fetcher.meth_names.append(name)
-
-class NameFetcher:
- def setup(self):
- self.meth_names = []
- def _cleanup_(self):
- self.__dict__.clear()
-global_name_fetcher = NameFetcher()
-
-def fetch_names(space):
- global_name_fetcher.setup()
- ropenssl.init_digests()
- ropenssl.OBJ_NAME_do_all(ropenssl.OBJ_NAME_TYPE_MD_METH,
- hash_name_mapper_callback, None)
- meth_names = global_name_fetcher.meth_names
- global_name_fetcher.meth_names = None
- return space.call_function(space.w_frozenset, space.newlist(
- [space.newtext(name) for name in meth_names]))
-
-class W_Hash(W_Root):
- NULL_CTX = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
- ctx = NULL_CTX
-
- def __init__(self, space, name, copy_from=NULL_CTX):
- self.name = name
- digest_type = self.digest_type_by_name(space)
- self.digest_size = ropenssl.EVP_MD_size(digest_type)
-
- # Allocate a lock for each HASH object.
- # An optimization would be to not release the GIL on small requests,
- # and use a custom lock only when needed.
- self.lock = Lock(space)
-
- ctx = ropenssl.EVP_MD_CTX_new()
- if ctx is None:
- raise MemoryError
- rgc.add_memory_pressure(ropenssl.HASH_MALLOC_SIZE + self.digest_size,
- self)
- try:
- if copy_from:
- if not ropenssl.EVP_MD_CTX_copy(ctx, copy_from):
- raise ValueError
- else:
- ropenssl.EVP_DigestInit(ctx, digest_type)
- self.ctx = ctx
- except:
- ropenssl.EVP_MD_CTX_free(ctx)
- raise
- self.register_finalizer(space)
-
- def _finalize_(self):
- ctx = self.ctx
- if ctx:
- self.ctx = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
- ropenssl.EVP_MD_CTX_free(ctx)
-
- def digest_type_by_name(self, space):
- digest_type = ropenssl.EVP_get_digestbyname(self.name)
- if not digest_type:
- raise oefmt(space.w_ValueError, "unknown hash function")
- return digest_type
-
- def descr_repr(self, space):
- addrstring = self.getaddrstring(space)
- return space.newtext("<%s HASH object at 0x%s>" % (
- self.name, addrstring))
-
- @unwrap_spec(string='bufferstr')
- def update(self, space, string):
- with rffi.scoped_nonmovingbuffer(string) as buf:
- with self.lock:
- # XXX try to not release the GIL for small requests
- ropenssl.EVP_DigestUpdate(self.ctx, buf, len(string))
-
- def copy(self, space):
- "Return a copy of the hash object."
- with self.lock:
- return W_Hash(space, self.name, copy_from=self.ctx)
-
- def digest(self, space):
- "Return the digest value as a string of binary data."
- digest = self._digest(space)
- return space.newbytes(digest)
-
- def hexdigest(self, space):
- "Return the digest value as a string of hexadecimal digits."
- digest = self._digest(space)
- hexdigits = '0123456789abcdef'
- result = StringBuilder(self.digest_size * 2)
- for c in digest:
- result.append(hexdigits[(ord(c) >> 4) & 0xf])
- result.append(hexdigits[ ord(c) & 0xf])
- return space.newtext(result.build())
-
- def get_digest_size(self, space):
- return space.newint(self.digest_size)
-
- def get_block_size(self, space):
- digest_type = self.digest_type_by_name(space)
- block_size = ropenssl.EVP_MD_block_size(digest_type)
- return space.newint(block_size)
-
- def get_name(self, space):
- return space.newtext(self.name)
-
- def _digest(self, space):
- ctx = ropenssl.EVP_MD_CTX_new()
- if ctx is None:
- raise MemoryError
- try:
- with self.lock:
- if not ropenssl.EVP_MD_CTX_copy(ctx, self.ctx):
- raise ValueError
- digest_size = self.digest_size
- with rffi.scoped_alloc_buffer(digest_size) as buf:
- ropenssl.EVP_DigestFinal(ctx, buf.raw, None)
- return buf.str(digest_size)
- finally:
- ropenssl.EVP_MD_CTX_free(ctx)
-
-
-W_Hash.typedef = TypeDef(
- 'HASH',
- __repr__=interp2app(W_Hash.descr_repr),
- update=interp2app(W_Hash.update),
- copy=interp2app(W_Hash.copy),
- digest=interp2app(W_Hash.digest),
- hexdigest=interp2app(W_Hash.hexdigest),
- #
- digest_size=GetSetProperty(W_Hash.get_digest_size),
- digestsize=GetSetProperty(W_Hash.get_digest_size),
- block_size=GetSetProperty(W_Hash.get_block_size),
- name=GetSetProperty(W_Hash.get_name),
-)
-W_Hash.typedef.acceptable_as_base_class = False
-
-@unwrap_spec(name='text', string='bufferstr')
-def new(space, name, string=''):
- w_hash = W_Hash(space, name)
- w_hash.update(space, string)
- return w_hash
-
-# shortcut functions
-def make_new_hash(name, funcname):
- @func_renamer(funcname)
- @unwrap_spec(string='bufferstr')
- def new_hash(space, string=''):
- return new(space, name, string)
- return new_hash
-
-for _name in algorithms:
- _newname = 'new_%s' % (_name,)
- globals()[_newname] = make_new_hash(_name, _newname)
-
-
-HAS_FAST_PKCS5_PBKDF2_HMAC = ropenssl.PKCS5_PBKDF2_HMAC is not None
-if HAS_FAST_PKCS5_PBKDF2_HMAC:
- @unwrap_spec(name='text', password='bytes', salt='bytes', rounds=int,
- w_dklen=WrappedDefault(None))
- def pbkdf2_hmac(space, name, password, salt, rounds, w_dklen):
- digest = ropenssl.EVP_get_digestbyname(name)
- if not digest:
- raise oefmt(space.w_ValueError, "unknown hash function")
- if space.is_w(w_dklen, space.w_None):
- dklen = ropenssl.EVP_MD_size(digest)
- else:
- dklen = space.int_w(w_dklen)
- if dklen < 1:
- raise oefmt(space.w_ValueError,
- "key length must be greater than 0.")
- with rffi.scoped_alloc_buffer(dklen) as buf:
- r = ropenssl.PKCS5_PBKDF2_HMAC(
- password, len(password), salt, len(salt), rounds, digest,
- dklen, buf.raw)
- if not r:
- raise ValueError
- return space.newbytes(buf.str(dklen))
diff --git a/pypy/module/_hashlib/moduledef.py
b/pypy/module/_hashlib/moduledef.py
deleted file mode 100644
--- a/pypy/module/_hashlib/moduledef.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from pypy.interpreter.mixedmodule import MixedModule
-from pypy.module._hashlib.interp_hashlib import (
- algorithms, fetch_names, HAS_FAST_PKCS5_PBKDF2_HMAC)
-
-
-class Module(MixedModule):
- interpleveldefs = {
- 'new' : 'interp_hashlib.new',
- }
-
- appleveldefs = {
- }
-
- for name in algorithms:
- interpleveldefs['openssl_' + name] = 'interp_hashlib.new_' + name
-
- if HAS_FAST_PKCS5_PBKDF2_HMAC:
- interpleveldefs['pbkdf2_hmac'] = 'interp_hashlib.pbkdf2_hmac'
-
- def startup(self, space):
- w_meth_names = fetch_names(space)
- space.setattr(self, space.newtext('openssl_md_meth_names'),
w_meth_names)
diff --git a/pypy/module/_hashlib/test/test_hashlib.py
b/pypy/module/_hashlib/test/test_hashlib.py
deleted file mode 100644
--- a/pypy/module/_hashlib/test/test_hashlib.py
+++ /dev/null
@@ -1,123 +0,0 @@
-class AppTestHashlib:
- spaceconfig = {
- "usemodules": ['_hashlib', 'array', 'struct', 'binascii'],
- }
-
- def test_method_names(self):
- import _hashlib
- assert isinstance(_hashlib.openssl_md_meth_names, frozenset)
- assert "md5" in _hashlib.openssl_md_meth_names
-
- def test_simple(self):
- import _hashlib
- assert _hashlib.new('md5').__class__.__name__ == 'HASH'
- assert len(_hashlib.new('md5').hexdigest()) == 32
-
- def test_attributes(self):
- import hashlib
- for name, (expected_size, expected_block_size) in {
- 'md5': (16, 64),
- 'sha1': (20, 64),
- 'sha224': (28, 64),
- 'sha256': (32, 64),
- 'sha384': (48, 128),
- 'sha512': (64, 128),
- }.items():
- h = hashlib.new(name)
- assert h.name == name
- assert h.digest_size == expected_size
- assert h.digestsize == expected_size
- assert h.block_size == expected_block_size
- #
- h.update('abc')
- h2 = h.copy()
- h.update('def')
- digest = h.digest()
- hexdigest = h.hexdigest()
- h2.update('d')
- h2.update('ef')
- assert digest == h2.digest()
- assert hexdigest == h2.hexdigest()
- assert len(digest) == h.digest_size
- assert len(hexdigest) == h.digest_size * 2
- c_digest = digest
- c_hexdigest = hexdigest
-
- # also test the pure Python implementation
- py_new = getattr(hashlib, '__get_builtin_constructor')
- h = py_new(name)('')
- assert h.digest_size == expected_size
- assert h.digestsize == expected_size
- assert h.block_size == expected_block_size
- #
- h.update('abc')
- h2 = h.copy()
- h.update('def')
- digest = h.digest()
- hexdigest = h.hexdigest()
- h2.update('d')
- h2.update('ef')
- assert digest == h2.digest()
- assert hexdigest == h2.hexdigest()
-
- # compare both implementations
- assert c_digest == digest
- assert c_hexdigest == hexdigest
-
- def test_shortcut(self):
- import hashlib
- assert repr(hashlib.md5()).startswith("<md5 HASH object")
-
- def test_unicode(self):
- import _hashlib
- assert _hashlib.new('sha1', u'xxx').__class__.__name__ == 'HASH'
-
- def test_uppercase(self):
- import _hashlib
- h = _hashlib.new('MD5')
- assert h.digest_size == 16
- assert len(h.hexdigest()) == 32
-
- def test_buffer(self):
- import _hashlib, array
- b = array.array('b', 'x' * 10)
- h = _hashlib.new('md5', b)
- h.update(b)
- assert h.digest() == _hashlib.openssl_md5('x' * 20).digest()
- _hashlib.openssl_sha1(b).digest()
-
- def test_extra_algorithms(self):
- expected_results = {
- "md5": "bb649c83dd1ea5c9d9dec9a18df0ffe9",
- "md4": "c275b8454684ea416b93d7a418b43176",
- "mdc2": None, # XXX find the correct expected value
- "sha": "e2b0a8609b47c58e5d984c9ccfe69f9b654b032b",
- "ripemd160": "cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc",
- "whirlpool": ("1a22b79fe5afda02c63a25927193ed01dc718b74"
- "026e597608ce431f9c3d2c9e74a7350b7fbb7c5d"
- "4effe5d7a31879b8b7a10fd2f544c4ca268ecc6793923583"),
- }
- import _hashlib
- test_string = "Nobody inspects the spammish repetition"
- for hash_name, expected in sorted(expected_results.items()):
- try:
- m = _hashlib.new(hash_name)
- except ValueError as e:
- print 'skipped %s: %s' % (hash_name, e)
- continue
- m.update(test_string)
- got = m.hexdigest()
- assert got and type(got) is str and len(got) % 2 == 0
- got.decode('hex')
- if expected is not None:
- assert got == expected
-
- def test_pbkdf2(self):
- try:
- from _hashlib import pbkdf2_hmac
- except ImportError:
- skip("Requires OpenSSL >= 1.1")
- out = pbkdf2_hmac('sha1', 'password', 'salt', 1)
- assert out == '0c60c80f961f0e71f3a9b524af6012062fe037a6'.decode('hex')
- out = pbkdf2_hmac('sha1', 'password', 'salt', 2, None)
- assert out == 'ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957'.decode('hex')
diff --git a/pypy/module/_hashlib/test/test_ztranslation.py
b/pypy/module/_hashlib/test/test_ztranslation.py
deleted file mode 100644
--- a/pypy/module/_hashlib/test/test_ztranslation.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from pypy.objspace.fake.checkmodule import checkmodule
-
-def test_checkmodule():
- checkmodule('_hashlib')
diff --git a/pypy/module/_minimal_curses/fficurses.py
b/pypy/module/_minimal_curses/fficurses.py
--- a/pypy/module/_minimal_curses/fficurses.py
+++ b/pypy/module/_minimal_curses/fficurses.py
@@ -5,11 +5,6 @@
from rpython.rtyper.tool import rffi_platform
from rpython.translator.tool.cbuild import ExternalCompilationInfo
-# We cannot trust ncurses5-config, it's broken in various ways in
-# various versions. For example it might not list -ltinfo even though
-# it's needed, or --cflags might be completely empty. On Ubuntu 10.04
-# it gives -I/usr/include/ncurses, which doesn't exist at all. Crap.
-
def try_cflags():
yield ExternalCompilationInfo(includes=['curses.h', 'term.h'])
yield ExternalCompilationInfo(includes=['curses.h', 'term.h'],
@@ -20,8 +15,9 @@
'ncurses/term.h'])
def try_ldflags():
+ yield ExternalCompilationInfo(libraries=['curses', 'tinfo'])
yield ExternalCompilationInfo(libraries=['curses'])
- yield ExternalCompilationInfo(libraries=['curses', 'tinfo'])
+ yield ExternalCompilationInfo(libraries=['ncurses', 'tinfo'])
yield ExternalCompilationInfo(libraries=['ncurses'])
yield ExternalCompilationInfo(libraries=['ncurses'],
library_dirs=['/usr/lib64'])
@@ -30,7 +26,11 @@
def try_tools():
try:
- yield ExternalCompilationInfo.from_pkg_config("ncurses")
+ yield ExternalCompilationInfo.from_config_tool("ncursesw6-config")
+ except Exception:
+ pass
+ try:
+ yield ExternalCompilationInfo.from_config_tool("ncurses5-config")
except Exception:
pass
try:
@@ -38,7 +38,7 @@
except Exception:
pass
try:
- yield ExternalCompilationInfo.from_config_tool("ncurses5-config")
+ yield ExternalCompilationInfo.from_pkg_config("ncursesw")
except Exception:
pass
diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py
--- a/pypy/module/cpyext/cparser.py
+++ b/pypy/module/cpyext/cparser.py
@@ -705,6 +705,7 @@
self.struct_typedefs = {}
self._handled = set()
self._frozen = False
+ self._cdecl_type_cache = {} # {cdecl: TYPE} cache
if includes is not None:
for header in includes:
self.include(header)
@@ -840,6 +841,14 @@
raise NotImplementedError
def gettype(self, cdecl):
+ try:
+ return self._cdecl_type_cache[cdecl]
+ except KeyError:
+ result = self._real_gettype(cdecl)
+ self._cdecl_type_cache[cdecl] = result
+ return result
+
+ def _real_gettype(self, cdecl):
obj = self.ctx.parse_type(cdecl)
result = self.convert_type(obj)
if isinstance(result, DelayedStruct):
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -448,14 +448,19 @@
return w_loader
def _getimporter(space, w_pathitem):
- # the function 'imp._getimporter' is a pypy-only extension
+ # 'imp._getimporter' is somewhat like CPython's get_path_importer
w_path_importer_cache = space.sys.get("path_importer_cache")
w_importer = space.finditem(w_path_importer_cache, w_pathitem)
if w_importer is None:
space.setitem(w_path_importer_cache, w_pathitem, space.w_None)
for w_hook in space.unpackiterable(space.sys.get("path_hooks")):
+ w_pathbytes = w_pathitem
+ if space.isinstance_w(w_pathitem, space.w_unicode):
+ from pypy.module.sys.interp_encoding import
getfilesystemencoding
+ w_pathbytes = space.call_method(space.w_unicode, 'encode',
+ w_pathitem, getfilesystemencoding(space))
try:
- w_importer = space.call_function(w_hook, w_pathitem)
+ w_importer = space.call_function(w_hook, w_pathbytes)
except OperationError as e:
if not e.match(space, space.w_ImportError):
raise
diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py
--- a/pypy/module/imp/test/test_app.py
+++ b/pypy/module/imp/test/test_app.py
@@ -4,7 +4,8 @@
class AppTestImpModule:
spaceconfig = {
- 'usemodules': ['binascii', 'imp', 'itertools', 'time', 'struct'],
+ 'usemodules': ['binascii', 'imp', 'itertools', 'time', 'struct',
+ 'zipimport'],
}
def setup_class(cls):
@@ -246,3 +247,14 @@
assert marshal.loads == 42
marshal.loads = old
+
+ def test_unicode_in_sys_path(self):
+ # issue 3112: when _getimporter calls
+ # for x in sys.path: for h in sys.path_hooks: h(x)
+ # make sure x is properly encoded
+ import sys
+ import zipimport # installs a sys.path_hook
+ if sys.getfilesystemencoding().lower() == 'utf-8':
+ sys.path.insert(0, u'\xef')
+ with raises(ImportError):
+ import impossible_module
diff --git a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
--- a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py
@@ -4,8 +4,10 @@
from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
from rpython.rlib.rawstorage import misaligned_is_fine
+IS_X86 = platform.machine().startswith('x86') or platform.machine() == 'i686'
+
def no_vector_backend():
- if platform.machine().startswith('x86'):
+ if IS_X86:
from rpython.jit.backend.x86.detect_feature import detect_sse4_2
if sys.maxsize < 2**31:
return True
@@ -19,7 +21,7 @@
return True
def align_check(input):
- if platform.machine().startswith('x86'):
+ if IS_X86:
return ""
if sys.maxsize > 2**32:
mask = 7
diff --git a/pypy/module/thread/test/test_thread.py
b/pypy/module/thread/test/test_thread.py
--- a/pypy/module/thread/test/test_thread.py
+++ b/pypy/module/thread/test/test_thread.py
@@ -1,38 +1,9 @@
import thread, time
from pypy.module.thread.test.support import GenericTestThread
+import pytest
class AppTestThread(GenericTestThread):
- def setup_class(cls):
- GenericTestThread.setup_class.im_func(cls)
- # if we cannot start more than, say, 1000 threads on this OS, then
- # we can check that we get the proper error at app-level
- space = cls.space
- lock = thread.allocate_lock()
- lock.acquire()
- def f():
- lock.acquire()
- lock.release()
- start = thread._count()
- try:
- try:
- for i in range(1000):
- thread.start_new_thread(f, ())
- finally:
- lock.release()
- except (thread.error, MemoryError):
- cls.w_can_start_many_threads = space.wrap(False)
- else:
- cls.w_can_start_many_threads = space.wrap(True)
- # wait a bit to allow all threads to finish now
- remaining = thread._count()
- retries = 0
- while remaining > start:
- retries += 1
- if retries == 200:
- raise Exception("the test's threads don't stop!")
- time.sleep(0.2)
- remaining = thread._count()
def test_start_new_thread(self):
import thread
@@ -189,35 +160,6 @@
assert done # see stderr for failures in threads
assert sorted(lst) == range(120)
- def test_many_threads(self):
- import thread, time
- if self.can_start_many_threads:
- skip("this OS supports too many threads to check (> 1000)")
- lock = thread.allocate_lock()
- lock.acquire()
- count = [0]
- def f():
- count[0] += 1
- lock.acquire()
- lock.release()
- count[0] -= 1
- try:
- try:
- for i in range(1000):
- thread.start_new_thread(f, ())
- finally:
- lock.release()
- # wait a bit to allow most threads to finish now
- while count[0] > 10:
- print count[0] # <- releases the GIL
- print "ok."
- except (thread.error, MemoryError):
- pass
- else:
- raise Exception("could unexpectedly start 1000 threads")
- # safety: check that we can start a new thread here
- thread.start_new_thread(lambda: None, ())
-
def test_stack_size(self):
import thread
thread.stack_size(0)
@@ -256,3 +198,74 @@
waiting = []
thread.start_new_thread(f, ())
raises(KeyboardInterrupt, busy_wait)
+
[email protected]("too slow")
+class _AppTestThread(GenericTestThread):
+ '''
+ This test is very slow, do not run it by default.
+ '''
+ def setup_class(cls):
+ GenericTestThread.setup_class.im_func(cls)
+ # if we cannot start more than, say, 1000 threads on this OS, then
+ # we can check that we get the proper error at app-level
+ space = cls.space
+ lock = thread.allocate_lock()
+ lock.acquire()
+ def f():
+ lock.acquire()
+ lock.release()
+ start = thread._count()
+ try:
+ try:
+ for i in range(1000):
+ thread.start_new_thread(f, ())
+ finally:
+ lock.release()
+ except (thread.error, MemoryError):
+ cls.w_can_start_many_threads = space.wrap(False)
+ else:
+ cls.w_can_start_many_threads = space.wrap(True)
+ # wait a bit to allow all threads to finish now
+ remaining = thread._count()
+ retries = 0
+ while remaining > start:
+ retries += 1
+ if retries == 200:
+ raise Exception("the test's threads don't stop!")
+ time.sleep(0.2)
+ remaining = thread._count()
+
+ def test_many_threads(self):
+ import time, sys
+ if sys.version_info[0] < 3:
+ import thread as _thread
+ else:
+ import _thread
+ if self.can_start_many_threads or sys.platform == 'win32':
+ skip("this OS supports too many threads to check (> 1000)")
+ lock = _thread.allocate_lock()
+ lock.acquire()
+ count = [0]
+ def f():
+ count[0] += 1
+ lock.acquire()
+ lock.release()
+ count[0] -= 1
+ try:
+ try:
+ for i in range(1000):
+ _thread.start_new_thread(f, ())
+ finally:
+ lock.release()
+ # wait a bit to allow most threads to finish now
+ while count[0] > 10:
+ print(count[0]) # <- releases the GIL
+ print("ok.")
+ except (_thread.error, MemoryError):
+ pass
+ else:
+ raise Exception("could unexpectedly start 1000 threads")
+ # safety: check that we can start a new thread here
+ _thread.start_new_thread(lambda: None, ())
+
+
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
@@ -345,7 +345,7 @@
assert (d1 + from_copy) == (d1 + from_compressor)
- @py.test.mark.skipif(rzlib.ZLIB_VERSION == '1.2.8', reason='does not error
check')
+ @py.test.mark.skipif(rzlib.ZLIB_VERSION in ('1.2.8', '1.2.3'),
reason='does not error check')
def test_cannot_copy_compressor_with_stream_in_inconsistent_state(self):
if self.runappdirect: skip("can't run with -A")
compressor = self.zlib.compressobj()
diff --git a/pypy/test_all.py b/pypy/test_all.py
--- a/pypy/test_all.py
+++ b/pypy/test_all.py
@@ -17,14 +17,20 @@
For more information, use test_all.py -h.
"""
import sys, os
+import shutil
if __name__ == '__main__':
if len(sys.argv) == 1 and os.path.dirname(sys.argv[0]) in '.':
print >> sys.stderr, __doc__
sys.exit(2)
- #Add toplevel repository dir to sys.path
-
sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
+ toplevel = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+ # Always remove the cached files
+ # Before translation this is done via "py.path.local(CACHE_DIR).remove()"
+ print 'removing %s/rpython/_cache' % toplevel
+ shutil.rmtree('%s/rpython/_cache' % toplevel, ignore_errors=True)
+ # Add toplevel repository dir to sys.path
+ sys.path.insert(0, toplevel)
import pytest
if sys.platform == 'win32':
#Try to avoid opening a dialog box if one of the tests causes a system
error
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -67,6 +67,8 @@
name = options.name
if not name:
name = 'pypy-nightly'
+ if options.make_portable and 'portable' not in name:
+ name += '-portable'
assert '/' not in name
rename_pypy_c = options.pypy_c
override_pypy_c = options.override_pypy_c
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -800,7 +800,7 @@
DIRENT = rffi_platform.Struct('struct dirent',
[('d_name', lltype.FixedSizeArray(rffi.CHAR, 1)),
('d_ino', lltype.Signed)]
- + [('d_type', rffi.INT)] if HAVE_D_TYPE else [])
+ + ([('d_type', rffi.INT)] if HAVE_D_TYPE else []))
if HAVE_D_TYPE:
DT_UNKNOWN = rffi_platform.ConstantInteger('DT_UNKNOWN')
DT_REG = rffi_platform.ConstantInteger('DT_REG')
@@ -1931,8 +1931,7 @@
rffi.INT, save_err=rffi.RFFI_FULL_ERRNO_ZERO)
c_sched_get_priority_min = external('sched_get_priority_min', [rffi.INT],
rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO)
- if not _WIN32:
- c_sched_yield = external('sched_yield', [], rffi.INT)
+ c_sched_yield = external('sched_yield', [], rffi.INT)
@enforceargs(int)
def sched_get_priority_max(policy):
@@ -1945,6 +1944,36 @@
def sched_yield():
return handle_posix_error('sched_yield', c_sched_yield())
+ c_getgroupslist = external('getgrouplist', [rffi.CCHARP, GID_T,
+ GID_GROUPS_T, rffi.INTP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+
+ def getgrouplist(user, group):
+ groups_p = lltype.malloc(GID_GROUPS_T.TO, 64, flavor='raw')
+ ngroups_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+ ngroups_p[0] = rffi.cast(rffi.INT, 64)
+ try:
+ n = handle_posix_error('getgrouplist', c_getgroupslist(user, group,
+ groups_p, ngroups_p))
+ if n == -1:
+ if widen(ngroups_p[0]) > 64:
+ # reallocate. Should never happen
+ lltype.free(groups_p, flavor='raw')
+ groups_p = lltype.nullptr(GID_GROUPS_T.TO)
+ groups_p = lltype.malloc(GID_GROUPS_T.TO,
widen(ngroups_p[0]),
+ flavor='raw')
+
+ n = handle_posix_error('getgrouplist',
c_getgroupslist(user,
+ group, groups_p,
ngroups_p))
+ ngroups = widen(ngroups_p[0])
+ groups = [0] * ngroups
+ for i in range(ngroups):
+ groups[i] = groups_p[i]
+ return groups
+ finally:
+ lltype.free(ngroups_p, flavor='raw')
+ if groups_p:
+ lltype.free(groups_p, flavor='raw')
#___________________________________________________________________
c_chroot = external('chroot', [rffi.CCHARP], rffi.INT,
diff --git a/rpython/rlib/rtime.py b/rpython/rlib/rtime.py
--- a/rpython/rlib/rtime.py
+++ b/rpython/rlib/rtime.py
@@ -9,7 +9,7 @@
from rpython.rtyper.tool import rffi_platform
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib.objectmodel import register_replacement_for
-from rpython.rlib.rarithmetic import intmask, UINT_MAX
+from rpython.rlib.rarithmetic import intmask, r_int64, UINT_MAX
from rpython.rlib import rposix
_WIN32 = sys.platform.startswith('win')
@@ -94,6 +94,10 @@
return (float(rffi.getintfield(t, 'c_tv_sec')) +
float(rffi.getintfield(t, 'c_tv_usec')) * 0.000001)
+def decode_timeval_ns(t):
+ return (r_int64(rffi.getintfield(t, 'c_tv_sec')) * 10**9 +
+ r_int64(rffi.getintfield(t, 'c_tv_usec')) * 10**3)
+
def external(name, args, result, compilation_info=eci, **kwds):
return rffi.llexternal(name, args, result,
diff --git a/rpython/rlib/test/test_rzlib.py b/rpython/rlib/test/test_rzlib.py
--- a/rpython/rlib/test/test_rzlib.py
+++ b/rpython/rlib/test/test_rzlib.py
@@ -274,7 +274,7 @@
rzlib.deflateEnd(copied)
assert bytes1 + bytes_copy == compressed
[email protected](rzlib.ZLIB_VERSION == '1.2.8', reason='does not error
check')
[email protected](rzlib.ZLIB_VERSION in ('1.2.3', '1.2.8'), reason='does
not error check')
def test_unsuccessful_compress_copy():
"""
Errors during unsuccesful deflateCopy operations raise RZlibErrors.
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit