[pypy-commit] pypy release-2.3.x: merge default into release branch
mattip
noreply at buildbot.pypy.org
Mon Apr 28 22:03:17 CEST 2014
Author: Matti Picus <matti.picus at gmail.com>
Branch: release-2.3.x
Changeset: r71052:80843924f836
Date: 2014-04-28 23:00 +0300
http://bitbucket.org/pypy/pypy/changeset/80843924f836/
Log: merge default into release branch
diff too long, truncating to 2000 out of 15405 lines
diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py
--- a/dotviewer/graphserver.py
+++ b/dotviewer/graphserver.py
@@ -160,15 +160,14 @@
" | instructions in dotviewer/sshgraphserver.py\n")
try:
import pygame
- except ImportError:
+ if isinstance(e, pygame.error):
+ print >> f, help
+ except Exception, e:
f.seek(0)
f.truncate()
- print >> f, "ImportError"
+ print >> f, "%s: %s" % (e.__class__.__name__, e)
print >> f, " | Pygame is not installed; either install it, or"
print >> f, help
- else:
- if isinstance(e, pygame.error):
- print >> f, help
io.sendmsg(msgstruct.MSG_ERROR, f.getvalue())
else:
listen_server(sys.argv[1])
diff --git a/lib-python/2.7/ctypes/util.py b/lib-python/2.7/ctypes/util.py
--- a/lib-python/2.7/ctypes/util.py
+++ b/lib-python/2.7/ctypes/util.py
@@ -86,9 +86,10 @@
elif os.name == "posix":
# Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
- import re, tempfile, errno
+ import re, errno
def _findLib_gcc(name):
+ import tempfile
expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
fdout, ccout = tempfile.mkstemp()
os.close(fdout)
diff --git a/lib-python/2.7/test/test_argparse.py b/lib-python/2.7/test/test_argparse.py
--- a/lib-python/2.7/test/test_argparse.py
+++ b/lib-python/2.7/test/test_argparse.py
@@ -51,7 +51,7 @@
for root, dirs, files in os.walk(self.temp_dir, topdown=False):
for name in files:
os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE)
- shutil.rmtree(self.temp_dir, True)
+ shutil.rmtree(self.temp_dir, True)
def create_readonly_file(self, filename):
file_path = os.path.join(self.temp_dir, filename)
diff --git a/lib-python/2.7/test/test_array.py b/lib-python/2.7/test/test_array.py
--- a/lib-python/2.7/test/test_array.py
+++ b/lib-python/2.7/test/test_array.py
@@ -298,6 +298,7 @@
b = array.array(self.badtypecode())
with self.assertRaises(TypeError):
a + b
+
with self.assertRaises(TypeError):
a + 'bad'
@@ -320,6 +321,7 @@
b = array.array(self.badtypecode())
with self.assertRaises(TypeError):
a += b
+
with self.assertRaises(TypeError):
a += 'bad'
diff --git a/lib-python/2.7/test/test_builtin.py b/lib-python/2.7/test/test_builtin.py
--- a/lib-python/2.7/test/test_builtin.py
+++ b/lib-python/2.7/test/test_builtin.py
@@ -250,14 +250,12 @@
self.assertRaises(TypeError, compile)
self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'badmode')
self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'single', 0xff)
- if check_impl_detail(cpython=True):
- self.assertRaises(TypeError, compile, chr(0), 'f', 'exec')
+ self.assertRaises(TypeError, compile, chr(0), 'f', 'exec')
self.assertRaises(TypeError, compile, 'pass', '?', 'exec',
mode='eval', source='0', filename='tmp')
if have_unicode:
compile(unicode('print u"\xc3\xa5"\n', 'utf8'), '', 'exec')
- if check_impl_detail(cpython=True):
- self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec')
+ self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec')
self.assertRaises(ValueError, compile, unicode('a = 1'), 'f', 'bad')
diff --git a/lib-python/2.7/test/test_file2k.py b/lib-python/2.7/test/test_file2k.py
--- a/lib-python/2.7/test/test_file2k.py
+++ b/lib-python/2.7/test/test_file2k.py
@@ -479,11 +479,10 @@
def _create_file(self):
if self.use_buffering:
- f = open(self.filename, "w+", buffering=1024*16)
+ self.f = open(self.filename, "w+", buffering=1024*16)
else:
- f = open(self.filename, "w+")
- self.f = f
- self.all_files.append(f)
+ self.f = open(self.filename, "w+")
+ self.all_files.append(self.f)
oldf = self.all_files.pop(0)
if oldf is not None:
oldf.close()
diff --git a/lib-python/2.7/test/test_httpservers.py b/lib-python/2.7/test/test_httpservers.py
--- a/lib-python/2.7/test/test_httpservers.py
+++ b/lib-python/2.7/test/test_httpservers.py
@@ -335,7 +335,7 @@
response = self.request(self.tempdir_name + '/')
self.check_status_and_reason(response, 404)
os.chmod(self.tempdir, 0755)
- f.close()
+ f.close()
def test_head(self):
response = self.request(
diff --git a/lib-python/2.7/test/test_itertools.py b/lib-python/2.7/test/test_itertools.py
--- a/lib-python/2.7/test/test_itertools.py
+++ b/lib-python/2.7/test/test_itertools.py
@@ -139,7 +139,6 @@
@test_support.impl_detail("tuple reuse is specific to CPython")
def test_combinations_tuple_reuse(self):
- # Test implementation detail: tuple re-use
self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1)
self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1)
@@ -211,7 +210,6 @@
@test_support.impl_detail("tuple reuse is specific to CPython")
def test_combinations_with_replacement_tuple_reuse(self):
- # Test implementation detail: tuple re-use
cwr = combinations_with_replacement
self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1)
self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1)
@@ -278,7 +276,6 @@
@test_support.impl_detail("tuple reuse is specific to CPython")
def test_permutations_tuple_reuse(self):
- # Test implementation detail: tuple re-use
self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1)
self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1)
diff --git a/lib-python/2.7/test/test_memoryview.py b/lib-python/2.7/test/test_memoryview.py
--- a/lib-python/2.7/test/test_memoryview.py
+++ b/lib-python/2.7/test/test_memoryview.py
@@ -115,8 +115,8 @@
self.assertRaises(TypeError, setitem, (0,), b"a")
self.assertRaises(TypeError, setitem, "a", b"a")
# Trying to resize the memory object
- self.assertRaises((ValueError, TypeError), setitem, 0, b"")
- self.assertRaises((ValueError, TypeError), setitem, 0, b"ab")
+ self.assertRaises(ValueError, setitem, 0, b"")
+ self.assertRaises(ValueError, setitem, 0, b"ab")
self.assertRaises(ValueError, setitem, slice(1,1), b"a")
self.assertRaises(ValueError, setitem, slice(0,2), b"a")
@@ -166,18 +166,11 @@
self.assertTrue(m[0:6] == m[:])
self.assertFalse(m[0:5] == m)
- if test_support.check_impl_detail(cpython=True):
- # what is supported and what is not supported by memoryview is
- # very inconsisten on CPython. In PyPy, memoryview supports
- # the buffer interface, and thus the following comparison
- # succeeds. See also the comment in
- # pypy.objspace.std.memoryview.W_MemoryView.descr_buffer
- #
- # Comparison with objects which don't support the buffer API
- self.assertFalse(m == u"abcdef", "%s %s" % (self, tp))
- self.assertTrue(m != u"abcdef")
- self.assertFalse(u"abcdef" == m)
- self.assertTrue(u"abcdef" != m)
+ # Comparison with objects which don't support the buffer API
+ self.assertFalse(m == u"abcdef")
+ self.assertTrue(m != u"abcdef")
+ self.assertFalse(u"abcdef" == m)
+ self.assertTrue(u"abcdef" != m)
# Unordered comparisons are unimplemented, and therefore give
# arbitrary results (they raise a TypeError in py3k)
diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py
--- a/lib_pypy/_ctypes_test.py
+++ b/lib_pypy/_ctypes_test.py
@@ -1,4 +1,5 @@
-import imp, os
+import imp
+import os
try:
import cpyext
@@ -17,7 +18,8 @@
output_dir = _pypy_testcapi.get_hashed_dir(os.path.join(thisdir, cfile))
try:
fp, filename, description = imp.find_module('_ctypes_test', path=[output_dir])
- imp.load_module('_ctypes_test', fp, filename, description)
+ with fp:
+ imp.load_module('_ctypes_test', fp, filename, description)
except ImportError:
print('could not find _ctypes_test in %s' % output_dir)
_pypy_testcapi.compile_shared('_ctypes_test.c', '_ctypes_test', output_dir)
diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -1,6 +1,7 @@
import os, sys, imp
import tempfile, binascii
+
def get_hashed_dir(cfile):
with open(cfile,'r') as fid:
content = fid.read()
@@ -15,7 +16,7 @@
output_dir = tempfile.gettempdir() + os.path.sep + 'tmp_%s%s' %(k1, k2)
if not os.path.exists(output_dir):
os.mkdir(output_dir)
- return output_dir
+ return output_dir
def _get_c_extension_suffix():
diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py
--- a/lib_pypy/_testcapi.py
+++ b/lib_pypy/_testcapi.py
@@ -1,4 +1,5 @@
-import imp, os
+import imp
+import os
try:
import cpyext
@@ -12,6 +13,7 @@
try:
fp, filename, description = imp.find_module('_testcapi', path=[output_dir])
- imp.load_module('_testcapi', fp, filename, description)
+ with fp:
+ imp.load_module('_testcapi', fp, filename, description)
except ImportError:
_pypy_testcapi.compile_shared(cfile, '_testcapi', output_dir)
diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py
--- a/lib_pypy/ctypes_support.py
+++ b/lib_pypy/ctypes_support.py
@@ -1,4 +1,3 @@
-
""" This file provides some support for things like standard_c_lib and
errno access, as portable as possible
"""
@@ -22,7 +21,7 @@
standard_c_lib._errno.argtypes = None
def _where_is_errno():
return standard_c_lib._errno()
-
+
elif sys.platform in ('linux2', 'freebsd6'):
standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
standard_c_lib.__errno_location.argtypes = None
@@ -42,5 +41,3 @@
def set_errno(value):
errno_p = _where_is_errno()
errno_p.contents.value = value
-
-
diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst
--- a/pypy/doc/cppyy.rst
+++ b/pypy/doc/cppyy.rst
@@ -560,6 +560,12 @@
Fixing these bootstrap problems is on the TODO list.
The global namespace is ``cppyy.gbl``.
+* **NULL**: Is represented as ``cppyy.gbl.nullptr``.
+ In C++11, the keyword ``nullptr`` is used to represent ``NULL``.
+ For clarity of intent, it is recommended to use this instead of ``None``
+ (or the integer ``0``, which can serve in some cases), as ``None`` is better
+ understood as ``void`` in C++.
+
* **operator conversions**: If defined in the C++ class and a python
equivalent exists (i.e. all builtin integer and floating point types, as well
as ``bool``), it will map onto that python conversion.
@@ -577,7 +583,7 @@
Special care needs to be taken for global operator overloads in C++: first,
make sure that they are actually reflected, especially for the global
overloads for ``operator==`` and ``operator!=`` of STL vector iterators in
- the case of gcc (note that they are not needed to iterator over a vector).
+ the case of gcc (note that they are not needed to iterate over a vector).
Second, make sure that reflection info is loaded in the proper order.
I.e. that these global overloads are available before use.
diff --git a/pypy/doc/extending.rst b/pypy/doc/extending.rst
--- a/pypy/doc/extending.rst
+++ b/pypy/doc/extending.rst
@@ -66,58 +66,26 @@
Reflex
======
-This method is still experimental. It adds the `cppyy`_ module.
-The method works by using the `Reflex package`_ to provide reflection
-information of the C++ code, which is then used to automatically generate
-bindings at runtime.
-From a python standpoint, there is no difference between generating bindings
-at runtime, or having them "statically" generated and available in scripts
-or compiled into extension modules: python classes and functions are always
-runtime structures, created when a script or module loads.
+The builtin `cppyy`_ module uses reflection information, provided by
+`Reflex`_ (which needs to be `installed separately`_), of C/C++ code to
+automatically generate bindings at runtime.
+In Python, classes and functions are always runtime structures, so when they
+are generated matters not for performance.
However, if the backend itself is capable of dynamic behavior, it is a much
-better functional match to python, allowing tighter integration and more
-natural language mappings.
-Full details are `available here`_.
+better functional match, allowing tighter integration and more natural
+language mappings.
+
+The `cppyy`_ module is written in RPython, thus PyPy's JIT is able to remove
+most cross-language call overhead.
+
+`Full details`_ are `available here`_.
.. _`cppyy`: cppyy.html
-.. _`reflex-support`: cppyy.html
-.. _`Reflex package`: http://root.cern.ch/drupal/content/reflex
+.. _`installed separately`: http://cern.ch/wlav/reflex-2013-08-14.tar.bz2
+.. _`Reflex`: http://root.cern.ch/drupal/content/reflex
+.. _`Full details`: cppyy.html
.. _`available here`: cppyy.html
-Pros
-----
-
-The cppyy module is written in RPython, which makes it possible to keep the
-code execution visible to the JIT all the way to the actual point of call into
-C++, thus allowing for a very fast interface.
-Reflex is currently in use in large software environments in High Energy
-Physics (HEP), across many different projects and packages, and its use can be
-virtually completely automated in a production environment.
-One of its uses in HEP is in providing language bindings for CPython.
-Thus, it is possible to use Reflex to have bound code work on both CPython and
-on PyPy.
-In the medium-term, Reflex will be replaced by `cling`_, which is based on
-`llvm`_.
-This will affect the backend only; the python-side interface is expected to
-remain the same, except that cling adds a lot of dynamic behavior to C++,
-enabling further language integration.
-
-.. _`cling`: http://root.cern.ch/drupal/content/cling
-.. _`llvm`: http://llvm.org/
-
-Cons
-----
-
-C++ is a large language, and cppyy is not yet feature-complete.
-Still, the experience gained in developing the equivalent bindings for CPython
-means that adding missing features is a simple matter of engineering, not a
-question of research.
-The module is written so that currently missing features should do no harm if
-you don't use them, if you do need a particular feature, it may be necessary
-to work around it in python or with a C++ helper function.
-Although Reflex works on various platforms, the bindings with PyPy have only
-been tested on Linux.
-
RPython Mixed Modules
=====================
diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst
--- a/pypy/doc/getting-started.rst
+++ b/pypy/doc/getting-started.rst
@@ -76,7 +76,7 @@
.. code-block:: console
$ curl -O http://python-distribute.org/distribute_setup.py
- $ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
+ $ curl -O https://raw.githubusercontent.com/pypa/pip/master/contrib/get-pip.py
$ ./pypy-2.1/bin/pypy distribute_setup.py
$ ./pypy-2.1/bin/pypy get-pip.py
$ ./pypy-2.1/bin/pip install pygments # for example
diff --git a/pypy/doc/release-2.3.0.rst b/pypy/doc/release-2.3.0.rst
--- a/pypy/doc/release-2.3.0.rst
+++ b/pypy/doc/release-2.3.0.rst
@@ -1,11 +1,17 @@
=======================================
-PyPy 2.3 - XXXX TODO
+PyPy 2.3 - Easier Than Ever
=======================================
We're pleased to announce PyPy 2.3, which targets version 2.7.6 of the Python
language. This release updates the stdlib from 2.7.3, jumping directly to 2.7.6.
-This release also contains several bugfixes and performance improvements.
+This release also contains several bugfixes and performance improvements,
+many generated by real users finding corner cases our `TDD`_ methods missed.
+`CFFI`_ has made it easier than ever to use existing C code with both cpython
+and PyPy, easing the transition for packages like `cryptography`_, `Pillow`_
+(Python Imaging Library [Fork]), a basic port of `pygame-cffi`_, and others.
+
+PyPy can now be embedded in a hosting application, for instance inside `uWSGI`_
You can download the PyPy 2.3 release here:
@@ -17,72 +23,112 @@
Please consider donating more so we can finish those projects! The three
projects are:
-* Py3k (supporting Python 3.x): the release PyPy3 2.2 is imminent.
+* `Py3k`_ (supporting Python 3.x): the release PyPy3 2.2 is imminent.
-* STM (software transactional memory): a preview will be released very soon,
- as soon as we fix a few bugs
+* `STM`_ (software transactional memory): a preview will be released very soon,
+ once we fix a few bugs
-* NumPy: the work done is included in the PyPy 2.2 release. More details below.
+* `NumPy`_ the work done is included in the PyPy 2.2 release. More details below.
-.. _`Raspberry Pi Foundation`: http://www.raspberrypi.org
+_`Py3k`: http://pypy.org/py3donate.html
+_`STM`: http://pypy.org/tmdonate2.html
+_ `Numpy`: http://pypy.org/numpydonate.html
+_`TDD`: http://doc.pypy.org/en/latest/how-to-contribute.html
+_`CFFI`: http://cffi.readthedocs.org
+_`cryptography`: https://cryptography.io
+_`Pillow`: https://pypi.python.org/pypi/Pillow/2.4.0
+_`pygame-cffi`: https://github.com/CTPUG/pygame_cffi
+_`uWSGI`: http://uwsgi-docs.readthedocs.org/en/latest/PyPy.html
What is PyPy?
=============
PyPy is a very compliant Python interpreter, almost a drop-in replacement for
-CPython 2.7. It's fast (`pypy 2.2 and cpython 2.7.2`_ performance comparison)
+CPython 2.7. It's fast (`pypy 2.2 and cpython 2.7.2`_ performance comparison;
+note that the latest cpython is not faster than cpython 2.7.2)
due to its integrated tracing JIT compiler.
-This release supports x86 machines running Linux 32/64, Mac OS X 64, Windows
-32, or ARM (ARMv6 or ARMv7, with VFPv3).
+This release supports x86 machines running Linux 32/64, Mac OS X 64, Windows,
+and OpenBSD,
+as well as newer ARM hardware (ARMv6 or ARMv7, with VFPv3) running Linux.
-Work on the native Windows 64 is still stalling, we would welcome a volunteer
-to handle that.
+While we support 32 bit python on Windows, work on the native Windows 64
+bit python is still stalling, we would welcome a volunteer
+to `handle that`_.
-.. _`pypy 2.2 and cpython 2.7.2`: http://speed.pypy.org
+_`pypy 2.2 and cpython 2.7.2`: http://speed.pypy.org
+_`handle that`: http://doc.pypy.org/en/latest/windows.html#what-is-missing-for-a-full-64-bit-translation
Highlights
==========
-* Our Garbage Collector is now "incremental". It should avoid almost
- all pauses due to a major collection taking place. Previously, it
- would pause the program (rarely) to walk all live objects, which
- could take arbitrarily long if your process is using a whole lot of
- RAM. Now the same work is done in steps. This should make PyPy
- more responsive, e.g. in games. There are still other pauses, from
- the GC and the JIT, but they should be on the order of 5
- milliseconds each.
+Bugfixes
+--------
-* The JIT counters for hot code were never reset, which meant that a
- process running for long enough would eventually JIT-compile more
- and more rarely executed code. Not only is it useless to compile
- such code, but as more compiled code means more memory used, this
- gives the impression of a memory leak. This has been tentatively
- fixed by decreasing the counters from time to time.
+Many issues were cleaned up after being reported by users to https://bugs.pypy.org (ignore the bad SSL certificate) or on IRC at #pypy. Note that we consider
+performance slowdowns as bugs.
-* NumPy has been split: now PyPy only contains the core module, called
- ``_numpypy``. The ``numpy`` module itself has been moved to
- ``https://bitbucket.org/pypy/numpy`` and ``numpypy`` disappeared.
- You need to install NumPy separately with a virtualenv:
+* The ARM port no longer crashes on unaligned memory access to floats and doubles,
+ and singlefloats are supported in the JIT.
+
+* Generators are faster since they now skip unecessary cleanup
+
+* A first time contributor simplified JIT traces by adding integer bound
+ propagation in indexing and logical operations.
+
+* Optimize consecutive dictionary lookups of the same key in a chain
+
+* Our extensive pre-translation test suite now runs nightly on more platforms
+
+* Fix issues with reimporting builtin modules
+
+* Fix a rpython bug with loop-unrolling that appeared in the `HippyVM`_ PHP port
+
+`HippyVM`_: http://www.hippyvm.com
+
+New Platforms and Features
+--------------------------
+
+* Support for OpenBSD
+
+* Code cleanup: we continue to prune out old and unused code, and to refactor
+ large parts of the codebase. We have sepearated rpython from the PyPy python
+ interpreter, and rpython is seeing use in other dynamic language projects.
+
+* Support for precompiled headers in the build process for MSVC
+
+* Support for objects with __int__ and __float__ methods
+
+* Tweak support of errno in cpyext (the PyPy implemenation of the capi)
+
+
+Numpy
+-----
+Numpy support has been split into a builtin ``_numpy`` module and a
+fork of the numpy code base adapted to pypy at
+ ``https://bitbucket.org/pypy/numpy``.
+You need to install NumPy separately with a virtualenv:
``pip install git+https://bitbucket.org/pypy/numpy.git``;
or directly:
``git clone https://bitbucket.org/pypy/numpy.git``;
``cd numpy``; ``pypy setup.py install``.
-* non-inlined calls have less overhead
+* NumPy support has been improved, many failures in indexing, dtypes,
+ and scalars were corrected. We are slowly approaching our goal of passing
+ the numpy test suite. We still do not support object or unicode ndarrays.
-* Things that use ``sys.set_trace`` are now JITted (like coverage)
+* speed of iteration in dot() is now within 1.5x of the numpy c
+ implementation (without BLAS acceleration). Since the same array
+ iterator is used throughout the ``_numpy`` module, speed increases should
+ be apparent in all Numpy functionality.
-* JSON decoding is now very fast (JSON encoding was already very fast)
+* Most of the core functionality of nditer has been implemented.
-* various buffer copying methods experience speedups (like list-of-ints to
- ``int[]`` buffer from cffi)
+* A cffi-based ``numpy.random`` module is available as a branch in the numpy
+ repository, it will be merged soon after this release.
-* We finally wrote (hopefully) all the missing ``os.xxx()`` functions,
- including ``os.startfile()`` on Windows and a handful of rare ones
- on Posix.
+* enhancements to the PyPy JIT were made to support virtualizing the raw_store/raw_load memory operations used in numpy arrays. Further work remains here in virtualizing the alloc_raw_storage when possible. This will allow scalars to have storages but still be virtualized when possible in loops.
-* numpy has a rudimentary C API that cooperates with ``cpyext``
+Cheers
+The PyPy Team
-Cheers,
-Armin Rigo and Maciej Fijalkowski
diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst
--- a/pypy/doc/sandbox.rst
+++ b/pypy/doc/sandbox.rst
@@ -42,6 +42,10 @@
use this sandboxed PyPy from a regular Python interpreter (CPython, or
an unsandboxed PyPy). Contributions welcome.
+.. warning::
+
+ Tested with PyPy2. May not work out of the box with PyPy3.
+
Overview
--------
diff --git a/pypy/doc/whatsnew-2.3.0.rst b/pypy/doc/whatsnew-2.3.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/whatsnew-2.3.0.rst
@@ -0,0 +1,154 @@
+=======================
+What's new in PyPy 2.2+
+=======================
+
+.. this is a revision shortly after release-2.2.x
+.. startrev: 4cd1bc8b3111
+
+.. branch: release-2.2.x
+
+.. branch: numpy-newbyteorder
+Clean up numpy types, add newbyteorder functionality
+
+.. branch: windows-packaging
+Package tk/tcl runtime with win32
+
+.. branch: armhf-singlefloat
+JIT support for singlefloats on ARM using the hardfloat ABI
+
+.. branch: voidtype_strformat
+Better support for record numpy arrays
+
+.. branch: osx-eci-frameworks-makefile
+OSX: Ensure frameworks end up in Makefile when specified in External compilation info
+
+.. branch: less-stringly-ops
+Use subclasses of SpaceOperation instead of SpaceOperator objects.
+Random cleanups in flowspace and annotator.
+
+.. branch: ndarray-buffer
+adds support for the buffer= argument to the ndarray ctor
+
+.. branch: better_ftime_detect2
+On OpenBSD do not pull in libcompat.a as it is about to be removed.
+And more generally, if you have gettimeofday(2) you will not need ftime(3).
+
+.. branch: timeb_h
+Remove dependency upon <sys/timeb.h> on OpenBSD. This will be disappearing
+along with libcompat.a.
+
+.. branch: OlivierBlanvillain/fix-3-broken-links-on-pypy-published-pap-1386250839215
+Fix 3 broken links on PyPy published papers in docs.
+
+.. branch: jit-ordereddict
+
+.. branch: refactor-str-types
+Remove multimethods on str/unicode/bytearray and make the implementations share code.
+
+.. branch: remove-del-from-generatoriterator
+Speed up generators that don't yield inside try or wait blocks by skipping
+unnecessary cleanup.
+
+.. branch: annotator
+Remove FlowObjSpace.
+Improve cohesion between rpython.flowspace and rpython.annotator.
+
+.. branch: detect-immutable-fields
+mapdicts keep track of whether or not an attribute is every assigned to
+multiple times. If it's only assigned once then an elidable lookup is used when
+possible.
+
+.. branch: precompiled-headers
+Create a Makefile using precompiled headers for MSVC platforms.
+The downside is a messy nmake-compatible Makefile. Since gcc shows minimal
+speedup, it was not implemented.
+
+.. branch: camelot
+With a properly configured 256-color terminal (TERM=...-256color), the
+Mandelbrot set shown during translation now uses a range of 50 colours.
+Essential!
+
+.. branch: NonConstant
+Simplify implementation of NonConstant.
+
+.. branch: array-propagate-len
+Kill some guards and operations in JIT traces by adding integer bounds
+propagation for getfield_(raw|gc) and getarrayitem_(raw|gc).
+
+.. branch: optimize-int-and
+Optimize away INT_AND with constant mask of 1s that fully cover the bitrange
+of other operand.
+
+.. branch: bounds-int-add-or
+Propagate appropriate bounds through INT_(OR|XOR|AND) operations if the
+operands are positive to kill some guards
+
+.. branch: remove-intlong-smm
+kills int/long/smalllong/bool multimethods
+
+.. branch: numpy-refactor
+Cleanup micronumpy module
+
+.. branch: int_w-refactor
+In a lot of places CPython allows objects with __int__ and __float__ instead of actual ints and floats, while until now pypy disallowed them. We fix it by making space.{int_w,float_w,etc.} accepting those objects by default, and disallowing conversions only when explicitly needed.
+
+.. branch: test-58c3d8552833
+Fix for getarrayitem_gc_pure optimization
+
+.. branch: simple-range-strategy
+Implements SimpleRangeListStrategy for case range(n) where n is a positive number.
+Makes some traces nicer by getting rid of multiplication for calculating loop counter
+and propagates that n > 0 further to get rid of guards.
+
+.. branch: popen-pclose
+Provide an exit status for popen'ed RFiles via pclose
+
+.. branch: stdlib-2.7.6
+Update stdlib to v2.7.6
+
+.. branch: virtual-raw-store-load
+Support for virtualizing raw_store/raw_load operations
+
+.. branch: refactor-buffer-api
+Separate the interp-level buffer API from the buffer type exposed to
+app-level. The `Buffer` class is now used by `W_MemoryView` and
+`W_Buffer`, which is not present in Python 3. Previously `W_Buffer` was
+an alias to `Buffer`, which was wrappable itself.
+
+.. branch: improve-consecutive-dict-lookups
+Improve the situation when dict lookups of the same key are performed in a chain
+
+.. branch: add_PyErr_SetFromErrnoWithFilenameObject_try_2
+.. branch: test_SetFromErrnoWithFilename_NULL
+.. branch: test_SetFromErrnoWithFilename__tweaks
+
+.. branch: refactor_PyErr_SetFromErrnoWithFilename
+Add support for PyErr_SetFromErrnoWithFilenameObject to cpyext
+
+.. branch: win32-fixes4
+fix more tests for win32
+
+.. branch: latest-improve-doc
+Fix broken links in documentation
+
+.. branch: ast-issue1673
+fix ast classes __dict__ are always empty problem and fix the ast deepcopy issue when
+there is missing field
+
+.. branch: issue1514
+Fix issues with reimporting builtin modules
+
+.. branch: numpypy-nditer
+Implement the core of nditer, without many of the fancy flags (external_loop, buffered)
+
+.. branch: numpy-speed
+Separate iterator from its state so jit can optimize better
+
+.. branch: numpy-searchsorted
+Implement searchsorted without sorter kwarg
+
+.. branch: openbsd-lib-prefix
+add 'lib' prefix to link libraries on OpenBSD
+
+.. branch: small-unroll-improvements
+Improve optimization of small allocation-heavy loops in the JIT
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
@@ -1,151 +1,14 @@
=======================
-What's new in PyPy 2.2+
+What's new in PyPy 2.3+
=======================
-.. this is a revision shortly after release-2.2.x
-.. startrev: 4cd1bc8b3111
+.. this is a revision shortly after release-2.3.x
+.. startrev: ba569fe1efdb
-.. branch: release-2.2.x
+.. branch: small-unroll-improvements
+Improve optimiziation of small allocation-heavy loops in the JIT
-.. branch: numpy-newbyteorder
-Clean up numpy types, add newbyteorder functionality
-
-.. branch: windows-packaging
-Package tk/tcl runtime with win32
-
-.. branch: armhf-singlefloat
-JIT support for singlefloats on ARM using the hardfloat ABI
-
-.. branch: voidtype_strformat
-Better support for record numpy arrays
-
-.. branch: osx-eci-frameworks-makefile
-OSX: Ensure frameworks end up in Makefile when specified in External compilation info
-
-.. branch: less-stringly-ops
-Use subclasses of SpaceOperation instead of SpaceOperator objects.
-Random cleanups in flowspace and annotator.
-
-.. branch: ndarray-buffer
-adds support for the buffer= argument to the ndarray ctor
-
-.. branch: better_ftime_detect2
-On OpenBSD do not pull in libcompat.a as it is about to be removed.
-And more generally, if you have gettimeofday(2) you will not need ftime(3).
-
-.. branch: timeb_h
-Remove dependency upon <sys/timeb.h> on OpenBSD. This will be disappearing
-along with libcompat.a.
-
-.. branch: OlivierBlanvillain/fix-3-broken-links-on-pypy-published-pap-1386250839215
-Fix 3 broken links on PyPy published papers in docs.
-
-.. branch: jit-ordereddict
-
-.. branch: refactor-str-types
-Remove multimethods on str/unicode/bytearray and make the implementations share code.
-
-.. branch: remove-del-from-generatoriterator
-Speed up generators that don't yield inside try or wait blocks by skipping
-unnecessary cleanup.
-
-.. branch: annotator
-Remove FlowObjSpace.
-Improve cohesion between rpython.flowspace and rpython.annotator.
-
-.. branch: detect-immutable-fields
-mapdicts keep track of whether or not an attribute is every assigned to
-multiple times. If it's only assigned once then an elidable lookup is used when
-possible.
-
-.. branch: precompiled-headers
-Create a Makefile using precompiled headers for MSVC platforms.
-The downside is a messy nmake-compatible Makefile. Since gcc shows minimal
-speedup, it was not implemented.
-
-.. branch: camelot
-With a properly configured 256-color terminal (TERM=...-256color), the
-Mandelbrot set shown during translation now uses a range of 50 colours.
-Essential!
-
-.. branch: NonConstant
-Simplify implementation of NonConstant.
-
-.. branch: array-propagate-len
-Kill some guards and operations in JIT traces by adding integer bounds
-propagation for getfield_(raw|gc) and getarrayitem_(raw|gc).
-
-.. branch: optimize-int-and
-Optimize away INT_AND with constant mask of 1s that fully cover the bitrange
-of other operand.
-
-.. branch: bounds-int-add-or
-Propagate appropriate bounds through INT_(OR|XOR|AND) operations if the
-operands are positive to kill some guards
-
-.. branch: remove-intlong-smm
-kills int/long/smalllong/bool multimethods
-
-.. branch: numpy-refactor
-Cleanup micronumpy module
-
-.. branch: int_w-refactor
-In a lot of places CPython allows objects with __int__ and __float__ instead of actual ints and floats, while until now pypy disallowed them. We fix it by making space.{int_w,float_w,etc.} accepting those objects by default, and disallowing conversions only when explicitly needed.
-
-.. branch: test-58c3d8552833
-Fix for getarrayitem_gc_pure optimization
-
-.. branch: simple-range-strategy
-Implements SimpleRangeListStrategy for case range(n) where n is a positive number.
-Makes some traces nicer by getting rid of multiplication for calculating loop counter
-and propagates that n > 0 further to get rid of guards.
-
-.. branch: popen-pclose
-Provide an exit status for popen'ed RFiles via pclose
-
-.. branch: stdlib-2.7.6
-Update stdlib to v2.7.6
-
-.. branch: virtual-raw-store-load
-Support for virtualizing raw_store/raw_load operations
+.. branch: reflex-support
.. branch: refactor-buffer-api
-Separate the interp-level buffer API from the buffer type exposed to
-app-level. The `Buffer` class is now used by `W_MemoryView` and
-`W_Buffer`, which is not present in Python 3. Previously `W_Buffer` was
-an alias to `Buffer`, which was wrappable itself.
-
-.. branch: improve-consecutive-dict-lookups
-Improve the situation when dict lookups of the same key are performed in a chain
-
-.. branch: add_PyErr_SetFromErrnoWithFilenameObject_try_2
-.. branch: test_SetFromErrnoWithFilename_NULL
-.. branch: test_SetFromErrnoWithFilename__tweaks
-
-.. branch: refactor_PyErr_SetFromErrnoWithFilename
-Add support for PyErr_SetFromErrnoWithFilenameObject to cpyext
-
-.. branch: win32-fixes4
-fix more tests for win32
-
-.. branch: latest-improve-doc
-Fix broken links in documentation
-
-.. branch: ast-issue1673
-fix ast classes __dict__ are always empty problem and fix the ast deepcopy issue when
-there is missing field
-
-.. branch: issue1514
-Fix issues with reimporting builtin modules
-
-.. branch: numpypy-nditer
-Implement the core of nditer, without many of the fancy flags (external_loop, buffered)
-
-.. branch: numpy-speed
-Separate iterator from its state so jit can optimize better
-
-.. branch: numpy-searchsorted
-Implement searchsorted without sorter kwarg
-
-.. branch: openbsd-lib-prefix
-add 'lib' prefix to link libraries on OpenBSD
+Properly implement old/new buffer API for objects and start work on replacing bufferstr usage
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -5,7 +5,7 @@
from rpython.rlib import jit, types
from rpython.rlib.debug import make_sure_not_resized
from rpython.rlib.objectmodel import (we_are_translated, newlist_hint,
- compute_unique_id)
+ compute_unique_id, specialize)
from rpython.rlib.signature import signature
from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \
INT_MIN, INT_MAX, UINT_MAX
@@ -194,13 +194,37 @@
def immutable_unique_id(self, space):
return None
- def buffer_w(self, space):
+ def buffer_w(self, space, flags):
w_impl = space.lookup(self, '__buffer__')
if w_impl is not None:
w_result = space.get_and_call_function(w_impl, self)
if space.isinstance_w(w_result, space.w_buffer):
- return w_result.buffer_w(space)
- self._typed_unwrap_error(space, "buffer")
+ return w_result.buffer_w(space, flags)
+ raise TypeError
+
+ def readbuf_w(self, space):
+ w_impl = space.lookup(self, '__buffer__')
+ if w_impl is not None:
+ w_result = space.get_and_call_function(w_impl, self)
+ if space.isinstance_w(w_result, space.w_buffer):
+ return w_result.readbuf_w(space)
+ raise TypeError
+
+ def writebuf_w(self, space):
+ w_impl = space.lookup(self, '__buffer__')
+ if w_impl is not None:
+ w_result = space.get_and_call_function(w_impl, self)
+ if space.isinstance_w(w_result, space.w_buffer):
+ return w_result.writebuf_w(space)
+ raise TypeError
+
+ def charbuf_w(self, space):
+ w_impl = space.lookup(self, '__buffer__')
+ if w_impl is not None:
+ w_result = space.get_and_call_function(w_impl, self)
+ if space.isinstance_w(w_result, space.w_buffer):
+ return w_result.charbuf_w(space)
+ raise TypeError
def str_w(self, space):
self._typed_unwrap_error(space, "string")
@@ -1340,25 +1364,111 @@
self.wrap('cannot convert negative integer '
'to unsigned int'))
- def buffer_w(self, w_obj):
- return w_obj.buffer_w(self)
+ BUF_SIMPLE = 0x0000
+ BUF_WRITABLE = 0x0001
+ BUF_FORMAT = 0x0004
+ BUF_ND = 0x0008
+ BUF_STRIDES = 0x0010 | BUF_ND
+ BUF_INDIRECT = 0x0100 | BUF_STRIDES
- def rwbuffer_w(self, w_obj):
- # returns a RWBuffer instance
- from pypy.interpreter.buffer import RWBuffer
- buffer = self.buffer_w(w_obj)
- if not isinstance(buffer, RWBuffer):
- raise OperationError(self.w_TypeError,
- self.wrap('read-write buffer expected'))
- return buffer
+ BUF_CONTIG_RO = BUF_ND
+ BUF_CONTIG = BUF_ND | BUF_WRITABLE
- def bufferstr_new_w(self, w_obj):
- # Implement the "new buffer interface" (new in Python 2.7)
- # returning an unwrapped string. It doesn't accept unicode
- # strings
- buffer = self.buffer_w(w_obj)
- return buffer.as_str()
+ BUF_FULL_RO = BUF_INDIRECT | BUF_FORMAT
+ BUF_FULL = BUF_INDIRECT | BUF_FORMAT | BUF_WRITABLE
+ def check_buf_flags(self, flags, readonly):
+ if readonly and flags & self.BUF_WRITABLE == self.BUF_WRITABLE:
+ raise oefmt(self.w_BufferError, "Object is not writable.")
+
+ def buffer_w(self, w_obj, flags):
+ # New buffer interface, returns a buffer based on flags (PyObject_GetBuffer)
+ try:
+ return w_obj.buffer_w(self, flags)
+ except TypeError:
+ raise oefmt(self.w_TypeError,
+ "'%T' does not have the buffer interface", w_obj)
+
+ def readbuf_w(self, w_obj):
+ # Old buffer interface, returns a readonly buffer (PyObject_AsReadBuffer)
+ try:
+ return w_obj.readbuf_w(self)
+ except TypeError:
+ raise oefmt(self.w_TypeError,
+ "expected a readable buffer object")
+
+ def writebuf_w(self, w_obj):
+ # Old buffer interface, returns a writeable buffer (PyObject_AsWriteBuffer)
+ try:
+ return w_obj.writebuf_w(self)
+ except TypeError:
+ raise oefmt(self.w_TypeError,
+ "expected a writeable buffer object")
+
+ def charbuf_w(self, w_obj):
+ # Old buffer interface, returns a character buffer (PyObject_AsCharBuffer)
+ try:
+ return w_obj.charbuf_w(self)
+ except TypeError:
+ raise oefmt(self.w_TypeError,
+ "expected a character buffer object")
+
+ def _getarg_error(self, expected, w_obj):
+ if self.is_none(w_obj):
+ name = "None"
+ else:
+ name = self.type(w_obj).get_module_type_name()
+ raise oefmt(self.w_TypeError, "must be %s, not %s", expected, name)
+
+ @specialize.arg(1)
+ def getarg_w(self, code, w_obj):
+ if code == 'z*':
+ if self.is_none(w_obj):
+ return None
+ code = 's*'
+ if code == 's*':
+ if self.isinstance_w(w_obj, self.w_str):
+ return w_obj.readbuf_w(self)
+ if self.isinstance_w(w_obj, self.w_unicode):
+ return self.str(w_obj).readbuf_w(self)
+ try:
+ return w_obj.buffer_w(self, 0)
+ except TypeError:
+ pass
+ try:
+ return w_obj.readbuf_w(self)
+ except TypeError:
+ self._getarg_error("string or buffer", w_obj)
+ elif code == 's#':
+ if self.isinstance_w(w_obj, self.w_str):
+ return w_obj.str_w(self)
+ if self.isinstance_w(w_obj, self.w_unicode):
+ return self.str(w_obj).str_w(self)
+ try:
+ return w_obj.readbuf_w(self).as_str()
+ except TypeError:
+ self._getarg_error("string or read-only buffer", w_obj)
+ elif code == 'w*':
+ try:
+ try:
+ return w_obj.buffer_w(self, self.BUF_WRITABLE)
+ except OperationError:
+ self._getarg_error("read-write buffer", w_obj)
+ except TypeError:
+ pass
+ try:
+ return w_obj.writebuf_w(self)
+ except TypeError:
+ self._getarg_error("read-write buffer", w_obj)
+ elif code == 't#':
+ try:
+ return w_obj.charbuf_w(self)
+ except TypeError:
+ self._getarg_error("string or read-only character buffer", w_obj)
+ else:
+ assert False
+
+ # XXX rename/replace with code more like CPython getargs for buffers
def bufferstr_w(self, w_obj):
# Directly returns an interp-level str. Note that if w_obj is a
# unicode string, this is different from str_w(buffer(w_obj)):
@@ -1373,8 +1483,18 @@
except OperationError, e:
if not e.match(self, self.w_TypeError):
raise
- buffer = self.buffer_w(w_obj)
- return buffer.as_str()
+ try:
+ buf = w_obj.buffer_w(self, 0)
+ except TypeError:
+ pass
+ else:
+ return buf.as_str()
+ try:
+ buf = w_obj.readbuf_w(self)
+ except TypeError:
+ self._getarg_error("string or buffer", w_obj)
+ else:
+ return buf.as_str()
def str_or_None_w(self, w_obj):
if self.is_w(w_obj, self.w_None):
@@ -1721,6 +1841,7 @@
'AssertionError',
'AttributeError',
'BaseException',
+ 'BufferError',
'DeprecationWarning',
'EOFError',
'EnvironmentError',
diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
deleted file mode 100644
--- a/pypy/interpreter/buffer.py
+++ /dev/null
@@ -1,118 +0,0 @@
-"""
-Buffer protocol support.
-"""
-from rpython.rlib.objectmodel import import_from_mixin
-
-
-class Buffer(object):
- """Abstract base class for buffers."""
- __slots__ = []
-
- def getlength(self):
- raise NotImplementedError
-
- def as_str(self):
- "Returns an interp-level string with the whole content of the buffer."
- # May be overridden.
- return self.getslice(0, self.getlength(), 1, self.getlength())
-
- def getitem(self, index):
- "Returns the index'th character in the buffer."
- raise NotImplementedError # Must be overriden. No bounds checks.
-
- def getslice(self, start, stop, step, size):
- # May be overridden. No bounds checks.
- return ''.join([self.getitem(i) for i in range(start, stop, step)])
-
- def get_raw_address(self):
- raise ValueError("no raw buffer")
-
- def is_writable(self):
- return False
-
-
-class RWBuffer(Buffer):
- """Abstract base class for read-write buffers."""
- __slots__ = []
-
- def is_writable(self):
- return True
-
- def setitem(self, index, char):
- "Write a character into the buffer."
- raise NotImplementedError # Must be overriden. No bounds checks.
-
- def setslice(self, start, string):
- # May be overridden. No bounds checks.
- for i in range(len(string)):
- self.setitem(start + i, string[i])
-
-
-class StringBuffer(Buffer):
- __slots__ = ['value']
-
- def __init__(self, value):
- self.value = value
-
- def getlength(self):
- return len(self.value)
-
- def as_str(self):
- return self.value
-
- def getitem(self, index):
- return self.value[index]
-
- def getslice(self, start, stop, step, size):
- if size == 0:
- return ""
- if step == 1:
- assert 0 <= start <= stop
- return self.value[start:stop]
- return "".join([self.value[start + i*step] for i in xrange(size)])
-# ____________________________________________________________
-
-
-class SubBufferMixin(object):
- _attrs_ = ['buffer', 'offset', 'size']
-
- def __init__(self, buffer, offset, size):
- self.buffer = buffer
- self.offset = offset
- self.size = size
-
- def getlength(self):
- at_most = self.buffer.getlength() - self.offset
- if 0 <= self.size <= at_most:
- return self.size
- elif at_most >= 0:
- return at_most
- else:
- return 0
-
- def getitem(self, index):
- return self.buffer.getitem(self.offset + index)
-
- def getslice(self, start, stop, step, size):
- if start == stop:
- return '' # otherwise, adding self.offset might make them
- # out of bounds
- return self.buffer.getslice(self.offset + start, self.offset + stop,
- step, size)
-
-
-class SubBuffer(Buffer):
- import_from_mixin(SubBufferMixin)
-
-
-class RWSubBuffer(RWBuffer):
- import_from_mixin(SubBufferMixin)
-
- def setitem(self, index, char):
- self.buffer.setitem(self.offset + index, char)
-
- def setslice(self, start, string):
- if len(string) == 0:
- return # otherwise, adding self.offset might make 'start'
- # out of bounds
- self.buffer.setslice(self.offset + start, string)
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -299,9 +299,13 @@
"""
self._application_traceback = traceback
- at specialize.memo()
+
+class ClearedOpErr:
+ def __init__(self, space):
+ self.operr = OperationError(space.w_None, space.w_None)
+
def get_cleared_operation_error(space):
- return OperationError(space.w_None, space.w_None)
+ return space.fromcache(ClearedOpErr).operr
# ____________________________________________________________
# optimization only: avoid the slowest operation -- the string
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -205,11 +205,14 @@
def sys_exc_info(self): # attn: the result is not the wrapped sys.exc_info() !!!
"""Implements sys.exc_info().
Return an OperationError instance or None."""
- frame = self.gettopframe_nohidden()
+ frame = self.gettopframe()
while frame:
if frame.last_exception is not None:
- return frame.last_exception
- frame = self.getnextframe_nohidden(frame)
+ if (not frame.hide() or
+ frame.last_exception is
+ get_cleared_operation_error(self.space)):
+ return frame.last_exception
+ frame = frame.f_backref()
return None
def set_sys_exc_info(self, operror):
diff --git a/pypy/interpreter/main.py b/pypy/interpreter/main.py
--- a/pypy/interpreter/main.py
+++ b/pypy/interpreter/main.py
@@ -15,10 +15,11 @@
space.setitem(w_modules, w_main, mainmodule)
return mainmodule
+
def compilecode(space, source, filename, cmd='exec'):
w = space.wrap
- w_code = space.builtin.call('compile',
- w(source), w(filename), w(cmd), w(0), w(0))
+ w_code = space.builtin.call(
+ 'compile', w(source), w(filename), w(cmd), w(0), w(0))
pycode = space.interp_w(eval.Code, w_code)
return pycode
@@ -28,7 +29,7 @@
cmd = 'eval'
else:
cmd = 'exec'
-
+
try:
if space is None:
from pypy.objspace.std import StdObjSpace
@@ -55,18 +56,22 @@
operationerr.record_interpreter_traceback()
raise
+
def run_string(source, filename=None, space=None):
_run_eval_string(source, filename, space, False)
+
def eval_string(source, filename=None, space=None):
return _run_eval_string(source, filename, space, True)
+
def run_file(filename, space=None):
- if __name__=='__main__':
+ if __name__ == '__main__':
print "Running %r with %r" % (filename, space)
istring = open(filename).read()
run_string(istring, filename, space)
+
def run_module(module_name, args, space=None):
"""Implements PEP 338 'Executing modules as scripts', overwriting
sys.argv[1:] using `args` and executing the module `module_name`.
@@ -89,7 +94,6 @@
return space.call_function(w_run_module, w(module_name), space.w_None,
w('__main__'), space.w_True)
-# ____________________________________________________________
def run_toplevel(space, f, verbose=False):
"""Calls f() and handle all OperationErrors.
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -881,8 +881,8 @@
def LOAD_NAME(self, nameindex, next_instr):
if self.w_locals is not self.w_globals:
- w_varname = self.getname_w(nameindex)
- w_value = self.space.finditem(self.w_locals, w_varname)
+ varname = self.getname_u(nameindex)
+ w_value = self.space.finditem_str(self.w_locals, varname)
if w_value is not None:
self.pushvalue(w_value)
return
diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -22,22 +22,6 @@
compile; if absent or zero these statements do influence the compilation,
in addition to any features explicitly specified.
"""
-
- ast_node = None
- w_ast_type = space.gettypeobject(ast.AST.typedef)
- str_ = None
- if space.isinstance_w(w_source, w_ast_type):
- ast_node = space.interp_w(ast.mod, w_source)
- ast_node.sync_app_attrs(space)
- elif space.isinstance_w(w_source, space.w_unicode):
- w_utf_8_source = space.call_method(w_source, "encode",
- space.wrap("utf-8"))
- str_ = space.str_w(w_utf_8_source)
- # This flag tells the parser to reject any coding cookies it sees.
- flags |= consts.PyCF_SOURCE_IS_UTF8
- else:
- str_ = space.str_w(w_source)
-
ec = space.getexecutioncontext()
if flags & ~(ec.compiler.compiler_flags | consts.PyCF_ONLY_AST |
consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8):
@@ -53,14 +37,30 @@
space.wrap("compile() arg 3 must be 'exec' "
"or 'eval' or 'single'"))
- if ast_node is None:
- if flags & consts.PyCF_ONLY_AST:
- mod = ec.compiler.compile_to_ast(str_, filename, mode, flags)
- return space.wrap(mod)
- else:
- code = ec.compiler.compile(str_, filename, mode, flags)
+ w_ast_type = space.gettypeobject(ast.AST.typedef)
+ if space.isinstance_w(w_source, w_ast_type):
+ ast_node = space.interp_w(ast.mod, w_source)
+ ast_node.sync_app_attrs(space)
+ code = ec.compiler.compile_ast(ast_node, filename, mode, flags)
+ return space.wrap(code)
+
+ if space.isinstance_w(w_source, space.w_unicode):
+ w_utf_8_source = space.call_method(w_source, "encode",
+ space.wrap("utf-8"))
+ str_ = space.str_w(w_utf_8_source)
+ # This flag tells the parser to reject any coding cookies it sees.
+ flags |= consts.PyCF_SOURCE_IS_UTF8
else:
- code = ec.compiler.compile_ast(ast_node, filename, mode, flags)
+ str_ = space.readbuf_w(w_source).as_str()
+
+ if '\x00' in str_:
+ raise OperationError(space.w_TypeError, space.wrap(
+ "compile() expected string without null bytes"))
+
+ if flags & consts.PyCF_ONLY_AST:
+ code = ec.compiler.compile_to_ast(str_, filename, mode, flags)
+ else:
+ code = ec.compiler.compile(str_, filename, mode, flags)
return space.wrap(code)
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -351,17 +351,17 @@
self.promote_step = promote_step
def descr_new(space, w_subtype, w_start, w_stop=None, w_step=None):
- start = _toint(space, w_start)
+ start = space.int_w(w_start)
if space.is_none(w_step): # no step argument provided
step = 1
promote_step = True
else:
- step = _toint(space, w_step)
+ step = space.int_w(w_step)
promote_step = False
if space.is_none(w_stop): # only 1 argument provided
start, stop = 0, start
else:
- stop = _toint(space, w_stop)
+ stop = space.int_w(w_stop)
howmany = get_len_of_range(space, start, stop, step)
obj = space.allocate_instance(W_XRange, w_subtype)
W_XRange.__init__(obj, space, start, howmany, step, promote_step)
@@ -425,11 +425,6 @@
minint = -sys.maxint - 1
return minint if last < minint - step else last + step
-def _toint(space, w_obj):
- # this also supports float arguments. CPython still does, too.
- # needs a bit more thinking in general...
- return space.int_w(space.int(w_obj))
-
W_XRange.typedef = TypeDef("xrange",
__new__ = interp2app(W_XRange.descr_new.im_func),
__repr__ = interp2app(W_XRange.descr_repr),
@@ -441,6 +436,7 @@
)
W_XRange.typedef.acceptable_as_base_class = False
+
class W_XRangeIterator(W_Root):
def __init__(self, space, current, remaining, step):
self.space = space
@@ -488,7 +484,10 @@
)
W_XRangeIterator.typedef.acceptable_as_base_class = False
+
class W_XRangeStepOneIterator(W_XRangeIterator):
+ _immutable_fields_ = ['stop']
+
def __init__(self, space, start, stop):
self.space = space
self.current = start
diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -311,14 +311,14 @@
def test_xrange_len(self):
x = xrange(33)
assert len(x) == 33
- x = xrange(33.2)
- assert len(x) == 33
+ exc = raises(TypeError, xrange, 33.2)
+ assert "integer" in str(exc.value)
x = xrange(33,0,-1)
assert len(x) == 33
x = xrange(33,0)
assert len(x) == 0
- x = xrange(33,0.2)
- assert len(x) == 0
+ exc = raises(TypeError, xrange, 33, 0.2)
+ assert "integer" in str(exc.value)
x = xrange(0,33)
assert len(x) == 33
x = xrange(0,33,-1)
@@ -490,6 +490,14 @@
def test_compile(self):
co = compile('1+2', '?', 'eval')
assert eval(co) == 3
+ co = compile(buffer('1+2'), '?', 'eval')
+ assert eval(co) == 3
+ exc = raises(TypeError, compile, chr(0), '?', 'eval')
+ assert str(exc.value) == "compile() expected string without null bytes"
+ exc = raises(TypeError, compile, unichr(0), '?', 'eval')
+ assert str(exc.value) == "compile() expected string without null bytes"
+ exc = raises(TypeError, compile, memoryview('1+2'), '?', 'eval')
+ assert str(exc.value) == "expected a readable buffer object"
compile("from __future__ import with_statement", "<test>", "exec")
raises(SyntaxError, compile, '-', '?', 'eval')
raises(ValueError, compile, '"\\xt"', '?', 'eval')
diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py
--- a/pypy/module/__builtin__/test/test_functional.py
+++ b/pypy/module/__builtin__/test/test_functional.py
@@ -1,5 +1,4 @@
class AppTestMap:
-
def test_trivial_map_one_seq(self):
assert map(lambda x: x+2, [1, 2, 3, 4]) == [3, 4, 5, 6]
@@ -77,6 +76,7 @@
assert result == [(2, 7), (1, 6), (None, 5), (None, 4),
(None, 3), (None, 2), (None, 1)]
+
class AppTestZip:
def test_one_list(self):
assert zip([1,2,3]) == [(1,), (2,), (3,)]
@@ -93,6 +93,7 @@
yield None
assert zip(Foo()) == []
+
class AppTestReduce:
def test_None(self):
raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None)
@@ -105,6 +106,7 @@
assert reduce(lambda x, y: x-y, [10, 2, 8]) == 0
assert reduce(lambda x, y: x-y, [2, 8], 10) == 0
+
class AppTestFilter:
def test_None(self):
assert filter(None, ['a', 'b', 1, 0, None]) == ['a', 'b', 1]
@@ -125,6 +127,7 @@
return i * 10
assert filter(lambda x: x != 20, T("abcd")) == (0, 10, 30)
+
class AppTestXRange:
def test_xrange(self):
x = xrange(2, 9, 3)
@@ -155,7 +158,8 @@
assert list(xrange(0, 10, A())) == [0, 5]
def test_xrange_float(self):
- assert list(xrange(0.1, 2.0, 1.1)) == [0, 1]
+ exc = raises(TypeError, xrange, 0.1, 2.0, 1.1)
+ assert "integer" in str(exc.value)
def test_xrange_long(self):
import sys
@@ -218,6 +222,7 @@
assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o']
raises(TypeError, reversed, reversed("hello"))
+
class AppTestApply:
def test_apply(self):
def f(*args, **kw):
@@ -228,6 +233,7 @@
assert apply(f, args) == (args, {})
assert apply(f, args, kw) == (args, kw)
+
class AppTestAllAny:
"""
These are copied directly and replicated from the Python 2.5 source code.
@@ -277,6 +283,7 @@
S = [10, 20, 30]
assert any([x > 42 for x in S]) == False
+
class AppTestMinMax:
def test_min(self):
assert min(1, 2) == 1
diff --git a/pypy/module/__pypy__/bytebuffer.py b/pypy/module/__pypy__/bytebuffer.py
--- a/pypy/module/__pypy__/bytebuffer.py
+++ b/pypy/module/__pypy__/bytebuffer.py
@@ -2,13 +2,16 @@
# A convenient read-write buffer. Located here for want of a better place.
#
-from pypy.interpreter.buffer import RWBuffer
+from rpython.rlib.buffer import Buffer
from pypy.interpreter.gateway import unwrap_spec
-class ByteBuffer(RWBuffer):
+class ByteBuffer(Buffer):
+ _immutable_ = True
+
def __init__(self, len):
self.data = ['\x00'] * len
+ self.readonly = False
def getlength(self):
return len(self.data)
diff --git a/pypy/module/__pypy__/test/test_bytebuffer.py b/pypy/module/__pypy__/test/test_bytebuffer.py
--- a/pypy/module/__pypy__/test/test_bytebuffer.py
+++ b/pypy/module/__pypy__/test/test_bytebuffer.py
@@ -13,3 +13,18 @@
assert b[-1] == '*'
assert b[-2] == '-'
assert b[-3] == '+'
+ exc = raises(TypeError, "b[3] = 'abc'")
+ assert str(exc.value) == "right operand must be a single byte"
+ exc = raises(TypeError, "b[3:5] = 'abc'")
+ assert str(exc.value) == "right operand length must match slice length"
+ exc = raises(TypeError, "b[3:7:2] = 'abc'")
+ assert str(exc.value) == "right operand length must match slice length"
+
+ b = bytebuffer(10)
+ b[1:3] = 'xy'
+ assert str(b) == "\x00xy" + "\x00" * 7
+ b[4:8:2] = 'zw'
+ assert str(b) == "\x00xy\x00z\x00w" + "\x00" * 3
+ r = str(buffer(u'#'))
+ b[6:6+len(r)] = u'#'
+ assert str(b[:6+len(r)]) == "\x00xy\x00z\x00" + r
diff --git a/pypy/module/_cffi_backend/cbuffer.py b/pypy/module/_cffi_backend/cbuffer.py
--- a/pypy/module/_cffi_backend/cbuffer.py
+++ b/pypy/module/_cffi_backend/cbuffer.py
@@ -1,21 +1,22 @@
-from pypy.interpreter.buffer import RWBuffer
-from pypy.interpreter.error import oefmt
+from pypy.interpreter.error import oefmt, OperationError
from pypy.interpreter.gateway import unwrap_spec, interp2app
from pypy.interpreter.typedef import TypeDef, make_weakref_descr
from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
-from pypy.objspace.std.memoryview import W_Buffer
+from pypy.objspace.std.bufferobject import W_Buffer
+from rpython.rlib.buffer import Buffer
from rpython.rtyper.annlowlevel import llstr
from rpython.rtyper.lltypesystem import rffi
from rpython.rtyper.lltypesystem.rstr import copy_string_to_raw
-class LLBuffer(RWBuffer):
+class LLBuffer(Buffer):
_immutable_ = True
def __init__(self, raw_cdata, size):
self.raw_cdata = raw_cdata
self.size = size
+ self.readonly = False
def getlength(self):
return self.size
@@ -32,7 +33,7 @@
def getslice(self, start, stop, step, size):
if step == 1:
return rffi.charpsize2str(rffi.ptradd(self.raw_cdata, start), size)
- return RWBuffer.getslice(self, start, stop, step, size)
+ return Buffer.getslice(self, start, stop, step, size)
def setslice(self, start, string):
raw_cdata = rffi.ptradd(self.raw_cdata, start)
@@ -46,6 +47,14 @@
W_Buffer.__init__(self, buffer)
self.keepalive = keepalive
+ def descr_setitem(self, space, w_index, w_obj):
+ try:
+ W_Buffer.descr_setitem(self, space, w_index, w_obj)
+ except OperationError as e:
+ if e.match(space, space.w_TypeError):
+ e.w_type = space.w_ValueError
+ raise
+
MiniBuffer.typedef = TypeDef(
"buffer",
__module__ = "_cffi_backend",
diff --git a/pypy/module/_codecs/__init__.py b/pypy/module/_codecs/__init__.py
--- a/pypy/module/_codecs/__init__.py
+++ b/pypy/module/_codecs/__init__.py
@@ -72,8 +72,8 @@
'utf_32_le_decode' : 'interp_codecs.utf_32_le_decode',
'utf_32_le_encode' : 'interp_codecs.utf_32_le_encode',
'utf_32_ex_decode' : 'interp_codecs.utf_32_ex_decode',
- 'charbuffer_encode': 'interp_codecs.buffer_encode',
- 'readbuffer_encode': 'interp_codecs.buffer_encode',
+ 'charbuffer_encode': 'interp_codecs.charbuffer_encode',
+ 'readbuffer_encode': 'interp_codecs.readbuffer_encode',
'charmap_decode' : 'interp_codecs.charmap_decode',
'charmap_encode' : 'interp_codecs.charmap_encode',
'escape_encode' : 'interp_codecs.escape_encode',
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
@@ -321,8 +321,14 @@
w_res = space.call_function(w_encoder, w_obj, space.wrap(errors))
return space.getitem(w_res, space.wrap(0))
- at unwrap_spec(s='bufferstr', errors='str_or_None')
-def buffer_encode(space, s, errors='strict'):
+ at unwrap_spec(errors='str_or_None')
+def readbuffer_encode(space, w_data, errors='strict'):
+ s = space.getarg_w('s#', w_data)
+ return space.newtuple([space.wrap(s), space.wrap(len(s))])
+
+ at unwrap_spec(errors='str_or_None')
+def charbuffer_encode(space, w_data, errors='strict'):
+ s = space.getarg_w('t#', w_data)
return space.newtuple([space.wrap(s), space.wrap(len(s))])
@unwrap_spec(errors=str)
@@ -673,7 +679,7 @@
if space.isinstance_w(w_string, space.w_unicode):
return space.newtuple([w_string, space.len(w_string)])
- string = space.str_w(w_string)
+ string = space.readbuf_w(w_string).as_str()
if len(string) == 0:
return space.newtuple([space.wrap(u''), space.wrap(0)])
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
@@ -276,7 +276,7 @@
assert enc == "a\x00\x00\x00"
def test_unicode_internal_decode(self):
- import sys
+ import sys, _codecs, array
if sys.maxunicode == 65535: # UCS2 build
if sys.byteorder == "big":
bytes = "\x00a"
@@ -291,6 +291,9 @@
bytes2 = "\x98\x00\x01\x00"
assert bytes2.decode("unicode_internal") == u"\U00010098"
assert bytes.decode("unicode_internal") == u"a"
+ assert _codecs.unicode_internal_decode(array.array('c', bytes))[0] == u"a"
+ exc = raises(TypeError, _codecs.unicode_internal_decode, memoryview(bytes))
+ assert str(exc.value) == "expected a readable buffer object"
def test_raw_unicode_escape(self):
assert unicode("\u0663", "raw-unicode-escape") == u"\u0663"
@@ -420,9 +423,13 @@
for (i, line) in enumerate(reader):
assert line == s[i]
- def test_array(self):
+ def test_buffer_encode(self):
import _codecs, array
- _codecs.readbuffer_encode(array.array('c', 'spam')) == ('spam', 4)
+ assert _codecs.readbuffer_encode(array.array('c', 'spam')) == ('spam', 4)
+ exc = raises(TypeError, _codecs.charbuffer_encode, array.array('c', 'spam'))
+ assert str(exc.value) == "must be string or read-only character buffer, not array.array"
+ assert _codecs.readbuffer_encode(u"test") == ('test', 4)
+ assert _codecs.charbuffer_encode(u"test") == ('test', 4)
def test_utf8sig(self):
import codecs
diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py
--- a/pypy/module/_continuation/interp_continuation.py
+++ b/pypy/module/_continuation/interp_continuation.py
@@ -1,6 +1,6 @@
from rpython.rlib.rstacklet import StackletThread
from rpython.rlib import jit
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, get_cleared_operation_error
from pypy.interpreter.executioncontext import ExecutionContext
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.typedef import TypeDef
@@ -39,6 +39,7 @@
bottomframe.locals_stack_w[1] = w_callable
bottomframe.locals_stack_w[2] = w_args
bottomframe.locals_stack_w[3] = w_kwds
+ bottomframe.last_exception = get_cleared_operation_error(space)
self.bottomframe = bottomframe
#
global_state.origin = self
diff --git a/pypy/module/_continuation/test/test_stacklet.py b/pypy/module/_continuation/test/test_stacklet.py
--- a/pypy/module/_continuation/test/test_stacklet.py
+++ b/pypy/module/_continuation/test/test_stacklet.py
@@ -684,3 +684,17 @@
execfile(self.translated, d)
d['set_fast_mode']()
d['test_various_depths']()
+
+ def test_exc_info_doesnt_follow_continuations(self):
+ import sys
+ from _continuation import continulet
+ #
+ def f1(c1):
+ return sys.exc_info()
+ #
+ c1 = continulet(f1)
+ try:
+ 1 // 0
+ except ZeroDivisionError:
+ got = c1.switch()
+ assert got == (None, None, None)
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -267,9 +267,14 @@
def direct_write(self, w_data):
space = self.space
- if not self.binary and space.isinstance_w(w_data, space.w_unicode):
- w_data = space.call_method(w_data, "encode", space.wrap(self.encoding), space.wrap(self.errors))
- data = space.bufferstr_w(w_data)
+ if self.binary:
+ data = space.getarg_w('s*', w_data).as_str()
+ else:
+ if space.isinstance_w(w_data, space.w_unicode):
+ w_data = space.call_method(w_data, "encode",
+ space.wrap(self.encoding),
+ space.wrap(self.errors))
+ data = space.charbuf_w(w_data)
self.do_direct_write(data)
def do_direct_write(self, data):
@@ -455,21 +460,24 @@
space = self.space
self.check_closed()
- w_iterator = space.iter(w_lines)
- while True:
- try:
- w_line = space.next(w_iterator)
- except OperationError, e:
- if not e.match(space, space.w_StopIteration):
- raise
- break # done
+ lines = space.fixedview(w_lines)
+ for i, w_line in enumerate(lines):
+ if not space.isinstance_w(w_line, space.w_str):
+ try:
+ line = w_line.charbuf_w(space)
+ except TypeError:
+ raise OperationError(space.w_TypeError, space.wrap(
+ "writelines() argument must be a sequence of strings"))
+ else:
+ lines[i] = space.wrap(line)
+ for w_line in lines:
self.file_write(w_line)
def file_readinto(self, w_rwbuffer):
"""readinto() -> Undocumented. Don't use this; it may go away."""
# XXX not the most efficient solution as it doesn't avoid the copying
space = self.space
- rwbuffer = space.rwbuffer_w(w_rwbuffer)
+ rwbuffer = space.writebuf_w(w_rwbuffer)
w_data = self.file_read(rwbuffer.getlength())
data = space.str_w(w_data)
rwbuffer.setslice(0, data)
diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py
--- a/pypy/module/_file/test/test_file_extra.py
+++ b/pypy/module/_file/test/test_file_extra.py
@@ -386,6 +386,32 @@
assert len(somelines) > 200
assert somelines == lines[:len(somelines)]
+ def test_writelines(self):
+ import array
+ fn = self.temptestfile
+ with file(fn, 'w') as f:
+ f.writelines(['abc'])
+ f.writelines([u'def'])
+ exc = raises(TypeError, f.writelines, [array.array('c', 'ghi')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ exc = raises(TypeError, f.writelines, [memoryview('jkl')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ assert open(fn, 'r').readlines() == ['abcdef']
+
+ with file(fn, 'wb') as f:
+ f.writelines(['abc'])
+ f.writelines([u'def'])
+ exc = raises(TypeError, f.writelines, [array.array('c', 'ghi')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ exc = raises(TypeError, f.writelines, [memoryview('jkl')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ assert open(fn, 'rb').readlines() == ['abcdef']
+
+ with file(fn, 'wb') as f:
+ exc = raises(TypeError, f.writelines, ['abc', memoryview('def')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ assert open(fn, 'rb').readlines() == []
+
def test_nasty_writelines(self):
# The stream lock should be released between writes
fn = self.temptestfile
diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -4,7 +4,7 @@
from pypy.interpreter.typedef import (
TypeDef, GetSetProperty, generic_new_descr, interp_attrproperty_w)
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from pypy.interpreter.buffer import RWBuffer
+from rpython.rlib.buffer import Buffer
from rpython.rlib.rstring import StringBuilder
from rpython.rlib.rarithmetic import r_longlong, intmask
from rpython.rlib import rposix
@@ -80,7 +80,7 @@
self._unsupportedoperation(space, "detach")
def readinto_w(self, space, w_buffer):
- rwbuffer = space.rwbuffer_w(w_buffer)
+ rwbuffer = space.getarg_w('w*', w_buffer)
length = rwbuffer.getlength()
w_data = space.call_method(self, "read", space.wrap(length))
@@ -101,11 +101,14 @@
readinto = interp2app(W_BufferedIOBase.readinto_w),
)
-class RawBuffer(RWBuffer):
+class RawBuffer(Buffer):
+ _immutable_ = True
+
def __init__(self, buf, start, length):
self.buf = buf
self.start = start
self.length = length
+ self.readonly = False
def getlength(self):
return self.length
@@ -698,7 +701,7 @@
def write_w(self, space, w_data):
self._check_init(space)
self._check_closed(space, "write to closed file")
- data = space.bufferstr_w(w_data)
+ data = space.getarg_w('s*', w_data).as_str()
size = len(data)
with self.lock:
diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py
--- a/pypy/module/_io/interp_bytesio.py
+++ b/pypy/module/_io/interp_bytesio.py
@@ -41,7 +41,7 @@
def readinto_w(self, space, w_buffer):
self._check_closed(space)
- rwbuffer = space.rwbuffer_w(w_buffer)
+ rwbuffer = space.getarg_w('w*', w_buffer)
size = rwbuffer.getlength()
output = self.read(size)
@@ -50,10 +50,7 @@
def write_w(self, space, w_data):
self._check_closed(space)
- if space.isinstance_w(w_data, space.w_unicode):
- raise OperationError(space.w_TypeError, space.wrap(
- "bytes string of buffer expected"))
- buf = space.bufferstr_w(w_data)
+ buf = space.buffer_w(w_data, space.BUF_CONTIG_RO).as_str()
length = len(buf)
if length <= 0:
return space.wrap(0)
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -333,7 +333,7 @@
def write_w(self, space, w_data):
self._check_closed(space)
self._check_writable(space)
- data = space.bufferstr_w(w_data)
+ data = space.getarg_w('s*', w_data).as_str()
try:
n = os.write(self.fd, data)
@@ -366,7 +366,7 @@
def readinto_w(self, space, w_buffer):
self._check_closed(space)
self._check_readable(space)
- rwbuffer = space.rwbuffer_w(w_buffer)
+ rwbuffer = space.getarg_w('w*', w_buffer)
length = rwbuffer.getlength()
try:
buf = os.read(self.fd, length)
diff --git a/pypy/module/_io/test/test_bufferedio.py b/pypy/module/_io/test/test_bufferedio.py
--- a/pypy/module/_io/test/test_bufferedio.py
+++ b/pypy/module/_io/test/test_bufferedio.py
@@ -139,6 +139,14 @@
raw = _io.FileIO(self.tmpfile)
f = _io.BufferedReader(raw)
assert f.readinto(a) == 5
+ exc = raises(TypeError, f.readinto, u"hello")
+ assert str(exc.value) == "cannot use unicode as modifiable buffer"
+ exc = raises(TypeError, f.readinto, buffer(b"hello"))
+ assert str(exc.value) == "must be read-write buffer, not buffer"
+ exc = raises(TypeError, f.readinto, buffer(bytearray("hello")))
+ assert str(exc.value) == "must be read-write buffer, not buffer"
+ exc = raises(TypeError, f.readinto, memoryview(b"hello"))
+ assert str(exc.value) == "must be read-write buffer, not memoryview"
f.close()
assert a == 'a\nb\ncxxxxx'
@@ -235,7 +243,8 @@
import _io
raw = _io.FileIO(self.tmpfile, 'w')
f = _io.BufferedWriter(raw)
- f.write("abcd")
+ f.write("ab")
+ f.write(u"cd")
f.close()
assert self.readfile() == "abcd"
diff --git a/pypy/module/_io/test/test_bytesio.py b/pypy/module/_io/test/test_bytesio.py
--- a/pypy/module/_io/test/test_bytesio.py
+++ b/pypy/module/_io/test/test_bytesio.py
@@ -38,6 +38,8 @@
More information about the pypy-commit
mailing list