Author: Justin Peel <notmuchtot...@gmail.com> Branch: streamio-bufinput Changeset: r46810:151a20159ae6 Date: 2011-08-27 00:55 -0600 http://bitbucket.org/pypy/pypy/changeset/151a20159ae6/
Log: merge in default diff --git a/ctypes_configure/configure.py b/ctypes_configure/configure.py --- a/ctypes_configure/configure.py +++ b/ctypes_configure/configure.py @@ -559,7 +559,9 @@ C_HEADER = """ #include <stdio.h> #include <stddef.h> /* for offsetof() */ -#include <stdint.h> /* FreeBSD: for uint64_t */ +#ifndef _WIN32 +# include <stdint.h> /* FreeBSD: for uint64_t */ +#endif void dump(char* key, int value) { printf("%s: %d\\n", key, value); diff --git a/lib_pypy/_subprocess.py b/lib_pypy/_subprocess.py --- a/lib_pypy/_subprocess.py +++ b/lib_pypy/_subprocess.py @@ -35,7 +35,7 @@ _DuplicateHandle.restype = ctypes.c_int _WaitForSingleObject = _kernel32.WaitForSingleObject -_WaitForSingleObject.argtypes = [ctypes.c_int, ctypes.c_int] +_WaitForSingleObject.argtypes = [ctypes.c_int, ctypes.c_uint] _WaitForSingleObject.restype = ctypes.c_int _GetExitCodeProcess = _kernel32.GetExitCodeProcess diff --git a/pypy/config/makerestdoc.py b/pypy/config/makerestdoc.py --- a/pypy/config/makerestdoc.py +++ b/pypy/config/makerestdoc.py @@ -134,7 +134,7 @@ for child in self._children: subpath = fullpath + "." + child._name toctree.append(subpath) - content.add(Directive("toctree", *toctree, maxdepth=4)) + content.add(Directive("toctree", *toctree, **{'maxdepth': 4})) content.join( ListItem(Strong("name:"), self._name), ListItem(Strong("description:"), self.doc)) diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py --- a/pypy/config/test/test_config.py +++ b/pypy/config/test/test_config.py @@ -1,5 +1,5 @@ from pypy.config.config import * -import py +import py, sys def make_description(): gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref') @@ -69,13 +69,15 @@ attrs = dir(config) assert '__repr__' in attrs # from the type assert '_cfgimpl_values' in attrs # from self - assert 'gc' in attrs # custom attribute - assert 'objspace' in attrs # custom attribute + if sys.version_info >= (2, 6): + assert 'gc' in attrs # custom attribute + assert 'objspace' in attrs # custom attribute # attrs = dir(config.gc) - assert 'name' in attrs - assert 'dummy' in attrs - assert 'float' in attrs + if sys.version_info >= (2, 6): + assert 'name' in attrs + assert 'dummy' in attrs + assert 'float' in attrs def test_arbitrary_option(): descr = OptionDescription("top", "", [ diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py --- a/pypy/jit/codewriter/jtransform.py +++ b/pypy/jit/codewriter/jtransform.py @@ -571,6 +571,7 @@ pure = '_pure' else: pure = '' + self.check_field_access(v_inst.concretetype.TO) argname = getattr(v_inst.concretetype.TO, '_gckind', 'gc') descr = self.cpu.fielddescrof(v_inst.concretetype.TO, c_fieldname.value) @@ -604,6 +605,7 @@ return [SpaceOperation('-live-', [], None), SpaceOperation('setfield_vable_%s' % kind, [v_inst, descr, v_value], None)] + self.check_field_access(v_inst.concretetype.TO) argname = getattr(v_inst.concretetype.TO, '_gckind', 'gc') descr = self.cpu.fielddescrof(v_inst.concretetype.TO, c_fieldname.value) @@ -616,6 +618,22 @@ return (op.args[1].value == 'typeptr' and op.args[0].concretetype.TO._hints.get('typeptr')) + def check_field_access(self, STRUCT): + # check against a GcStruct with a nested GcStruct as a first argument + # but which is not an object at all; see metainterp/test/test_loop, + # test_regular_pointers_in_short_preamble. + if not isinstance(STRUCT, lltype.GcStruct): + return + if STRUCT._first_struct() == (None, None): + return + PARENT = STRUCT + while not PARENT._hints.get('typeptr'): + _, PARENT = PARENT._first_struct() + if PARENT is None: + raise NotImplementedError("%r is a GcStruct using nesting but " + "not inheriting from object" % + (STRUCT,)) + def get_vinfo(self, v_virtualizable): if self.callcontrol is None: # for tests return None diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py --- a/pypy/jit/codewriter/test/test_jtransform.py +++ b/pypy/jit/codewriter/test/test_jtransform.py @@ -1014,3 +1014,13 @@ assert op1.opname == 'jit_force_quasi_immutable' assert op1.args[0] == v_x assert op1.args[1] == ('fielddescr', STRUCT, 'mutate_x') + +def test_no_gcstruct_nesting_outside_of_OBJECT(): + PARENT = lltype.GcStruct('parent') + STRUCT = lltype.GcStruct('struct', ('parent', PARENT), + ('x', lltype.Signed)) + v_x = varoftype(lltype.Ptr(STRUCT)) + op = SpaceOperation('getfield', [v_x, Constant('x', lltype.Void)], + varoftype(lltype.Signed)) + tr = Transformer(None, None) + raises(NotImplementedError, tr.rewrite_operation, op) diff --git a/pypy/jit/metainterp/test/test_loop.py b/pypy/jit/metainterp/test/test_loop.py --- a/pypy/jit/metainterp/test/test_loop.py +++ b/pypy/jit/metainterp/test/test_loop.py @@ -801,8 +801,6 @@ res = self.meta_interp(f, [200]) def test_regular_pointers_in_short_preamble(self): - # XXX do we really care about this case? If not, we should - # at least detect it and complain during codewriter/jtransform from pypy.rpython.lltypesystem import lltype BASE = lltype.GcStruct('BASE') A = lltype.GcStruct('A', ('parent', BASE), ('val', lltype.Signed)) @@ -829,9 +827,8 @@ assert n>0 and m>0 i += j return sa - expected = f(20, 10, 1) - res = self.meta_interp(f, [20, 10, 1]) - assert res == expected + # This is detected as invalid by the codewriter, for now + py.test.raises(NotImplementedError, self.meta_interp, f, [20, 10, 1]) def test_unerased_pointers_in_short_preamble(self): from pypy.rlib.rerased import new_erasing_pair diff --git a/pypy/module/__builtin__/test/test_classobj.py b/pypy/module/__builtin__/test/test_classobj.py --- a/pypy/module/__builtin__/test/test_classobj.py +++ b/pypy/module/__builtin__/test/test_classobj.py @@ -981,6 +981,86 @@ assert a.x == 2 raises(TypeError, descr.__delete__, a) + def test_partial_ordering(self): + class A: + def __lt__(self, other): + return self + a1 = A() + a2 = A() + assert (a1 < a2) is a1 + assert (a1 > a2) is a2 + + def test_eq_order(self): + # this gives the ordering of equality-related functions on top of + # CPython **for old-style classes**. + class A: + def __eq__(self, other): return self.__class__.__name__+':A.eq' + def __ne__(self, other): return self.__class__.__name__+':A.ne' + def __lt__(self, other): return self.__class__.__name__+':A.lt' + def __le__(self, other): return self.__class__.__name__+':A.le' + def __gt__(self, other): return self.__class__.__name__+':A.gt' + def __ge__(self, other): return self.__class__.__name__+':A.ge' + class B: + def __eq__(self, other): return self.__class__.__name__+':B.eq' + def __ne__(self, other): return self.__class__.__name__+':B.ne' + def __lt__(self, other): return self.__class__.__name__+':B.lt' + def __le__(self, other): return self.__class__.__name__+':B.le' + def __gt__(self, other): return self.__class__.__name__+':B.gt' + def __ge__(self, other): return self.__class__.__name__+':B.ge' + # + assert (A() == B()) == 'A:A.eq' + assert (A() != B()) == 'A:A.ne' + assert (A() < B()) == 'A:A.lt' + assert (A() <= B()) == 'A:A.le' + assert (A() > B()) == 'A:A.gt' + assert (A() >= B()) == 'A:A.ge' + # + assert (B() == A()) == 'B:B.eq' + assert (B() != A()) == 'B:B.ne' + assert (B() < A()) == 'B:B.lt' + assert (B() <= A()) == 'B:B.le' + assert (B() > A()) == 'B:B.gt' + assert (B() >= A()) == 'B:B.ge' + # + class C(A): + def __eq__(self, other): return self.__class__.__name__+':C.eq' + def __ne__(self, other): return self.__class__.__name__+':C.ne' + def __lt__(self, other): return self.__class__.__name__+':C.lt' + def __le__(self, other): return self.__class__.__name__+':C.le' + def __gt__(self, other): return self.__class__.__name__+':C.gt' + def __ge__(self, other): return self.__class__.__name__+':C.ge' + # + assert (A() == C()) == 'A:A.eq' + assert (A() != C()) == 'A:A.ne' + assert (A() < C()) == 'A:A.lt' + assert (A() <= C()) == 'A:A.le' + assert (A() > C()) == 'A:A.gt' + assert (A() >= C()) == 'A:A.ge' + # + assert (C() == A()) == 'C:C.eq' + assert (C() != A()) == 'C:C.ne' + assert (C() < A()) == 'C:C.lt' + assert (C() <= A()) == 'C:C.le' + assert (C() > A()) == 'C:C.gt' + assert (C() >= A()) == 'C:C.ge' + # + class D(A): + pass + # + assert (A() == D()) == 'A:A.eq' + assert (A() != D()) == 'A:A.ne' + assert (A() < D()) == 'A:A.lt' + assert (A() <= D()) == 'A:A.le' + assert (A() > D()) == 'A:A.gt' + assert (A() >= D()) == 'A:A.ge' + # + assert (D() == A()) == 'D:A.eq' + assert (D() != A()) == 'D:A.ne' + assert (D() < A()) == 'D:A.lt' + assert (D() <= A()) == 'D:A.le' + assert (D() > A()) == 'D:A.gt' + assert (D() >= A()) == 'D:A.ge' + class AppTestOldStyleClassStrDict(object): def setup_class(cls): diff --git a/pypy/module/__pypy__/interp_builders.py b/pypy/module/__pypy__/interp_builders.py --- a/pypy/module/__pypy__/interp_builders.py +++ b/pypy/module/__pypy__/interp_builders.py @@ -7,7 +7,7 @@ class W_UnicodeBuilder(Wrappable): def __init__(self, space, size): - if size == -1: + if size < 0: self.builder = UnicodeBuilder() else: self.builder = UnicodeBuilder(size) @@ -47,4 +47,4 @@ append_slice = interp2app(W_UnicodeBuilder.descr_append_slice), build = interp2app(W_UnicodeBuilder.descr_build), ) -W_UnicodeBuilder.typedef.acceptable_as_base_class = False \ No newline at end of file +W_UnicodeBuilder.typedef.acceptable_as_base_class = False diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py --- a/pypy/module/cpyext/eval.py +++ b/pypy/module/cpyext/eval.py @@ -1,11 +1,16 @@ from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( - cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP) + cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP, + cpython_struct) from pypy.module.cpyext.pyobject import PyObject, borrow_from from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno from pypy.module.__builtin__ import compiling +PyCompilerFlags = cpython_struct( + "PyCompilerFlags", ()) +PyCompilerFlagsPtr = lltype.Ptr(PyCompilerFlags) + @cpython_api([PyObject, PyObject, PyObject], PyObject) def PyEval_CallObjectWithKeywords(space, w_obj, w_arg, w_kwds): return space.call(w_obj, w_arg, w_kwds) @@ -69,7 +74,7 @@ Py_file_input = 257 Py_eval_input = 258 -def run_string(space, source, filename, start, w_globals, w_locals): +def compile_string(space, source, filename, start): w_source = space.wrap(source) start = rffi.cast(lltype.Signed, start) if start == Py_file_input: @@ -80,8 +85,11 @@ mode = 'single' else: raise OperationError(space.w_ValueError, space.wrap( - "invalid mode parameter for PyRun_String")) - w_code = compiling.compile(space, w_source, filename, mode) + "invalid mode parameter for compilation")) + return compiling.compile(space, w_source, filename, mode) + +def run_string(space, source, filename, start, w_globals, w_locals): + w_code = compile_string(space, source, filename, start) return compiling.eval(space, w_code, w_globals, w_locals) @cpython_api([CONST_STRING], rffi.INT_real, error=-1) @@ -140,3 +148,19 @@ pi[0] = space.getindex_w(w_obj, None) return 1 +@cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, PyCompilerFlagsPtr], + PyObject) +def Py_CompileStringFlags(space, source, filename, start, flags): + """Parse and compile the Python source code in str, returning the + resulting code object. The start token is given by start; this + can be used to constrain the code which can be compiled and should + be Py_eval_input, Py_file_input, or Py_single_input. The filename + specified by filename is used to construct the code object and may + appear in tracebacks or SyntaxError exception messages. This + returns NULL if the code cannot be parsed or compiled.""" + source = rffi.charp2str(source) + filename = rffi.charp2str(filename) + if flags: + raise OperationError(space.w_NotImplementedError, space.wrap( + "cpyext Py_CompileStringFlags does not accept flags")) + return compile_string(space, source, filename, start) 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 @@ -2,9 +2,11 @@ from pypy.module.cpyext.api import ( generic_cpy_call, cpython_api, PyObject, CONST_STRING) from pypy.module.cpyext.pyobject import borrow_from -from pypy.rpython.lltypesystem import rffi +from pypy.rpython.lltypesystem import lltype, rffi from pypy.interpreter.error import OperationError from pypy.interpreter.module import Module +from pypy.interpreter.pycode import PyCode +from pypy.module.imp import importing @cpython_api([PyObject], PyObject) def PyImport_Import(space, w_name): @@ -80,3 +82,44 @@ w_modulesDict = space.sys.get('modules') return borrow_from(None, w_modulesDict) +@cpython_api([rffi.CCHARP, PyObject], PyObject) +def PyImport_ExecCodeModule(space, name, w_code): + """Given a module name (possibly of the form package.module) and a code + object read from a Python bytecode file or obtained from the built-in + function compile(), load the module. Return a new reference to the module + object, or NULL with an exception set if an error occurred. Before Python + 2.4, the module could still be created in error cases. Starting with Python + 2.4, name is removed from sys.modules in error cases, and even if name was + already in sys.modules on entry to PyImport_ExecCodeModule(). Leaving + incompletely initialized modules in sys.modules is dangerous, as imports of + such modules have no way to know that the module object is an unknown (and + probably damaged with respect to the module author's intents) state. + + The module's __file__ attribute will be set to the code object's + co_filename. + + This function will reload the module if it was already imported. See + PyImport_ReloadModule() for the intended way to reload a module. + + If name points to a dotted name of the form package.module, any package + structures not already created will still not be created. + + name is removed from sys.modules in error cases.""" + return PyImport_ExecCodeModuleEx(space, name, w_code, + lltype.nullptr(rffi.CCHARP.TO)) + + +@cpython_api([rffi.CCHARP, PyObject, rffi.CCHARP], PyObject) +def PyImport_ExecCodeModuleEx(space, name, w_code, pathname): + """Like PyImport_ExecCodeModule(), but the __file__ attribute of + the module object is set to pathname if it is non-NULL.""" + code = space.interp_w(PyCode, w_code) + w_name = space.wrap(rffi.charp2str(name)) + if pathname: + pathname = rffi.charp2str(pathname) + else: + pathname = code.co_filename + w_mod = importing.add_module(space, w_name) + space.setattr(w_mod, space.wrap('__file__'), space.wrap(pathname)) + importing.exec_code_module(space, w_mod, code) + return w_mod diff --git a/pypy/module/cpyext/include/pythonrun.h b/pypy/module/cpyext/include/pythonrun.h --- a/pypy/module/cpyext/include/pythonrun.h +++ b/pypy/module/cpyext/include/pythonrun.h @@ -13,6 +13,12 @@ #define Py_FrozenFlag 0 +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ +} PyCompilerFlags; + +#define Py_CompileString(str, filename, start) Py_CompileStringFlags(str, filename, start, NULL) + #ifdef __cplusplus } #endif diff --git a/pypy/module/cpyext/presetup.py b/pypy/module/cpyext/presetup.py --- a/pypy/module/cpyext/presetup.py +++ b/pypy/module/cpyext/presetup.py @@ -42,4 +42,4 @@ patch_distutils() del sys.argv[0] -execfile(sys.argv[0]) +execfile(sys.argv[0], {'__file__': sys.argv[0]}) diff --git a/pypy/module/cpyext/setobject.py b/pypy/module/cpyext/setobject.py --- a/pypy/module/cpyext/setobject.py +++ b/pypy/module/cpyext/setobject.py @@ -14,6 +14,11 @@ @cpython_api([PyObject], PyObject) def PySet_New(space, w_iterable): + """Return a new set containing objects returned by the iterable. The + iterable may be NULL to create a new empty set. Return the new set on + success or NULL on failure. Raise TypeError if iterable is not + actually iterable. The constructor is also useful for copying a set + (c=set(s)).""" if w_iterable is None: return space.call_function(space.w_set) else: @@ -21,6 +26,15 @@ @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) def PySet_Add(space, w_s, w_obj): + """Add key to a set instance. Does not apply to frozenset + instances. Return 0 on success or -1 on failure. Raise a TypeError if + the key is unhashable. Raise a MemoryError if there is no room to grow. + Raise a SystemError if set is an not an instance of set or its + subtype. + + Now works with instances of frozenset or its subtypes. + Like PyTuple_SetItem() in that it can be used to fill-in the + values of brand new frozensets before they are exposed to other code.""" if not PySet_Check(space, w_s): PyErr_BadInternalCall(space) space.call_method(w_s, 'add', w_obj) @@ -28,6 +42,12 @@ @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) def PySet_Discard(space, w_s, w_obj): + """Return 1 if found and removed, 0 if not found (no action taken), and -1 if an + error is encountered. Does not raise KeyError for missing keys. Raise a + TypeError if the key is unhashable. Unlike the Python discard() + method, this function does not automatically convert unhashable sets into + temporary frozensets. Raise PyExc_SystemError if set is an not an + instance of set or its subtype.""" if not PySet_Check(space, w_s): PyErr_BadInternalCall(space) space.call_method(w_s, 'discard', w_obj) @@ -36,11 +56,25 @@ @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) def PySet_GET_SIZE(space, w_s): + """Macro form of PySet_Size() without error checking.""" return space.int_w(space.len(w_s)) @cpython_api([PyObject], Py_ssize_t, error=-1) def PySet_Size(space, ref): + """Return the length of a set or frozenset object. Equivalent to + len(anyset). Raises a PyExc_SystemError if anyset is not a set, frozenset, + or an instance of a subtype.""" if not PySet_Check(space, ref): raise OperationError(space.w_TypeError, space.wrap("expected set object")) return PySet_GET_SIZE(space, ref) + +@cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) +def PySet_Contains(space, w_obj, w_key): + """Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike + the Python __contains__() method, this function does not automatically + convert unhashable sets into temporary frozensets. Raise a TypeError if + the key is unhashable. Raise PyExc_SystemError if anyset is not a + set, frozenset, or an instance of a subtype.""" + w_res = space.contains(w_obj, w_key) + return space.int_w(w_res) diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -1048,37 +1048,6 @@ """ raise NotImplementedError -@cpython_api([rffi.CCHARP, PyObject], PyObject) -def PyImport_ExecCodeModule(space, name, co): - """Given a module name (possibly of the form package.module) and a code - object read from a Python bytecode file or obtained from the built-in - function compile(), load the module. Return a new reference to the module - object, or NULL with an exception set if an error occurred. Before Python - 2.4, the module could still be created in error cases. Starting with Python - 2.4, name is removed from sys.modules in error cases, and even if name was - already in sys.modules on entry to PyImport_ExecCodeModule(). Leaving - incompletely initialized modules in sys.modules is dangerous, as imports of - such modules have no way to know that the module object is an unknown (and - probably damaged with respect to the module author's intents) state. - - The module's __file__ attribute will be set to the code object's - co_filename. - - This function will reload the module if it was already imported. See - PyImport_ReloadModule() for the intended way to reload a module. - - If name points to a dotted name of the form package.module, any package - structures not already created will still not be created. - - name is removed from sys.modules in error cases.""" - raise NotImplementedError - -@cpython_api([rffi.CCHARP, PyObject, rffi.CCHARP], PyObject) -def PyImport_ExecCodeModuleEx(space, name, co, pathname): - """Like PyImport_ExecCodeModule(), but the __file__ attribute of - the module object is set to pathname if it is non-NULL.""" - raise NotImplementedError - @cpython_api([], lltype.Signed, error=CANNOT_FAIL) def PyImport_GetMagicNumber(space): """Return the magic number for Python bytecode files (a.k.a. .pyc and @@ -1958,12 +1927,6 @@ raise NotImplementedError @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) -def PySet_Check(space, p): - """Return true if p is a set object or an instance of a subtype. - """ - raise NotImplementedError - -@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyFrozenSet_Check(space, p): """Return true if p is a frozenset object or an instance of a subtype. @@ -1989,15 +1952,6 @@ raise NotImplementedError @cpython_api([PyObject], PyObject) -def PySet_New(space, iterable): - """Return a new set containing objects returned by the iterable. The - iterable may be NULL to create a new empty set. Return the new set on - success or NULL on failure. Raise TypeError if iterable is not - actually iterable. The constructor is also useful for copying a set - (c=set(s)).""" - raise NotImplementedError - -@cpython_api([PyObject], PyObject) def PyFrozenSet_New(space, iterable): """Return a new frozenset containing objects returned by the iterable. The iterable may be NULL to create a new empty frozenset. Return the new @@ -2009,53 +1963,6 @@ building-up new frozensets with PySet_Add().""" raise NotImplementedError -@cpython_api([PyObject], Py_ssize_t, error=-1) -def PySet_Size(space, anyset): - """Return the length of a set or frozenset object. Equivalent to - len(anyset). Raises a PyExc_SystemError if anyset is not a set, frozenset, - or an instance of a subtype. - - This function returned an int. This might require changes in - your code for properly supporting 64-bit systems.""" - raise NotImplementedError - -@cpython_api([PyObject], Py_ssize_t, error=-1) -def PySet_GET_SIZE(space, anyset): - """Macro form of PySet_Size() without error checking.""" - raise NotImplementedError - -@cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) -def PySet_Contains(space, anyset, key): - """Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike - the Python __contains__() method, this function does not automatically - convert unhashable sets into temporary frozensets. Raise a TypeError if - the key is unhashable. Raise PyExc_SystemError if anyset is not a - set, frozenset, or an instance of a subtype.""" - raise NotImplementedError - -@cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) -def PySet_Add(space, set, key): - """Add key to a set instance. Does not apply to frozenset - instances. Return 0 on success or -1 on failure. Raise a TypeError if - the key is unhashable. Raise a MemoryError if there is no room to grow. - Raise a SystemError if set is an not an instance of set or its - subtype. - - Now works with instances of frozenset or its subtypes. - Like PyTuple_SetItem() in that it can be used to fill-in the - values of brand new frozensets before they are exposed to other code.""" - raise NotImplementedError - -@cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) -def PySet_Discard(space, set, key): - """Return 1 if found and removed, 0 if not found (no action taken), and -1 if an - error is encountered. Does not raise KeyError for missing keys. Raise a - TypeError if the key is unhashable. Unlike the Python discard() - method, this function does not automatically convert unhashable sets into - temporary frozensets. Raise PyExc_SystemError if set is an not an - instance of set or its subtype.""" - raise NotImplementedError - @cpython_api([PyObject], PyObject) def PySet_Pop(space, set): """Return a new reference to an arbitrary object in the set, and removes the @@ -2224,29 +2131,6 @@ """Return 1 or 0 depending on whether ch is an alphabetic character.""" raise NotImplementedError -@cpython_api([Py_UNICODE], Py_UNICODE, error=CANNOT_FAIL) -def Py_UNICODE_TOTITLE(space, ch): - """Return the character ch converted to title case.""" - raise NotImplementedError - -@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) -def Py_UNICODE_TODECIMAL(space, ch): - """Return the character ch converted to a decimal positive integer. Return - -1 if this is not possible. This macro does not raise exceptions.""" - raise NotImplementedError - -@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) -def Py_UNICODE_TODIGIT(space, ch): - """Return the character ch converted to a single digit integer. Return -1 if - this is not possible. This macro does not raise exceptions.""" - raise NotImplementedError - -@cpython_api([Py_UNICODE], rffi.DOUBLE, error=CANNOT_FAIL) -def Py_UNICODE_TONUMERIC(space, ch): - """Return the character ch converted to a double. Return -1.0 if this is not - possible. This macro does not raise exceptions.""" - raise NotImplementedError - @cpython_api([rffi.CCHARP], PyObject) def PyUnicode_FromFormat(space, format): """Take a C printf()-style format string and a variable number of @@ -2732,12 +2616,6 @@ use the default error handling.""" raise NotImplementedError -@cpython_api([PyObject, PyObject], PyObject) -def PyUnicode_Join(space, separator, seq): - """Join a sequence of strings using the given separator and return the resulting - Unicode string.""" - raise NotImplementedError - @cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], rffi.INT_real, error=-1) def PyUnicode_Tailmatch(space, str, substr, start, end, direction): """Return 1 if substr matches str*[*start:end] at the given tail end @@ -2800,12 +2678,6 @@ Py_NE, Py_LT, and Py_LE.""" raise NotImplementedError -@cpython_api([PyObject, PyObject], PyObject) -def PyUnicode_Format(space, format, args): - """Return a new string object from format and args; this is analogous to - format % args. The args argument must be a tuple.""" - raise NotImplementedError - @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) def PyUnicode_Contains(space, container, element): """Check whether element is contained in container and return true or false @@ -2992,23 +2864,6 @@ returns.""" raise NotImplementedError -@cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real], PyObject) -def Py_CompileString(space, str, filename, start): - """This is a simplified interface to Py_CompileStringFlags() below, leaving - flags set to NULL.""" - raise NotImplementedError - -@cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, PyCompilerFlags], PyObject) -def Py_CompileStringFlags(space, str, filename, start, flags): - """Parse and compile the Python source code in str, returning the resulting code - object. The start token is given by start; this can be used to constrain the - code which can be compiled and should be Py_eval_input, - Py_file_input, or Py_single_input. The filename specified by - filename is used to construct the code object and may appear in tracebacks or - SyntaxError exception messages. This returns NULL if the code cannot - be parsed or compiled.""" - raise NotImplementedError - @cpython_api([PyCodeObject, PyObject, PyObject], PyObject) def PyEval_EvalCode(space, co, globals, locals): """This is a simplified interface to PyEval_EvalCodeEx(), with just @@ -3076,11 +2931,3 @@ None, or NULL, this will return NULL and raise TypeError. """ raise NotImplementedError - -@cpython_api([PyObject], PyObject) -def PyWeakref_GET_OBJECT(space, ref): - """Similar to PyWeakref_GetObject(), but implemented as a macro that does no - error checking. - """ - borrow_from() - raise NotImplementedError diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py --- a/pypy/module/cpyext/test/test_eval.py +++ b/pypy/module/cpyext/test/test_eval.py @@ -221,4 +221,38 @@ return args assert module.call_func(f) == (None,) assert module.call_method("text") == 2 - + + def test_CompileString_and_Exec(self): + module = self.import_extension('foo', [ + ("compile_string", "METH_NOARGS", + """ + return Py_CompileString( + "f = lambda x: x+5", "someFile", Py_file_input); + """), + ("exec_code", "METH_O", + """ + return PyImport_ExecCodeModule("cpyext_test_modname", args); + """), + ("exec_code_ex", "METH_O", + """ + return PyImport_ExecCodeModuleEx("cpyext_test_modname", + args, "otherFile"); + """), + ]) + code = module.compile_string() + assert code.co_filename == "someFile" + assert code.co_name == "<module>" + + mod = module.exec_code(code) + assert mod.__name__ == "cpyext_test_modname" + assert mod.__file__ == "someFile" + print dir(mod) + print mod.__dict__ + assert mod.f(42) == 47 + + mod = module.exec_code_ex(code) + assert mod.__name__ == "cpyext_test_modname" + assert mod.__file__ == "otherFile" + print dir(mod) + print mod.__dict__ + assert mod.f(42) == 47 diff --git a/pypy/module/cpyext/test/test_setobject.py b/pypy/module/cpyext/test/test_setobject.py --- a/pypy/module/cpyext/test/test_setobject.py +++ b/pypy/module/cpyext/test/test_setobject.py @@ -27,3 +27,8 @@ assert api.PySet_Size(w_set) == 5 api.PySet_Discard(w_set, space.wrap(6)) assert api.PySet_Size(w_set) == 4 + + def test_set_contains(self, space, api): + w_set = api.PySet_New(space.wrap([1,2,3,4])) + assert api.PySet_Contains(w_set, space.wrap(1)) + assert not api.PySet_Contains(w_set, space.wrap(0)) diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -219,6 +219,24 @@ assert api.Py_UNICODE_TOUPPER(u'�') == u'�' assert api.Py_UNICODE_TOUPPER(u'�') == u'�' + def test_TOTITLE(self, space, api): + assert api.Py_UNICODE_TOTITLE(u'/') == u'/' + assert api.Py_UNICODE_TOTITLE(u'�') == u'�' + assert api.Py_UNICODE_TOTITLE(u'�') == u'�' + + def test_TODECIMAL(self, space, api): + assert api.Py_UNICODE_TODECIMAL(u'6') == 6 + assert api.Py_UNICODE_TODECIMAL(u'A') == -1 + + def test_TODIGIT(self, space, api): + assert api.Py_UNICODE_TODIGIT(u'6') == 6 + assert api.Py_UNICODE_TODIGIT(u'A') == -1 + + def test_TONUMERIC(self, space, api): + assert api.Py_UNICODE_TONUMERIC(u'6') == 6.0 + assert api.Py_UNICODE_TONUMERIC(u'A') == -1.0 + assert api.Py_UNICODE_TONUMERIC(u'\N{VULGAR FRACTION ONE HALF}') == .5 + def test_fromobject(self, space, api): w_u = space.wrap(u'a') assert api.PyUnicode_FromObject(w_u) is w_u diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py --- a/pypy/module/cpyext/unicodeobject.py +++ b/pypy/module/cpyext/unicodeobject.py @@ -122,6 +122,38 @@ """Return the character ch converted to upper case.""" return unichr(unicodedb.toupper(ord(ch))) +@cpython_api([Py_UNICODE], Py_UNICODE, error=CANNOT_FAIL) +def Py_UNICODE_TOTITLE(space, ch): + """Return the character ch converted to title case.""" + return unichr(unicodedb.totitle(ord(ch))) + +@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) +def Py_UNICODE_TODECIMAL(space, ch): + """Return the character ch converted to a decimal positive integer. Return + -1 if this is not possible. This macro does not raise exceptions.""" + try: + return unicodedb.decimal(ord(ch)) + except KeyError: + return -1 + +@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL) +def Py_UNICODE_TODIGIT(space, ch): + """Return the character ch converted to a single digit integer. Return -1 if + this is not possible. This macro does not raise exceptions.""" + try: + return unicodedb.digit(ord(ch)) + except KeyError: + return -1 + +@cpython_api([Py_UNICODE], rffi.DOUBLE, error=CANNOT_FAIL) +def Py_UNICODE_TONUMERIC(space, ch): + """Return the character ch converted to a double. Return -1.0 if this is not + possible. This macro does not raise exceptions.""" + try: + return unicodedb.numeric(ord(ch)) + except KeyError: + return -1.0 + @cpython_api([PyObject], rffi.CCHARP, error=CANNOT_FAIL) def PyUnicode_AS_DATA(space, ref): """Return a pointer to the internal buffer of the object. o has to be a @@ -526,8 +558,12 @@ @cpython_api([PyObject, PyObject], PyObject) def PyUnicode_Format(space, w_format, w_args): + """Return a new string object from format and args; this is analogous to + format % args. The args argument must be a tuple.""" return space.mod(w_format, w_args) @cpython_api([PyObject, PyObject], PyObject) def PyUnicode_Join(space, w_sep, w_seq): + """Join a sequence of strings using the given separator and return the resulting + Unicode string.""" return space.call_method(w_sep, 'join', w_seq) diff --git a/pypy/module/cpyext/weakrefobject.py b/pypy/module/cpyext/weakrefobject.py --- a/pypy/module/cpyext/weakrefobject.py +++ b/pypy/module/cpyext/weakrefobject.py @@ -25,6 +25,9 @@ @cpython_api([PyObject], PyObject) def PyWeakref_GET_OBJECT(space, w_ref): + """Similar to PyWeakref_GetObject(), but implemented as a macro that does no + error checking. + """ return borrow_from(w_ref, space.call_function(w_ref)) @cpython_api([PyObject], PyObject) 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 @@ -540,6 +540,13 @@ if pkgdir is not None: space.setattr(w_mod, w('__path__'), space.newlist([w(pkgdir)])) +def add_module(space, w_name): + w_mod = check_sys_modules(space, w_name) + if w_mod is None: + w_mod = space.wrap(Module(space, w_name)) + space.sys.setmodule(w_mod) + return w_mod + def load_c_extension(space, filename, modulename): # the next line is mandatory to init cpyext space.getbuiltinmodule("cpyext") 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 @@ -176,6 +176,38 @@ descr_argmax = _reduce_argmax_argmin_impl(maximum) descr_argmin = _reduce_argmax_argmin_impl(minimum) + def descr_sort(self, space): + size = self.find_size() + stack = [(0,size-1)] + first=0; last=size-1; splitpoint=first; + while (len(stack) > 0): + first, last = stack.pop() + while last>first: + #splitpoint = split(first,last) + x = self.eval(first) + splitpoint = first + unknown = first+1 + while (unknown<=last): + if (self.eval(unknown)<x): + splitpoint = splitpoint + 1 + #interchange(splitpoint,unknown) + temp = self.eval(splitpoint) + self.storage[splitpoint] = self.eval(unknown) + self.storage[unknown] = temp + unknown = unknown + 1 + #interchange(first,splitpoint) + temp = self.eval(splitpoint) + self.storage[splitpoint] = self.eval(first) + self.storage[first] = temp + + if (last-splitpoint<splitpoint-first): + stack.append((first,splitpoint-1)); + first = splitpoint + 1 + else: + stack.append((splitpoint+1,last)); + last = splitpoint - 1 + + def descr_dot(self, space, w_other): if isinstance(w_other, BaseArray): w_res = self.descr_mul(space, w_other) @@ -563,4 +595,5 @@ all = interp2app(BaseArray.descr_all), any = interp2app(BaseArray.descr_any), dot = interp2app(BaseArray.descr_dot), + sort = interp2app(BaseArray.descr_sort), ) diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -427,6 +427,24 @@ b = array([]) raises(ValueError, "b.argmin()") + def test_sort(self): + from numpy import array + a = [3.0,4.0,0.0,-1.0] + b = array(a) + a.sort() + b.sort() + assert(len(a)==len(b)) + for i in range(len(a)): + assert(a[i]==b[i]) + a = array(list(reversed(range(6)))) + b = array(range(6)) + a.sort() + assert(len(a)==len(b)) + for i in range(len(a)): + assert(a[i]==b[i]) + + + def test_all(self): from numpy import array a = array(range(5)) diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py --- a/pypy/module/pyexpat/interp_pyexpat.py +++ b/pypy/module/pyexpat/interp_pyexpat.py @@ -9,6 +9,7 @@ from pypy.rpython.tool import rffi_platform from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.translator.platform import platform import sys import py @@ -19,7 +20,9 @@ libname = 'expat' eci = ExternalCompilationInfo( libraries=[libname], + library_dirs=platform.preprocess_library_dirs([]), includes=['expat.h'], + include_dirs=platform.preprocess_include_dirs([]), ) eci = rffi_platform.configure_external_library( diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py --- a/pypy/module/pypyjit/policy.py +++ b/pypy/module/pypyjit/policy.py @@ -15,7 +15,7 @@ if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions', 'imp', 'sys', 'array', '_ffi', 'itertools', 'operator', 'posix', '_socket', '_sre', '_lsprof', '_weakref', - '__pypy__', 'cStringIO']: + '__pypy__', 'cStringIO', '_collections']: return True return False diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py --- a/pypy/module/pypyjit/test/test_policy.py +++ b/pypy/module/pypyjit/test/test_policy.py @@ -37,8 +37,10 @@ assert pypypolicy.look_inside_function(Local.getdict.im_func) def test_pypy_module(): + from pypy.module._collections.interp_deque import W_Deque from pypy.module._random.interp_random import W_Random assert not pypypolicy.look_inside_function(W_Random.random) + assert pypypolicy.look_inside_function(W_Deque.length) assert not pypypolicy.look_inside_pypy_module('select.interp_epoll') assert pypypolicy.look_inside_pypy_module('__builtin__.operation') assert pypypolicy.look_inside_pypy_module('__builtin__.abstractinst') diff --git a/pypy/module/pypyjit/test_pypy_c/test_math.py b/pypy/module/pypyjit/test_pypy_c/test_math.py --- a/pypy/module/pypyjit/test_pypy_c/test_math.py +++ b/pypy/module/pypyjit/test_pypy_c/test_math.py @@ -60,4 +60,32 @@ i7 = int_add(i0, f1) --TICK-- jump(..., descr=) + """) + + def test_fmod(self): + def main(n): + import math + + s = 0 + while n > 0: + s += math.fmod(n, 2.0) + n -= 1 + return s + log = self.run(main, [500]) + assert log.result == main(500) + loop, = log.loops_by_filename(self.filepath) + assert loop.match(""" + i1 = int_gt(i0, 0) + guard_true(i1, descr=...) + f1 = cast_int_to_float(i0) + i2 = float_eq(f1, inf) + i3 = float_eq(f1, -inf) + i4 = int_or(i2, i3) + i5 = int_is_true(i4) + guard_false(i5, descr=...) + f2 = call(ConstClass(fmod), f1, 2.0, descr=<FloatCallDescr>) + f3 = float_add(f0, f2) + i6 = int_sub(i0, 1) + --TICK-- + jump(..., descr=) """) \ No newline at end of file diff --git a/pypy/module/thread/test/test_ll_thread.py b/pypy/module/thread/test/test_ll_thread.py --- a/pypy/module/thread/test/test_ll_thread.py +++ b/pypy/module/thread/test/test_ll_thread.py @@ -34,6 +34,10 @@ use_threads = True def test_start_new_thread(self): + py.test.skip("xxx ideally, investigate why it fails randomly") + # xxx but in practice start_new_thread() is also tested by the + # next test, and it's a mess to test start_new_thread() without + # the proper GIL to protect the GC import time class State: diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -724,13 +724,22 @@ w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) w_first = w_obj1 w_second = w_obj2 - - if _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): + # + if left == right and _same_class_w(space, w_obj1, w_obj2, + w_typ1, w_typ2): + # for __eq__ and __ne__, if the objects have the same + # (old-style or new-style) class, then don't try the + # opposite method, which is the same one. w_right_impl = None else: - w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2, right) - # XXX see binop_impl - if space.is_true(space.issubtype(w_typ2, w_typ1)): + # in all other cases, try the opposite method. + w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2,right) + if space.is_w(w_typ1, w_typ2): + # if the type is the same, *or* if both are old-style classes, + # then don't reverse: try left first, right next. + pass + elif space.is_true(space.issubtype(w_typ2, w_typ1)): + # for new-style classes, if typ2 is a subclass of typ1. w_obj1, w_obj2 = w_obj2, w_obj1 w_left_impl, w_right_impl = w_right_impl, w_left_impl diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py --- a/pypy/objspace/test/test_descroperation.py +++ b/pypy/objspace/test/test_descroperation.py @@ -377,7 +377,26 @@ setattr(P, "__weakref__", 0) + def test_subclass_addition(self): + # the __radd__ is never called (compare with the next test) + l = [] + class A(object): + def __add__(self, other): + l.append(self.__class__) + l.append(other.__class__) + return 123 + def __radd__(self, other): + # should never be called! + return 456 + class B(A): + pass + res1 = A() + B() + res2 = B() + A() + assert res1 == res2 == 123 + assert l == [A, B, B, A] + def test_subclass_comparison(self): + # the __eq__ *is* called with reversed arguments l = [] class A(object): def __eq__(self, other): @@ -395,7 +414,27 @@ A() == B() A() < B() - assert l == [B, A, A, B] + B() < A() + assert l == [B, A, A, B, B, A] + + def test_subclass_comparison_more(self): + # similarly, __gt__(b,a) is called instead of __lt__(a,b) + l = [] + class A(object): + def __lt__(self, other): + l.append(self.__class__) + l.append(other.__class__) + return '<' + def __gt__(self, other): + l.append(self.__class__) + l.append(other.__class__) + return '>' + class B(A): + pass + res1 = A() < B() + res2 = B() < A() + assert res1 == '>' and res2 == '<' + assert l == [B, A, B, A] def test_rich_comparison(self): # Old-style @@ -434,6 +473,84 @@ assert not(C(1) == D(2)) assert not(D(1) == C(2)) + def test_partial_ordering(self): + class A(object): + def __lt__(self, other): + return self + a1 = A() + a2 = A() + assert (a1 < a2) is a1 + assert (a1 > a2) is a2 + + def test_eq_order(self): + class A(object): + def __eq__(self, other): return self.__class__.__name__+':A.eq' + def __ne__(self, other): return self.__class__.__name__+':A.ne' + def __lt__(self, other): return self.__class__.__name__+':A.lt' + def __le__(self, other): return self.__class__.__name__+':A.le' + def __gt__(self, other): return self.__class__.__name__+':A.gt' + def __ge__(self, other): return self.__class__.__name__+':A.ge' + class B(object): + def __eq__(self, other): return self.__class__.__name__+':B.eq' + def __ne__(self, other): return self.__class__.__name__+':B.ne' + def __lt__(self, other): return self.__class__.__name__+':B.lt' + def __le__(self, other): return self.__class__.__name__+':B.le' + def __gt__(self, other): return self.__class__.__name__+':B.gt' + def __ge__(self, other): return self.__class__.__name__+':B.ge' + # + assert (A() == B()) == 'A:A.eq' + assert (A() != B()) == 'A:A.ne' + assert (A() < B()) == 'A:A.lt' + assert (A() <= B()) == 'A:A.le' + assert (A() > B()) == 'A:A.gt' + assert (A() >= B()) == 'A:A.ge' + # + assert (B() == A()) == 'B:B.eq' + assert (B() != A()) == 'B:B.ne' + assert (B() < A()) == 'B:B.lt' + assert (B() <= A()) == 'B:B.le' + assert (B() > A()) == 'B:B.gt' + assert (B() >= A()) == 'B:B.ge' + # + class C(A): + def __eq__(self, other): return self.__class__.__name__+':C.eq' + def __ne__(self, other): return self.__class__.__name__+':C.ne' + def __lt__(self, other): return self.__class__.__name__+':C.lt' + def __le__(self, other): return self.__class__.__name__+':C.le' + def __gt__(self, other): return self.__class__.__name__+':C.gt' + def __ge__(self, other): return self.__class__.__name__+':C.ge' + # + assert (A() == C()) == 'C:C.eq' + assert (A() != C()) == 'C:C.ne' + assert (A() < C()) == 'C:C.gt' + assert (A() <= C()) == 'C:C.ge' + assert (A() > C()) == 'C:C.lt' + assert (A() >= C()) == 'C:C.le' + # + assert (C() == A()) == 'C:C.eq' + assert (C() != A()) == 'C:C.ne' + assert (C() < A()) == 'C:C.lt' + assert (C() <= A()) == 'C:C.le' + assert (C() > A()) == 'C:C.gt' + assert (C() >= A()) == 'C:C.ge' + # + class D(A): + pass + # + assert (A() == D()) == 'D:A.eq' + assert (A() != D()) == 'D:A.ne' + assert (A() < D()) == 'D:A.gt' + assert (A() <= D()) == 'D:A.ge' + assert (A() > D()) == 'D:A.lt' + assert (A() >= D()) == 'D:A.le' + # + assert (D() == A()) == 'D:A.eq' + assert (D() != A()) == 'D:A.ne' + assert (D() < A()) == 'D:A.lt' + assert (D() <= A()) == 'D:A.le' + assert (D() > A()) == 'D:A.gt' + assert (D() >= A()) == 'D:A.ge' + def test_addition(self): # Old-style class A: diff --git a/pypy/rlib/parsing/makepackrat.py b/pypy/rlib/parsing/makepackrat.py --- a/pypy/rlib/parsing/makepackrat.py +++ b/pypy/rlib/parsing/makepackrat.py @@ -251,9 +251,11 @@ return "ErrorInformation(%s, %s)" % (self.pos, self.expected) def get_line_column(self, source): - uptoerror = source[:self.pos] + pos = self.pos + assert pos >= 0 + uptoerror = source[:pos] lineno = uptoerror.count("\n") - columnno = self.pos - uptoerror.rfind("\n") + columnno = pos - uptoerror.rfind("\n") return lineno, columnno def nice_error_message(self, filename='<filename>', source=""): diff --git a/pypy/rpython/extfuncregistry.py b/pypy/rpython/extfuncregistry.py --- a/pypy/rpython/extfuncregistry.py +++ b/pypy/rpython/extfuncregistry.py @@ -44,6 +44,13 @@ ('log10', [float], float), ('sin', [float], float), ('cos', [float], float), + ('atan2', [float, float], float), + ('hypot', [float, float], float), + ('frexp', [float], (float, int)), + ('ldexp', [float, int], float), + ('modf', [float], (float, float)), + ('fmod', [float, float], float), + ('pow', [float, float], float), ]), ] for module, methods in _register: @@ -54,23 +61,6 @@ sandboxsafe=True, llimpl=getattr(ll_math, method_name)) - -complex_math_functions = [ - ('frexp', [float], (float, int)), - ('ldexp', [float, int], float), - ('modf', [float], (float, float)), - ] + [(name, [float, float], float) - for name in 'atan2', 'fmod', 'hypot', 'pow'] - -for name, args, res in complex_math_functions: - func = getattr(math, name) - llimpl = getattr(ll_math, 'll_math_%s' % name, None) - oofake = getattr(oo_math, 'll_math_%s' % name, None) - register_external(func, args, res, 'll_math.ll_math_%s' % name, - llimpl=llimpl, oofakeimpl=oofake, - sandboxsafe=True) - - # ___________________________ # os.path functions diff --git a/pypy/rpython/lltypesystem/module/ll_math.py b/pypy/rpython/lltypesystem/module/ll_math.py --- a/pypy/rpython/lltypesystem/module/ll_math.py +++ b/pypy/rpython/lltypesystem/module/ll_math.py @@ -223,22 +223,13 @@ def ll_math_fmod(x, y): - if isinf(y): - if isinf(x): - raise ValueError("math domain error") - return x # fmod(x, +/-Inf) returns x for finite x (or if x is a NaN). + if isinf(x) and not isnan(y): + raise ValueError("math domain error") - _error_reset() - r = math_fmod(x, y) - errno = rposix.get_errno() - if isnan(r): - if isnan(x) or isnan(y): - errno = 0 - else: - errno = EDOM - if errno: - _likely_raise(errno, r) - return r + if y == 0: + raise ValueError("math domain error") + + return math_fmod(x, y) def ll_math_hypot(x, y): diff --git a/pypy/rpython/memory/gc/env.py b/pypy/rpython/memory/gc/env.py --- a/pypy/rpython/memory/gc/env.py +++ b/pypy/rpython/memory/gc/env.py @@ -116,6 +116,10 @@ def get_total_memory(): return get_total_memory_darwin(get_darwin_sysctl_signed('hw.memsize')) +elif sys.platform.startswith('freebsd'): + def get_total_memory(): + return get_total_memory_darwin(get_darwin_sysctl_signed('hw.usermem')) + else: def get_total_memory(): return addressable_size # XXX implement me for other platforms diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py --- a/pypy/tool/release/package.py +++ b/pypy/tool/release/package.py @@ -133,6 +133,8 @@ if copy_to_dir is not None: print "Copying %s to %s" % (archive, copy_to_dir) shutil.copy(archive, str(copy_to_dir)) + else: + print "Ready in %s" % (builddir,) return builddir # for tests if __name__ == '__main__': _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit