[pypy-commit] cffi default: Add 'relements' to enum ctypes.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
