[pypy-commit] pypy kill-flowobjspace: hg merge default
rlamy
noreply at buildbot.pypy.org
Sat Feb 9 17:50:16 CET 2013
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: kill-flowobjspace
Changeset: r61004:581e3b2a8a35
Date: 2013-02-09 16:49 +0000
http://bitbucket.org/pypy/pypy/changeset/581e3b2a8a35/
Log: hg merge default
diff too long, truncating to 2000 out of 5859 lines
diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py
--- a/lib-python/2.7/collections.py
+++ b/lib-python/2.7/collections.py
@@ -6,11 +6,12 @@
__all__ += _abcoll.__all__
from _collections import deque, defaultdict
+from operator import itemgetter as _itemgetter, eq as _eq
from keyword import iskeyword as _iskeyword
import sys as _sys
import heapq as _heapq
-from operator import itemgetter as _itemgetter
from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
+from itertools import imap as _imap
try:
from thread import get_ident as _get_ident
@@ -50,49 +51,45 @@
self.__map = {}
self.__update(*args, **kwds)
- def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
+ def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link at the end of the linked list,
# and the inherited dictionary is updated with the new key/value pair.
if key not in self:
root = self.__root
- last = root[PREV]
- last[NEXT] = root[PREV] = self.__map[key] = [last, root, key]
- dict_setitem(self, key, value)
+ last = root[0]
+ last[1] = root[0] = self.__map[key] = [last, root, key]
+ return dict_setitem(self, key, value)
- def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
+ def __delitem__(self, key, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
# Deleting an existing item uses self.__map to find the link which gets
# removed by updating the links in the predecessor and successor nodes.
dict_delitem(self, key)
link_prev, link_next, key = self.__map.pop(key)
- link_prev[NEXT] = link_next
- link_next[PREV] = link_prev
+ link_prev[1] = link_next # update link_prev[NEXT]
+ link_next[0] = link_prev # update link_next[PREV]
def __iter__(self):
'od.__iter__() <==> iter(od)'
# Traverse the linked list in order.
- NEXT, KEY = 1, 2
root = self.__root
- curr = root[NEXT]
+ curr = root[1] # start at the first node
while curr is not root:
- yield curr[KEY]
- curr = curr[NEXT]
+ yield curr[2] # yield the curr[KEY]
+ curr = curr[1] # move to next node
def __reversed__(self):
'od.__reversed__() <==> reversed(od)'
# Traverse the linked list in reverse order.
- PREV, KEY = 0, 2
root = self.__root
- curr = root[PREV]
+ curr = root[0] # start at the last node
while curr is not root:
- yield curr[KEY]
- curr = curr[PREV]
+ yield curr[2] # yield the curr[KEY]
+ curr = curr[0] # move to previous node
def clear(self):
'od.clear() -> None. Remove all items from od.'
- for node in self.__map.itervalues():
- del node[:]
root = self.__root
root[:] = [root, root, None]
self.__map.clear()
@@ -208,7 +205,7 @@
'''
if isinstance(other, OrderedDict):
- return len(self)==len(other) and self.items() == other.items()
+ return dict.__eq__(self, other) and all(_imap(_eq, self, other))
return dict.__eq__(self, other)
def __ne__(self, other):
diff --git a/lib-python/2.7/test/test_modulefinder.py b/lib-python/2.7/test/test_modulefinder.py
--- a/lib-python/2.7/test/test_modulefinder.py
+++ b/lib-python/2.7/test/test_modulefinder.py
@@ -16,7 +16,7 @@
# library.
TEST_DIR = tempfile.mkdtemp()
-TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)]
+TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)]
# Each test description is a list of 5 items:
#
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -160,7 +160,7 @@
RegrTest('test_codeop.py', core=True),
RegrTest('test_coding.py', core=True),
RegrTest('test_coercion.py', core=True),
- RegrTest('test_collections.py'),
+ RegrTest('test_collections.py', usemodules='binascii struct'),
RegrTest('test_colorsys.py'),
RegrTest('test_commands.py'),
RegrTest('test_compare.py', core=True),
@@ -181,7 +181,7 @@
RegrTest('test_csv.py', usemodules='_csv'),
RegrTest('test_ctypes.py', usemodules="_rawffi thread"),
RegrTest('test_curses.py'),
- RegrTest('test_datetime.py'),
+ RegrTest('test_datetime.py', usemodules='binascii struct'),
RegrTest('test_dbm.py'),
RegrTest('test_decimal.py'),
RegrTest('test_decorators.py', core=True),
diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py
--- a/lib_pypy/_collections.py
+++ b/lib_pypy/_collections.py
@@ -142,12 +142,18 @@
return c
def remove(self, value):
- # Need to be defensive for mutating comparisons
- for i in range(len(self)):
- if self[i] == value:
- del self[i]
- return
- raise ValueError("deque.remove(x): x not in deque")
+ # Need to defend mutating or failing comparisons
+ i = 0
+ try:
+ for i in range(len(self)):
+ if self[0] == value:
+ self.popleft()
+ return
+ self.append(self.popleft())
+ i += 1
+ raise ValueError("deque.remove(x): x not in deque")
+ finally:
+ self.rotate(i)
def rotate(self, n=1):
length = len(self)
diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py
--- a/lib_pypy/cPickle.py
+++ b/lib_pypy/cPickle.py
@@ -1,5 +1,5 @@
#
-# One-liner implementation of cPickle
+# Reimplementation of cPickle, mostly as a copy of pickle.py
#
from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass
@@ -131,6 +131,13 @@
# Unpickling machinery
+class _Stack(list):
+ def pop(self, index=-1):
+ try:
+ return list.pop(self, index)
+ except IndexError:
+ raise UnpicklingError("unpickling stack underflow")
+
class Unpickler(object):
def __init__(self, file):
@@ -155,7 +162,7 @@
Return the reconstituted object hierarchy specified in the file.
"""
self.mark = object() # any new unique object
- self.stack = []
+ self.stack = _Stack()
self.append = self.stack.append
try:
key = ord(self.read(1))
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
@@ -19,16 +19,19 @@
if sys.platform == 'win32':
standard_c_lib._errno.restype = ctypes.POINTER(ctypes.c_int)
+ 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
def _where_is_errno():
return standard_c_lib.__errno_location()
elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'):
standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int)
+ standard_c_lib.__error.argtypes = None
def _where_is_errno():
return standard_c_lib.__error()
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -18,6 +18,7 @@
import time as _time
import math as _math
+import decimal as _decimal
MINYEAR = 1
MAXYEAR = 9999
@@ -270,10 +271,15 @@
return offset
raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))
+def _check_int_field(value):
+ if not isinstance(value, (int, long, _decimal.Decimal)):
+ raise TypeError('integer argument expected')
+ return int(value)
+
def _check_date_fields(year, month, day):
- for value in [year, day]:
- if not isinstance(value, (int, long)):
- raise TypeError('int expected')
+ year = _check_int_field(year)
+ month = _check_int_field(month)
+ day = _check_int_field(day)
if not MINYEAR <= year <= MAXYEAR:
raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
if not 1 <= month <= 12:
@@ -281,11 +287,13 @@
dim = _days_in_month(year, month)
if not 1 <= day <= dim:
raise ValueError('day must be in 1..%d' % dim, day)
+ return year, month, day
def _check_time_fields(hour, minute, second, microsecond):
- for value in [hour, minute, second, microsecond]:
- if not isinstance(value, (int, long)):
- raise TypeError('int expected')
+ hour = _check_int_field(hour)
+ minute = _check_int_field(minute)
+ second = _check_int_field(second)
+ microsecond = _check_int_field(microsecond)
if not 0 <= hour <= 23:
raise ValueError('hour must be in 0..23', hour)
if not 0 <= minute <= 59:
@@ -294,6 +302,7 @@
raise ValueError('second must be in 0..59', second)
if not 0 <= microsecond <= 999999:
raise ValueError('microsecond must be in 0..999999', microsecond)
+ return hour, minute, second, microsecond
def _check_tzinfo_arg(tz):
if tz is not None and not isinstance(tz, tzinfo):
@@ -768,7 +777,7 @@
self = object.__new__(cls)
self.__setstate(year)
return self
- _check_date_fields(year, month, day)
+ year, month, day = _check_date_fields(year, month, day)
self = object.__new__(cls)
self._year = year
self._month = month
@@ -889,7 +898,7 @@
month = self._month
if day is None:
day = self._day
- _check_date_fields(year, month, day)
+ year, month, day = _check_date_fields(year, month, day)
return date(year, month, day)
# Comparisons of date objects with other.
@@ -1150,13 +1159,14 @@
second, microsecond (default to zero)
tzinfo (default to None)
"""
- self = object.__new__(cls)
if isinstance(hour, str):
# Pickle support
+ self = object.__new__(cls)
self.__setstate(hour, minute or None)
return self
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_check_tzinfo_arg(tzinfo)
- _check_time_fields(hour, minute, second, microsecond)
+ self = object.__new__(cls)
self._hour = hour
self._minute = minute
self._second = second
@@ -1387,7 +1397,7 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- _check_time_fields(hour, minute, second, microsecond)
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_check_tzinfo_arg(tzinfo)
return time(hour, minute, second, microsecond, tzinfo)
@@ -1449,10 +1459,10 @@
self = date.__new__(cls, year[:4])
self.__setstate(year, month)
return self
+ year, month, day = _check_date_fields(year, month, day)
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_check_tzinfo_arg(tzinfo)
- _check_time_fields(hour, minute, second, microsecond)
- self = date.__new__(cls, year, month, day)
- # XXX This duplicates __year, __month, __day for convenience :-(
+ self = object.__new__(cls)
self._year = year
self._month = month
self._day = day
@@ -1617,8 +1627,8 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- _check_date_fields(year, month, day)
- _check_time_fields(hour, minute, second, microsecond)
+ year, month, day = _check_date_fields(year, month, day)
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_check_tzinfo_arg(tzinfo)
return datetime(year, month, day, hour, minute, second,
microsecond, tzinfo)
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,5 +1,6 @@
import _continuation, sys
+__version__ = "0.4.0"
# ____________________________________________________________
# Exceptions
@@ -57,7 +58,8 @@
def __switch(target, methodname, *args):
current = getcurrent()
#
- while not target:
+ while not (target.__main or _continulet.is_pending(target)):
+ # inlined __nonzero__ ^^^ in case it's overridden
if not target.__started:
if methodname == 'switch':
greenlet_func = _greenlet_start
diff --git a/lib_pypy/pypy_test/test_cPickle.py b/lib_pypy/pypy_test/test_cPickle.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pypy_test/test_cPickle.py
@@ -0,0 +1,7 @@
+from __future__ import absolute_import
+import py
+
+from lib_pypy import cPickle
+
+def test_stack_underflow():
+ py.test.raises(cPickle.UnpicklingError, cPickle.loads, "a string")
diff --git a/lib_pypy/pypy_test/test_collections.py b/lib_pypy/pypy_test/test_collections.py
--- a/lib_pypy/pypy_test/test_collections.py
+++ b/lib_pypy/pypy_test/test_collections.py
@@ -16,6 +16,17 @@
d = collections.deque([MutatingCmp()])
py.test.raises(IndexError, d.remove, 1)
+ def test_remove_failing(self):
+ class FailingCmp(object):
+ def __eq__(self, other):
+ assert False
+
+ f = FailingCmp()
+ d = collections.deque([1, 2, 3, f, 4, 5])
+ d.remove(3)
+ py.test.raises(AssertionError, d.remove, 4)
+ assert d == collections.deque([1, 2, f, 4, 5])
+
def test_maxlen(self):
d = collections.deque([], 3)
d.append(1); d.append(2); d.append(3); d.append(4)
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -398,6 +398,7 @@
if hasattr(self, 'old_sigwinch'):
signal.signal(signal.SIGWINCH, self.old_sigwinch)
+ del self.old_sigwinch
def __sigwinch(self, signum, frame):
self.height, self.width = self.getheightwidth()
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -84,10 +84,11 @@
if self.config.option.runappdirect:
# only collect regular tests if we are in an 'app_test' directory,
# or in test_lib_pypy
- names = self.listnames()
- return "app_test" in names or "test_lib_pypy" in names
- else:
- return True
+ for name in self.listnames():
+ if "app_test" in name or "test_lib_pypy" in name:
+ return True
+ return False
+ return True
def funcnamefilter(self, name):
if name.startswith('test_'):
diff --git a/pypy/doc/arm.rst b/pypy/doc/arm.rst
--- a/pypy/doc/arm.rst
+++ b/pypy/doc/arm.rst
@@ -145,7 +145,7 @@
::
- pypy ~/path_to_pypy_checkout/pypy/translator/goal/translate.py -O1 --platform=arm target.py
+ pypy ~/path_to_pypy_checkout/rpython/translator/goal/translate.py -O1 --platform=arm target.py
If everything worked correctly this should yield an ARM binary. Running this binary in the ARM chroot or on an ARM device should produce the output ``"Hello World"``.
diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst
--- a/pypy/doc/cppyy.rst
+++ b/pypy/doc/cppyy.rst
@@ -86,10 +86,10 @@
$ hg clone https://bitbucket.org/pypy/pypy
$ cd pypy
$ hg up reflex-support # optional
- $ cd pypy/translator/goal
+ $ cd pypy/goal
# This example shows python, but using pypy-c is faster and uses less memory
- $ python translate.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy
+ $ python ../../rpython/bin/rpython.py -O jit --gcrootfinder=shadowstack targetpypystandalone.py --withmod-cppyy
This will build a ``pypy-c`` that includes the cppyy module, and through that,
Reflex support.
diff --git a/pypy/doc/ctypes-implementation.rst b/pypy/doc/ctypes-implementation.rst
--- a/pypy/doc/ctypes-implementation.rst
+++ b/pypy/doc/ctypes-implementation.rst
@@ -113,7 +113,7 @@
The pypy-c translated to run the ctypes tests can be used to run the pyglet examples as well. They can be run like e.g.::
$ cd pyglet/
- $ PYTHONPATH=. ../ctypes-stable/pypy/translator/goal/pypy-c examples/opengl.py
+ $ PYTHONPATH=. ../ctypes-stable/pypy/goal/pypy-c examples/opengl.py
they usually should be terminated with ctrl-c. Refer to the their doc strings for details about how they should behave.
diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst
--- a/pypy/doc/getting-started-dev.rst
+++ b/pypy/doc/getting-started-dev.rst
@@ -24,7 +24,7 @@
python bin/translatorshell.py
Test snippets of translatable code are provided in the file
-``pypy/translator/test/snippet.py``, which is imported under the name
+``rpython/translator/test/snippet.py``, which is imported under the name
``snippet``. For example::
>>> t = Translation(snippet.is_perfect_number, [int])
@@ -52,16 +52,18 @@
The graph can be turned into C code::
>>> t.rtype()
- >>> f = t.compile_c()
+ >>> lib = t.compile_c()
The first command replaces the operations with other low level versions that
-only use low level types that are available in C (e.g. int). To try out the
-compiled version::
+only use low level types that are available in C (e.g. int). The compiled
+version is now in a ``.so`` library. You can run it say using ctypes:
+ >>> from ctypes import CDLL
+ >>> f = CDLL(lib)
>>> f(5)
- False
+ 0
>>> f(6)
- True
+ 1
Translating the flow graph to CLI or JVM code
+++++++++++++++++++++++++++++++++++++++++++++
@@ -108,7 +110,7 @@
There is a small-to-medium demo showing the translator and the annotator::
cd demo
- ../pypy/translator/goal/translate.py --view --annotate bpnn.py
+ ../rpython/translator/goal/translate.py --view --annotate bpnn.py
This causes ``bpnn.py`` to display itself as a call graph and class
hierarchy. Clicking on functions shows the flow graph of the particular
@@ -119,17 +121,17 @@
To turn this example to C code (compiled to the executable ``bpnn-c``),
type simply::
- ../pypy/translator/goal/translate.py bpnn.py
+ ../rpython/translator/goal/translate.py bpnn.py
Translating Full Programs
+++++++++++++++++++++++++
To translate full RPython programs, there is the script ``translate.py`` in
-``translator/goal``. Examples for this are a slightly changed version of
+``rpython/translator/goal``. Examples for this are a slightly changed version of
Pystone::
- cd pypy/translator/goal
+ cd rpython/translator/goal
python translate.py targetrpystonedalone
This will produce the executable "targetrpystonedalone-c".
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -220,9 +220,8 @@
================================ ===========================================
Directory explanation/links
================================ ===========================================
-`pypy/annotation/`_ `type inferencing code`_ for `RPython`_ programs
-`pypy/bin/`_ command-line scripts, mainly `py.py`_ and `translatorshell.py`_
+`pypy/bin/`_ command-line scripts, mainly `pyinteractive.py`_
`pypy/config/`_ handles the numerous options for building and running PyPy
@@ -249,20 +248,8 @@
`pypy/objspace/`_ `object space`_ implementations
-`pypy/objspace/flow/`_ the FlowObjSpace_ implementing `abstract interpretation`_
-
`pypy/objspace/std/`_ the StdObjSpace_ implementing CPython's objects and types
-`pypy/rlib/`_ a `"standard library"`_ for RPython_ programs
-
-`pypy/rpython/`_ the `RPython Typer`_
-
-`pypy/rpython/lltypesystem/`_ the `low-level type system`_ for C-like backends
-
-`pypy/rpython/ootypesystem/`_ the `object-oriented type system`_ for OO backends
-
-`pypy/rpython/memory/`_ the `garbage collector`_ construction framework
-
`pypy/tool/`_ various utilities and hacks used from various places
`pypy/tool/algo/`_ general-purpose algorithmic and mathematic
@@ -270,20 +257,39 @@
`pypy/tool/pytest/`_ support code for our `testing methods`_
-`pypy/translator/`_ translation_ backends and support code
-`pypy/translator/backendopt/`_ general optimizations that run before a backend generates code
+`rpython/annotator/`_ `type inferencing code`_ for `RPython`_ programs
-`pypy/translator/c/`_ the `GenC backend`_, producing C code from an
+`rpython/config/`_ handles the numerous options for RPython
+
+
+`rpython/flowspace/`_ the FlowObjSpace_ implementing `abstract interpretation`_
+
+
+`rpython/rlib/`_ a `"standard library"`_ for RPython_ programs
+
+`rpython/rtyper/`_ the `RPython Typer`_
+
+`rpython/rtyper/lltypesystem/`_ the `low-level type system`_ for C-like backends
+
+`rpython/rtyper/ootypesystem/`_ the `object-oriented type system`_ for OO backends
+
+`rpython/rtyper/memory/`_ the `garbage collector`_ construction framework
+
+`rpython/translator/`_ translation_ backends and support code
+
+`rpython/translator/backendopt/`_ general optimizations that run before a backend generates code
+
+`rpython/translator/c/`_ the `GenC backend`_, producing C code from an
RPython program (generally via the rtyper_)
-`pypy/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_)
+`rpython/translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_)
-`pypy/translator/goal/`_ our `main PyPy-translation scripts`_ live here
+`pypy/goal/`_ our `main PyPy-translation scripts`_ live here
-`pypy/translator/jvm/`_ the Java backend
+`rpython/translator/jvm/`_ the Java backend
-`pypy/translator/tool/`_ helper tools for translation, including the Pygame
+`rpython/translator/tool/`_ helper tools for translation, including the Pygame
`graph viewer`_
``*/test/`` many directories have a test subdirectory containing test
diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst
--- a/pypy/doc/sandbox.rst
+++ b/pypy/doc/sandbox.rst
@@ -87,15 +87,15 @@
-----
-In pypy/translator/goal::
+In pypy/goal::
- ./translate.py -O2 --sandbox targetpypystandalone.py
+ ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone.py
If you don't have a regular PyPy installed, you should, because it's
faster to translate, but you can also run ``python translate.py`` instead.
-To run it, use the tools in the pypy/translator/sandbox directory::
+To run it, use the tools in the pypy/sandbox directory::
./pypy_interact.py /some/path/pypy-c-sandbox [args...]
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
@@ -37,6 +37,7 @@
.. branch: fix-e4fa0b2
.. branch: win32-fixes
.. branch: fix-version-tool
+.. branch: popen2-removal
.. branch: release-2.0-beta1
@@ -50,3 +51,6 @@
.. branch: inline-virtualref-2
Better optimized certain types of frame accesses in the JIT, particularly
around exceptions that escape the function they were raised in.
+
+.. branch: missing-ndarray-attributes
+Some missing attributes from ndarrays
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -436,11 +436,14 @@
# (relevant in case of "reload(sys)")
sys.argv[:] = argv
- if PYTHON26 and not options["ignore_environment"]:
- if os.getenv('PYTHONNOUSERSITE'):
- options["no_user_site"] = 1
- if os.getenv('PYTHONDONTWRITEBYTECODE'):
- options["dont_write_bytecode"] = 1
+ if not options["ignore_environment"]:
+ if os.getenv('PYTHONUNBUFFERED'):
+ options["unbuffered"] = 1
+ if PYTHON26:
+ if os.getenv('PYTHONNOUSERSITE'):
+ options["no_user_site"] = 1
+ if os.getenv('PYTHONDONTWRITEBYTECODE'):
+ options["dont_write_bytecode"] = 1
if (options["interactive"] or
(not options["ignore_environment"] and os.getenv('PYTHONINSPECT'))):
@@ -716,7 +719,7 @@
root = dn(dn(dn(thisfile)))
return [join(root, 'lib-python', '2.7'),
join(root, 'lib_pypy')]
-
+
def pypy_resolvedirof(s):
# we ignore the issue of symlinks; for tests, the executable is always
# interpreter/app_main.py anyway
@@ -756,6 +759,10 @@
del os # make sure that os is not available globally, because this is what
# happens in "real life" outside the tests
+ if 'time' not in sys.builtin_module_names:
+ # make some tests happy by loading this before we clobber sys.path
+ import time; del time
+
# no one should change to which lists sys.argv and sys.path are bound
old_argv = sys.argv
old_path = sys.path
diff --git a/pypy/interpreter/test2/test_app_main.py b/pypy/interpreter/test2/test_app_main.py
--- a/pypy/interpreter/test2/test_app_main.py
+++ b/pypy/interpreter/test2/test_app_main.py
@@ -712,6 +712,26 @@
assert data == '\x00(STDOUT)\n\x00' # from stdout
child_out_err.close()
+ def test_non_interactive_stdout_unbuffered(self, monkeypatch):
+ monkeypatch.setenv('PYTHONUNBUFFERED', '1')
+ path = getscript(r"""
+ import sys, time
+ sys.stdout.write('\x00(STDOUT)\n\x00')
+ time.sleep(1)
+ sys.stderr.write('\x00[STDERR]\n\x00')
+ time.sleep(1)
+ # stdout flushed automatically here
+ """)
+ cmdline = '%s -E "%s" %s' % (sys.executable, app_main, path)
+ print 'POPEN:', cmdline
+ child_in, child_out_err = os.popen4(cmdline)
+ data = child_out_err.read(11)
+ assert data == '\x00(STDOUT)\n\x00' # from stderr
+ data = child_out_err.read(11)
+ assert data == '\x00[STDERR]\n\x00' # from stdout
+ child_out_err.close()
+ child_in.close()
+
def test_proper_sys_path(self, tmpdir):
data = self.run('-c "import _ctypes"', python_flags='-S')
if data.startswith('Traceback'):
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -14,7 +14,7 @@
class TimeModule(MixedModule):
appleveldefs = {}
interpleveldefs = {}
- if sys.platform.startswith("linux"):
+ if sys.platform.startswith("linux") or 'bsd' in sys.platform:
from pypy.module.__pypy__ import interp_time
interpleveldefs["clock_gettime"] = "interp_time.clock_gettime"
interpleveldefs["clock_getres"] = "interp_time.clock_getres"
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
@@ -2,7 +2,7 @@
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.buffer import RWBuffer
from pypy.interpreter.gateway import unwrap_spec, interp2app
-from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.typedef import TypeDef, make_weakref_descr
from rpython.rtyper.lltypesystem import rffi
from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
@@ -41,8 +41,9 @@
# a different subclass of Wrappable for the MiniBuffer, because we
# want a slightly different (simplified) API at the level of Python.
- def __init__(self, buffer):
+ def __init__(self, buffer, keepalive=None):
self.buffer = buffer
+ self.keepalive = keepalive
def descr_len(self, space):
return self.buffer.descr_len(space)
@@ -65,6 +66,7 @@
__getitem__ = interp2app(MiniBuffer.descr_getitem),
__setitem__ = interp2app(MiniBuffer.descr_setitem),
__buffer__ = interp2app(MiniBuffer.descr__buffer__),
+ __weakref__ = make_weakref_descr(MiniBuffer),
)
MiniBuffer.typedef.acceptable_as_base_class = False
@@ -86,4 +88,4 @@
raise operationerrfmt(space.w_TypeError,
"don't know the size pointed to by '%s'",
ctype.name)
- return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size)))
+ return space.wrap(MiniBuffer(LLBuffer(cdata._cdata, size), cdata))
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -252,7 +252,10 @@
def _prepare_pointer_call_argument(self, w_init, cdata):
space = self.space
- if (space.isinstance_w(w_init, space.w_list) or
+ if space.is_w(w_init, space.w_None):
+ rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO)
+ return 3
+ elif (space.isinstance_w(w_init, space.w_list) or
space.isinstance_w(w_init, space.w_tuple)):
length = space.int_w(space.len(w_init))
elif space.isinstance_w(w_init, space.w_basestring):
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -12,6 +12,7 @@
return eval('u'+repr(other).replace(r'\\u', r'\u')
.replace(r'\\U', r'\U'))
u = U()
+ str2bytes = str
else:
type_or_class = "class"
long = int
@@ -22,6 +23,7 @@
bytechr = lambda n: bytes([n])
bitem2bchr = bytechr
u = ""
+ str2bytes = lambda s: bytes(s, "ascii")
def size_of_int():
BInt = new_primitive_type("int")
@@ -996,6 +998,8 @@
f = cast(BFunc23, _testfunc(23))
res = f(b"foo")
assert res == 1000 * ord(b'f')
+ res = f(None)
+ assert res == -42
def test_call_function_23_bis():
# declaring the function as int(unsigned char*)
@@ -1438,10 +1442,16 @@
import _weakref
BInt = new_primitive_type("int")
BPtr = new_pointer_type(BInt)
- _weakref.ref(BInt)
- _weakref.ref(newp(BPtr, 42))
- _weakref.ref(cast(BPtr, 42))
- _weakref.ref(cast(BInt, 42))
+ rlist = [_weakref.ref(BInt),
+ _weakref.ref(newp(BPtr, 42)),
+ _weakref.ref(cast(BPtr, 42)),
+ _weakref.ref(cast(BInt, 42)),
+ _weakref.ref(buffer(newp(BPtr, 42))),
+ ]
+ for i in range(5):
+ import gc; gc.collect()
+ if [r() for r in rlist] == [None for r in rlist]:
+ break
def test_no_inheritance():
BInt = new_primitive_type("int")
@@ -2544,3 +2554,15 @@
BCharP = new_pointer_type(new_primitive_type("char"))
BCharArray = new_array_type(BCharP, None)
py.test.raises(TypeError, newp, BCharArray, u+'foobar')
+
+def test_buffer_keepalive():
+ BCharP = new_pointer_type(new_primitive_type("char"))
+ BCharArray = new_array_type(BCharP, None)
+ buflist = []
+ for i in range(20):
+ c = newp(BCharArray, str2bytes("hi there %d" % i))
+ buflist.append(buffer(c))
+ import gc; gc.collect()
+ for i in range(20):
+ buf = buflist[i]
+ assert buf[:] == str2bytes("hi there %d\x00" % i)
diff --git a/pypy/module/_cffi_backend/test/_test_lib.c b/pypy/module/_cffi_backend/test/_test_lib.c
--- a/pypy/module/_cffi_backend/test/_test_lib.c
+++ b/pypy/module/_cffi_backend/test/_test_lib.c
@@ -174,7 +174,9 @@
static int _testfunc23(char *p)
{
- return 1000 * p[0];
+ if (p)
+ return 1000 * p[0];
+ return -42;
}
DLLEXPORT void *gettestfunc(int num)
diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py
--- a/pypy/module/_multibytecodec/c_codecs.py
+++ b/pypy/module/_multibytecodec/c_codecs.py
@@ -62,7 +62,7 @@
"pypy_cjk_enc_init", "pypy_cjk_enc_free", "pypy_cjk_enc_chunk",
"pypy_cjk_enc_reset", "pypy_cjk_enc_outbuf", "pypy_cjk_enc_outlen",
"pypy_cjk_enc_inbuf_remaining", "pypy_cjk_enc_inbuf_consumed",
- "pypy_cjk_enc_replace_on_error",
+ "pypy_cjk_enc_replace_on_error", "pypy_cjk_enc_getcodec",
] + ["pypy_cjkcodec_%s" % codec for codec in codecs],
)
diff --git a/pypy/module/bz2/test/test_bz2_compdecomp.py b/pypy/module/bz2/test/test_bz2_compdecomp.py
--- a/pypy/module/bz2/test/test_bz2_compdecomp.py
+++ b/pypy/module/bz2/test/test_bz2_compdecomp.py
@@ -12,7 +12,7 @@
if os.name == "nt":
from py.test import skip
skip("bz2 module is not available on Windows")
-
+
def setup_module(mod):
DATA = 'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2<Q\xb5\x0fH\xd3\xd4\xdd\xd5\x87\xbb\xf8\x94\r\x8f\xafI\x12\xe1\xc9\xf8/E\x00pu\x89\x12]\xc9\xbbDL\nQ\x0e\t1\x12\xdf\xa0\xc0\x97\xac2O9\x89\x13\x94\x0e\x1c7\x0ed\x95I\x0c\xaaJ\xa4\x18L\x10\x05#\x9c\xaf\xba\xbc/\x97\x8a#C\xc8\xe1\x8cW\xf9\xe2\xd0\xd6M\xa7\x8bXa<e\x84t\xcbL\xb3\xa7\xd9\xcd\xd1\xcb\x84.\xaf\xb3\xab\xab\xad`n}\xa0lh\tE,\x8eZ\x15\x17VH>\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`'
@@ -54,27 +54,27 @@
def test_creation(self):
from bz2 import BZ2Compressor
-
+
raises(TypeError, BZ2Compressor, "foo")
raises(ValueError, BZ2Compressor, 10)
-
+
BZ2Compressor(1)
BZ2Compressor(9)
-
+
def test_compress(self):
from bz2 import BZ2Compressor
-
+
bz2c = BZ2Compressor()
raises(TypeError, bz2c.compress)
data = bz2c.compress(self.TEXT)
data = "%s%s" % (data, bz2c.flush())
assert self.decompress(data) == self.TEXT
-
+
def test_compress_huge_data(self):
if not self.HUGE_OK:
skip("skipping test requiring lots of memory")
- from bz2 import BZ2Compressor
-
+ from bz2 import BZ2Compressor
+
HUGE_DATA = self.TEXT * 10000
bz2c = BZ2Compressor()
raises(TypeError, bz2c.compress)
@@ -83,8 +83,8 @@
assert self.decompress(data) == HUGE_DATA
def test_compress_chunks_10(self):
- from bz2 import BZ2Compressor
-
+ from bz2 import BZ2Compressor
+
bz2c = BZ2Compressor()
n = 0
data = ""
@@ -112,23 +112,23 @@
cls.w_TEXT = cls.space.wrap(TEXT)
cls.w_DATA = cls.space.wrap(DATA)
cls.w_BUGGY_DATA = cls.space.wrap(BUGGY_DATA)
-
+
def test_creation(self):
from bz2 import BZ2Decompressor
-
+
raises(TypeError, BZ2Decompressor, "foo")
-
+
BZ2Decompressor()
-
+
def test_attribute(self):
from bz2 import BZ2Decompressor
-
+
bz2d = BZ2Decompressor()
assert bz2d.unused_data == ""
def test_decompress(self):
from bz2 import BZ2Decompressor
-
+
bz2d = BZ2Decompressor()
raises(TypeError, bz2d.decompress)
decompressed_data = bz2d.decompress(self.DATA)
@@ -136,7 +136,7 @@
def test_decompress_chunks_10(self):
from bz2 import BZ2Decompressor
-
+
bz2d = BZ2Decompressor()
decompressed_data = ""
n = 0
@@ -146,13 +146,13 @@
break
decompressed_data = "%s%s" % (decompressed_data, bz2d.decompress(temp))
n += 1
-
+
assert decompressed_data == self.TEXT
-
+
def test_decompress_unused_data(self):
# test with unused data. (data after EOF)
from bz2 import BZ2Decompressor
-
+
bz2d = BZ2Decompressor()
unused_data = "this is unused data"
decompressed_data = bz2d.decompress(self.DATA + unused_data)
@@ -161,7 +161,7 @@
def test_EOF_error(self):
from bz2 import BZ2Decompressor
-
+
bz2d = BZ2Decompressor()
bz2d.decompress(self.DATA)
raises(EOFError, bz2d.decompress, "foo")
@@ -195,11 +195,11 @@
def test_compress_function(self):
from bz2 import compress
-
+
raises(TypeError, compress, 123)
raises(ValueError, compress, "foo", 10)
raises(TypeError, compress, "foo", "foo")
-
+
data = compress(self.TEXT)
assert self.decompress(data) == self.TEXT
@@ -207,7 +207,7 @@
if not self.HUGE_OK:
skip("skipping test requiring lots of memory")
from bz2 import compress
-
+
HUGE_DATA = self.TEXT * 10000
data = compress(HUGE_DATA)
@@ -215,7 +215,7 @@
def test_decompress_function(self):
import bz2
-
+
raises(TypeError, bz2.decompress)
assert bz2.decompress("") == ""
decompressed_data = bz2.decompress(self.DATA)
diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py
--- a/pypy/module/bz2/test/test_bz2_file.py
+++ b/pypy/module/bz2/test/test_bz2_file.py
@@ -6,6 +6,7 @@
import py
from pypy.interpreter.gateway import unwrap_spec, interp2app
+from pypy.module.bz2.test.support import CheckAllocation
if os.name == "nt":
@@ -50,10 +51,7 @@
mod.RANDOM_DATA = ''.join([s[int(random.random() * len(s))] for i in range(30000)])
-class AppTestBZ2File: #(CheckAllocation):
- # XXX for unknown reasons, we cannot do allocation checks, as sth is
- # keeping those objects alive (BZ2File objects)
-
+class AppTestBZ2File(CheckAllocation):
spaceconfig = {
"usemodules": ["bz2", "binascii", "rctime"]
}
@@ -85,15 +83,15 @@
assert bz2f.closed == False
bz2f.close()
assert bz2f.closed == True
-
+
def test_creation(self):
from bz2 import BZ2File
-
+
raises(ValueError, BZ2File, self.temppath, mode='w', compresslevel=10)
raises(ValueError, BZ2File, self.temppath, mode='XYZ')
# XXX the following is fine, currently:
#raises(ValueError, BZ2File, self.temppath, mode='ww')
-
+
BZ2File(self.temppath, mode='wU', buffering=0, compresslevel=8)
BZ2File(self.temppath, mode='wb')
# a large buf size
@@ -101,50 +99,50 @@
def test_close(self):
from bz2 import BZ2File
-
+
# writeonly
bz2f = BZ2File(self.temppath, mode='w')
bz2f.close()
- # since we use fclose() internally you can't close it twice
- # bz2f.close()
-
+ bz2f.close()
+
# readonly
bz2f = BZ2File(self.temppath, mode='r')
bz2f.close()
-
+ bz2f.close()
+
def test_tell(self):
from bz2 import BZ2File
-
+
bz2f = BZ2File(self.temppath, mode='w')
bz2f.close()
raises(ValueError, bz2f.tell)
-
+
bz2f = BZ2File(self.temppath, mode='w')
pos = bz2f.tell()
bz2f.close()
assert pos == 0
-
+
def test_seek(self):
from bz2 import BZ2File
-
+
# hack to create a foo file
open(self.temppath, "w").close()
-
+
# cannot seek if close
bz2f = BZ2File(self.temppath, mode='r')
bz2f.close()
raises(ValueError, bz2f.seek, 0)
-
+
# cannot seek if 'w'
bz2f = BZ2File(self.temppath, mode='w')
raises(IOError, bz2f.seek, 0)
bz2f.close()
-
+
bz2f = BZ2File(self.temppath, mode='r')
raises(TypeError, bz2f.seek)
raises(TypeError, bz2f.seek, "foo")
raises(TypeError, bz2f.seek, 0, "foo")
-
+
bz2f.seek(0)
assert bz2f.tell() == 0
del bz2f # delete from this frame, which is captured in the traceback
@@ -152,21 +150,21 @@
def test_open_close_del(self):
from bz2 import BZ2File
self.create_temp_file()
-
+
for i in range(10):
f = BZ2File(self.temppath)
f.close()
del f
-
+
def test_open_non_existent(self):
from bz2 import BZ2File
raises(IOError, BZ2File, "/non/existent/path")
-
+
def test_open_mode_U(self):
# bug #1194181: bz2.BZ2File opened for write with mode "U"
from bz2 import BZ2File
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath, "U")
bz2f.close()
f = open(self.temppath)
@@ -174,7 +172,7 @@
f.read()
assert f.tell() == len(self.DATA)
f.close()
-
+
def test_seek_forward(self):
from bz2 import BZ2File
self.create_temp_file()
@@ -214,7 +212,7 @@
assert bz2f.tell() == len(self.TEXT)
assert bz2f.read() == ""
bz2f.close()
-
+
def test_seek_post_end_twice(self):
from bz2 import BZ2File
self.create_temp_file()
@@ -240,10 +238,9 @@
from bz2 import BZ2File
from cStringIO import StringIO
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath)
- # XXX
- #raises(TypeError, bz2f.readline, None)
+ raises(TypeError, bz2f.readline, None)
sio = StringIO(self.TEXT)
for line in sio.readlines():
line_read = bz2f.readline()
@@ -253,10 +250,9 @@
def test_read(self):
from bz2 import BZ2File
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath)
- # XXX
- # raises(TypeError, bz2f.read, None)
+ raises(TypeError, bz2f.read, None)
text_read = bz2f.read()
assert text_read == self.TEXT
bz2f.close()
@@ -291,7 +287,7 @@
def test_read_chunk9(self):
from bz2 import BZ2File
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath)
text_read = ""
while True:
@@ -305,7 +301,7 @@
def test_read_100_bytes(self):
from bz2 import BZ2File
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath)
assert bz2f.read(100) == self.TEXT[:100]
bz2f.close()
@@ -313,7 +309,7 @@
def test_universal_newlines_lf(self):
from bz2 import BZ2File
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath, "rU")
assert bz2f.read() == self.TEXT
assert bz2f.newlines == "\n"
@@ -322,7 +318,7 @@
def test_universal_newlines_crlf(self):
from bz2 import BZ2File
self.create_temp_file(crlf=True)
-
+
bz2f = BZ2File(self.temppath, "rU")
data = bz2f.read()
assert data == self.TEXT
@@ -333,10 +329,9 @@
from bz2 import BZ2File
from cStringIO import StringIO
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath)
- # XXX
- #raises(TypeError, bz2f.readlines, None)
+ raises(TypeError, bz2f.readlines, None)
sio = StringIO(self.TEXT)
assert bz2f.readlines() == sio.readlines()
bz2f.close()
@@ -345,17 +340,17 @@
from bz2 import BZ2File
from cStringIO import StringIO
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath)
sio = StringIO(self.TEXT)
assert list(iter(bz2f)) == sio.readlines()
bz2f.close()
-
+
def test_xreadlines(self):
from bz2 import BZ2File
from cStringIO import StringIO
self.create_temp_file()
-
+
bz2f = BZ2File(self.temppath)
sio = StringIO(self.TEXT)
assert list(bz2f.xreadlines()) == sio.readlines()
@@ -364,12 +359,12 @@
def test_readlines_bug_1191043(self):
# readlines()/xreadlines() for files containing no newline
from bz2 import BZ2File
-
+
DATA = 'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t'
f = open(self.temppath, "wb")
f.write(DATA)
f.close()
-
+
bz2f = BZ2File(self.temppath)
lines = bz2f.readlines()
bz2f.close()
@@ -379,7 +374,7 @@
xlines = list(bz2f.xreadlines())
bz2f.close()
assert xlines == ['Test']
-
+
def test_write(self):
from bz2 import BZ2File
@@ -387,7 +382,7 @@
raises(TypeError, bz2f.write)
bz2f.write(self.TEXT)
bz2f.close()
-
+
f = open(self.temppath, "rb")
assert self.decompress(f.read()) == self.TEXT
f.close()
@@ -401,11 +396,11 @@
data = self.TEXT[n * 10:(n + 1) * 10]
if not data:
break
-
+
bz2f.write(data)
n += 1
bz2f.close()
-
+
f = open(self.temppath, "rb")
assert self.decompress(f.read()) == self.TEXT
f.close()
@@ -422,7 +417,7 @@
f = open(self.temppath, "rb")
assert self.decompress(f.read()) == self.TEXT
f.close()
-
+
def test_write_methods_on_readonly_file(self):
from bz2 import BZ2File
@@ -453,8 +448,8 @@
assert data == "abc"
assert f.closed
-
-
+
+
# has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx", "riscos")
#
# if has_cmdline_bunzip2:
diff --git a/pypy/module/imp/__init__.py b/pypy/module/imp/__init__.py
--- a/pypy/module/imp/__init__.py
+++ b/pypy/module/imp/__init__.py
@@ -6,12 +6,14 @@
__import__ function.
"""
interpleveldefs = {
+ 'SEARCH_ERROR': 'space.wrap(importing.SEARCH_ERROR)',
'PY_SOURCE': 'space.wrap(importing.PY_SOURCE)',
'PY_COMPILED': 'space.wrap(importing.PY_COMPILED)',
'C_EXTENSION': 'space.wrap(importing.C_EXTENSION)',
'PKG_DIRECTORY': 'space.wrap(importing.PKG_DIRECTORY)',
'C_BUILTIN': 'space.wrap(importing.C_BUILTIN)',
'PY_FROZEN': 'space.wrap(importing.PY_FROZEN)',
+ 'IMP_HOOK': 'space.wrap(importing.IMP_HOOK)',
'get_suffixes': 'interp_imp.get_suffixes',
'get_magic': 'interp_imp.get_magic',
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -27,6 +27,9 @@
'True_': 'types.Bool.True',
'False_': 'types.Bool.False',
+ 'bool': 'space.w_bool',
+ 'int': 'space.w_int',
+
'typeinfo': 'interp_dtype.get_dtype_cache(space).w_typeinfo',
'generic': 'interp_boxes.W_GenericBox',
diff --git a/pypy/module/micronumpy/arrayimpl/base.py b/pypy/module/micronumpy/arrayimpl/base.py
--- a/pypy/module/micronumpy/arrayimpl/base.py
+++ b/pypy/module/micronumpy/arrayimpl/base.py
@@ -3,6 +3,12 @@
def is_scalar(self):
return False
+ def base(self):
+ raise NotImplementedError
+
+ def create_iter(self, shape=None):
+ raise NotImplementedError
+
class BaseArrayIterator(object):
def next(self):
raise NotImplementedError # purely abstract base class
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -1,178 +1,20 @@
from pypy.module.micronumpy.arrayimpl import base
-from pypy.module.micronumpy import support, loop
+from pypy.module.micronumpy import support, loop, iter
from pypy.module.micronumpy.base import convert_to_array, W_NDimArray,\
ArrayArgumentException
from pypy.module.micronumpy.strides import calc_new_strides, shape_agreement,\
calculate_broadcast_strides, calculate_dot_strides
from pypy.module.micronumpy.iter import Chunk, Chunks, NewAxisChunk, RecordChunk
from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.buffer import RWBuffer
+from rpython.rlib import jit
from rpython.rtyper.lltypesystem import rffi, lltype
-from rpython.rlib import jit
-from rpython.rlib.rawstorage import free_raw_storage, RAW_STORAGE
+from rpython.rlib.rawstorage import free_raw_storage, raw_storage_getitem,\
+ raw_storage_setitem, RAW_STORAGE
+from pypy.module.micronumpy.arrayimpl.sort import argsort_array
from rpython.rlib.debug import make_sure_not_resized
-class ConcreteArrayIterator(base.BaseArrayIterator):
- _immutable_fields_ = ['dtype', 'skip', 'size']
- def __init__(self, array):
- self.array = array
- self.offset = 0
- self.dtype = array.dtype
- self.skip = self.dtype.itemtype.get_element_size()
- self.size = array.size
-
- def setitem(self, elem):
- self.dtype.setitem(self.array, self.offset, elem)
-
- def getitem(self):
- return self.dtype.getitem(self.array, self.offset)
-
- def getitem_bool(self):
- return self.dtype.getitem_bool(self.array, self.offset)
-
- def next(self):
- self.offset += self.skip
-
- def next_skip_x(self, x):
- self.offset += self.skip * x
-
- def done(self):
- return self.offset >= self.size
-
- def reset(self):
- self.offset %= self.size
-
-class OneDimViewIterator(ConcreteArrayIterator):
- ''' The view iterator dtype can be different from the
- array.dtype, this is what makes it a View
- '''
- def __init__(self, array, dtype, start, strides, shape):
- self.array = array
- self.dtype = dtype
- self.offset = start
- self.skip = strides[0]
- self.index = 0
- self.size = shape[0]
-
- def next(self):
- self.offset += self.skip
- self.index += 1
-
- def next_skip_x(self, x):
- self.offset += self.skip * x
- self.index += x
-
- def done(self):
- return self.index >= self.size
-
- def reset(self):
- self.offset %= self.size
-
-class MultiDimViewIterator(ConcreteArrayIterator):
- ''' The view iterator dtype can be different from the
- array.dtype, this is what makes it a View
- '''
- def __init__(self, array, dtype, start, strides, backstrides, shape):
- self.indexes = [0] * len(shape)
- self.array = array
- self.dtype = dtype
- self.shape = shape
- self.offset = start
- self.shapelen = len(shape)
- self._done = False
- self.strides = strides
- self.backstrides = backstrides
- self.size = array.size
-
- @jit.unroll_safe
- def next(self):
- offset = self.offset
- for i in range(self.shapelen - 1, -1, -1):
- if self.indexes[i] < self.shape[i] - 1:
- self.indexes[i] += 1
- offset += self.strides[i]
- break
- else:
- self.indexes[i] = 0
- offset -= self.backstrides[i]
- else:
- self._done = True
- self.offset = offset
-
- @jit.unroll_safe
- def next_skip_x(self, step):
- for i in range(len(self.shape) - 1, -1, -1):
- if self.indexes[i] < self.shape[i] - step:
- self.indexes[i] += step
- self.offset += self.strides[i] * step
- break
- else:
- remaining_step = (self.indexes[i] + step) // self.shape[i]
- this_i_step = step - remaining_step * self.shape[i]
- self.offset += self.strides[i] * this_i_step
- self.indexes[i] = self.indexes[i] + this_i_step
- step = remaining_step
- else:
- self._done = True
-
- def done(self):
- return self._done
-
- def reset(self):
- self.offset %= self.size
-
-class AxisIterator(base.BaseArrayIterator):
- def __init__(self, array, shape, dim):
- self.shape = shape
- strides = array.get_strides()
- backstrides = array.get_backstrides()
- if len(shape) == len(strides):
- # keepdims = True
- self.strides = strides[:dim] + [0] + strides[dim + 1:]
- self.backstrides = backstrides[:dim] + [0] + backstrides[dim + 1:]
- else:
- self.strides = strides[:dim] + [0] + strides[dim:]
- self.backstrides = backstrides[:dim] + [0] + backstrides[dim:]
- self.first_line = True
- self.indices = [0] * len(shape)
- self._done = False
- self.offset = array.start
- self.dim = dim
- self.array = array
- self.dtype = array.dtype
-
- def setitem(self, elem):
- self.dtype.setitem(self.array, self.offset, elem)
-
- def getitem(self):
- return self.dtype.getitem(self.array, self.offset)
-
- @jit.unroll_safe
- def next(self):
- for i in range(len(self.shape) - 1, -1, -1):
- if self.indices[i] < self.shape[i] - 1:
- if i == self.dim:
- self.first_line = False
- self.indices[i] += 1
- self.offset += self.strides[i]
- break
- else:
- if i == self.dim:
- self.first_line = True
- self.indices[i] = 0
- self.offset -= self.backstrides[i]
- else:
- self._done = True
-
- def done(self):
- return self._done
-
-def int_w(space, w_obj):
- try:
- return space.int_w(space.index(w_obj))
- except OperationError:
- return space.int_w(space.int(w_obj))
-
class BaseConcreteArray(base.BaseArrayImplementation):
start = 0
parent = None
@@ -213,7 +55,7 @@
def get_size(self):
return self.size // self.dtype.itemtype.get_element_size()
- def reshape(self, space, new_shape):
+ def reshape(self, space, orig_array, new_shape):
# Since we got to here, prod(new_shape) == self.size
new_strides = None
if self.size > 0:
@@ -226,31 +68,31 @@
for nd in range(ndims):
new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd]
return SliceArray(self.start, new_strides, new_backstrides,
- new_shape, self)
+ new_shape, self, orig_array)
else:
return None
- def get_real(self):
+ def get_real(self, orig_array):
strides = self.get_strides()
backstrides = self.get_backstrides()
if self.dtype.is_complex_type():
dtype = self.dtype.float_type
return SliceArray(self.start, strides, backstrides,
- self.get_shape(), self, dtype=dtype)
+ self.get_shape(), self, orig_array, dtype=dtype)
return SliceArray(self.start, strides, backstrides,
- self.get_shape(), self)
+ self.get_shape(), self, orig_array)
- def get_imag(self):
+ def get_imag(self, orig_array):
strides = self.get_strides()
backstrides = self.get_backstrides()
if self.dtype.is_complex_type():
dtype = self.dtype.float_type
return SliceArray(self.start + dtype.get_size(), strides,
- backstrides, self.get_shape(), self, dtype=dtype)
+ backstrides, self.get_shape(), self, orig_array, dtype=dtype)
if self.dtype.is_flexible_type():
# numpy returns self for self.imag
return SliceArray(self.start, strides, backstrides,
- self.get_shape(), self)
+ self.get_shape(), self, orig_array)
impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides,
backstrides)
impl.fill(self.dtype.box(0))
@@ -265,7 +107,7 @@
for i, w_index in enumerate(view_w):
if space.isinstance_w(w_index, space.w_slice):
raise IndexError
- idx = int_w(space, w_index)
+ idx = support.int_w(space, w_index)
if idx < 0:
idx = self.get_shape()[i] + idx
if idx < 0 or idx >= self.get_shape()[i]:
@@ -339,7 +181,7 @@
return self._lookup_by_index(space, view_w)
if shape_len > 1:
raise IndexError
- idx = int_w(space, w_idx)
+ idx = support.int_w(space, w_idx)
return self._lookup_by_index(space, [space.wrap(idx)])
@jit.unroll_safe
@@ -367,26 +209,26 @@
i += 1
return Chunks(result)
- def descr_getitem(self, space, w_index):
+ def descr_getitem(self, space, orig_arr, w_index):
try:
item = self._single_item_index(space, w_index)
return self.getitem(item)
except IndexError:
# not a single result
chunks = self._prepare_slice_args(space, w_index)
- return chunks.apply(self)
+ return chunks.apply(orig_arr)
- def descr_setitem(self, space, w_index, w_value):
+ def descr_setitem(self, space, orig_arr, w_index, w_value):
try:
item = self._single_item_index(space, w_index)
self.setitem(item, self.dtype.coerce(space, w_value))
except IndexError:
w_value = convert_to_array(space, w_value)
chunks = self._prepare_slice_args(space, w_index)
- view = chunks.apply(self)
+ view = chunks.apply(orig_arr)
view.implementation.setslice(space, w_value)
- def transpose(self):
+ def transpose(self, orig_array):
if len(self.get_shape()) < 2:
return self
strides = []
@@ -397,7 +239,7 @@
backstrides.append(self.get_backstrides()[i])
shape.append(self.get_shape()[i])
return SliceArray(self.start, strides,
- backstrides, shape, self)
+ backstrides, shape, self, orig_array)
def copy(self):
strides, backstrides = support.calc_strides(self.get_shape(), self.dtype,
@@ -406,15 +248,15 @@
backstrides)
return loop.setslice(self.get_shape(), impl, self)
- def create_axis_iter(self, shape, dim):
- return AxisIterator(self, shape, dim)
+ def create_axis_iter(self, shape, dim, cum):
+ return iter.AxisIterator(self, shape, dim, cum)
def create_dot_iter(self, shape, skip):
r = calculate_dot_strides(self.get_strides(), self.get_backstrides(),
shape, skip)
- return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape)
+ return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape)
- def swapaxes(self, axis1, axis2):
+ def swapaxes(self, orig_arr, axis1, axis2):
shape = self.get_shape()[:]
strides = self.get_strides()[:]
backstrides = self.get_backstrides()[:]
@@ -422,13 +264,25 @@
strides[axis1], strides[axis2] = strides[axis2], strides[axis1]
backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1]
return W_NDimArray.new_slice(self.start, strides,
- backstrides, shape, self)
+ backstrides, shape, self, orig_arr)
def get_storage_as_int(self, space):
return rffi.cast(lltype.Signed, self.storage)
+ def get_storage(self):
+ return self.storage
+
+ def get_buffer(self, space):
+ return ArrayBuffer(self)
+
+ def astype(self, space, dtype):
+ new_arr = W_NDimArray.from_shape(self.get_shape(), dtype)
+ loop.copy_from_to(self, new_arr.implementation, dtype)
+ return new_arr
+
class ConcreteArrayNotOwning(BaseConcreteArray):
def __init__(self, shape, dtype, order, strides, backstrides, storage):
+
make_sure_not_resized(shape)
make_sure_not_resized(strides)
make_sure_not_resized(backstrides)
@@ -442,19 +296,26 @@
def create_iter(self, shape=None):
if shape is None or shape == self.get_shape():
- return ConcreteArrayIterator(self)
+ return iter.ConcreteArrayIterator(self)
r = calculate_broadcast_strides(self.get_strides(),
self.get_backstrides(),
self.get_shape(), shape)
- return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape)
+ return iter.MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape)
def fill(self, box):
self.dtype.fill(self.storage, box, 0, self.size)
- def set_shape(self, space, new_shape):
+ def set_shape(self, space, orig_array, new_shape):
strides, backstrides = support.calc_strides(new_shape, self.dtype,
self.order)
- return SliceArray(0, strides, backstrides, new_shape, self)
+ return SliceArray(0, strides, backstrides, new_shape, self,
+ orig_array)
+
+ def argsort(self, space, w_axis):
+ return argsort_array(self, space, w_axis)
+
+ def base(self):
+ return None
class ConcreteArray(ConcreteArrayNotOwning):
def __init__(self, shape, dtype, order, strides, backstrides):
@@ -469,14 +330,17 @@
free_raw_storage(self.storage, track_allocation=False)
+
+
class NonWritableArray(ConcreteArray):
- def descr_setitem(self, space, w_index, w_value):
+ def descr_setitem(self, space, orig_array, w_index, w_value):
raise OperationError(space.w_RuntimeError, space.wrap(
"array is not writable"))
class SliceArray(BaseConcreteArray):
- def __init__(self, start, strides, backstrides, shape, parent, dtype=None):
+ def __init__(self, start, strides, backstrides, shape, parent, orig_arr,
+ dtype=None):
self.strides = strides
self.backstrides = backstrides
self.shape = shape
@@ -490,6 +354,10 @@
self.dtype = dtype
self.size = support.product(shape) * self.dtype.itemtype.get_element_size()
self.start = start
+ self.orig_arr = orig_arr
+
+ def base(self):
+ return self.orig_arr
def fill(self, box):
loop.fill(self, box.convert_to(self.dtype))
@@ -499,16 +367,16 @@
r = calculate_broadcast_strides(self.get_strides(),
self.get_backstrides(),
self.get_shape(), shape)
- return MultiDimViewIterator(self.parent, self.dtype,
- self.start, r[0], r[1], shape)
+ return iter.MultiDimViewIterator(self.parent, self.dtype,
+ self.start, r[0], r[1], shape)
if len(self.get_shape()) == 1:
- return OneDimViewIterator(self.parent, self.dtype, self.start,
+ return iter.OneDimViewIterator(self.parent, self.dtype, self.start,
self.get_strides(), self.get_shape())
- return MultiDimViewIterator(self.parent, self.dtype, self.start,
+ return iter.MultiDimViewIterator(self.parent, self.dtype, self.start,
self.get_strides(),
self.get_backstrides(), self.get_shape())
- def set_shape(self, space, new_shape):
+ def set_shape(self, space, orig_array, new_shape):
if len(self.get_shape()) < 2 or self.size == 0:
# TODO: this code could be refactored into calc_strides
# but then calc_strides would have to accept a stepping factor
@@ -527,7 +395,7 @@
backstrides.reverse()
new_shape.reverse()
return SliceArray(self.start, strides, backstrides, new_shape,
- self)
+ self, orig_array)
new_strides = calc_new_strides(new_shape, self.get_shape(),
self.get_strides(),
self.order)
@@ -538,4 +406,18 @@
for nd in range(len(new_shape)):
new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd]
return SliceArray(self.start, new_strides, new_backstrides, new_shape,
- self)
+ self, orig_array)
+
+class ArrayBuffer(RWBuffer):
+ def __init__(self, impl):
+ self.impl = impl
+
+ def getitem(self, item):
+ return raw_storage_getitem(lltype.Char, self.impl.storage, item)
+
+ def setitem(self, item, v):
+ return raw_storage_setitem(self.impl.storage, item,
+ rffi.cast(lltype.Char, v))
+
+ def getlength(self):
+ return self.impl.size
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -7,18 +7,19 @@
class ScalarIterator(base.BaseArrayIterator):
def __init__(self, v):
self.v = v
+ self.called_once = False
def next(self):
- pass
+ self.called_once = True
def getitem(self):
- return self.v
+ return self.v.get_scalar_value()
def setitem(self, v):
- raise Exception("Don't call setitem on scalar iterators")
+ self.v.set_scalar_value(v)
def done(self):
- raise Exception("should not call done on scalar")
+ return self.called_once
def reset(self):
pass
@@ -38,7 +39,7 @@
return []
def create_iter(self, shape=None):
- return ScalarIterator(self.value)
+ return ScalarIterator(self)
def get_scalar_value(self):
return self.value
@@ -54,10 +55,10 @@
def get_size(self):
return 1
- def transpose(self):
+ def transpose(self, _):
return self
- def descr_getitem(self, space, w_idx):
+ def descr_getitem(self, space, _, w_idx):
raise OperationError(space.w_IndexError,
space.wrap("scalars cannot be indexed"))
@@ -65,14 +66,14 @@
raise OperationError(space.w_IndexError,
space.wrap("scalars cannot be indexed"))
- def descr_setitem(self, space, w_idx, w_val):
+ def descr_setitem(self, space, _, w_idx, w_val):
raise OperationError(space.w_IndexError,
space.wrap("scalars cannot be indexed"))
def setitem_index(self, space, idx, w_val):
raise OperationError(space.w_IndexError,
space.wrap("scalars cannot be indexed"))
- def set_shape(self, space, new_shape):
+ def set_shape(self, space, orig_array, new_shape):
if not new_shape:
return self
if support.product(new_shape) == 1:
@@ -83,13 +84,13 @@
raise OperationError(space.w_ValueError, space.wrap(
"total size of the array must be unchanged"))
- def reshape(self, space, new_shape):
- return self.set_shape(space, new_shape)
+ def reshape(self, space, orig_array, new_shape):
+ return self.set_shape(space, orig_array, new_shape)
- def create_axis_iter(self, shape, dim):
+ def create_axis_iter(self, shape, dim, cum):
raise Exception("axis iter should not happen on scalar")
- def swapaxes(self, axis1, axis2):
+ def swapaxes(self, orig_array, axis1, axis2):
raise Exception("should not be called")
def fill(self, w_value):
@@ -98,3 +99,17 @@
def get_storage_as_int(self, space):
raise OperationError(space.w_ValueError,
space.wrap("scalars have no address"))
+
+ def argsort(self, space, w_axis):
+ return space.wrap(0)
+
+ def astype(self, space, dtype):
+ return W_NDimArray.new_scalar(space, dtype, self.value)
+
+ def base(self):
+ return None
+
+ def get_buffer(self, space):
+ raise OperationError(space.w_ValueError, space.wrap(
+ "cannot point buffer to a scalar"))
+
diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/arrayimpl/sort.py
@@ -0,0 +1,195 @@
+
+""" This is the implementation of various sorting routines in numpy. It's here
+because it only makes sense on a concrete array
+"""
+
+from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rlib.listsort import make_timsort_class
+from rpython.rlib.rawstorage import raw_storage_getitem, raw_storage_setitem, \
+ free_raw_storage, alloc_raw_storage
+from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.objectmodel import specialize
+from pypy.interpreter.error import OperationError
+from pypy.module.micronumpy.base import W_NDimArray
+from pypy.module.micronumpy import interp_dtype, types
+from pypy.module.micronumpy.iter import AxisIterator
+
+INT_SIZE = rffi.sizeof(lltype.Signed)
+
+def make_sort_function(space, itemtype, comp_type, count=1):
+ TP = itemtype.T
+ step = rffi.sizeof(TP)
+
+ class Repr(object):
+ def __init__(self, index_stride_size, stride_size, size, values,
+ indexes, index_start, start):
+ self.index_stride_size = index_stride_size
+ self.stride_size = stride_size
+ self.index_start = index_start
+ self.start = start
+ self.size = size
+ self.values = values
+ self.indexes = indexes
+
+ def getitem(self, item):
+ if count < 2:
+ v = raw_storage_getitem(TP, self.values, item * self.stride_size
+ + self.start)
+ else:
+ v = []
+ for i in range(count):
+ _v = raw_storage_getitem(TP, self.values, item * self.stride_size
+ + self.start + step * i)
+ v.append(_v)
+ if comp_type == 'int':
+ v = intmask(v)
+ elif comp_type == 'float':
+ v = float(v)
+ elif comp_type == 'complex':
+ v = [float(v[0]),float(v[1])]
+ else:
+ raise NotImplementedError('cannot reach')
+ return (v, raw_storage_getitem(lltype.Signed, self.indexes,
+ item * self.index_stride_size +
More information about the pypy-commit
mailing list