[pypy-commit] pypy gc_no_cleanup_nursery: hg merge default
arigo
noreply at buildbot.pypy.org
Fri Sep 26 09:25:54 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: gc_no_cleanup_nursery
Changeset: r73716:bf10e6f91f1a
Date: 2014-09-26 09:25 +0200
http://bitbucket.org/pypy/pypy/changeset/bf10e6f91f1a/
Log: hg merge default
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -1242,7 +1242,7 @@
(other._hour, other._minute, other._second,
other._microsecond))
if myoff is None or otoff is None:
- raise TypeError("cannot compare naive and aware times")
+ raise TypeError("can't compare offset-naive and offset-aware times")
myhhmm = self._hour * 60 + self._minute - myoff
othhmm = other._hour * 60 + other._minute - otoff
return _cmp((myhhmm, self._second, self._microsecond),
@@ -1838,7 +1838,7 @@
other._hour, other._minute, other._second,
other._microsecond))
if myoff is None or otoff is None:
- raise TypeError("cannot compare naive and aware datetimes")
+ raise TypeError("can't compare offset-naive and offset-aware datetimes")
# XXX What follows could be done more efficiently...
diff = self - other # this will take offsets into account
if diff.days < 0:
@@ -1885,7 +1885,7 @@
if myoff == otoff:
return base
if myoff is None or otoff is None:
- raise TypeError("cannot mix naive and timezone-aware time")
+ raise TypeError("can't subtract offset-naive and offset-aware datetimes")
return base + timedelta(minutes = otoff-myoff)
def __hash__(self):
diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.rst
+++ b/pypy/doc/how-to-release.rst
@@ -38,14 +38,16 @@
no JIT: windows, linux, os/x
sandbox: linux, os/x
+* repackage and upload source tar.bz2 to bitbucket and to cobra, as some packagers
+ prefer a clearly labeled source package
* write release announcement pypy/doc/release-x.y(.z).txt
the release announcement should contain a direct link to the download page
* update pypy.org (under extradoc/pypy.org), rebuild and commit
* post announcement on morepypy.blogspot.com
-* send announcements to pypy-dev, python-list,
+* send announcements to twitter.com, pypy-dev, python-list,
python-announce, python-dev ...
* add a tag on the pypy/jitviewer repo that corresponds to pypy release
* add a tag on the codespeed web site that corresponds to pypy release
-
+* revise versioning at https://readthedocs.org/projects/pypy
diff --git a/pypy/doc/release-2.4.0.rst b/pypy/doc/release-2.4.0.rst
--- a/pypy/doc/release-2.4.0.rst
+++ b/pypy/doc/release-2.4.0.rst
@@ -105,7 +105,7 @@
* Many issues were resolved_ since the 2.3.1 release on June 8
-.. _`whats-new`: http://doc.pypy.org/en/latest/whatsnew-2.3.1.html
+.. _`whats-new`: http://doc.pypy.org/en/latest/whatsnew-2.4.0.html
.. _resolved: https://bitbucket.org/pypy/pypy/issues?status=resolved
.. _sandbox: http://doc.pypy.org/en/latest/sandbox.html
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -407,8 +407,19 @@
--------
numpy.swapaxes : equivalent function
"""
- if self.is_scalar():
+ if axis1 == axis2:
return self
+ n = len(self.get_shape())
+ if n <= 1:
+ return self
+ if axis1 < 0:
+ axis1 += n
+ if axis2 < 0:
+ axis2 += n
+ if axis1 < 0 or axis1 >= n:
+ raise oefmt(space.w_ValueError, "bad axis1 argument to swapaxes")
+ if axis2 < 0 or axis2 >= n:
+ raise oefmt(space.w_ValueError, "bad axis2 argument to swapaxes")
return self.implementation.swapaxes(space, self, axis1, axis2)
def descr_nonzero(self, space):
diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -2020,6 +2020,14 @@
def test_swapaxes(self):
from numpypy import array
+ x = array([])
+ assert x.swapaxes(0, 2) is x
+ x = array([[1, 2]])
+ assert x.swapaxes(0, 0) is x
+ exc = raises(ValueError, x.swapaxes, -3, 0)
+ assert exc.value.message == "bad axis1 argument to swapaxes"
+ exc = raises(ValueError, x.swapaxes, 0, 3)
+ assert exc.value.message == "bad axis2 argument to swapaxes"
# testcases from numpy docstring
x = array([[1, 2, 3]])
assert (x.swapaxes(0, 1) == array([[1], [2], [3]])).all()
diff --git a/pypy/module/select/interp_select.py b/pypy/module/select/interp_select.py
--- a/pypy/module/select/interp_select.py
+++ b/pypy/module/select/interp_select.py
@@ -173,9 +173,9 @@
On Windows, only sockets are supported; on Unix, all file descriptors.
"""
- iwtd_w = space.listview(w_iwtd)
- owtd_w = space.listview(w_owtd)
- ewtd_w = space.listview(w_ewtd)
+ iwtd_w = space.unpackiterable(w_iwtd)
+ owtd_w = space.unpackiterable(w_owtd)
+ ewtd_w = space.unpackiterable(w_ewtd)
if space.is_w(w_timeout, space.w_None):
timeout = -1.0
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -244,6 +244,20 @@
raises(OverflowError, pollster.modify, 1, -1)
raises(OverflowError, pollster.modify, 1, 1 << 64)
+ def test_resize_list_in_select(self):
+ import select
+ class Foo(object):
+ def fileno(self):
+ print len(l)
+ if len(l) < 100:
+ l.append(Foo())
+ return 0
+ l = [Foo()]
+ select.select(l, (), (), 0)
+ assert 1 <= len(l) <= 100
+ # ^^^ CPython gives 100, PyPy gives 1. I think both are OK as
+ # long as there is no crash.
+
class AppTestSelectWithPipes(_AppTestSelect):
"Use a pipe to get pairs of file descriptors"
diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py
--- a/pypy/module/test_lib_pypy/test_datetime.py
+++ b/pypy/module/test_lib_pypy/test_datetime.py
@@ -1,193 +1,221 @@
"""Additional tests for datetime."""
from __future__ import absolute_import
-from lib_pypy import datetime
import py
-def test_repr():
- print datetime
- expected = "datetime.datetime(1, 2, 3, 0, 0)"
- assert repr(datetime.datetime(1,2,3)) == expected
+class BaseTestDatetime:
+ def test_repr(self):
+ print datetime
+ expected = "datetime.datetime(1, 2, 3, 0, 0)"
+ assert repr(datetime.datetime(1,2,3)) == expected
-def test_attributes():
- for x in [datetime.date.today(),
- datetime.time(),
- datetime.datetime.utcnow(),
- datetime.timedelta(),
- datetime.tzinfo()]:
- raises(AttributeError, 'x.abc = 1')
+ def test_attributes(self):
+ for x in [datetime.date.today(),
+ datetime.time(),
+ datetime.datetime.utcnow(),
+ datetime.timedelta(),
+ datetime.tzinfo()]:
+ raises(AttributeError, 'x.abc = 1')
-def test_timedelta_init_long():
- td = datetime.timedelta(microseconds=20000000000000000000)
- assert td.days == 231481481
- assert td.seconds == 41600
- td = datetime.timedelta(microseconds=20000000000000000000.)
- assert td.days == 231481481
- assert td.seconds == 41600
+ def test_timedelta_init_long(self):
+ td = datetime.timedelta(microseconds=20000000000000000000)
+ assert td.days == 231481481
+ assert td.seconds == 41600
+ td = datetime.timedelta(microseconds=20000000000000000000.)
+ assert td.days == 231481481
+ assert td.seconds == 41600
-def test_unpickle():
- e = raises(TypeError, datetime.date, '123')
- assert e.value.args[0] == 'an integer is required'
- e = raises(TypeError, datetime.time, '123')
- assert e.value.args[0] == 'an integer is required'
- e = raises(TypeError, datetime.datetime, '123')
- assert e.value.args[0] == 'an integer is required'
+ def test_unpickle(self):
+ e = raises(TypeError, datetime.date, '123')
+ assert e.value.args[0] == 'an integer is required'
+ e = raises(TypeError, datetime.time, '123')
+ assert e.value.args[0] == 'an integer is required'
+ e = raises(TypeError, datetime.datetime, '123')
+ assert e.value.args[0] == 'an integer is required'
- datetime.time('\x01' * 6, None)
- with raises(TypeError) as e:
- datetime.time('\x01' * 6, 123)
- assert str(e.value) == "bad tzinfo state arg"
+ datetime.time('\x01' * 6, None)
+ with raises(TypeError) as e:
+ datetime.time('\x01' * 6, 123)
+ assert str(e.value) == "bad tzinfo state arg"
- datetime.datetime('\x01' * 10, None)
- with raises(TypeError) as e:
- datetime.datetime('\x01' * 10, 123)
- assert str(e.value) == "bad tzinfo state arg"
+ datetime.datetime('\x01' * 10, None)
+ with raises(TypeError) as e:
+ datetime.datetime('\x01' * 10, 123)
+ assert str(e.value) == "bad tzinfo state arg"
-def test_strptime():
- import time, sys
- if sys.version_info < (2, 6):
- py.test.skip("needs the _strptime module")
+ def test_strptime(self):
+ import time, sys
+ if sys.version_info < (2, 6):
+ py.test.skip("needs the _strptime module")
- string = '2004-12-01 13:02:47'
- format = '%Y-%m-%d %H:%M:%S'
- expected = datetime.datetime(*(time.strptime(string, format)[0:6]))
- got = datetime.datetime.strptime(string, format)
- assert expected == got
+ string = '2004-12-01 13:02:47'
+ format = '%Y-%m-%d %H:%M:%S'
+ expected = datetime.datetime(*(time.strptime(string, format)[0:6]))
+ got = datetime.datetime.strptime(string, format)
+ assert expected == got
-def test_datetime_rounding():
- b = 0.0000001
- a = 0.9999994
+ def test_datetime_rounding(self):
+ b = 0.0000001
+ a = 0.9999994
- assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999
- assert datetime.datetime.utcfromtimestamp(a).second == 0
- a += b
- assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999
- assert datetime.datetime.utcfromtimestamp(a).second == 0
- a += b
- assert datetime.datetime.utcfromtimestamp(a).microsecond == 0
- assert datetime.datetime.utcfromtimestamp(a).second == 1
+ assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999
+ assert datetime.datetime.utcfromtimestamp(a).second == 0
+ a += b
+ assert datetime.datetime.utcfromtimestamp(a).microsecond == 999999
+ assert datetime.datetime.utcfromtimestamp(a).second == 0
+ a += b
+ assert datetime.datetime.utcfromtimestamp(a).microsecond == 0
+ assert datetime.datetime.utcfromtimestamp(a).second == 1
-def test_more_datetime_rounding():
- # this test verified on top of CPython 2.7 (using a plain
- # "import datetime" above)
- expected_results = {
- -1000.0: 'datetime.datetime(1969, 12, 31, 23, 43, 20)',
- -999.9999996: 'datetime.datetime(1969, 12, 31, 23, 43, 20)',
- -999.4: 'datetime.datetime(1969, 12, 31, 23, 43, 20, 600000)',
- -999.0000004: 'datetime.datetime(1969, 12, 31, 23, 43, 21)',
- -1.0: 'datetime.datetime(1969, 12, 31, 23, 59, 59)',
- -0.9999996: 'datetime.datetime(1969, 12, 31, 23, 59, 59)',
- -0.4: 'datetime.datetime(1969, 12, 31, 23, 59, 59, 600000)',
- -0.0000004: 'datetime.datetime(1970, 1, 1, 0, 0)',
- 0.0: 'datetime.datetime(1970, 1, 1, 0, 0)',
- 0.0000004: 'datetime.datetime(1970, 1, 1, 0, 0)',
- 0.4: 'datetime.datetime(1970, 1, 1, 0, 0, 0, 400000)',
- 0.9999996: 'datetime.datetime(1970, 1, 1, 0, 0, 1)',
- 1000.0: 'datetime.datetime(1970, 1, 1, 0, 16, 40)',
- 1000.0000004: 'datetime.datetime(1970, 1, 1, 0, 16, 40)',
- 1000.4: 'datetime.datetime(1970, 1, 1, 0, 16, 40, 400000)',
- 1000.9999996: 'datetime.datetime(1970, 1, 1, 0, 16, 41)',
- 1293843661.191: 'datetime.datetime(2011, 1, 1, 1, 1, 1, 191000)',
- }
- for t in sorted(expected_results):
- dt = datetime.datetime.utcfromtimestamp(t)
- assert repr(dt) == expected_results[t]
+ def test_more_datetime_rounding(self):
+ # this test verified on top of CPython 2.7 (using a plain
+ # "import datetime" above)
+ expected_results = {
+ -1000.0: 'datetime.datetime(1969, 12, 31, 23, 43, 20)',
+ -999.9999996: 'datetime.datetime(1969, 12, 31, 23, 43, 20)',
+ -999.4: 'datetime.datetime(1969, 12, 31, 23, 43, 20, 600000)',
+ -999.0000004: 'datetime.datetime(1969, 12, 31, 23, 43, 21)',
+ -1.0: 'datetime.datetime(1969, 12, 31, 23, 59, 59)',
+ -0.9999996: 'datetime.datetime(1969, 12, 31, 23, 59, 59)',
+ -0.4: 'datetime.datetime(1969, 12, 31, 23, 59, 59, 600000)',
+ -0.0000004: 'datetime.datetime(1970, 1, 1, 0, 0)',
+ 0.0: 'datetime.datetime(1970, 1, 1, 0, 0)',
+ 0.0000004: 'datetime.datetime(1970, 1, 1, 0, 0)',
+ 0.4: 'datetime.datetime(1970, 1, 1, 0, 0, 0, 400000)',
+ 0.9999996: 'datetime.datetime(1970, 1, 1, 0, 0, 1)',
+ 1000.0: 'datetime.datetime(1970, 1, 1, 0, 16, 40)',
+ 1000.0000004: 'datetime.datetime(1970, 1, 1, 0, 16, 40)',
+ 1000.4: 'datetime.datetime(1970, 1, 1, 0, 16, 40, 400000)',
+ 1000.9999996: 'datetime.datetime(1970, 1, 1, 0, 16, 41)',
+ 1293843661.191: 'datetime.datetime(2011, 1, 1, 1, 1, 1, 191000)',
+ }
+ for t in sorted(expected_results):
+ dt = datetime.datetime.utcfromtimestamp(t)
+ assert repr(dt) == expected_results[t]
-def test_utcfromtimestamp():
- """Confirm that utcfromtimestamp and fromtimestamp give consistent results.
+ def test_utcfromtimestamp(self):
+ """Confirm that utcfromtimestamp and fromtimestamp give consistent results.
- Based on danchr's test script in https://bugs.pypy.org/issue986
- """
- import os
- import time
- if os.name == 'nt':
- skip("setting os.environ['TZ'] ineffective on windows")
- try:
- prev_tz = os.environ.get("TZ")
- os.environ["TZ"] = "GMT"
- time.tzset()
- for unused in xrange(100):
- now = time.time()
- delta = (datetime.datetime.utcfromtimestamp(now) -
- datetime.datetime.fromtimestamp(now))
- assert delta.days * 86400 + delta.seconds == 0
- finally:
- if prev_tz is None:
- del os.environ["TZ"]
- else:
- os.environ["TZ"] = prev_tz
- time.tzset()
+ Based on danchr's test script in https://bugs.pypy.org/issue986
+ """
+ import os
+ import time
+ if os.name == 'nt':
+ skip("setting os.environ['TZ'] ineffective on windows")
+ try:
+ prev_tz = os.environ.get("TZ")
+ os.environ["TZ"] = "GMT"
+ time.tzset()
+ for unused in xrange(100):
+ now = time.time()
+ delta = (datetime.datetime.utcfromtimestamp(now) -
+ datetime.datetime.fromtimestamp(now))
+ assert delta.days * 86400 + delta.seconds == 0
+ finally:
+ if prev_tz is None:
+ del os.environ["TZ"]
+ else:
+ os.environ["TZ"] = prev_tz
+ time.tzset()
-def test_utcfromtimestamp_microsecond():
- dt = datetime.datetime.utcfromtimestamp(0)
- assert isinstance(dt.microsecond, int)
+ def test_utcfromtimestamp_microsecond(self):
+ dt = datetime.datetime.utcfromtimestamp(0)
+ assert isinstance(dt.microsecond, int)
-def test_default_args():
- with py.test.raises(TypeError):
- datetime.datetime()
- with py.test.raises(TypeError):
- datetime.datetime(10)
- with py.test.raises(TypeError):
- datetime.datetime(10, 10)
- datetime.datetime(10, 10, 10)
+ def test_default_args(self):
+ with py.test.raises(TypeError):
+ datetime.datetime()
+ with py.test.raises(TypeError):
+ datetime.datetime(10)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10)
+ datetime.datetime(10, 10, 10)
-def test_check_arg_types():
- import decimal
- class Number:
- def __init__(self, value):
- self.value = value
- def __int__(self):
- return self.value
+ def test_check_arg_types(self):
+ import decimal
+ class Number:
+ def __init__(self, value):
+ self.value = value
+ def __int__(self):
+ return self.value
- for xx in [10L,
- decimal.Decimal(10),
- decimal.Decimal('10.9'),
- Number(10),
- Number(10L)]:
- assert datetime.datetime(10, 10, 10, 10, 10, 10, 10) == \
- datetime.datetime(xx, xx, xx, xx, xx, xx, xx)
+ for xx in [10L,
+ decimal.Decimal(10),
+ decimal.Decimal('10.9'),
+ Number(10),
+ Number(10L)]:
+ assert datetime.datetime(10, 10, 10, 10, 10, 10, 10) == \
+ datetime.datetime(xx, xx, xx, xx, xx, xx, xx)
- with py.test.raises(TypeError) as e:
- datetime.datetime(10, 10, '10')
- assert str(e.value) == 'an integer is required'
+ with py.test.raises(TypeError) as e:
+ datetime.datetime(10, 10, '10')
+ assert str(e.value) == 'an integer is required'
- f10 = Number(10.9)
- with py.test.raises(TypeError) as e:
- datetime.datetime(10, 10, f10)
- assert str(e.value) == '__int__ method should return an integer'
+ f10 = Number(10.9)
+ with py.test.raises(TypeError) as e:
+ datetime.datetime(10, 10, f10)
+ assert str(e.value) == '__int__ method should return an integer'
- class Float(float):
- pass
- s10 = Float(10.9)
- with py.test.raises(TypeError) as e:
- datetime.datetime(10, 10, s10)
- assert str(e.value) == 'integer argument expected, got float'
+ class Float(float):
+ pass
+ s10 = Float(10.9)
+ with py.test.raises(TypeError) as e:
+ datetime.datetime(10, 10, s10)
+ assert str(e.value) == 'integer argument expected, got float'
- with py.test.raises(TypeError):
- datetime.datetime(10., 10, 10)
- with py.test.raises(TypeError):
- datetime.datetime(10, 10., 10)
- with py.test.raises(TypeError):
- datetime.datetime(10, 10, 10.)
- with py.test.raises(TypeError):
- datetime.datetime(10, 10, 10, 10.)
- with py.test.raises(TypeError):
- datetime.datetime(10, 10, 10, 10, 10.)
- with py.test.raises(TypeError):
- datetime.datetime(10, 10, 10, 10, 10, 10.)
- with py.test.raises(TypeError):
- datetime.datetime(10, 10, 10, 10, 10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10., 10, 10)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10., 10)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10, 10, 10, 10.)
-def test_utcnow_microsecond():
- import copy
+ def test_utcnow_microsecond(self):
+ import copy
- dt = datetime.datetime.utcnow()
- assert type(dt.microsecond) is int
+ dt = datetime.datetime.utcnow()
+ assert type(dt.microsecond) is int
- copy.copy(dt)
+ copy.copy(dt)
-def test_radd():
- class X(object):
- def __radd__(self, other):
- return "radd"
- assert datetime.date(10, 10, 10) + X() == "radd"
+ def test_radd(self):
+ class X(object):
+ def __radd__(self, other):
+ return "radd"
+ assert datetime.date(10, 10, 10) + X() == "radd"
+
+ def test_raises_if_passed_naive_datetime_and_start_or_end_time_defined(self):
+ class Foo(datetime.tzinfo):
+ def utcoffset(self, dt):
+ return datetime.timedelta(0.1)
+ naive = datetime.datetime(2014, 9, 22)
+ aware = datetime.datetime(2014, 9, 22, tzinfo=Foo())
+ with py.test.raises(TypeError) as e:
+ naive == aware
+ assert str(e.value) == "can't compare offset-naive and offset-aware datetimes"
+ with py.test.raises(TypeError) as e:
+ naive - aware
+ assert str(e.value) == "can't subtract offset-naive and offset-aware datetimes"
+ naive = datetime.time(7, 32, 12)
+ aware = datetime.time(7, 32, 12, tzinfo=Foo())
+ with py.test.raises(TypeError) as e:
+ naive == aware
+ assert str(e.value) == "can't compare offset-naive and offset-aware times"
+
+class TestDatetimeCPython(BaseTestDatetime):
+ def setup_class(cls):
+ global datetime
+ import datetime
+
+class TestDatetimePyPy(BaseTestDatetime):
+ def setup_class(cls):
+ global datetime
+ from lib_pypy import datetime
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -15,6 +15,7 @@
from rpython.rlib.rbigint import rbigint
from rpython.rlib import rfloat
from rpython.tool.sourcetools import func_with_new_name
+from rpython.rtyper.lltypesystem.module.ll_math import math_fmod
from pypy.objspace.std.intobject import W_IntObject
@@ -360,21 +361,17 @@
y = w_float2.floatval
if y == 0.0:
raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float modulo"))
- try:
- mod = math.fmod(x, y)
- except ValueError:
- mod = rfloat.NAN
+ mod = math_fmod(x, y)
+ if mod:
+ # ensure the remainder has the same sign as the denominator
+ if (y < 0.0) != (mod < 0.0):
+ mod += y
else:
- if mod:
- # ensure the remainder has the same sign as the denominator
- if (y < 0.0) != (mod < 0.0):
- mod += y
- else:
- # the remainder is zero, and in the presence of signed zeroes
- # fmod returns different results across platforms; ensure
- # it has the same sign as the denominator; we'd like to do
- # "mod = y * 0.0", but that may get optimized away
- mod = copysign(0.0, y)
+ # the remainder is zero, and in the presence of signed zeroes
+ # fmod returns different results across platforms; ensure
+ # it has the same sign as the denominator; we'd like to do
+ # "mod = y * 0.0", but that may get optimized away
+ mod = copysign(0.0, y)
return W_FloatObject(mod)
@@ -383,10 +380,7 @@
y = w_float2.floatval
if y == 0.0:
raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float modulo"))
- try:
- mod = math.fmod(x, y)
- except ValueError:
- return [W_FloatObject(rfloat.NAN), W_FloatObject(rfloat.NAN)]
+ mod = math_fmod(x, y)
# fmod is typically exact, so vx-mod is *mathematically* an
# exact multiple of wx. But this is fp arithmetic, and fp
# vx - mod is an approximation; the result is that div may
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -580,11 +580,11 @@
elif self._thousands_sep:
dec = "."
thousands = ","
- grouping = "\3\0"
+ grouping = "\3"
else:
dec = "."
thousands = ""
- grouping = "\256"
+ grouping = "\xFF" # special value to mean 'stop'
if self.is_unicode:
self._loc_dec = dec.decode("ascii")
self._loc_thousands = thousands.decode("ascii")
@@ -677,14 +677,16 @@
done = False
previous = 0
while True:
- group = ord(grouping[grouping_state])
- if group > 0:
- if group == 256:
+ if grouping_state >= len(grouping):
+ group = previous # end of string
+ else:
+ # else, get the next value from the string
+ group = ord(grouping[grouping_state])
+ if group == 0xFF: # special value to mean 'stop'
break
grouping_state += 1
previous = group
- else:
- group = previous
+ #
final_grouping = min(group, max(left, max(min_width, 1)))
n_zeros = max(0, final_grouping - left)
n_chars = max(0, min(left, final_grouping))
diff --git a/pypy/objspace/std/test/test_floatobject.py b/pypy/objspace/std/test/test_floatobject.py
--- a/pypy/objspace/std/test/test_floatobject.py
+++ b/pypy/objspace/std/test/test_floatobject.py
@@ -794,7 +794,7 @@
raises(ValueError, float.fromhex, "0P")
def test_division_edgecases(self):
- import math
+ import math, os
# inf
inf = float("inf")
@@ -803,6 +803,16 @@
x, y = divmod(inf, 3)
assert math.isnan(x)
assert math.isnan(y)
+ x, y = divmod(3, inf)
+ z = 3 % inf
+ if os.name == 'nt':
+ assert math.isnan(x)
+ assert math.isnan(y)
+ assert math.isnan(z)
+ else:
+ assert x == 0
+ assert y == 3
+ assert z == 3
# divide by 0
raises(ZeroDivisionError, lambda: inf % 0)
diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -372,6 +372,7 @@
try:
assert locale.format('%g', x, grouping=True) == '1,234.57'
assert format(x, 'n') == '1,234.57'
+ assert format(12345678901234, 'n') == '12,345,678,901,234'
finally:
locale.setlocale(locale.LC_NUMERIC, 'C')
diff --git a/pypy/sandbox/pypy_interact.py b/pypy/sandbox/pypy_interact.py
--- a/pypy/sandbox/pypy_interact.py
+++ b/pypy/sandbox/pypy_interact.py
@@ -55,7 +55,7 @@
return Dir({
'bin': Dir({
- 'pypy-c': RealFile(self.executable),
+ 'pypy-c': RealFile(self.executable, mode=0111),
'lib-python': RealDir(os.path.join(libroot, 'lib-python'),
exclude=exclude),
'lib_pypy': RealDir(os.path.join(libroot, 'lib_pypy'),
diff --git a/rpython/translator/backendopt/storesink.py b/rpython/translator/backendopt/storesink.py
--- a/rpython/translator/backendopt/storesink.py
+++ b/rpython/translator/backendopt/storesink.py
@@ -1,6 +1,8 @@
from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.flowspace.model import mkentrymap, Variable
from rpython.translator.backendopt import removenoops
+from rpython.translator import simplify
def has_side_effects(op):
if op.opname == 'debug_assert':
@@ -10,38 +12,86 @@
except AttributeError:
return True
+
def storesink_graph(graph):
+ """ remove superfluous getfields. use a super-local method: all non-join
+ blocks inherit the heap information from their (single) predecessor
+ """
+ added_some_same_as = False
+ entrymap = mkentrymap(graph)
+ # all merge blocks are starting points
+ todo = [(block, None, None) for (block, prev_blocks) in entrymap.iteritems()
+ if len(prev_blocks) > 1 or block is graph.startblock]
+
+ visited = 0
+
+ while todo:
+ block, cache, inputlink = todo.pop()
+ visited += 1
+ if cache is None:
+ cache = {}
+
+ if block.operations:
+ changed_block = _storesink_block(block, cache, inputlink)
+ added_some_same_as = changed_block or added_some_same_as
+ for link in block.exits:
+ if len(entrymap[link.target]) == 1:
+ new_cache = _translate_cache(cache, link)
+ todo.append((link.target, new_cache, link))
+
+ assert visited == len(entrymap)
+ if added_some_same_as:
+ removenoops.remove_same_as(graph)
+ simplify.transform_dead_op_vars(graph)
+
+def _translate_cache(cache, link):
+ if link.target.operations == (): # exit or except block:
+ return {}
+ block = link.target
+ local_versions = {var1: var2 for var1, var2 in zip(link.args, block.inputargs)}
+ def _translate_arg(arg):
+ if isinstance(arg, Variable):
+ res = local_versions.get(arg, None)
+ if res is None:
+ res = Variable(arg)
+ res.concretetype = arg.concretetype
+ link.args.append(arg)
+ block.inputargs.append(res)
+ local_versions[arg] = res
+ return res
+ else:
+ return arg
+ new_cache = {}
+ for (var, field), res in cache.iteritems():
+ if var in local_versions or not isinstance(var, Variable):
+ new_cache[_translate_arg(var), field] = _translate_arg(res)
+ return new_cache
+
+def _storesink_block(block, cache, inputlink):
def clear_cache_for(cache, concretetype, fieldname):
for k in cache.keys():
if k[0].concretetype == concretetype and k[1] == fieldname:
del cache[k]
added_some_same_as = False
-
- for block in graph.iterblocks():
- newops = []
- cache = {}
- for op in block.operations:
- if op.opname == 'getfield':
- tup = (op.args[0], op.args[1].value)
- res = cache.get(tup, None)
- if res is not None:
- op.opname = 'same_as'
- op.args = [res]
- added_some_same_as = True
- else:
- cache[tup] = op.result
- elif op.opname in ['setarrayitem', 'setinteriorfield']:
- pass
- elif op.opname == 'setfield':
- clear_cache_for(cache, op.args[0].concretetype,
- op.args[1].value)
- elif has_side_effects(op):
- cache = {}
- newops.append(op)
- if block.operations:
- block.operations = newops
-
- if added_some_same_as:
- removenoops.remove_same_as(graph)
+ for op in block.operations:
+ if op.opname == 'getfield':
+ tup = (op.args[0], op.args[1].value)
+ res = cache.get(tup, None)
+ if res is not None:
+ op.opname = 'same_as'
+ op.args = [res]
+ added_some_same_as = True
+ else:
+ cache[tup] = op.result
+ elif op.opname in ('setarrayitem', 'setinteriorfield', "malloc", "malloc_varsize"):
+ pass
+ elif op.opname == 'setfield':
+ target = op.args[0]
+ field = op.args[1].value
+ clear_cache_for(cache, target.concretetype, field)
+ cache[target, field] = op.args[2]
+ elif has_side_effects(op):
+ cache.clear()
+ return added_some_same_as
diff --git a/rpython/translator/backendopt/test/test_storesink.py b/rpython/translator/backendopt/test/test_storesink.py
--- a/rpython/translator/backendopt/test/test_storesink.py
+++ b/rpython/translator/backendopt/test/test_storesink.py
@@ -42,7 +42,7 @@
a.x = i
return a.x
- self.check(f, [int], 1)
+ self.check(f, [int], 0)
def test_simple(self):
class A(object):
@@ -53,7 +53,7 @@
a.x = i
return a.x + a.x
- self.check(f, [int], 1)
+ self.check(f, [int], 0)
def test_irrelevant_setfield(self):
class A(object):
@@ -67,7 +67,7 @@
two = a.x
return one + two
- self.check(f, [int], 1)
+ self.check(f, [int], 0)
def test_relevant_setfield(self):
class A(object):
@@ -101,7 +101,7 @@
two = a.x
return one + two
- self.check(f, [int], 1)
+ self.check(f, [int], 0)
def test_subclass(self):
class A(object):
@@ -119,7 +119,7 @@
two = a.x
return one + two
- self.check(f, [int], 2)
+ self.check(f, [int], 1)
def test_bug_1(self):
class A(object):
@@ -133,4 +133,37 @@
return True
return n
- self.check(f, [int], 1)
+ self.check(f, [int], 0)
+
+
+ def test_cfg_splits(self):
+ class A(object):
+ pass
+
+ def f(i):
+ a = A()
+ j = i
+ for i in range(i):
+ a.x = i
+ if i:
+ j = a.x + a.x
+ else:
+ j = a.x * 5
+ return j
+
+ self.check(f, [int], 0)
+
+ def test_malloc_does_not_invalidate(self):
+ class A(object):
+ pass
+ class B(object):
+ pass
+
+ def f(i):
+ a = A()
+ a.x = i
+ b = B()
+ return a.x
+
+ self.check(f, [int], 0)
+
diff --git a/rpython/translator/sandbox/sandlib.py b/rpython/translator/sandbox/sandlib.py
--- a/rpython/translator/sandbox/sandlib.py
+++ b/rpython/translator/sandbox/sandlib.py
@@ -459,6 +459,15 @@
do_ll_os__ll_os_lstat = do_ll_os__ll_os_stat
+ def do_ll_os__ll_os_access(self, vpathname, mode):
+ try:
+ node = self.get_node(vpathname)
+ except OSError, e:
+ if e.errno == errno.ENOENT:
+ return False
+ raise
+ return node.access(mode)
+
def do_ll_os__ll_os_isatty(self, fd):
return self.virtual_console_isatty and fd in (0, 1, 2)
diff --git a/rpython/translator/sandbox/test/test_vfs.py b/rpython/translator/sandbox/test/test_vfs.py
--- a/rpython/translator/sandbox/test/test_vfs.py
+++ b/rpython/translator/sandbox/test/test_vfs.py
@@ -33,6 +33,8 @@
py.test.raises(OSError, d.join, 'bar')
st = d.stat()
assert stat.S_ISDIR(st.st_mode)
+ assert d.access(os.R_OK | os.X_OK)
+ assert not d.access(os.W_OK)
def test_file():
f = File('hello world')
@@ -46,6 +48,8 @@
st = f.stat()
assert stat.S_ISREG(st.st_mode)
assert st.st_size == 11
+ assert f.access(os.R_OK)
+ assert not f.access(os.W_OK)
def test_realdir_realfile():
for show_dotfiles in [False, True]:
@@ -78,6 +82,7 @@
f = v_test_vfs.join('symlink2')
assert stat.S_ISREG(f.stat().st_mode)
+ assert f.access(os.R_OK)
assert f.open().read() == 'secret'
else:
py.test.raises(OSError, v_test_vfs.join, 'symlink1')
diff --git a/rpython/translator/sandbox/vfs.py b/rpython/translator/sandbox/vfs.py
--- a/rpython/translator/sandbox/vfs.py
+++ b/rpython/translator/sandbox/vfs.py
@@ -22,7 +22,7 @@
st_size = self.getsize()
st_mode = self.kind
st_mode |= stat.S_IWUSR | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
- if self.kind == stat.S_IFDIR:
+ if stat.S_ISDIR(self.kind):
st_mode |= stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
if self.read_only:
st_uid = 0 # read-only files are virtually owned by root
@@ -37,6 +37,15 @@
(st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,
st_size, st_atime, st_mtime, st_ctime))
+ def access(self, mode):
+ s = self.stat()
+ e_mode = s.st_mode & stat.S_IRWXO
+ if UID == s.st_uid:
+ e_mode |= (s.st_mode & stat.S_IRWXU) >> 6
+ if GID == s.st_gid:
+ e_mode |= (s.st_mode & stat.S_IRWXG) >> 3
+ return (e_mode & mode) == mode
+
def keys(self):
raise OSError(errno.ENOTDIR, self)
@@ -114,8 +123,9 @@
return cStringIO.StringIO(self.data)
class RealFile(File):
- def __init__(self, path):
+ def __init__(self, path, mode=0):
self.path = path
+ self.kind |= mode
def __repr__(self):
return '<RealFile %s>' % (self.path,)
def getsize(self):
More information about the pypy-commit
mailing list