[pypy-commit] cffi default: Add 'relements' to enum ctypes.

2012-12-14 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r1097:012670e62732
Date: 2012-12-14 18:19 +0100
http://bitbucket.org/cffi/cffi/changeset/012670e62732/

Log:Add 'relements' to enum ctypes.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -443,6 +443,16 @@
 return nosuchattr("elements");
 }
 
+static PyObject *ctypeget_relements(CTypeDescrObject *ct, void *context)
+{
+if (ct->ct_flags & CT_IS_ENUM) {
+PyObject *res = PyTuple_GetItem(ct->ct_stuff, 0);
+if (res) res = PyDict_Copy(res);
+return res;
+}
+return nosuchattr("relements");
+}
+
 static PyGetSetDef ctypedescr_getsets[] = {
 {"kind", (getter)ctypeget_kind, NULL, "kind"},
 {"cname", (getter)ctypeget_cname, NULL, "C name"},
@@ -454,6 +464,7 @@
 {"ellipsis", (getter)ctypeget_ellipsis, NULL, "function has '...'"},
 {"abi", (getter)ctypeget_abi, NULL, "function ABI"},
 {"elements", (getter)ctypeget_elements, NULL, "enum elements"},
+{"relements", (getter)ctypeget_relements, NULL, "enum elements, reverse"},
 {NULL}/* sentinel */
 };
 
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1276,6 +1276,10 @@
 # 'elements' is not the real dict, but merely a copy
 BEnum.elements[2] = '??'
 assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'}
+#
+BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5))
+assert BEnum.elements == {5: 'ab'}
+assert BEnum.relements == {'ab': 5, 'cd': 5}
 
 def test_cast_to_enum():
 BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Ported cffi/012670e62732

2012-12-14 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r59421:6739201f1220
Date: 2012-12-14 18:24 +0100
http://bitbucket.org/pypy/pypy/changeset/6739201f1220/

Log:Ported cffi/012670e62732

diff --git a/pypy/module/_cffi_backend/ctypeenum.py 
b/pypy/module/_cffi_backend/ctypeenum.py
--- a/pypy/module/_cffi_backend/ctypeenum.py
+++ b/pypy/module/_cffi_backend/ctypeenum.py
@@ -37,6 +37,13 @@
 space.setitem(w_dct, space.wrap(enumvalue),
  space.wrap(enumerator))
 return w_dct
+if attrchar == 'R': # relements
+space = self.space
+w_dct = space.newdict()
+for enumerator, enumvalue in self.enumerators2values.iteritems():
+space.setitem(w_dct, space.wrap(enumerator),
+ space.wrap(enumvalue))
+return w_dct
 return W_CTypePrimitiveSigned._fget(self, attrchar)
 
 def string(self, cdataobj, maxlen):
diff --git a/pypy/module/_cffi_backend/ctypeobj.py 
b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -188,7 +188,7 @@
 if attrchar == 'c': # cname
 return space.wrap(self.name)
 raise operationerrfmt(space.w_AttributeError,
-  "cdata '%s' has no such attribute",
+  "ctype '%s' has no such attribute",
   self.name)
 
 def fget_kind(self, space): return self._fget('k')
@@ -201,6 +201,7 @@
 def fget_ellipsis(self, space): return self._fget('E')
 def fget_abi(self, space):  return self._fget('A')
 def fget_elements(self, space): return self._fget('e')
+def fget_relements(self, space):return self._fget('R')
 
 
 W_CType.typedef = TypeDef(
@@ -218,6 +219,8 @@
 ellipsis = GetSetProperty(W_CType.fget_ellipsis, doc="function has '...'"),
 abi = GetSetProperty(W_CType.fget_abi, doc="function ABI"),
 elements = GetSetProperty(W_CType.fget_elements, doc="enum elements"),
+relements = GetSetProperty(W_CType.fget_relements,
+   doc="enum elements, reversed"),
 __dir__ = interp2app(W_CType.dir),
 )
 W_CType.typedef.acceptable_as_base_class = False
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
@@ -1272,6 +1272,10 @@
 # 'elements' is not the real dict, but merely a copy
 BEnum.elements[2] = '??'
 assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'}
+#
+BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5))
+assert BEnum.elements == {5: 'ab'}
+assert BEnum.relements == {'ab': 5, 'cd': 5}
 
 def test_cast_to_enum():
 BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: fix translation on 32bit

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r59422:c0fb33799a59
Date: 2012-12-14 11:54 -0800
http://bitbucket.org/pypy/pypy/changeset/c0fb33799a59/

Log:fix translation on 32bit

diff --git a/pypy/module/binascii/interp_crc32.py 
b/pypy/module/binascii/interp_crc32.py
--- a/pypy/module/binascii/interp_crc32.py
+++ b/pypy/module/binascii/interp_crc32.py
@@ -71,4 +71,5 @@
 for c in data:
 crc = crc_32_tab[(crc & 0xff) ^ ord(c)] ^ (crc >> 8)
 
-return space.wrap(crc ^ 0x)
+return space.wrap(rffi.cast(rffi.UINT, ~crc))
+
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] cffi default: Document how to indirectly define callbacks using unsupported

2012-12-14 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r1098:448276ce8477
Date: 2012-12-14 21:49 +0100
http://bitbucket.org/cffi/cffi/changeset/448276ce8477/

Log:Document how to indirectly define callbacks using unsupported
features

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -963,11 +963,36 @@
 the callback to remain valid forever, store the object in a fresh global
 variable somewhere.)
 
-Note that callbacks of a variadic function type are not supported.
+Note that callbacks of a variadic function type are not supported.  A
+workaround is to add custom C code.  In the following example, a
+callback gets a first argument that counts how many extra ``int``
+arguments are passed::
+
+ffi.cdef("""
+int (*python_callback)(int how_many, int *values);
+void *const c_callback;   /* pass this ptr to C routines */
+""")
+lib = ffi.verify("""
+#include 
+#include 
+static int (*python_callback)(int how_many, int *values);
+static int c_callback(int how_many, ...) {
+va_list ap;
+/* collect the "..." arguments into the values[] array */
+int i, *values = alloca(how_many * sizeof(int));
+va_start(ap, how_many);
+for (i=0; i
+#include 
+static int (*python_callback)(int how_many, int *values);
+static int c_callback(int how_many, ...) {
+va_list ap;
+/* collect the "..." arguments into the values[] array */
+int i, *values = alloca(how_many * sizeof(int));
+va_start(ap, how_many);
+for (i=0; ihttp://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Change the Makefile to contain "-Os" instead of "-O3" on Linux. It

2012-12-14 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r59423:6df0aaf4caf2
Date: 2012-12-14 23:47 +0100
http://bitbucket.org/pypy/pypy/changeset/6df0aaf4caf2/

Log:Change the Makefile to contain "-Os" instead of "-O3" on Linux. It
seems to give executables that are a bit faster, and definitely
smaller.

diff --git a/pypy/translator/platform/linux.py 
b/pypy/translator/platform/linux.py
--- a/pypy/translator/platform/linux.py
+++ b/pypy/translator/platform/linux.py
@@ -13,7 +13,8 @@
  + os.environ.get('LDFLAGS', '').split())
 extra_libs = ('-lrt',)
 cflags = tuple(
- ['-O3', '-pthread', '-fomit-frame-pointer',
+ ['-Os',   # more compact and actually a bit faster
+  '-pthread', '-fomit-frame-pointer',
   '-Wall', '-Wno-unused']
  + os.environ.get('CFLAGS', '').split())
 standalone_only = ()
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: readd rfloat tests that seem to have been mistakenly removed in d7a6c72

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: 
Changeset: r59424:c05f096eebc9
Date: 2012-12-14 15:03 -0800
http://bitbucket.org/pypy/pypy/changeset/c05f096eebc9/

Log:readd rfloat tests that seem to have been mistakenly removed in
d7a6c72

diff --git a/pypy/rpython/test/test_rfloat.py b/pypy/rpython/test/test_rfloat.py
--- a/pypy/rpython/test/test_rfloat.py
+++ b/pypy/rpython/test/test_rfloat.py
@@ -215,6 +215,165 @@
 # https://bugzilla.novell.com/show_bug.cgi?id=692493
 assert not self.interpret(fn, [1e200, 1e200]) # nan
 
+def test_break_up_float(self):
+from pypy.rlib.rfloat import break_up_float
+assert break_up_float('1') == ('', '1', '', '')
+assert break_up_float('+1') == ('+', '1', '', '')
+assert break_up_float('-1') == ('-', '1', '', '')
+
+assert break_up_float('.5') == ('', '', '5', '')
+
+assert break_up_float('1.2e3') == ('', '1', '2', '3')
+assert break_up_float('1.2e+3') == ('', '1', '2', '+3')
+assert break_up_float('1.2e-3') == ('', '1', '2', '-3')
+
+# some that will get thrown out on return:
+assert break_up_float('.') == ('', '', '', '')
+assert break_up_float('+') == ('+', '', '', '')
+assert break_up_float('-') == ('-', '', '', '')
+assert break_up_float('e1') == ('', '', '', '1')
+
+raises(ValueError, break_up_float, 'e')
+
+def test_formatd(self):
+from pypy.rlib.rfloat import formatd
+def f(x):
+return formatd(x, 'f', 2, 0)
+res = self.ll_to_string(self.interpret(f, [10/3.0]))
+assert res == '3.33'
+
+def test_formatd_repr(self):
+from pypy.rlib.rfloat import formatd
+def f(x):
+return formatd(x, 'r', 0, 0)
+res = self.ll_to_string(self.interpret(f, [1.1]))
+assert res == '1.1'
+
+def test_formatd_huge(self):
+from pypy.rlib.rfloat import formatd
+def f(x):
+return formatd(x, 'f', 1234, 0)
+res = self.ll_to_string(self.interpret(f, [1.0]))
+assert res == '1.' + 1234 * '0'
+
+def test_formatd_F(self):
+from pypy.translator.c.test.test_genc import compile
+from pypy.rlib.rfloat import formatd
+
+def func(x):
+# Test the %F format, which is not supported by
+# the Microsoft's msvcrt library.
+return formatd(x, 'F', 4)
+
+f = compile(func, [float])
+assert f(10/3.0) == '3.'
+
+def test_parts_to_float(self):
+from pypy.rlib.rfloat import parts_to_float, break_up_float
+def f(x):
+if x == 0:
+s = '1.0'
+else:
+s = '1e-100'
+sign, beforept, afterpt, expt = break_up_float(s)
+return parts_to_float(sign, beforept, afterpt, expt)
+res = self.interpret(f, [0])
+assert res == 1.0
+
+res = self.interpret(f, [1])
+assert res == 1e-100
+
+def test_string_to_float(self):
+from pypy.rlib.rfloat import rstring_to_float
+def func(x):
+if x == 0:
+s = '1e23'
+else:
+s = '-1e23'
+return rstring_to_float(s)
+
+assert self.interpret(func, [0]) == 1e23
+assert self.interpret(func, [1]) == -1e23
+
+def test_copysign(self):
+from pypy.rlib.rfloat import copysign
+assert copysign(1, 1) == 1
+assert copysign(-1, 1) == 1
+assert copysign(-1, -1) == -1
+assert copysign(1, -1) == -1
+assert copysign(1, -0.) == -1
+
+def test_round_away(self):
+from pypy.rlib.rfloat import round_away
+assert round_away(.1) == 0.
+assert round_away(.5) == 1.
+assert round_away(.7) == 1.
+assert round_away(1.) == 1.
+assert round_away(-.5) == -1.
+assert round_away(-.1) == 0.
+assert round_away(-.7) == -1.
+assert round_away(0.) == 0.
+
+def test_round_double(self):
+from pypy.rlib.rfloat import round_double
+def almost_equal(x, y):
+assert round(abs(x-y), 7) == 0
+
+almost_equal(round_double(0.125, 2), 0.13)
+almost_equal(round_double(0.375, 2), 0.38)
+almost_equal(round_double(0.625, 2), 0.63)
+almost_equal(round_double(0.875, 2), 0.88)
+almost_equal(round_double(-0.125, 2), -0.13)
+almost_equal(round_double(-0.375, 2), -0.38)
+almost_equal(round_double(-0.625, 2), -0.63)
+almost_equal(round_double(-0.875, 2), -0.88)
+
+almost_equal(round_double(0.25, 1), 0.3)
+almost_equal(round_double(0.75, 1), 0.8)
+almost_equal(round_double(-0.25, 1), -0.3)
+almost_equal(round_double(-0.75, 1), -0.8)
+
+round_double(-6.5, 0) == -7.0
+round_double(-5.5, 0) == -6.0
+round_double(-1.5, 0) == -2.0
+round_double(-0.5, 0) == -1.0
+round_double(0.5, 0) == 1.0
+

[pypy-commit] pypy default: add a half even rounding mode to round_double for py3k

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: 
Changeset: r59425:1fce20d13b3c
Date: 2012-12-14 16:03 -0800
http://bitbucket.org/pypy/pypy/changeset/1fce20d13b3c/

Log:add a half even rounding mode to round_double for py3k

diff --git a/pypy/rlib/rfloat.py b/pypy/rlib/rfloat.py
--- a/pypy/rlib/rfloat.py
+++ b/pypy/rlib/rfloat.py
@@ -170,13 +170,17 @@
 result = formatd(value, tp, precision, flags)
 return result, special
 
-def round_double(value, ndigits):
+def round_double(value, ndigits, half_even=False):
+"""Round a float half away from zero.
+
+Specify half_even=True to round half even instead.
+"""
 if USE_SHORT_FLOAT_REPR:
-return round_double_short_repr(value, ndigits)
+return round_double_short_repr(value, ndigits, half_even)
 else:
-return round_double_fallback_repr(value, ndigits)
+return round_double_fallback_repr(value, ndigits, half_even)
 
-def round_double_short_repr(value, ndigits):
+def round_double_short_repr(value, ndigits, half_even):
 # The basic idea is very simple: convert and round the double to
 # a decimal string using _Py_dg_dtoa, then convert that decimal
 # string back to a double with _Py_dg_strtod.  There's one minor
@@ -209,7 +213,7 @@
 
 # determine whether this is a halfway case.
 halfway_case = 0
-if expo == -ndigits - 1:
+if not half_even and expo == -ndigits - 1:
 if ndigits >= 0:
 halfway_case = 1
 elif ndigits >= -22:
@@ -224,7 +228,7 @@
 # round to a decimal string; use an extra place for halfway case
 strvalue = formatd(value, 'f', ndigits + halfway_case)
 
-if halfway_case:
+if not half_even and halfway_case:
 buf = [c for c in strvalue]
 if ndigits >= 0:
 endpos = len(buf) - 1
@@ -263,7 +267,7 @@
 
 # fallback version, to be used when correctly rounded
 # binary<->decimal conversions aren't available
-def round_double_fallback_repr(value, ndigits):
+def round_double_fallback_repr(value, ndigits, half_even):
 if ndigits >= 0:
 if ndigits > 22:
 # pow1 and pow2 are each safe from overflow, but
@@ -284,12 +288,17 @@
 pow2 = 1.0 # unused; for translation
 y = value / pow1
 
-if y >= 0.0:
-z = math.floor(y + 0.5)
+if half_even:
+z = round_away(y)
+if math.fabs(y - z) == 0.5:
+z = 2.0 * round_away(y / 2.0)
 else:
-z = math.ceil(y - 0.5)
-if math.fabs(y-z) == 1.0:   # obscure case, see the test
-z = y
+if y >= 0.0:
+z = math.floor(y + 0.5)
+else:
+z = math.ceil(y - 0.5)
+if math.fabs(y - z) == 1.0:   # obscure case, see the test
+z = y
 
 if ndigits >= 0:
 z = (z / pow2) / pow1
diff --git a/pypy/rpython/test/test_rfloat.py b/pypy/rpython/test/test_rfloat.py
--- a/pypy/rpython/test/test_rfloat.py
+++ b/pypy/rpython/test/test_rfloat.py
@@ -374,6 +374,15 @@
 almost_equal(round_double(0.5e22, -22), 1e22)
 almost_equal(round_double(1.5e22, -22), 2e22)
 
+def test_round_half_even(self):
+from pypy.rlib import rfloat
+for func in (rfloat.round_double_short_repr,
+ rfloat.round_double_fallback_repr):
+# 2.x behavior
+assert func(2.5, 0, False) == 3.0
+# 3.x behavior
+assert func(2.5, 0, True) == 2.0
+
 
 class TestLLtype(BaseTestRfloat, LLRtypeMixin):
 
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: merge default

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r59426:c0aed73821fb
Date: 2012-12-14 16:12 -0800
http://bitbucket.org/pypy/pypy/changeset/c0aed73821fb/

Log:merge default

diff --git a/pypy/module/_cffi_backend/ctypeenum.py 
b/pypy/module/_cffi_backend/ctypeenum.py
--- a/pypy/module/_cffi_backend/ctypeenum.py
+++ b/pypy/module/_cffi_backend/ctypeenum.py
@@ -37,6 +37,13 @@
 space.setitem(w_dct, space.wrap(enumvalue),
  space.wrap(enumerator))
 return w_dct
+if attrchar == 'R': # relements
+space = self.space
+w_dct = space.newdict()
+for enumerator, enumvalue in self.enumerators2values.iteritems():
+space.setitem(w_dct, space.wrap(enumerator),
+ space.wrap(enumvalue))
+return w_dct
 return W_CTypePrimitiveSigned._fget(self, attrchar)
 
 def string(self, cdataobj, maxlen):
diff --git a/pypy/module/_cffi_backend/ctypeobj.py 
b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -188,7 +188,7 @@
 if attrchar == 'c': # cname
 return space.wrap(self.name)
 raise operationerrfmt(space.w_AttributeError,
-  "cdata '%s' has no such attribute",
+  "ctype '%s' has no such attribute",
   self.name)
 
 def fget_kind(self, space): return self._fget('k')
@@ -201,6 +201,7 @@
 def fget_ellipsis(self, space): return self._fget('E')
 def fget_abi(self, space):  return self._fget('A')
 def fget_elements(self, space): return self._fget('e')
+def fget_relements(self, space):return self._fget('R')
 
 
 W_CType.typedef = TypeDef(
@@ -218,6 +219,8 @@
 ellipsis = GetSetProperty(W_CType.fget_ellipsis, doc="function has '...'"),
 abi = GetSetProperty(W_CType.fget_abi, doc="function ABI"),
 elements = GetSetProperty(W_CType.fget_elements, doc="enum elements"),
+relements = GetSetProperty(W_CType.fget_relements,
+   doc="enum elements, reversed"),
 __dir__ = interp2app(W_CType.dir),
 )
 W_CType.typedef.acceptable_as_base_class = False
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
@@ -1272,6 +1272,10 @@
 # 'elements' is not the real dict, but merely a copy
 BEnum.elements[2] = '??'
 assert BEnum.elements == {-20: 'ab', 0: 'def', 1: 'c'}
+#
+BEnum = new_enum_type("bar", ('ab', 'cd'), (5, 5))
+assert BEnum.elements == {5: 'ab'}
+assert BEnum.relements == {'ab': 5, 'cd': 5}
 
 def test_cast_to_enum():
 BEnum = new_enum_type("foo", ('def', 'c', 'ab'), (0, 1, -20))
diff --git a/pypy/module/math/test/test_direct.py 
b/pypy/module/math/test/test_direct.py
--- a/pypy/module/math/test/test_direct.py
+++ b/pypy/module/math/test/test_direct.py
@@ -72,9 +72,10 @@
 ('exp', (.9,), OverflowError),
 ('pow', (10.0, 4.0), OverflowError),
 ('ldexp', (10.0, 4), OverflowError),
-('log', (0.0,), ValueError),
+('log', (0.0,), ValueError), #cpython does it this way
+('log1p', (-1.0,), OverflowError),
 ('log', (-1.,), ValueError),
-('log10', (0.0,), ValueError),
+('log10', (0.0,), ValueError), #cpython does it this way
 ]
 
 INFCASES = [
diff --git a/pypy/module/math/test/test_math.py 
b/pypy/module/math/test/test_math.py
--- a/pypy/module/math/test/test_math.py
+++ b/pypy/module/math/test/test_math.py
@@ -17,7 +17,8 @@
 if type(expected) is type and issubclass(expected, Exception):
 expected = getattr(space, "w_%s" % expected.__name__)
 elif callable(expected):
-expected = cls.make_callable_wrapper(expected)
+if not cls.runappdirect:
+expected = cls.make_callable_wrapper(expected)
 else:
 expected = space.wrap(expected)
 cases.append(space.newtuple([space.wrap(a), space.wrap(b), 
expected]))
diff --git a/pypy/module/micronumpy/test/test_complex.py 
b/pypy/module/micronumpy/test/test_complex.py
--- a/pypy/module/micronumpy/test/test_complex.py
+++ b/pypy/module/micronumpy/test/test_complex.py
@@ -94,30 +94,42 @@
 cls.w_testcases128 = cls.space.wrap(list(parse_testfile(fname128)))
 cls.w_testcases64 = cls.space.wrap(list(parse_testfile(fname64)))
 
-def cls_c_pow(space, args_w):
-try:
-retVal = c_pow(*map(space.unwrap, args_w))
-return space.wrap(retVal)
-except ValueError, e:
-if option.runappdirect:
-raise
-raise OperationError(cls.space.w_Val

[pypy-commit] pypy py3k: adapt to ll_math now matching 2.x's log1p OverflowError case

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r59427:293521d40d29
Date: 2012-12-14 17:19 -0800
http://bitbucket.org/pypy/pypy/changeset/293521d40d29/

Log:adapt to ll_math now matching 2.x's log1p OverflowError case

diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py
--- a/pypy/module/math/interp_math.py
+++ b/pypy/module/math/interp_math.py
@@ -394,8 +394,8 @@
 try:
 return math1(space, rfloat.log1p, w_x)
 except OperationError as e:
-# Python 2.x raises a OverflowError improperly.
-if we_are_translated() or not e.match(space, space.w_OverflowError):
+# Python 2.x (and thus ll_math) raises a OverflowError improperly.
+if not e.match(space, space.w_OverflowError):
 raise
 raise OperationError(space.w_ValueError, space.wrap("math domain 
error"))
 
diff --git a/pypy/module/math/test/test_direct.py 
b/pypy/module/math/test/test_direct.py
--- a/pypy/module/math/test/test_direct.py
+++ b/pypy/module/math/test/test_direct.py
@@ -73,7 +73,11 @@
 ('pow', (10.0, 4.0), OverflowError),
 ('ldexp', (10.0, 4), OverflowError),
 ('log', (0.0,), ValueError), #cpython does it this way
+
+# an OverflowError to match 2.x/ll_math, but test_math switches
+# this to ValueError to match 3.x
 ('log1p', (-1.0,), OverflowError),
+
 ('log', (-1.,), ValueError),
 ('log10', (0.0,), ValueError), #cpython does it this way
 ]
diff --git a/pypy/module/math/test/test_math.py 
b/pypy/module/math/test/test_math.py
--- a/pypy/module/math/test/test_math.py
+++ b/pypy/module/math/test/test_math.py
@@ -14,6 +14,11 @@
 space = cls.space
 cases = []
 for a, b, expected in test_direct.MathTests.TESTCASES:
+# marked as OverflowError to match 2.x/ll_math in
+# test_direct, but this is a ValueError on 3.x
+if (a, b, expected) == ('log1p', (-1.0,), OverflowError):
+expected = ValueError
+
 if type(expected) is type and issubclass(expected, Exception):
 expected = getattr(space, "w_%s" % expected.__name__)
 elif callable(expected):
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: py3 floats round half even

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r59429:6719c0d71e7c
Date: 2012-12-14 17:20 -0800
http://bitbucket.org/pypy/pypy/changeset/6719c0d71e7c/

Log:py3 floats round half even

diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py
--- a/pypy/objspace/std/floattype.py
+++ b/pypy/objspace/std/floattype.py
@@ -304,7 +304,7 @@
 return space.wrap(0.0 * x)
 
 # finite x, and ndigits is not unreasonably large
-z = rfloat.round_double(x, ndigits)
+z = rfloat.round_double(x, ndigits, half_even=True)
 if rfloat.isinf(z):
 raise OperationError(space.w_OverflowError,
  space.wrap("overflow occurred during round"))
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
@@ -188,6 +188,7 @@
 assert round(123.456, -700) == 0.0
 assert round(123.456, -2**100) == 0.0
 assert math.copysign(1., round(-123.456, -700)) == -1.
+assert round(2.5, 0) == 2.0
 
 def test_special_float_method(self):
 class a(object):
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: also fix round on floats w/ ndigits=None

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r59428:fe21273988c5
Date: 2012-12-14 17:20 -0800
http://bitbucket.org/pypy/pypy/changeset/fe21273988c5/

Log:also fix round on floats w/ ndigits=None

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
@@ -740,6 +740,7 @@
 raises(TypeError, round, t, 0)
 
 raises(TypeError, round, 3, None)
+raises(TypeError, round, 3.0, None)
 
 def test_vars_obscure_case(self):
 class C_get_vars(object):
diff --git a/pypy/objspace/std/floattype.py b/pypy/objspace/std/floattype.py
--- a/pypy/objspace/std/floattype.py
+++ b/pypy/objspace/std/floattype.py
@@ -272,7 +272,6 @@
 NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103)
 NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103)
 
-@unwrap_spec(w_ndigits=WrappedDefault(None))
 def descr___round__(space, w_float, w_ndigits=None):
 # Algorithm copied directly from CPython
 from pypy.objspace.std.floatobject import W_FloatObject
@@ -280,7 +279,7 @@
 assert isinstance(w_float, W_FloatObject)
 x = w_float.floatval
 
-if space.is_none(w_ndigits):
+if w_ndigits is None:
 # single-argument round: round to nearest integer
 rounded = rfloat.round_away(x)
 if math.fabs(x - rounded) == 0.5:
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3k: pypy doesn't support the optimize compile flag

2012-12-14 Thread pjenvey
Author: Philip Jenvey 
Branch: py3k
Changeset: r59430:bd675fc4cd0b
Date: 2012-12-14 17:27 -0800
http://bitbucket.org/pypy/pypy/changeset/bd675fc4cd0b/

Log:pypy doesn't support the optimize compile flag

diff --git a/lib-python/3.2/test/test_builtin.py 
b/lib-python/3.2/test/test_builtin.py
--- a/lib-python/3.2/test/test_builtin.py
+++ b/lib-python/3.2/test/test_builtin.py
@@ -12,7 +12,8 @@
 import builtins
 import random
 import traceback
-from test.support import fcmp, TESTFN, unlink,  run_unittest, check_warnings
+from test.support import (TESTFN, check_impl_detail, check_warnings, fcmp,
+  run_unittest, unlink)
 from operator import neg
 try:
 import pty, signal
@@ -293,6 +294,8 @@
 self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad')
 
 # test the optimize argument
+if check_impl_detail(pypy=True):
+return
 
 codestr = '''def f():
 """doc"""
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: support isalpha on strings

2012-12-14 Thread alex_gaynor
Author: Alex Gaynor 
Branch: 
Changeset: r59431:ff3a90231b35
Date: 2012-12-14 20:15 -0800
http://bitbucket.org/pypy/pypy/changeset/ff3a90231b35/

Log:support isalpha on strings

diff --git a/pypy/annotation/test/test_annrpython.py 
b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -255,13 +255,6 @@
 assert getcdef(snippet.H).about_attribute('attr') == (
   a.bookkeeper.immutablevalue(1))
 
-def DISABLED_test_knownkeysdict(self):
-# disabled, SomeDict() is now a general {s_key: s_value} dict
-a = self.RPythonAnnotator()
-s = a.build_types(snippet.knownkeysdict, [int])
-# result should be an integer
-assert s.knowntype == int
-
 def test_generaldict(self):
 a = self.RPythonAnnotator()
 s = a.build_types(snippet.generaldict, [str, int, str, int])
@@ -483,6 +476,13 @@
 s = a.build_types(f, [str])
 assert isinstance(s, annmodel.SomeString)
 
+def test_str_isalpha(self):
+def f(s):
+return s.isalpha()
+a = self.RPythonAnnotator()
+s = a.build_types(f, [str])
+assert isinstance(s, annmodel.SomeBool)
+
 def test_simple_slicing(self):
 a = self.RPythonAnnotator()
 s = a.build_types(snippet.simple_slice, [somelist(annmodel.s_Int)])
diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py
--- a/pypy/annotation/unaryop.py
+++ b/pypy/annotation/unaryop.py
@@ -526,7 +526,11 @@
 return SomeString()
 method_encode.can_only_throw = [UnicodeEncodeError]
 
+
 class __extend__(SomeString):
+def method_isalpha(chr):
+return s_Bool
+
 def method_upper(str):
 return SomeString()
 
diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py
--- a/pypy/rpython/rstr.py
+++ b/pypy/rpython/rstr.py
@@ -249,6 +249,12 @@
 hop.exception_cannot_occur()
 return hop.gendirectcall(self.ll.ll_lower, v_str)
 
+def rtype_method_isalpha(self, hop):
+string_repr = hop.args_r[0].repr
+[v_str] = hop.inputargs(string_repr)
+hop.exception_cannot_occur()
+return hop.gendirectcall(self.ll.ll_isalpha, v_str)
+
 def _list_length_items(self, hop, v_lst, LIST):
 """Return two Variables containing the length and items of a
 list. Need to be overriden because it is typesystem-specific."""
@@ -746,6 +752,17 @@
 c = ord(ch)
 return c <= 57 and c >= 48
 
+def ll_isalpha(s):
+from pypy.rpython.annlowlevel import hlstr
+
+s = hlstr(s)
+if not s:
+return False
+for ch in s:
+if not ch.isalpha():
+return False
+return True
+
 def ll_char_isalpha(ch):
 c = ord(ch)
 if c >= 97:
diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py
--- a/pypy/rpython/test/test_rstr.py
+++ b/pypy/rpython/test/test_rstr.py
@@ -138,6 +138,15 @@
 res = self.interpret(fn, [ch])
 assert res == fn(ch)
 
+def test_str_isalpha(self):
+const = self.const
+
+def fn(i):
+consts = [const(''), const('anc'), const('abc123')]
+return consts[i].isalpha()
+for i in xrange(3):
+assert self.interpret(fn, [i]) == fn(i)
+
 def test_char_compare(self):
 const = self.const
 res = self.interpret(lambda c1, c2: c1 == c2,  [const('a'),
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy reflex-support: for by-value returns, there is no reason to cast

2012-12-14 Thread wlav
Author: Wim Lavrijsen 
Branch: reflex-support
Changeset: r59432:bf6fc9a0c114
Date: 2012-12-13 16:15 -0800
http://bitbucket.org/pypy/pypy/changeset/bf6fc9a0c114/

Log:for by-value returns, there is no reason to cast

diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -188,7 +188,7 @@
 from pypy.module.cppyy import interp_cppyy
 long_result = capi.c_call_o(cppmethod, cppthis, num_args, args, 
self.cppclass)
 ptr_result = rffi.cast(capi.C_OBJECT, long_result)
-return interp_cppyy.wrap_cppobject(
+return interp_cppyy.wrap_cppobject_nocast(
 space, space.w_None, self.cppclass, ptr_result, isref=False, 
python_owns=True)
 
 def execute_libffi(self, space, cif_descr, funcaddr, buffer):
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy reflex-support: optimization: prevent copies of TClassRef handles

2012-12-14 Thread wlav
Author: Wim Lavrijsen 
Branch: reflex-support
Changeset: r59433:06e52a567243
Date: 2012-12-13 16:16 -0800
http://bitbucket.org/pypy/pypy/changeset/06e52a567243/

Log:optimization: prevent copies of TClassRef handles

diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx 
b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -173,13 +173,13 @@
 return cppstring_to_cstring(true_name);
 }
 
-static inline TClassRef type_from_handle(cppyy_type_t handle) {
+static inline TClassRef& type_from_handle(cppyy_type_t handle) {
 assert((ClassRefs_t::size_type)handle < g_classrefs.size());
 return g_classrefs[(ClassRefs_t::size_type)handle];
 }
 
 static inline TFunction* type_get_method(cppyy_type_t handle, cppyy_index_t 
idx) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 if (cr.GetClass())
 return (TFunction*)cr->GetListOfMethods()->At(idx);
 return (TFunction*)idx;
@@ -220,7 +220,7 @@
 
 /* name to opaque C++ scope representation  */
 int cppyy_num_scopes(cppyy_scope_t handle) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 if (cr.GetClass()) {
 /* not supported as CINT does not store classes hierarchically */
 return 0;
@@ -229,7 +229,7 @@
 }
 
 char* cppyy_scope_name(cppyy_scope_t handle, int iscope) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 if (cr.GetClass()) {
 /* not supported as CINT does not store classes hierarchically */
 assert(!"scope name lookup not supported on inner scopes");
@@ -278,7 +278,10 @@
 if (icr != g_classref_indices.end())
 return (cppyy_type_t)icr->second;
 
-// use TClass directly, to enable auto-loading
+if (strcmp(scope_name, "#define") == 0)
+return (cppyy_type_t)NULL;
+
+ // use TClass directly, to enable auto-loading
 TClassRef cr(TClass::GetClass(scope_name, kTRUE, kTRUE));
 if (!cr.GetClass())
 return (cppyy_type_t)NULL;
@@ -311,7 +314,7 @@
 }
 
 cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t obj) {
-TClassRef cr = type_from_handle(klass);
+TClassRef& cr = type_from_handle(klass);
 TClass* clActual = cr->GetActualClass( (void*)obj );
 if (clActual && clActual != cr.GetClass()) {
 // TODO: lookup through name should not be needed
@@ -323,7 +326,7 @@
 
 /* memory management -- */
 cppyy_object_t cppyy_allocate(cppyy_type_t handle) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 return (cppyy_object_t)malloc(cr->Size());
 }
 
@@ -332,7 +335,7 @@
 }
 
 void cppyy_destruct(cppyy_type_t handle, cppyy_object_t self) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 cr->Destructor((void*)self, true);
 }
 
@@ -492,7 +495,7 @@
 
 /* scope reflection information --- */
 int cppyy_is_namespace(cppyy_scope_t handle) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 if (cr.GetClass() && cr->GetClassInfo())
 return cr->Property() & G__BIT_ISNAMESPACE;
 if (strcmp(cr.GetClassName(), "") == 0)
@@ -508,7 +511,7 @@
 
 /* type/class reflection information -- */
 char* cppyy_final_name(cppyy_type_t handle) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 if (cr.GetClass() && cr->GetClassInfo()) {
 std::string true_name = G__TypeInfo(cr->GetName()).TrueName();
 std::string::size_type pos = true_name.rfind("::");
@@ -520,7 +523,7 @@
 }
 
 char* cppyy_scoped_final_name(cppyy_type_t handle) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 if (cr.GetClass() && cr->GetClassInfo()) {
 std::string true_name = G__TypeInfo(cr->GetName()).TrueName();
 return cppstring_to_cstring(true_name);
@@ -535,29 +538,29 @@
 }
 
 int cppyy_num_bases(cppyy_type_t handle) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 if (cr.GetClass() && cr->GetListOfBases() != 0)
 return cr->GetListOfBases()->GetSize();
 return 0;
 }
 
 char* cppyy_base_name(cppyy_type_t handle, int base_index) {
-TClassRef cr = type_from_handle(handle);
+TClassRef& cr = type_from_handle(handle);
 TBaseClass* b = (TBaseClass*)cr->GetListOfBases()->At(base_index);
 return type_cppstring_to_cstring(b->GetName());
 }
 
 int cppyy_is_subtype(cppyy_type_t derived_handle, cppyy_type_t base_handle) {
-TClassRef derived_type = type_from_handle(derived_handle);
-TClassRef base_type = type_from_handle(base_handle);
+TClassRef& derived_type = 

[pypy-commit] pypy reflex-support: rework how constructors are used to allow for overloader operator new/delete (albeit that Reflex does not support that, but cling/llvm does)

2012-12-14 Thread wlav
Author: Wim Lavrijsen 
Branch: reflex-support
Changeset: r59434:a3036ea55d22
Date: 2012-12-14 17:13 -0800
http://bitbucket.org/pypy/pypy/changeset/a3036ea55d22/

Log:rework how constructors are used to allow for overloader operator
new/delete (albeit that Reflex does not support that, but cling/llvm
does)

diff --git a/pypy/module/cppyy/capi/__init__.py 
b/pypy/module/cppyy/capi/__init__.py
--- a/pypy/module/cppyy/capi/__init__.py
+++ b/pypy/module/cppyy/capi/__init__.py
@@ -168,7 +168,7 @@
 
 c_constructor = rffi.llexternal(
 "cppyy_constructor",
-[C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], lltype.Void,
+[C_METHOD, C_TYPE, rffi.INT, rffi.VOIDP], C_OBJECT,
 threadsafe=ts_call,
 compilation_info=backend.eci)
 _c_call_o = rffi.llexternal(
diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -137,11 +137,13 @@
 return space.wrap(result)
 
 
-class ConstructorExecutor(VoidExecutor):
+class ConstructorExecutor(FunctionExecutor):
 
-def execute(self, space, cppmethod, cppthis, num_args, args):
-capi.c_constructor(cppmethod, cppthis, num_args, args)
-return space.w_None
+def execute(self, space, cppmethod, cpptype, num_args, args):
+from pypy.module.cppyy import interp_cppyy
+newthis = capi.c_constructor(cppmethod, cpptype, num_args, args)
+assert lltype.typeOf(newthis) == capi.C_OBJECT
+return space.wrap(newthis)
 
 
 class InstancePtrExecutor(FunctionExecutor):
diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h
--- a/pypy/module/cppyy/include/capi.h
+++ b/pypy/module/cppyy/include/capi.h
@@ -42,7 +42,7 @@
 void*  cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args);
 char*  cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args);
 
-void cppyy_constructor(cppyy_method_t method, cppyy_object_t self, int 
nargs, void* args);
+cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t 
klass, int nargs, void* args);
 cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, 
int nargs, void* args, cppyy_type_t result_type);
 
 cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_scope_t scope, 
cppyy_index_t idx);
diff --git a/pypy/module/cppyy/interp_cppyy.py 
b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -373,20 +373,19 @@
 
 
 class CPPConstructor(CPPMethod):
-"""Method dispatcher that constructs new objects. In addition to the call,
-it allocates memory for the newly constructed object and sets ownership
-to Python."""
+"""Method dispatcher that constructs new objects. This method can not have
+a fast path, a the allocation of the object is currently left to the
+reflection layer only, b/c the C++ class may have an overloaded operator
+new, disallowing malloc here."""
 
 _immutable_ = True
 
 def call(self, cppthis, args_w):
-newthis = capi.c_allocate(self.scope)
-assert lltype.typeOf(newthis) == capi.C_OBJECT
-try:
-CPPMethod.call(self, newthis, args_w)
-except:
-capi.c_deallocate(self.scope, newthis)
-raise
+# TODO: these casts are very, very un-pretty; need to find a way of
+# re-using CPPMethod's features w/o these roundabouts
+vscope = rffi.cast(capi.C_OBJECT, self.scope.handle)
+w_result = CPPMethod.call(self, vscope, args_w)
+newthis = rffi.cast(capi.C_OBJECT, self.space.int_w(w_result))
 return wrap_new_cppobject_nocast(
 self.space, self.space.w_None, self.scope, newthis, isref=False, 
python_owns=True)
 
diff --git a/pypy/module/cppyy/src/cintcwrapper.cxx 
b/pypy/module/cppyy/src/cintcwrapper.cxx
--- a/pypy/module/cppyy/src/cintcwrapper.cxx
+++ b/pypy/module/cppyy/src/cintcwrapper.cxx
@@ -451,10 +451,19 @@
 return cppstring_to_cstring("");
 }
 
-void cppyy_constructor(cppyy_method_t method, cppyy_object_t self, int nargs, 
void* args) {
-G__setgvp((long)self);
-cppyy_call_T(method, self, nargs, args);
+cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t handle, 
int nargs, void* args) {
+cppyy_object_t self = (cppyy_object_t)NULL;
+if ((InterpretedFuncs_t::size_type)method >= g_interpreted.size()) {
+G__setgvp((long)G__PVOID);
+self = (cppyy_object_t)cppyy_call_l(method, (cppyy_object_t)NULL, 
nargs, args);
+} else {
+// for macro's/interpreted classes
+self = cppyy_allocate(handle);
+G__setgvp((long)self);
+cppyy_call_T(method, self, nargs, args);
+}
 G__setgvp((long)G__PVOID);
+return self;
 }
 
 cppyy_object_t cppyy_call_o(cppyy_type_t method, cppyy_object_t self, int 
nargs, void* args,
diff --git a/pypy/module/cppyy/src/reflexcwrapper.cxx 
b/

[pypy-commit] pypy reflex-support: merge default into branch

2012-12-14 Thread wlav
Author: Wim Lavrijsen 
Branch: reflex-support
Changeset: r59435:1fe71cc07c8c
Date: 2012-12-14 20:28 -0800
http://bitbucket.org/pypy/pypy/changeset/1fe71cc07c8c/

Log:merge default into branch

diff --git a/pypy/annotation/annrpython.py b/pypy/annotation/annrpython.py
--- a/pypy/annotation/annrpython.py
+++ b/pypy/annotation/annrpython.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
 import types
 from pypy.tool.ansi_print import ansi_log
 from pypy.tool.pairtype import pair
@@ -373,7 +375,12 @@
 # Merge the new 'cells' with each of the block's existing input
 # variables.
 oldcells = [self.binding(a) for a in block.inputargs]
-unions = [annmodel.unionof(c1,c2) for c1, c2 in 
zip(oldcells,inputcells)]
+try:
+unions = [annmodel.unionof(c1,c2) for c1, c2 in 
zip(oldcells,inputcells)]
+except annmodel.UnionError, e:
+e.args = e.args + (
+ErrorWrapper(gather_error(self, graph, block, None)),)
+raise
 # if the merged cells changed, we must redo the analysis
 if unions != oldcells:
 self.bindinputargs(graph, block, unions)
diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py
--- a/pypy/annotation/bookkeeper.py
+++ b/pypy/annotation/bookkeeper.py
@@ -1,6 +1,9 @@
 """
 The Bookkeeper class.
 """
+
+from __future__ import absolute_import
+
 import sys, types, inspect, weakref
 
 from pypy.objspace.flow.model import Constant
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -1,4 +1,6 @@
+from __future__ import absolute_import
 import types, py
+from pypy.annotation.signature import enforce_signature_args, 
enforce_signature_return
 from pypy.objspace.flow.model import Constant, FunctionGraph
 from pypy.objspace.flow.bytecode import cpython_code_signature
 from pypy.objspace.flow.argument import rawshape, ArgErr
@@ -275,12 +277,17 @@
 policy = self.bookkeeper.annotator.policy
 self.specializer = policy.get_specializer(tag)
 enforceargs = getattr(self.pyobj, '_annenforceargs_', None)
+signature = getattr(self.pyobj, '_signature_', None)
+if enforceargs and signature:
+raise Exception("%r: signature and enforceargs cannot both be 
used" % (self,))
 if enforceargs:
 if not callable(enforceargs):
 from pypy.annotation.policy import Sig
 enforceargs = Sig(*enforceargs)
 self.pyobj._annenforceargs_ = enforceargs
 enforceargs(self, inputcells) # can modify inputcells in-place
+if signature:
+enforce_signature_args(self, signature[0], inputcells) # mutates 
inputcells
 if getattr(self.pyobj, '_annspecialcase_', 
'').endswith("call_location"):
 return self.specializer(self, inputcells, op)
 else:
@@ -297,6 +304,10 @@
 new_args = args.unmatch_signature(self.signature, inputcells)
 inputcells = self.parse_arguments(new_args, graph)
 result = schedule(graph, inputcells)
+signature = getattr(self.pyobj, '_signature_', None)
+if signature:
+result = enforce_signature_return(self, signature[1], result)
+self.bookkeeper.annotator.addpendingblock(graph, 
graph.returnblock, [result])
 # Some specializations may break the invariant of returning
 # annotations that are always more general than the previous time.
 # We restore it here:
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -27,6 +27,7 @@
 #\_/
 #
 
+from __future__ import absolute_import
 
 from types import BuiltinFunctionType, MethodType, FunctionType
 import pypy
diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py
--- a/pypy/annotation/signature.py
+++ b/pypy/annotation/signature.py
@@ -1,3 +1,5 @@
+
+from __future__ import absolute_import
 
 import types
 from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\
@@ -128,3 +130,25 @@
  s_arg,
  s_input))
 inputcells[:] = args_s
+
+def finish_type(paramtype, bookkeeper, func):
+from pypy.rlib.types import SelfTypeMarker
+if isinstance(paramtype, SomeObject):
+return paramtype
+elif isinstance(paramtype, SelfTypeMarker):
+raise Exception("%r argument declared as annotation.types.self(); 
class needs decorator rlib.signature.finishsigs()" % (func,))
+else:
+return paramtype(bookkeeper)
+
+def enforce_signature_args(funcdesc, paramtypes, actualtypes):
+assert len(paramtypes) == len(actualtypes)
+params_s = [finish_type(paramtype, funcdesc.bookkeeper, funcde

[pypy-commit] pypy default: isdigit on strings

2012-12-14 Thread alex_gaynor
Author: Alex Gaynor 
Branch: 
Changeset: r59436:e35b7884dcc9
Date: 2012-12-14 20:29 -0800
http://bitbucket.org/pypy/pypy/changeset/e35b7884dcc9/

Log:isdigit on strings

diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py
--- a/pypy/annotation/unaryop.py
+++ b/pypy/annotation/unaryop.py
@@ -528,6 +528,9 @@
 
 
 class __extend__(SomeString):
+def method_isdigit(chr):
+return s_Bool
+
 def method_isalpha(chr):
 return s_Bool
 
@@ -566,12 +569,6 @@
 def method_isspace(chr):
 return s_Bool
 
-def method_isdigit(chr):
-return s_Bool
-
-def method_isalpha(chr):
-return s_Bool
-
 def method_isalnum(chr):
 return s_Bool
 
diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py
--- a/pypy/rpython/rstr.py
+++ b/pypy/rpython/rstr.py
@@ -249,6 +249,12 @@
 hop.exception_cannot_occur()
 return hop.gendirectcall(self.ll.ll_lower, v_str)
 
+def rtype_method_isdigit(self, hop):
+string_repr = hop.args_r[0].repr
+[v_str] = hop.inputargs(string_repr)
+hop.exception_cannot_occur()
+return hop.gendirectcall(self.ll.ll_isdigit, v_str)
+
 def rtype_method_isalpha(self, hop):
 string_repr = hop.args_r[0].repr
 [v_str] = hop.inputargs(string_repr)
@@ -744,13 +750,16 @@
 class AbstractLLHelpers:
 __metaclass__ = StaticMethods
 
-def ll_char_isspace(ch):
-c = ord(ch)
-return c == 32 or (9 <= c <= 13)   # c in (9, 10, 11, 12, 13, 32)
+def ll_isdigit(s):
+from pypy.rpython.annlowlevel import hlstr
 
-def ll_char_isdigit(ch):
-c = ord(ch)
-return c <= 57 and c >= 48
+s = hlstr(s)
+if not s:
+return False
+for ch in s:
+if not ch.isdigit():
+return False
+return True
 
 def ll_isalpha(s):
 from pypy.rpython.annlowlevel import hlstr
@@ -763,6 +772,14 @@
 return False
 return True
 
+def ll_char_isspace(ch):
+c = ord(ch)
+return c == 32 or (9 <= c <= 13)   # c in (9, 10, 11, 12, 13, 32)
+
+def ll_char_isdigit(ch):
+c = ord(ch)
+return c <= 57 and c >= 48
+
 def ll_char_isalpha(ch):
 c = ord(ch)
 if c >= 97:
diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py
--- a/pypy/rpython/test/test_rstr.py
+++ b/pypy/rpython/test/test_rstr.py
@@ -138,6 +138,15 @@
 res = self.interpret(fn, [ch])
 assert res == fn(ch)
 
+def test_isdigit(self):
+const = self.const
+
+def fn(i):
+consts = [const(''), const('anc'), const('abc123'), const('123')]
+return consts[i].isdigit()
+for i in xrange(3):
+assert self.interpret(fn, [i]) == fn(i)
+
 def test_str_isalpha(self):
 const = self.const
 
___
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit