Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r61529:42ae84d5dfef Date: 2013-02-21 11:43 +0200 http://bitbucket.org/pypy/pypy/changeset/42ae84d5dfef/
Log: merge diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -303,7 +303,7 @@ dicts with a unique key type only, provided it is hashable. Custom hash functions and custom equality will not be honored. - Use ``pypy.rlib.objectmodel.r_dict`` for custom hash functions. + Use ``rpython.rlib.objectmodel.r_dict`` for custom hash functions. **list comprehensions** @@ -365,7 +365,7 @@ We use normal integers for signed arithmetic. It means that before translation we get longs in case of overflow, and after translation we get a silent wrap-around. Whenever we need more control, we use the following -helpers (which live the `pypy/rlib/rarithmetic.py`_): +helpers (which live in `rpython/rlib/rarithmetic.py`_): **ovfcheck()** diff --git a/pypy/doc/rlib.rst b/pypy/doc/rlib.rst --- a/pypy/doc/rlib.rst +++ b/pypy/doc/rlib.rst @@ -7,18 +7,18 @@ .. contents:: -This page lists some of the modules in `pypy/rlib`_ together with some hints +This page lists some of the modules in `rpython/rlib`_ together with some hints for what they can be used for. The modules here will make up some general library useful for RPython programs (since most of the standard library modules are not RPython). Most of these modules are somewhat rough still and are likely to change at some point. Usually it is useful to look at the tests in -`pypy/rlib/test`_ to get an impression of how to use a module. +`rpython/rlib/test`_ to get an impression of how to use a module. ``listsort`` ============ -The `pypy/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm +The `rpython/rlib/listsort.py`_ module contains an implementation of the timsort sorting algorithm (the sort method of lists is not RPython). To use it, subclass from the ``listsort.TimSort`` class and override the ``lt`` method to change the comparison behaviour. The constructor of ``TimSort`` takes a list as an @@ -30,7 +30,7 @@ ``nonconst`` ============ -The `pypy/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and +The `rpython/rlib/nonconst.py`_ module is useful mostly for tests. The `flow object space`_ and the `annotator`_ do quite some constant folding, which is sometimes not desired in a test. To prevent constant folding on a certain value, use the ``NonConst`` class. The constructor of ``NonConst`` takes an arbitrary value. The instance of @@ -44,7 +44,7 @@ ``objectmodel`` =============== -The `pypy/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the +The `rpython/rlib/objectmodel.py`_ module is a mixed bag of various functionality. Some of the more useful ones are: ``ComputedIntSymbolic``: @@ -94,7 +94,7 @@ ``rarithmetic`` =============== -The `pypy/rlib/rarithmetic.py`_ module contains functionality to handle the small differences +The `rpython/rlib/rarithmetic.py`_ module contains functionality to handle the small differences in the behaviour of arithmetic code in regular Python and RPython code. Most of them are already described in the `coding guide`_ @@ -104,7 +104,7 @@ ``rbigint`` =========== -The `pypy/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` +The `rpython/rlib/rbigint.py`_ module contains a full RPython implementation of the Python ``long`` type (which itself is not supported in RPython). The ``rbigint`` class contains that implementation. To construct ``rbigint`` instances use the static methods ``fromint``, ``frombool``, ``fromfloat`` and ``fromdecimalstr``. To convert back @@ -118,7 +118,7 @@ ``rrandom`` =========== -The `pypy/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random +The `rpython/rlib/rrandom.py`_ module contains an implementation of the mersenne twister random number generator. It contains one class ``Random`` which most importantly has a ``random`` method which returns a pseudo-random floating point number between 0.0 and 1.0. @@ -126,7 +126,7 @@ ``rsocket`` =========== -The `pypy/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of +The `rpython/rlib/rsocket.py`_ module contains an RPython implementation of the functionality of the socket standard library with a slightly different interface. The difficulty with the Python socket API is that addresses are not "well-typed" objects: depending on the address family they are tuples, or strings, and @@ -137,7 +137,7 @@ ``streamio`` ============ -The `pypy/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started +The `rpython/rlib/streamio.py`_ contains an RPython stream I/O implementation (which was started by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the upcoming new file implementation in Python 3000). @@ -146,7 +146,7 @@ ``unroll`` ========== -The `pypy/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` +The `rpython/rlib/unroll.py`_ module most importantly contains the function ``unrolling_iterable`` which wraps an iterator. Looping over the iterator in RPython code will not produce a loop in the resulting flow graph but will unroll the loop instead. @@ -154,7 +154,7 @@ ``parsing`` =========== -The `pypy/rlib/parsing/`_ module is a still in-development module to generate tokenizers and +The `rpython/rlib/parsing/`_ module is a still in-development module to generate tokenizers and parsers in RPython. It is still highly experimental and only really used by the `Prolog interpreter`_ (although in slightly non-standard ways). The easiest way to specify a tokenizer/grammar is to write it down using regular expressions and @@ -204,7 +204,7 @@ anything except a. To parse a regular expression and to get a matcher for it, you can use the -function ``make_runner(s)`` in the ``pypy.rlib.parsing.regexparse`` module. It +function ``make_runner(s)`` in the ``rpython.rlib.parsing.regexparse`` module. It returns a object with a ``recognize(input)`` method that returns True or False depending on whether ``input`` matches the string or not. @@ -213,7 +213,7 @@ EBNF ---- -To describe a tokenizer and a grammar the ``pypy.rlib.parsing.ebnfparse`` +To describe a tokenizer and a grammar the ``rpython.rlib.parsing.ebnfparse`` defines a syntax for doing that. The syntax file contains a sequence or rules. Every rule either describes a @@ -295,7 +295,7 @@ The parsing process builds up a tree consisting of instances of ``Symbol`` and ``Nonterminal``, the former corresponding to tokens, the latter to nonterminal -symbols. Both classes live in the `pypy/rlib/parsing/tree.py`_ module. You can use +symbols. Both classes live in the `rpython/rlib/parsing/tree.py`_ module. You can use the ``view()`` method ``Nonterminal`` instances to get a pygame view of the parse tree. @@ -310,7 +310,7 @@ ++++++++ To write tree visitors for the parse trees that are RPython, there is a special -baseclass ``RPythonVisitor`` in `pypy/rlib/parsing/tree.py`_ to use. If your +baseclass ``RPythonVisitor`` in `rpython/rlib/parsing/tree.py`_ to use. If your class uses this, it will grow a ``dispatch(node)`` method, that calls an appropriate ``visit_<symbol>`` method, depending on the ``node`` argument. Here the <symbol> is replaced by the ``symbol`` attribute of the visited node. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1494,10 +1494,11 @@ ) return fd - def warn(self, msg, w_warningcls): - self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): + def warn(self, w_msg, w_warningcls, stacklevel=2): + self.appexec([w_msg, w_warningcls, self.wrap(stacklevel)], + """(msg, warningcls, stacklevel): import _warnings - _warnings.warn(msg, warningcls, stacklevel=2) + _warnings.warn(msg, warningcls, stacklevel=stacklevel) """) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -776,17 +776,16 @@ @jit.unroll_safe def cmp_exc_match(self, w_1, w_2): - if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)): - for w_t in self.space.fixedview(w_2): - if self.space.is_true(self.space.isinstance(w_t, - self.space.w_str)): - self.space.warn("catching of string exceptions is " - "deprecated", - self.space.w_DeprecationWarning) - elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)): - self.space.warn("catching of string exceptions is deprecated", - self.space.w_DeprecationWarning) - return self.space.newbool(self.space.exception_match(w_1, w_2)) + space = self.space + if space.is_true(space.isinstance(w_2, space.w_tuple)): + for w_t in space.fixedview(w_2): + if space.is_true(space.isinstance(w_t, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + elif space.is_true(space.isinstance(w_2, space.w_str)): + msg = "catching of string exceptions is deprecated" + space.warn(space.wrap(msg), space.w_DeprecationWarning) + return space.newbool(space.exception_match(w_1, w_2)) def COMPARE_OP(self, testnum, next_instr): w_2 = self.popvalue() diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py --- a/pypy/module/__builtin__/functional.py +++ b/pypy/module/__builtin__/functional.py @@ -203,6 +203,7 @@ return min_max_unroll(space, args, implementation_of) else: return min_max_normal(space, args, implementation_of) +min_max._always_inline = True def max(space, __args__): """max(iterable[, key=func]) -> value diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py --- a/pypy/module/__builtin__/interp_classobj.py +++ b/pypy/module/__builtin__/interp_classobj.py @@ -154,9 +154,9 @@ return elif name == "__del__": if self.lookup(space, name) is None: - msg = ("a __del__ method added to an existing class " - "will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing class will " + "not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) space.setitem(self.w_dict, w_attr, w_value) def descr_delattr(self, space, w_attr): @@ -395,9 +395,9 @@ cache = space.fromcache(Cache) if (not isinstance(self, cache.cls_with_del) and self.getdictvalue(space, '__del__') is None): - msg = ("a __del__ method added to an instance " - "with no __del__ in the class will not be called") - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an instance with no " + "__del__ in the class will not be called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if w_meth is not None: space.call_function(w_meth, w_name, w_value) else: @@ -454,11 +454,9 @@ else: w_as_str = self.descr_str(space) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = ("object.__format__ with a non-empty format string is " + "deprecated") + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr_len(self, space): diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -76,7 +76,7 @@ raise NotImplementedError def _deprecated_max_buffer_size(self, space): - space.warn("max_buffer_size is deprecated", + space.warn(space.wrap("max_buffer_size is deprecated"), space.w_DeprecationWarning) def read_w(self, space, w_size=None): diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py --- a/pypy/module/_io/interp_fileio.py +++ b/pypy/module/_io/interp_fileio.py @@ -3,6 +3,7 @@ from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2 from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.rstring import StringBuilder +from rpython.rlib.rposix import validate_fd from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC import sys, os, stat, errno from pypy.module._io.interp_iobase import W_RawIOBase, convert_size @@ -117,9 +118,6 @@ return currentsize + BIGCHUNK return currentsize + SMALLCHUNK -def verify_fd(fd): - return - class W_FileIO(W_RawIOBase): def __init__(self, space): W_RawIOBase.__init__(self, space) @@ -156,7 +154,7 @@ fd_is_own = False try: if fd >= 0: - verify_fd(fd) + validate_fd(fd) try: os.fstat(fd) except OSError, e: @@ -237,7 +235,7 @@ self.fd = -1 try: - verify_fd(fd) + validate_fd(fd) os.close(fd) except OSError, e: raise wrap_oserror(space, e, diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py --- a/pypy/module/cpyext/import_.py +++ b/pypy/module/cpyext/import_.py @@ -46,8 +46,9 @@ @cpython_api([CONST_STRING], PyObject) def PyImport_ImportModuleNoBlock(space, name): - space.warn('PyImport_ImportModuleNoBlock() is not non-blocking', - space.w_RuntimeWarning) + space.warn( + space.wrap('PyImport_ImportModuleNoBlock() is not non-blocking'), + space.w_RuntimeWarning) return PyImport_Import(space, space.wrap(rffi.charp2str(name))) @cpython_api([PyObject], PyObject) diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -176,8 +176,8 @@ if self.w_message is None: raise OperationError(space.w_AttributeError, space.wrap("message was deleted")) - space.warn("BaseException.message has been deprecated as of Python 2.6", - space.w_DeprecationWarning) + msg = "BaseException.message has been deprecated as of Python 2.6" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return self.w_message def descr_message_set(self, space, w_new): diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -174,9 +174,9 @@ "Parent module '%s' not loaded, " "cannot perform relative import" % ctxt_package)) else: - space.warn("Parent module '%s' not found " - "while handling absolute import" % ctxt_package, - space.w_RuntimeWarning) + msg = ("Parent module '%s' not found while handling absolute " + "import" % ctxt_package) + space.warn(space.wrap(msg), space.w_RuntimeWarning) rel_modulename = ctxt_package[:dot_position] rel_level = rel_modulename.count('.') + 1 @@ -533,9 +533,9 @@ if modtype in (PY_SOURCE, PY_COMPILED): return FindInfo(PKG_DIRECTORY, filepart, None) else: - msg = "Not importing directory " +\ - "'%s' missing __init__.py" % (filepart,) - space.warn(msg, space.w_ImportWarning) + msg = ("Not importing directory '%s' missing __init__.py" % + (filepart,)) + space.warn(space.wrap(msg), space.w_ImportWarning) modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION): diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -67,11 +67,15 @@ def min(a, axis=None, out=None): if not hasattr(a, "min"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.min(axis=axis, out=out) def max(a, axis=None, out=None): if not hasattr(a, "max"): a = _numpypy.array(a) + if a.size < 1: + return _numpypy.array([]) return a.max(axis=axis, out=out) def arange(start, stop=None, step=1, dtype=None): diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py --- a/pypy/module/micronumpy/interp_numarray.py +++ b/pypy/module/micronumpy/interp_numarray.py @@ -250,7 +250,7 @@ ret = self.implementation.get_imag(self) if ret: return W_NDimArray(ret) - raise OperationError(space.w_NotImplementedError, + raise OperationError(space.w_NotImplementedError, space.wrap('imag not implemented for this dtype')) def descr_set_real(self, space, w_value): @@ -261,7 +261,7 @@ def descr_set_imag(self, space, w_value): # if possible, copy (broadcast) values into self if not self.get_dtype().is_complex_type(): - raise OperationError(space.w_TypeError, + raise OperationError(space.w_TypeError, space.wrap('array does not have imaginary part to set')) tmp = self.implementation.get_imag(self) tmp.setslice(space, convert_to_array(space, w_value)) @@ -302,11 +302,11 @@ @unwrap_spec(axis1=int, axis2=int) def descr_swapaxes(self, space, axis1, axis2): """a.swapaxes(axis1, axis2) - + Return a view of the array with `axis1` and `axis2` interchanged. - + Refer to `numpy.swapaxes` for full documentation. - + See Also -------- numpy.swapaxes : equivalent function @@ -439,7 +439,7 @@ ret = impl.base() if ret is None: return space.w_None - return ret + return ret @unwrap_spec(inplace=bool) def descr_byteswap(self, space, inplace=False): @@ -492,7 +492,7 @@ "axis1 and axis2 cannot be the same")) return interp_arrayops.diagonal(space, self.implementation, offset, axis1, axis2) - + def descr_dump(self, space, w_file): raise OperationError(space.w_NotImplementedError, space.wrap( "dump not implemented yet")) @@ -509,7 +509,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setting flags not implemented yet")) - @unwrap_spec(offset=int) + @unwrap_spec(offset=int) def descr_getfield(self, space, w_dtype, offset): raise OperationError(space.w_NotImplementedError, space.wrap( "getfield not implemented yet")) @@ -518,7 +518,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "itemset not implemented yet")) - @unwrap_spec(neworder=str) + @unwrap_spec(neworder=str) def descr_newbyteorder(self, space, neworder): raise OperationError(space.w_NotImplementedError, space.wrap( "newbyteorder not implemented yet")) @@ -551,7 +551,7 @@ raise OperationError(space.w_NotImplementedError, space.wrap( "setfield not implemented yet")) - def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): + def descr_setflags(self, space, w_write=None, w_align=None, w_uic=None): raise OperationError(space.w_NotImplementedError, space.wrap( "setflags not implemented yet")) @@ -572,7 +572,7 @@ "tofile not implemented yet")) def descr_trace(self, space, w_offset=0, w_axis1=0, w_axis2=1, - w_dtype=None, w_out=None): + w_dtype=None, w_out=None): raise OperationError(space.w_NotImplementedError, space.wrap( "trace not implemented yet")) @@ -627,12 +627,23 @@ w_remainder = self.descr_mod(space, w_other) return space.newtuple([w_quotient, w_remainder]) - descr_eq = _binop_impl("equal") - descr_ne = _binop_impl("not_equal") - descr_lt = _binop_impl("less") - descr_le = _binop_impl("less_equal") - descr_gt = _binop_impl("greater") - descr_ge = _binop_impl("greater_equal") + def _binop_comp_impl(ufunc): + def impl(self, space, w_other, w_out=None): + try: + return ufunc(self, space, w_other, w_out) + except OperationError, e: + if e.match(space, space.w_ValueError): + return space.w_False + raise e + + return func_with_new_name(impl, ufunc.func_name) + + descr_eq = _binop_comp_impl(_binop_impl("equal")) + descr_ne = _binop_comp_impl(_binop_impl("not_equal")) + descr_lt = _binop_comp_impl(_binop_impl("less")) + descr_le = _binop_comp_impl(_binop_impl("less_equal")) + descr_gt = _binop_comp_impl(_binop_impl("greater")) + descr_ge = _binop_comp_impl(_binop_impl("greater_equal")) def _binop_right_impl(ufunc_name): def impl(self, space, w_other, w_out=None): @@ -698,7 +709,7 @@ if space.is_none(w_out): out = None elif not isinstance(w_out, W_NDimArray): - raise OperationError(space.w_TypeError, space.wrap( + raise OperationError(space.w_TypeError, space.wrap( 'output must be an array')) else: out = w_out @@ -718,7 +729,7 @@ descr_cumsum = _reduce_ufunc_impl('add', cumultative=True) descr_cumprod = _reduce_ufunc_impl('multiply', cumultative=True) - + def descr_mean(self, space, w_axis=None, w_out=None): if space.is_none(w_axis): w_denom = space.wrap(self.get_size()) @@ -863,7 +874,7 @@ swapaxes = interp2app(W_NDimArray.descr_swapaxes), flat = GetSetProperty(W_NDimArray.descr_get_flatiter), item = interp2app(W_NDimArray.descr_item), - real = GetSetProperty(W_NDimArray.descr_get_real, + real = GetSetProperty(W_NDimArray.descr_get_real, W_NDimArray.descr_set_real), imag = GetSetProperty(W_NDimArray.descr_get_imag, W_NDimArray.descr_set_imag), @@ -923,7 +934,7 @@ dtype) #if dtype is interp_dtype.get_dtype_cache(space).w_float64dtype: # break - + if dtype is None: dtype = interp_dtype.get_dtype_cache(space).w_float64dtype if ndmin > len(shape): diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py --- a/pypy/module/struct/formatiterator.py +++ b/pypy/module/struct/formatiterator.py @@ -84,11 +84,10 @@ def _maybe_float(self, w_obj): space = self.space if space.is_true(space.isinstance(w_obj, space.w_float)): - space.warn("struct: integer argument expected, got float", - space.w_DeprecationWarning) + msg = "struct: integer argument expected, got float" else: - space.warn("integer argument expected, got non-integer", - space.w_DeprecationWarning) + msg = "integer argument expected, got non-integer" + space.warn(space.wrap(msg), space.w_DeprecationWarning) return space.int(w_obj) # wrapped float -> wrapped int or long else: diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py --- a/pypy/objspace/std/complexobject.py +++ b/pypy/objspace/std/complexobject.py @@ -80,10 +80,8 @@ return W_ComplexObject(rr, ir) def divmod(self, space, other): - space.warn( - "complex divmod(), // and % are deprecated", - space.w_DeprecationWarning - ) + space.warn(space.wrap("complex divmod(), // and % are deprecated"), + space.w_DeprecationWarning) w_div = self.div(other) div = math.floor(w_div.realval) w_mod = self.sub( diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py --- a/pypy/objspace/std/floatobject.py +++ b/pypy/objspace/std/floatobject.py @@ -10,7 +10,7 @@ from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT from rpython.rlib.rfloat import ( isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd, - DTSF_ADD_DOT_0, DTSF_STR_PRECISION) + DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio) from rpython.rlib.rbigint import rbigint from rpython.rlib import rfloat from rpython.tool.sourcetools import func_with_new_name @@ -553,27 +553,18 @@ def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval - if isinf(value): + try: + num, den = float_as_rbigint_ratio(value) + except OverflowError: w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) - elif isnan(value): + except ValueError: w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) - float_part, exp = math.frexp(value) - for i in range(300): - if float_part == math.floor(float_part): - break - float_part *= 2.0 - exp -= 1 - w_num = W_LongObject.fromfloat(space, float_part) - w_den = space.newlong(1) - w_exp = space.newlong(abs(exp)) - w_exp = space.lshift(w_den, w_exp) - if exp > 0: - w_num = space.mul(w_num, w_exp) - else: - w_den = w_exp - # Try to return int. + + w_num = space.newlong_from_rbigint(num) + w_den = space.newlong_from_rbigint(den) + # Try to return int return space.newtuple([space.int(w_num), space.int(w_den)]) def float_is_integer__Float(space, w_float): diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py --- a/pypy/objspace/std/objecttype.py +++ b/pypy/objspace/std/objecttype.py @@ -126,11 +126,8 @@ msg = "format_spec must be a string" raise OperationError(space.w_TypeError, space.wrap(msg)) if space.len_w(w_format_spec) > 0: - space.warn( - ("object.__format__ with a non-empty format string is " - "deprecated"), - space.w_PendingDeprecationWarning - ) + msg = "object.__format__ with a non-empty format string is deprecated" + space.warn(space.wrap(msg), space.w_PendingDeprecationWarning) return space.format(w_as_str, w_format_spec) def descr___subclasshook__(space, __args__): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -295,8 +295,9 @@ msg = "can't set attributes on type object '%s'" raise operationerrfmt(space.w_TypeError, msg, w_self.name) if name == "__del__" and name not in w_self.dict_w: - msg = "a __del__ method added to an existing type will not be called" - space.warn(msg, space.w_RuntimeWarning) + msg = ("a __del__ method added to an existing type will not be " + "called") + space.warn(space.wrap(msg), space.w_RuntimeWarning) if space.config.objspace.std.withtypeversion: version_tag = w_self.version_tag() if version_tag is not None: diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -119,13 +119,10 @@ w_uni2 = uni_from_str(space, w_str) except OperationError, e: if e.match(space, space.w_UnicodeDecodeError): - if inverse: - msg = "Unicode unequal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - else : - msg = "Unicode equal comparison failed to convert both " \ - "arguments to Unicode - interpreting them as being unequal" - space.warn(msg, space.w_UnicodeWarning) + msg = ("Unicode %s comparison failed to convert both arguments to " + "Unicode - interpreting them as being unequal" % + "unequal" if inverse else "equal") + space.warn(space.wrap(msg), space.w_UnicodeWarning) return space.newbool(inverse) raise result = space.eq(w_uni, w_uni2) diff --git a/rpython/rlib/rfloat.py b/rpython/rlib/rfloat.py --- a/rpython/rlib/rfloat.py +++ b/rpython/rlib/rfloat.py @@ -419,3 +419,25 @@ def isfinite(x): "NOT_RPYTHON" return not isinf(x) and not isnan(x) + +def float_as_rbigint_ratio(value): + from rpython.rlib.rbigint import rbigint + + if isinf(value): + raise OverflowError("cannot pass infinity to as_integer_ratio()") + elif isnan(value): + raise ValueError("cannot pass nan to as_integer_ratio()") + float_part, exp_int = math.frexp(value) + for i in range(300): + if float_part == math.floor(float_part): + break + float_part *= 2.0 + exp_int -= 1 + num = rbigint.fromfloat(float_part) + den = rbigint.fromint(1) + exp = den.lshift(abs(exp_int)) + if exp_int > 0: + num = num.mul(exp) + else: + den = exp + return num, den diff --git a/rpython/rlib/test/test_rfloat.py b/rpython/rlib/test/test_rfloat.py new file mode 100644 --- /dev/null +++ b/rpython/rlib/test/test_rfloat.py @@ -0,0 +1,131 @@ +import sys, py + +from rpython.rlib.rfloat import float_as_rbigint_ratio +from rpython.rlib.rfloat import break_up_float +from rpython.rlib.rfloat import copysign +from rpython.rlib.rfloat import round_away +from rpython.rlib.rfloat import round_double +from rpython.rlib.rbigint import rbigint + +def test_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(): + 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(): + 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(): + from rpython.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 + +def test_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') + + py.test.raises(ValueError, break_up_float, 'e') + + +def test_float_as_rbigint_ratio(): + for f, ratio in [ + (0.875, (7, 8)), + (-0.875, (-7, 8)), + (0.0, (0, 1)), + (11.5, (23, 2)), + ]: + num, den = float_as_rbigint_ratio(f) + assert num.eq(rbigint.fromint(ratio[0])) + assert den.eq(rbigint.fromint(ratio[1])) + + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('inf')) + with py.test.raises(OverflowError): + float_as_rbigint_ratio(float('-inf')) + with py.test.raises(ValueError): + float_as_rbigint_ratio(float('nan')) diff --git a/rpython/rtyper/test/test_rfloat.py b/rpython/rtyper/test/test_rfloat.py --- a/rpython/rtyper/test/test_rfloat.py +++ b/rpython/rtyper/test/test_rfloat.py @@ -216,26 +216,6 @@ # https://bugzilla.novell.com/show_bug.cgi?id=692493 assert not self.interpret(fn, [1e200, 1e200]) # nan - def test_break_up_float(self): - from rpython.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') - - py.test.raises(ValueError, break_up_float, 'e') - def test_formatd(self): from rpython.rlib.rfloat import formatd def f(x): @@ -296,93 +276,6 @@ assert self.interpret(func, [0]) == 1e23 assert self.interpret(func, [1]) == -1e23 - def test_copysign(self): - from rpython.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 rpython.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 rpython.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 rpython.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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit