Commits

wlav  committed 1fe71cc Merge

merge default into branch

  • Participants
  • Parent commits a3036ea, 1fce20d
  • Branches reflex-support

Comments (0)

Files changed (33)

File pypy/annotation/annrpython.py

+from __future__ import absolute_import
+
 import types
 from pypy.tool.ansi_print import ansi_log
 from pypy.tool.pairtype import pair
         # 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)

File pypy/annotation/bookkeeper.py

 """
 The Bookkeeper class.
 """
+
+from __future__ import absolute_import
+
 import sys, types, inspect, weakref
 
 from pypy.objspace.flow.model import Constant

File pypy/annotation/description.py

+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
             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:
             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:

File pypy/annotation/model.py

 #    \_____________________________________________________/
 #
 
+from __future__ import absolute_import
 
 from types import BuiltinFunctionType, MethodType, FunctionType
 import pypy

File pypy/annotation/signature.py

+
+from __future__ import absolute_import
 
 import types
 from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\
                                              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, funcdesc.pyobj) for paramtype in paramtypes]
+    for i, (s_param, s_actual) in enumerate(zip(params_s, actualtypes)):
+        if not s_param.contains(s_actual):
+            raise Exception("%r argument %d:\n"
+                            "expected %s,\n"
+                            "     got %s" % (funcdesc, i+1, s_param, s_actual))
+    actualtypes[:] = params_s
+
+def enforce_signature_return(funcdesc, sigtype, inferredtype):
+    return finish_type(sigtype, funcdesc.bookkeeper, funcdesc.pyobj)

File pypy/annotation/unaryop.py

 Unary operations on SomeValues.
 """
 
+from __future__ import absolute_import
+
 from types import MethodType
 from pypy.annotation.model import \
      SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \

File pypy/doc/faq.rst

 .. _JVM: translation.html#genjvm
 .. _`translation document`: translation.html
 
+------------------
+Could we use LLVM?
+------------------
+
+In theory yes.  But we tried to use it 5 or 6 times already, as a
+translation backend or as a JIT backend --- and failed each time.
+
+In more details: using LLVM as a (static) translation backend is
+pointless nowadays because you can generate C code and compile it with
+clang.  (Note that compiling PyPy with clang gives a result that is not
+faster than compiling it with gcc.)  We might in theory get extra
+benefits from LLVM's GC integration, but this requires more work on the
+LLVM side before it would be remotely useful.  Anyway, it could be
+interfaced via a custom primitive in the C code.
+
+On the other hand, using LLVM as our JIT backend looks interesting as
+well --- but again we made an attempt, and it failed: LLVM has no way to
+patch the generated machine code.
+
+So the position of the core PyPy developers is that if anyone wants to
+make an N+1'th attempt with LLVM, he is welcome, and he will receive a
+bit of help on the IRC channel, but he is left with the burden of proof
+that it works.
+
 ----------------------
 How do I compile PyPy?
 ----------------------

File pypy/module/_cffi_backend/ctypeenum.py

                 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):

File pypy/module/_cffi_backend/ctypeobj.py

         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')
     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(
     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

File pypy/module/_cffi_backend/test/_backend_test_c.py

     # '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))

File pypy/module/_ffi/test/test_struct.py

             array = ptr_array[0]
             lst = [array[i] for i in range(length)]
             return space.wrap(lst)
-        cls.w_read_raw_mem = cls.space.wrap(interp2app(read_raw_mem))
+        if cls.runappdirect:
+            cls.w_read_raw_mem = lambda self, *args: read_raw_mem(cls.space, *args)
+        else:
+            cls.w_read_raw_mem = cls.space.wrap(interp2app(read_raw_mem))
         #
         from pypy.rlib import clibffi
         from pypy.rlib.rarithmetic import r_uint

File pypy/module/_ssl/thread_lock.py

 }
 """
 
+from pypy.module.thread import ll_thread
 
-eci = ExternalCompilationInfo(
+eci = ll_thread.eci.merge(ExternalCompilationInfo(
     separate_module_sources=[separate_module_source],
     post_include_bits=[
         "int _PyPy_SSL_SetupThreads(void);"],
     export_symbols=['_PyPy_SSL_SetupThreads'],
-)
+))
 
 _PyPy_SSL_SetupThreads = rffi.llexternal('_PyPy_SSL_SetupThreads',
                                          [], rffi.INT,

File pypy/module/bz2/test/test_bz2_compdecomp.py

 
     def setup_class(cls):
         cls.w_TEXT = cls.space.wrap(TEXT)
-        cls.w_decompress = cls.space.wrap(interp2app(decompress))
+        if cls.runappdirect:
+            cls.w_decompress = lambda self, *args: decompress(cls.space, *args)
+        else:
+            cls.w_decompress = cls.space.wrap(interp2app(decompress))
         cls.w_HUGE_OK = cls.space.wrap(HUGE_OK)
 
     def test_creation(self):
     def setup_class(cls):
         cls.w_TEXT = cls.space.wrap(TEXT)
         cls.w_DATA = cls.space.wrap(DATA)
-        cls.w_decompress = cls.space.wrap(interp2app(decompress))
+        if cls.runappdirect:
+            cls.w_decompress = lambda self, *args: decompress(cls.space, *args)
+        else:
+            cls.w_decompress = cls.space.wrap(interp2app(decompress))
         cls.w_HUGE_OK = cls.space.wrap(HUGE_OK)
 
     def test_compress_function(self):

File pypy/module/bz2/test/test_bz2_file.py

             str(py.test.ensuretemp("bz2").join("foo")))
         if cls.runappdirect:
             cls.w_create_temp_file = create_temp_file
+            cls.w_create_broken_temp_file = lambda self: create_broken_temp_file()
+            cls.w_decompress = lambda self, *args: decompress(cls.space, *args)
         else:
             cls.w_create_temp_file = cls.space.wrap(interp2app(create_temp_file))
-        cls.w_decompress = cls.space.wrap(interp2app(decompress))
-        cls.w_create_broken_temp_file = cls.space.wrap(interp2app(create_broken_temp_file))
+            cls.w_create_broken_temp_file = cls.space.wrap(interp2app(create_broken_temp_file))
+            cls.w_decompress = cls.space.wrap(interp2app(decompress))
         cls.w_random_data = cls.space.wrap(RANDOM_DATA)
 
     def test_attributes(self):

File pypy/module/cpyext/test/test_cpyext.py

                     space.sys.get('modules'),
                     space.wrap(name))
             else:
-                return os.path.dirname(mod)
+                return space.wrap(os.path.dirname(mod))
 
         @unwrap_spec(mod=str, name=str)
         def reimport_module(space, mod, name):

File pypy/module/math/test/test_direct.py

         ('exp', (9999.9,), OverflowError),
         ('pow', (10.0, 40000.0), OverflowError),
         ('ldexp', (10.0, 40000), 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 = [

File pypy/module/math/test/test_math.py

             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]))

File pypy/module/micronumpy/test/test_complex.py

         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_ValueError,
-                        cls.space.wrap(e.message))
-        cls.w_c_pow = cls.space.wrap(interp2app(cls_c_pow))
         cls.w_runAppDirect = cls.space.wrap(option.runappdirect)
         cls.w_isWindows = cls.space.wrap(os.name == 'nt')
 
-        def cls_rAlmostEqual(space, __args__):
-            args, kwargs = __args__.unpack()
-            args = map(space.unwrap, args)
-            kwargs = dict([
-                (k, space.unwrap(v))
-                for k, v in kwargs.iteritems()
-            ])
-            if '__pypy__' not in sys.builtin_module_names:
-                kwargs['isnumpy'] = True
-            return space.wrap(rAlmostEqual(*args, **kwargs))
-        cls.w_rAlmostEqual = cls.space.wrap(interp2app(cls_rAlmostEqual))
+        if cls.runappdirect:
+            def cls_rAlmostEqual(space, *args, **kwargs):
+                return rAlmostEqual(*args, **kwargs)
+            cls.w_rAlmostEqual = cls.space.wrap(cls_rAlmostEqual)
+            def cls_c_pow(space, *args):
+                return c_pow(*args)
+            cls.w_c_pow = cls.space.wrap(cls_c_pow)
+        else:
+            def cls_rAlmostEqual(space, __args__):
+                args, kwargs = __args__.unpack()
+                args = map(space.unwrap, args)
+                kwargs = dict([
+                    (k, space.unwrap(v))
+                    for k, v in kwargs.iteritems()
+                ])
+                if '__pypy__' not in sys.builtin_module_names:
+                    kwargs['isnumpy'] = True
+                return space.wrap(rAlmostEqual(*args, **kwargs))
+            cls.w_rAlmostEqual = cls.space.wrap(interp2app(cls_rAlmostEqual))
+            def cls_c_pow(space, args_w):
+                try:
+                    retVal = c_pow(*map(space.unwrap, args_w))
+                    return space.wrap(retVal)
+                except ZeroDivisionError, e:
+                    raise OperationError(cls.space.w_ZeroDivisionError,
+                            cls.space.wrap(e.message))
+                except OverflowError, e:
+                    raise OperationError(cls.space.w_OverflowError,
+                            cls.space.wrap(e.message))
+                except ValueError, e:
+                    raise OperationError(cls.space.w_ValueError,
+                            cls.space.wrap(e.message))
+            cls.w_c_pow = cls.space.wrap(interp2app(cls_c_pow))
 
     def test_fabs(self):
         from _numpypy import fabs, complex128

File pypy/module/posix/test/test_posix2.py

 import signal
 
 def setup_module(mod):
+    usemodules = ['binascii', 'posix', 'struct', 'rctime']
     if os.name != 'nt':
-        mod.space = gettestobjspace(usemodules=['posix', 'fcntl', 'struct'])
+        usemodules += ['fcntl']
     else:
         # On windows, os.popen uses the subprocess module
-        mod.space = gettestobjspace(usemodules=['posix', '_rawffi', 'thread', 'struct'])
+        usemodules += ['_rawffi', 'thread']
+    mod.space = gettestobjspace(usemodules=usemodules)
     mod.path = udir.join('posixtestfile.txt')
     mod.path.write("this is a test")
     mod.path2 = udir.join('test_posix2-')
 
 
 class AppTestPosix:
-    spaceconfig = {
-        "usemodules": ["binascii", "struct", "rctime"],
-    }
 
     def setup_class(cls):
         cls.space = space
             u = "caf\xe9".decode(sys.getfilesystemencoding())
         except UnicodeDecodeError:
             # Could not decode, listdir returned the byte string
-            assert (str, "caf\xe9") in typed_result
+            if sys.platform != 'darwin':
+                assert (str, "caf\xe9") in typed_result
+            else:
+                # darwin 'normalized' it
+                assert (unicode, 'caf%E9') in typed_result
         else:
             assert (unicode, u) in typed_result
 

File pypy/module/select/test/test_select.py

         w_import = space.getattr(space.builtin, space.wrap("__import__"))
         w_socketmod = space.call_function(w_import, space.wrap("socket"))
         cls.w_sock = cls.space.call_method(w_socketmod, "socket")
+        cls.w_sock_err = space.getattr(w_socketmod, space.wrap("error"))
 
         try_ports = [1023] + range(20000, 30000, 437)
         for port in try_ports:
             cls.w_sockaddress = space.wrap(('127.0.0.1', port))
             try:
                 space.call_method(cls.w_sock, "bind", cls.w_sockaddress)
-                print 'works'
                 break
-            except OperationError, e:   # should get a "Permission denied"
-                if not e.match(space, space.getattr(w_socketmod, space.wrap("error"))):
-                    raise
+            except cls.w_sock_err, e:   # should get a "Permission denied"
                 print e
             else:
                 raise e

File pypy/rlib/objectmodel.py

 RPython-compliant way.
 """
 
+from __future__ import absolute_import
+
 import py
 import sys
 import types
     return decorator
 
 
+
 # ____________________________________________________________
 
 class Symbolic(object):

File pypy/rlib/rbigint.py

     def frombytes(s, byteorder, signed):
         if byteorder not in ('big', 'little'):
             raise InvalidEndiannessError()
+        if not s:
+            return NULLRBIGINT
 
         if byteorder != BYTEORDER:
             msb = ord(s[0])

File pypy/rlib/rfloat.py

     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
 
     # 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:
     # 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
 
 # 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
         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

File pypy/rlib/rgc.py

+from __future__ import absolute_import
+
 import gc
 import types
 

File pypy/rlib/signature.py

+from pypy.rlib import types
+
+def signature(*paramtypes, **kwargs):
+    """Decorate a function to specify its type signature.
+
+    Usage:
+      @signature(param1type, param2type, ..., returns=returntype)
+      def foo(...)
+
+    The arguments paramNtype and returntype should be instances
+    of the classes in pypy.annotation.types.
+    """
+    returntype = kwargs.pop('returns', None)
+    if returntype is None:
+        raise TypeError, "signature: parameter 'returns' required"
+
+    def decorator(f):
+        f._signature_ = (paramtypes, returntype)
+        return f
+    return decorator
+
+
+def finishsigs(cls):
+    """Decorate a class to finish any method signatures involving types.self().
+
+    This is required if any method has a signature with types.self() in it.
+    """
+    # A bit annoying to have to use this, but it avoids performing any
+    # terrible hack in the implementation.  Eventually we'll offer signatures
+    # on classes, and then that decorator can do this on the side.
+    def fix(sigtype):
+        if isinstance(sigtype, types.SelfTypeMarker):
+            return types.instance(cls)
+        return sigtype
+    for attr in cls.__dict__.values():
+        if hasattr(attr, '_signature_'):
+            paramtypes, returntype = attr._signature_
+            attr._signature_ = (tuple(fix(t) for t in paramtypes), fix(returntype))
+    return cls

File pypy/rlib/test/test_objectmodel.py

 import py
 from pypy.rlib.objectmodel import *
+from pypy.rlib import types
+from pypy.annotation import model
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 from pypy.rpython.test.test_llinterp import interpret
     TYPES = [v.concretetype for v in graph.getargs()]
     assert TYPES == [lltype.Signed, lltype.Float]
 
+
 def getgraph(f, argtypes):
     from pypy.translator.translator import TranslationContext, graphof
     from pypy.translator.backendopt.all import backend_optimizations

File pypy/rlib/test/test_rbigint.py

         assert res == -42.0
 
     def test_frombytes(self):
+        bigint = rbigint.frombytes('', byteorder='big', signed=True)
+        assert bigint.tolong() == 0
         s = "\xFF\x12\x34\x56"
         bigint = rbigint.frombytes(s, byteorder="big", signed=False)
         assert bigint.tolong() == 0xFF123456

File pypy/rlib/test/test_signature.py

+import py
+from pypy.rlib.signature import signature, finishsigs
+from pypy.rlib import types
+from pypy.annotation import model
+from pypy.translator.translator import TranslationContext, graphof
+
+
+def annotate_at(f):
+    t = TranslationContext()
+    a = t.buildannotator()
+    a.annotate_helper(f, [model.s_ImpossibleValue]*f.func_code.co_argcount)
+    return a
+
+def sigof(a, f):
+    # returns [param1, param2, ..., ret]
+    g = graphof(a.translator, f)
+    return [a.bindings[v] for v in g.startblock.inputargs] + [a.bindings[g.getreturnvar()]]
+
+def getsig(f):
+    a = annotate_at(f)
+    return sigof(a, f)
+
+def check_annotator_fails(caller):
+    exc = py.test.raises(Exception, annotate_at, caller).value
+    assert caller.func_name in repr(exc.args)
+
+
+def test_signature_bookkeeping():
+    @signature('x', 'y', returns='z')
+    def f(a, b):
+        return a + len(b)
+    f.foo = 'foo'
+    assert f._signature_ == (('x', 'y'), 'z')
+    assert f.func_name == 'f'
+    assert f.foo == 'foo'
+    assert f(1, 'hello') == 6
+
+def test_signature_basic():
+    @signature(types.int(), types.str(), returns=types.char())
+    def f(a, b):
+        return b[a]
+    assert getsig(f) == [model.SomeInteger(), model.SomeString(), model.SomeChar()]
+
+def test_signature_arg_errors():
+    @signature(types.int(), types.str(), returns=types.int())
+    def f(a, b):
+        return a + len(b)
+    @check_annotator_fails
+    def ok_for_body(): # would give no error without signature
+        f(2.0, 'b')
+    @check_annotator_fails
+    def bad_for_body(): # would give error inside 'f' body, instead errors at call
+        f('a', 'b')
+
+def test_signature_return():
+    @signature(returns=types.str())
+    def f():
+        return 'a'
+    assert getsig(f) == [model.SomeString()]
+
+    @signature(types.str(), returns=types.str())
+    def f(x):
+        return x
+    def g():
+        return f('a')
+    a = annotate_at(g)
+    assert sigof(a, f) == [model.SomeString(), model.SomeString()]
+
+def test_signature_return_errors():
+    @check_annotator_fails
+    @signature(returns=types.int())
+    def int_not_char():
+        return 'a'
+    @check_annotator_fails
+    @signature(types.str(), returns=types.int())
+    def str_to_int(s):
+        return s
+
+
+def test_signature_none():
+    @signature(returns=types.none())
+    def f():
+        pass
+    assert getsig(f) == [model.s_None]
+
+def test_signature_float():
+    @signature(types.longfloat(), types.singlefloat(), returns=types.float())
+    def f(a, b):
+        return 3.0
+    assert getsig(f) == [model.SomeLongFloat(), model.SomeSingleFloat(), model.SomeFloat()]
+
+def test_signature_unicode():
+    @signature(types.unicode(), returns=types.int())
+    def f(u):
+        return len(u)
+    assert getsig(f) == [model.SomeUnicodeString(), model.SomeInteger()]
+
+
+def test_signature_list():
+    @signature(types.list(types.int()), returns=types.int())
+    def f(a):
+        return len(a)
+    argtype = getsig(f)[0]
+    assert isinstance(argtype, model.SomeList)
+    item = argtype.listdef.listitem
+    assert item.s_value == model.SomeInteger()
+    assert item.resized == True
+
+    @check_annotator_fails
+    def ok_for_body():
+        f(['a'])
+    @check_annotator_fails
+    def bad_for_body():
+        f('a')
+
+    @signature(returns=types.list(types.char()))
+    def ff():
+        return ['a']
+    @check_annotator_fails
+    def mutate_broader():
+        ff()[0] = 'abc'
+    @check_annotator_fails
+    def mutate_unrelated():
+        ff()[0] = 1
+    @check_annotator_fails
+    @signature(types.list(types.char()), returns=types.int())
+    def mutate_in_body(l):
+        l[0] = 'abc'
+        return len(l)
+
+    def can_append():
+        l = ff()
+        l.append('b')
+    getsig(can_append)
+
+def test_signature_array():
+    @signature(returns=types.array(types.int()))
+    def f():
+        return [1]
+    rettype = getsig(f)[0]
+    assert isinstance(rettype, model.SomeList)
+    item = rettype.listdef.listitem
+    assert item.s_value == model.SomeInteger()
+    assert item.resized == False
+
+    def try_append():
+        l = f()
+        l.append(2)
+    check_annotator_fails(try_append)
+
+def test_signature_dict():
+    @signature(returns=types.dict(types.str(), types.int()))
+    def f():
+        return {'a': 1, 'b': 2}
+    rettype = getsig(f)[0]
+    assert isinstance(rettype, model.SomeDict)
+    assert rettype.dictdef.dictkey.s_value   == model.SomeString()
+    assert rettype.dictdef.dictvalue.s_value == model.SomeInteger()
+
+
+def test_signature_instance():
+    class C1(object):
+        pass
+    class C2(C1):
+        pass
+    class C3(C2):
+        pass
+    @signature(types.instance(C3), returns=types.instance(C2))
+    def f(x):
+        assert isinstance(x, C2)
+        return x
+    argtype, rettype = getsig(f)
+    assert isinstance(argtype, model.SomeInstance)
+    assert argtype.classdef.classdesc.pyobj == C3
+    assert isinstance(rettype, model.SomeInstance)
+    assert rettype.classdef.classdesc.pyobj == C2
+
+    @check_annotator_fails
+    def ok_for_body():
+        f(C2())
+    @check_annotator_fails
+    def bad_for_body():
+        f(C1())
+
+def test_signature_self():
+    @finishsigs
+    class C(object):
+        @signature(types.self(), types.self(), returns=types.none())
+        def f(self, other):
+            pass
+    class D1(C):
+        pass
+    class D2(C):
+        pass
+
+    def g():
+        D1().f(D2())
+    a = annotate_at(g)
+
+    argtype = sigof(a, C.__dict__['f'])[0]
+    assert isinstance(argtype, model.SomeInstance)
+    assert argtype.classdef.classdesc.pyobj == C
+
+def test_signature_self_error():
+    class C(object):
+        @signature(types.self(), returns=types.none())
+        def incomplete_sig_meth(self):
+            pass
+
+    exc = py.test.raises(Exception, annotate_at, C.incomplete_sig_meth).value
+    assert 'incomplete_sig_meth' in repr(exc.args)
+    assert 'finishsigs' in repr(exc.args)

File pypy/rlib/types.py

+from pypy.annotation import model
+from pypy.annotation.listdef import ListDef
+from pypy.annotation.dictdef import DictDef
+
+
+def none():
+    return model.s_None
+
+
+def float():
+    return model.SomeFloat()
+
+def singlefloat():
+    return model.SomeSingleFloat()
+
+def longfloat():
+    return model.SomeLongFloat()
+
+
+def int():
+    return model.SomeInteger()
+
+
+def unicode():
+    return model.SomeUnicodeString()
+
+def str():
+    return model.SomeString()
+
+def char():
+    return model.SomeChar()
+
+
+def list(element):
+    listdef = ListDef(None, element, mutated=True, resized=True)
+    return model.SomeList(listdef)
+
+def array(element):
+    listdef = ListDef(None, element, mutated=True, resized=False)
+    return model.SomeList(listdef)
+
+def dict(keytype, valuetype):
+    dictdef = DictDef(None, keytype, valuetype)
+    return model.SomeDict(dictdef)
+
+
+def instance(class_):
+    return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(class_))
+
+class SelfTypeMarker(object):
+    pass
+
+def self():
+    return SelfTypeMarker()

File pypy/rpython/lltypesystem/module/ll_math.py

     if x == 0.0:
         return x      # returns 0.0 or -0.0
     if x <= -1.0:
+        if x == -1:
+            raise OverflowError("math range  error")
         raise ValueError("math domain error")
     return math_log1p(x)
 

File pypy/rpython/test/test_rfloat.py

             # 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.3333'
+
+    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
+        round_double(1.5, 0) == 2.0
+        round_double(2.5, 0) == 3.0
+        round_double(3.5, 0) == 4.0
+        round_double(4.5, 0) == 5.0
+        round_double(5.5, 0) == 6.0
+        round_double(6.5, 0) == 7.0
+
+        round_double(-25.0, -1) == -30.0
+        round_double(-15.0, -1) == -20.0
+        round_double(-5.0, -1) == -10.0
+        round_double(5.0, -1) == 10.0
+        round_double(15.0, -1) == 20.0
+        round_double(25.0, -1) == 30.0
+        round_double(35.0, -1) == 40.0
+        round_double(45.0, -1) == 50.0
+        round_double(55.0, -1) == 60.0
+        round_double(65.0, -1) == 70.0
+        round_double(75.0, -1) == 80.0
+        round_double(85.0, -1) == 90.0
+        round_double(95.0, -1) == 100.0
+        round_double(12325.0, -1) == 12330.0
+
+        round_double(350.0, -2) == 400.0
+        round_double(450.0, -2) == 500.0
+
+        almost_equal(round_double(0.5e21, -21), 1e21)
+        almost_equal(round_double(1.5e21, -21), 2e21)
+        almost_equal(round_double(2.5e21, -21), 3e21)
+        almost_equal(round_double(5.5e21, -21), 6e21)
+        almost_equal(round_double(8.5e21, -21), 9e21)
+
+        almost_equal(round_double(-1.5e22, -22), -2e22)
+        almost_equal(round_double(-0.5e22, -22), -1e22)
+        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):
 
 
 
 class TestOOtype(BaseTestRfloat, OORtypeMixin):
-    pass
+
+    def test_formatd(self):
+        skip('formatd is broken on ootype')
+
+    def test_formatd_repr(self):
+        skip('formatd is broken on ootype')
+
+    def test_formatd_huge(self):
+        skip('formatd is broken on ootype')
+
+    def test_string_to_float(self):
+        skip('string_to_float is broken on ootype')

File pypy/tool/pytest/objspace.py

                 py.test.skip("cannot runappdirect test: space needs %s = %s, "\
                     "while pypy-c was built with %s" % (key, value, has))
 
-        for name in ('int', 'long', 'str', 'unicode', 'None'):
+        for name in ('int', 'long', 'str', 'unicode', 'None', 'ValueError',
+                'OverflowError'):
             setattr(self, 'w_' + name, eval(name))
+        import __builtin__ as __builtin__
+        self.builtin = __builtin__
 
     def appexec(self, args, body):
         body = body.lstrip()

File pypy/translator/platform/linux.py

                  + 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 = ()