[pypy-commit] pypy streamio-bufinput: merge in default
justinpeel
noreply at buildbot.pypy.org
Sat Aug 27 08:50:13 CEST 2011
Author: Justin Peel <notmuchtotell at 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
+ at 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)
+ at 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))
+
+
+ at 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)
+
+ at 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
- at 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
-
- at 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
-
- at 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
-
- at 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
- at 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
-
- at cpython_api([PyObject], Py_ssize_t, error=-1)
-def PySet_GET_SIZE(space, anyset):
- """Macro form of PySet_Size() without error checking."""
- raise NotImplementedError
-
- at 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
-
- at 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
-
- at 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
- at 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
-
- at 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
-
- at 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
-
- at 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
- at 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
- at 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
- at 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
-
- at 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
-
- at 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)))
+ at 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)))
+
+ at 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
+
+ at 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
+
+ at 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__':
More information about the pypy-commit
mailing list