[pypy-commit] pypy win64-stage1: Merge with default
ctismer
noreply at buildbot.pypy.org
Mon Nov 14 23:27:29 CET 2011
Author: Christian Tismer <tismer at stackless.com>
Branch: win64-stage1
Changeset: r49421:4b214639c276
Date: 2011-11-14 18:54 +0100
http://bitbucket.org/pypy/pypy/changeset/4b214639c276/
Log: Merge with default
diff --git a/lib-python/modified-2.7/test/test_import.py b/lib-python/modified-2.7/test/test_import.py
--- a/lib-python/modified-2.7/test/test_import.py
+++ b/lib-python/modified-2.7/test/test_import.py
@@ -64,6 +64,7 @@
except ImportError, err:
self.fail("import from %s failed: %s" % (ext, err))
else:
+ # XXX importing .pyw is missing on Windows
self.assertEqual(mod.a, a,
"module loaded (%s) but contents invalid" % mod)
self.assertEqual(mod.b, b,
diff --git a/lib-python/modified-2.7/test/test_repr.py b/lib-python/modified-2.7/test/test_repr.py
--- a/lib-python/modified-2.7/test/test_repr.py
+++ b/lib-python/modified-2.7/test/test_repr.py
@@ -254,8 +254,14 @@
eq = self.assertEqual
touch(os.path.join(self.subpkgname, self.pkgname + os.extsep + 'py'))
from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation
- eq(repr(areallylongpackageandmodulenametotestreprtruncation),
- "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
+ # On PyPy, we use %r to format the file name; on CPython it is done
+ # with '%s'. It seems to me that %r is safer <arigo>.
+ if '__pypy__' in sys.builtin_module_names:
+ eq(repr(areallylongpackageandmodulenametotestreprtruncation),
+ "<module %r from %r>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
+ else:
+ eq(repr(areallylongpackageandmodulenametotestreprtruncation),
+ "<module '%s' from '%s'>" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__))
eq(repr(sys), "<module 'sys' (built-in)>")
def test_type(self):
diff --git a/lib-python/2.7/test/test_subprocess.py b/lib-python/modified-2.7/test/test_subprocess.py
copy from lib-python/2.7/test/test_subprocess.py
copy to lib-python/modified-2.7/test/test_subprocess.py
--- a/lib-python/2.7/test/test_subprocess.py
+++ b/lib-python/modified-2.7/test/test_subprocess.py
@@ -16,11 +16,11 @@
# Depends on the following external programs: Python
#
-if mswindows:
- SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
- 'os.O_BINARY);')
-else:
- SETBINARY = ''
+#if mswindows:
+# SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
+# 'os.O_BINARY);')
+#else:
+# SETBINARY = ''
try:
@@ -420,8 +420,9 @@
self.assertStderrEqual(stderr, "")
def test_universal_newlines(self):
- p = subprocess.Popen([sys.executable, "-c",
- 'import sys,os;' + SETBINARY +
+ # NB. replaced SETBINARY with the -u flag
+ p = subprocess.Popen([sys.executable, "-u", "-c",
+ 'import sys,os;' + #SETBINARY +
'sys.stdout.write("line1\\n");'
'sys.stdout.flush();'
'sys.stdout.write("line2\\r");'
@@ -448,8 +449,9 @@
def test_universal_newlines_communicate(self):
# universal newlines through communicate()
- p = subprocess.Popen([sys.executable, "-c",
- 'import sys,os;' + SETBINARY +
+ # NB. replaced SETBINARY with the -u flag
+ p = subprocess.Popen([sys.executable, "-u", "-c",
+ 'import sys,os;' + #SETBINARY +
'sys.stdout.write("line1\\n");'
'sys.stdout.flush();'
'sys.stdout.write("line2\\r");'
diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -292,7 +292,7 @@
import os, sys
print sys.executable, self.tmpfile
if sys.platform == "win32":
- cmdformat = '""%s" "%s""' # excellent! tons of "!
+ cmdformat = '"%s" "%s"'
else:
cmdformat = "'%s' '%s'"
g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r')
diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py
--- a/pypy/jit/codewriter/call.py
+++ b/pypy/jit/codewriter/call.py
@@ -212,7 +212,10 @@
elidable = False
loopinvariant = False
if op.opname == "direct_call":
- func = getattr(get_funcobj(op.args[0].value), '_callable', None)
+ funcobj = get_funcobj(op.args[0].value)
+ assert getattr(funcobj, 'calling_conv', 'c') == 'c', (
+ "%r: getcalldescr() with a non-default call ABI" % (op,))
+ func = getattr(funcobj, '_callable', None)
elidable = getattr(func, "_elidable_function_", False)
loopinvariant = getattr(func, "_jit_loop_invariant_", False)
if loopinvariant:
diff --git a/pypy/module/_rawffi/structure.py b/pypy/module/_rawffi/structure.py
--- a/pypy/module/_rawffi/structure.py
+++ b/pypy/module/_rawffi/structure.py
@@ -212,6 +212,8 @@
while count + basic_size <= total_size:
fieldtypes.append(basic_ffi_type)
count += basic_size
+ if basic_size == 0: # corner case. get out of this infinite
+ break # loop after 1 iteration ("why not")
self.ffi_struct = clibffi.make_struct_ffitype_e(self.size,
self.alignment,
fieldtypes)
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -1022,6 +1022,12 @@
assert ret.y == 1234500, "ret.y == %d" % (ret.y,)
s.free()
+ def test_ffi_type(self):
+ import _rawffi
+ EMPTY = _rawffi.Structure([])
+ S2E = _rawffi.Structure([('bah', (EMPTY, 1))])
+ S2E.get_ffi_type() # does not hang
+
class AppTestAutoFree:
def setup_class(cls):
space = gettestobjspace(usemodules=('_rawffi', 'struct'))
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
@@ -513,7 +513,7 @@
space.warn(msg, space.w_ImportWarning)
modtype, suffix, filemode = find_modtype(space, filepart)
try:
- if modtype in (PY_SOURCE, PY_COMPILED):
+ if modtype in (PY_SOURCE, PY_COMPILED, C_EXTENSION):
assert suffix is not None
filename = filepart + suffix
stream = streamio.open_file_as_stream(filename, filemode)
@@ -522,9 +522,6 @@
except:
stream.close()
raise
- if modtype == C_EXTENSION:
- filename = filepart + suffix
- return FindInfo(modtype, filename, None, suffix, filemode)
except StreamErrors:
pass # XXX! must not eat all exceptions, e.g.
# Out of file descriptors.
diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -137,6 +137,8 @@
interpleveldefs['execve'] = 'interp_posix.execve'
if hasattr(posix, 'spawnv'):
interpleveldefs['spawnv'] = 'interp_posix.spawnv'
+ if hasattr(posix, 'spawnve'):
+ interpleveldefs['spawnve'] = 'interp_posix.spawnve'
if hasattr(os, 'uname'):
interpleveldefs['uname'] = 'interp_posix.uname'
if hasattr(os, 'sysconf'):
diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -760,6 +760,14 @@
except OSError, e:
raise wrap_oserror(space, e)
+def _env2interp(space, w_env):
+ env = {}
+ w_keys = space.call_method(w_env, 'keys')
+ for w_key in space.unpackiterable(w_keys):
+ w_value = space.getitem(w_env, w_key)
+ env[space.str_w(w_key)] = space.str_w(w_value)
+ return env
+
def execve(space, w_command, w_args, w_env):
""" execve(path, args, env)
@@ -771,11 +779,7 @@
"""
command = fsencode_w(space, w_command)
args = [fsencode_w(space, w_arg) for w_arg in space.unpackiterable(w_args)]
- env = {}
- w_keys = space.call_method(w_env, 'keys')
- for w_key in space.unpackiterable(w_keys):
- w_value = space.getitem(w_env, w_key)
- env[space.str_w(w_key)] = space.str_w(w_value)
+ env = _env2interp(space, w_env)
try:
os.execve(command, args, env)
except OSError, e:
@@ -790,6 +794,16 @@
raise wrap_oserror(space, e)
return space.wrap(ret)
+ at unwrap_spec(mode=int, path=str)
+def spawnve(space, mode, path, w_args, w_env):
+ args = [space.str_w(w_arg) for w_arg in space.unpackiterable(w_args)]
+ env = _env2interp(space, w_env)
+ try:
+ ret = os.spawnve(mode, path, args, env)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+ return space.wrap(ret)
+
def utime(space, w_path, w_tuple):
""" utime(path, (atime, mtime))
utime(path, None)
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -471,6 +471,17 @@
['python', '-c', 'raise(SystemExit(42))'])
assert ret == 42
+ if hasattr(__import__(os.name), "spawnve"):
+ def test_spawnve(self):
+ os = self.posix
+ import sys
+ print self.python
+ ret = os.spawnve(os.P_WAIT, self.python,
+ ['python', '-c',
+ "raise(SystemExit(int(__import__('os').environ['FOOBAR'])))"],
+ {'FOOBAR': '42'})
+ assert ret == 42
+
def test_popen(self):
os = self.posix
for i in range(5):
diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py
--- a/pypy/module/pypyjit/test_pypy_c/model.py
+++ b/pypy/module/pypyjit/test_pypy_c/model.py
@@ -285,6 +285,11 @@
guard_false(ticker_cond1, descr=...)
"""
src = src.replace('--EXC-TICK--', exc_ticker_check)
+ #
+ # ISINF is done as a macro; fix it here
+ r = re.compile('(\w+) = --ISINF--[(](\w+)[)]')
+ src = r.sub(r'\2\B999 = float_add(\2, ...)\n\1 = float_eq(\2\B999, \2)',
+ src)
return src
@classmethod
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
@@ -1,3 +1,4 @@
+import py
from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
@@ -49,10 +50,7 @@
guard_true(i2, descr=...)
guard_not_invalidated(descr=...)
f1 = cast_int_to_float(i0)
- i3 = float_eq(f1, inf)
- i4 = float_eq(f1, -inf)
- i5 = int_or(i3, i4)
- i6 = int_is_true(i5)
+ i6 = --ISINF--(f1)
guard_false(i6, descr=...)
f2 = call(ConstClass(sin), f1, descr=<FloatCallDescr>)
f3 = call(ConstClass(cos), f1, descr=<FloatCallDescr>)
@@ -64,6 +62,7 @@
""")
def test_fmod(self):
+ py.test.skip("test relies on the old and broken ll_math_fmod")
def main(n):
import math
@@ -90,4 +89,4 @@
i6 = int_sub(i0, 1)
--TICK--
jump(..., descr=)
- """)
\ No newline at end of file
+ """)
diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py
--- a/pypy/module/test_lib_pypy/test_pwd.py
+++ b/pypy/module/test_lib_pypy/test_pwd.py
@@ -1,7 +1,10 @@
+import py, sys
from pypy.conftest import gettestobjspace
class AppTestPwd:
def setup_class(cls):
+ if sys.platform == 'win32':
+ py.test.skip("Unix only")
cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi'))
cls.space.appexec((), "(): import pwd")
diff --git a/pypy/objspace/std/bytearraytype.py b/pypy/objspace/std/bytearraytype.py
--- a/pypy/objspace/std/bytearraytype.py
+++ b/pypy/objspace/std/bytearraytype.py
@@ -122,10 +122,11 @@
return -1
def descr_fromhex(space, w_type, w_hexstring):
- "bytearray.fromhex(string) -> bytearray\n\nCreate a bytearray object "
- "from a string of hexadecimal numbers.\nSpaces between two numbers are "
- "accepted.\nExample: bytearray.fromhex('B9 01EF') -> "
- "bytearray(b'\\xb9\\x01\\xef')."
+ "bytearray.fromhex(string) -> bytearray\n"
+ "\n"
+ "Create a bytearray object from a string of hexadecimal numbers.\n"
+ "Spaces between two numbers are accepted.\n"
+ "Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."
hexstring = space.str_w(w_hexstring)
hexstring = hexstring.lower()
data = []
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -16,7 +16,10 @@
something CPython does not do anymore.
"""
-class W_IntObject(W_Object):
+class W_AbstractIntObject(W_Object):
+ __slots__ = ()
+
+class W_IntObject(W_AbstractIntObject):
__slots__ = 'intval'
_immutable_fields_ = ['intval']
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -4,7 +4,10 @@
from pypy.objspace.std.register_all import register_all
-class W_AbstractSeqIterObject(W_Object):
+class W_AbstractIterObject(W_Object):
+ __slots__ = ()
+
+class W_AbstractSeqIterObject(W_AbstractIterObject):
from pypy.objspace.std.itertype import iter_typedef as typedef
def __init__(w_self, w_seq, index=0):
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -11,7 +11,10 @@
from pypy.rlib.listsort import make_timsort_class
from pypy.interpreter.argument import Signature
-class W_ListObject(W_Object):
+class W_AbstractListObject(W_Object):
+ __slots__ = ()
+
+class W_ListObject(W_AbstractListObject):
from pypy.objspace.std.listtype import list_typedef as typedef
def __init__(w_self, wrappeditems):
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -8,7 +8,10 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.rlib.rbigint import rbigint, SHIFT
-class W_LongObject(W_Object):
+class W_AbstractLongObject(W_Object):
+ __slots__ = ()
+
+class W_LongObject(W_AbstractLongObject):
"""This is a wrapper of rbigint."""
from pypy.objspace.std.longtype import long_typedef as typedef
_immutable_fields_ = ['num']
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -83,12 +83,7 @@
if self.config.objspace.std.withtproxy:
transparent.setup(self)
- interplevel_classes = {}
- for type, classes in self.model.typeorder.iteritems():
- if len(classes) >= 3: # XXX what does this 3 mean??!
- # W_Root, AnyXxx and actual object
- interplevel_classes[self.gettypefor(type)] = classes[0][0]
- self._interplevel_classes = interplevel_classes
+ self.setup_isinstance_cache()
def get_builtin_types(self):
return self.builtin_types
@@ -592,6 +587,63 @@
def isinstance_w(space, w_inst, w_type):
return space._type_isinstance(w_inst, w_type)
+ def setup_isinstance_cache(self):
+ # This assumes that all classes in the stdobjspace implementing a
+ # particular app-level type are distinguished by a common base class.
+ # Alternatively, you can turn off the cache on specific classes,
+ # like e.g. proxyobject. It is just a bit less performant but
+ # should not have any bad effect.
+ from pypy.objspace.std.model import W_Root, W_Object
+ #
+ # Build a dict {class: w_typeobject-or-None}. The value None is used
+ # on classes that are known to be abstract base classes.
+ class2type = {}
+ class2type[W_Root] = None
+ class2type[W_Object] = None
+ for cls in self.model.typeorder.keys():
+ if getattr(cls, 'typedef', None) is None:
+ continue
+ if getattr(cls, 'ignore_for_isinstance_cache', False):
+ continue
+ w_type = self.gettypefor(cls)
+ w_oldtype = class2type.setdefault(cls, w_type)
+ assert w_oldtype is w_type
+ #
+ # Build the real dict {w_typeobject: class-or-base-class}. For every
+ # w_typeobject we look for the most precise common base class of all
+ # the registered classes. If no such class is found, we will find
+ # W_Object or W_Root, and complain. Then you must either add an
+ # artificial common base class, or disable caching on one of the
+ # two classes with ignore_for_isinstance_cache.
+ def getmro(cls):
+ while True:
+ yield cls
+ if cls is W_Root:
+ break
+ cls = cls.__bases__[0]
+ self._interplevel_classes = {}
+ for cls, w_type in class2type.items():
+ if w_type is None:
+ continue
+ if w_type not in self._interplevel_classes:
+ self._interplevel_classes[w_type] = cls
+ else:
+ cls1 = self._interplevel_classes[w_type]
+ mro1 = list(getmro(cls1))
+ for base in getmro(cls):
+ if base in mro1:
+ break
+ if base in class2type and class2type[base] is not w_type:
+ if class2type.get(base) is None:
+ msg = ("cannot find a common interp-level base class"
+ " between %r and %r" % (cls1, cls))
+ else:
+ msg = ("%s is a base class of both %r and %r" % (
+ class2type[base], cls1, cls))
+ raise AssertionError("%r: %s" % (w_type, msg))
+ class2type[base] = w_type
+ self._interplevel_classes[w_type] = base
+
@specialize.memo()
def _get_interplevel_cls(self, w_type):
if not hasattr(self, "_interplevel_classes"):
diff --git a/pypy/objspace/std/proxyobject.py b/pypy/objspace/std/proxyobject.py
--- a/pypy/objspace/std/proxyobject.py
+++ b/pypy/objspace/std/proxyobject.py
@@ -16,6 +16,8 @@
def transparent_class(name, BaseCls):
class W_Transparent(BaseCls):
+ ignore_for_isinstance_cache = True
+
def __init__(self, space, w_type, w_controller):
self.w_type = w_type
self.w_controller = w_controller
diff --git a/pypy/objspace/std/rangeobject.py b/pypy/objspace/std/rangeobject.py
--- a/pypy/objspace/std/rangeobject.py
+++ b/pypy/objspace/std/rangeobject.py
@@ -5,7 +5,7 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.listobject import W_AbstractListObject, W_ListObject
from pypy.objspace.std import listtype, iterobject, slicetype
from pypy.interpreter import gateway, baseobjspace
@@ -21,7 +21,7 @@
return (start - stop - step - 1)/-step
-class W_RangeListObject(W_Object):
+class W_RangeListObject(W_AbstractListObject):
typedef = listtype.list_typedef
def __init__(w_self, start, step, length):
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -6,7 +6,7 @@
from pypy.rlib.objectmodel import we_are_translated
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std import slicetype
+from pypy.objspace.std import stringobject, slicetype, iterobject
from pypy.objspace.std.listobject import W_ListObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.tupleobject import W_TupleObject
@@ -19,7 +19,7 @@
str_format__String as str_format__Rope,
_upper, _lower, DEFAULT_NOOP_TABLE)
-class W_RopeObject(W_Object):
+class W_RopeObject(stringobject.W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
_immutable_fields_ = ['_node']
@@ -59,7 +59,7 @@
registerimplementation(W_RopeObject)
-class W_RopeIterObject(W_Object):
+class W_RopeIterObject(iterobject.W_AbstractIterObject):
from pypy.objspace.std.itertype import iter_typedef as typedef
def __init__(w_self, w_rope, index=0):
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -9,7 +9,7 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.rlib import rope
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
-from pypy.objspace.std import slicetype
+from pypy.objspace.std import unicodeobject, slicetype, iterobject
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.rlib.rarithmetic import intmask, ovfcheck
from pypy.module.unicodedata import unicodedb
@@ -76,7 +76,7 @@
return encode_object(space, w_unistr, encoding, errors)
-class W_RopeUnicodeObject(W_Object):
+class W_RopeUnicodeObject(unicodeobject.W_AbstractUnicodeObject):
from pypy.objspace.std.unicodetype import unicode_typedef as typedef
_immutable_fields_ = ['_node']
@@ -117,7 +117,7 @@
return rope.LiteralUnicodeNode(space.unicode_w(w_str))
-class W_RopeUnicodeIterObject(W_Object):
+class W_RopeUnicodeIterObject(iterobject.W_AbstractIterObject):
from pypy.objspace.std.itertype import iter_typedef as typedef
def __init__(w_self, w_rope, index=0):
diff --git a/pypy/objspace/std/smallintobject.py b/pypy/objspace/std/smallintobject.py
--- a/pypy/objspace/std/smallintobject.py
+++ b/pypy/objspace/std/smallintobject.py
@@ -6,7 +6,7 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.noneobject import W_NoneObject
-from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject
from pypy.interpreter.error import OperationError
from pypy.rlib.objectmodel import UnboxedValue
from pypy.rlib.rbigint import rbigint
@@ -14,7 +14,7 @@
from pypy.tool.sourcetools import func_with_new_name
from pypy.objspace.std.inttype import wrapint
-class W_SmallIntObject(W_Object, UnboxedValue):
+class W_SmallIntObject(W_AbstractIntObject, UnboxedValue):
__slots__ = 'intval'
from pypy.objspace.std.inttype import int_typedef as typedef
diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py
--- a/pypy/objspace/std/smalllongobject.py
+++ b/pypy/objspace/std/smalllongobject.py
@@ -9,7 +9,7 @@
from pypy.rlib.rarithmetic import r_longlong, r_int, r_uint
from pypy.rlib.rarithmetic import intmask, LONGLONG_BIT
from pypy.rlib.rbigint import rbigint
-from pypy.objspace.std.longobject import W_LongObject
+from pypy.objspace.std.longobject import W_AbstractLongObject, W_LongObject
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.interpreter.error import OperationError
@@ -17,7 +17,7 @@
LONGLONG_MIN = r_longlong((-1) << (LONGLONG_BIT-1))
-class W_SmallLongObject(W_Object):
+class W_SmallLongObject(W_AbstractLongObject):
from pypy.objspace.std.longtype import long_typedef as typedef
_immutable_fields_ = ['longlong']
diff --git a/pypy/objspace/std/smalltupleobject.py b/pypy/objspace/std/smalltupleobject.py
--- a/pypy/objspace/std/smalltupleobject.py
+++ b/pypy/objspace/std/smalltupleobject.py
@@ -9,9 +9,9 @@
from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
from pypy.rlib.unroll import unrolling_iterable
-from pypy.objspace.std.tupleobject import W_TupleObject
+from pypy.objspace.std.tupleobject import W_AbstractTupleObject, W_TupleObject
-class W_SmallTupleObject(W_Object):
+class W_SmallTupleObject(W_AbstractTupleObject):
from pypy.objspace.std.tupletype import tuple_typedef as typedef
def tolist(self):
diff --git a/pypy/objspace/std/strbufobject.py b/pypy/objspace/std/strbufobject.py
--- a/pypy/objspace/std/strbufobject.py
+++ b/pypy/objspace/std/strbufobject.py
@@ -1,11 +1,12 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stringobject import W_AbstractStringObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import delegate_String2Unicode
from pypy.rlib.rstring import StringBuilder
from pypy.interpreter.buffer import Buffer
-class W_StringBufferObject(W_Object):
+class W_StringBufferObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
w_str = None
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -19,7 +19,10 @@
from pypy.objspace.std.formatting import mod_format
-class W_StringObject(W_Object):
+class W_AbstractStringObject(W_Object):
+ __slots__ = ()
+
+class W_StringObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
_immutable_fields_ = ['_value']
diff --git a/pypy/objspace/std/strjoinobject.py b/pypy/objspace/std/strjoinobject.py
--- a/pypy/objspace/std/strjoinobject.py
+++ b/pypy/objspace/std/strjoinobject.py
@@ -1,11 +1,12 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stringobject import W_AbstractStringObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import delegate_String2Unicode
from pypy.objspace.std.stringtype import wrapstr
-class W_StringJoinObject(W_Object):
+class W_StringJoinObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
def __init__(w_self, joined_strs, until=-1):
diff --git a/pypy/objspace/std/strsliceobject.py b/pypy/objspace/std/strsliceobject.py
--- a/pypy/objspace/std/strsliceobject.py
+++ b/pypy/objspace/std/strsliceobject.py
@@ -1,6 +1,7 @@
from pypy.interpreter.error import OperationError
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
+from pypy.objspace.std.stringobject import W_AbstractStringObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.unicodeobject import delegate_String2Unicode
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
@@ -12,7 +13,7 @@
stringendswith, stringstartswith
-class W_StringSliceObject(W_Object):
+class W_StringSliceObject(W_AbstractStringObject):
from pypy.objspace.std.stringtype import str_typedef as typedef
def __init__(w_self, str, start, stop):
diff --git a/pypy/objspace/std/test/test_sliceobject.py b/pypy/objspace/std/test/test_sliceobject.py
--- a/pypy/objspace/std/test/test_sliceobject.py
+++ b/pypy/objspace/std/test/test_sliceobject.py
@@ -1,3 +1,4 @@
+import sys
from pypy.objspace.std.sliceobject import normalize_simple_slice
@@ -56,8 +57,9 @@
sl = space.newslice(w(start), w(stop), w(step))
mystart, mystop, mystep, slicelength = sl.indices4(space, length)
assert len(range(length)[start:stop:step]) == slicelength
- assert slice(start, stop, step).indices(length) == (
- mystart, mystop, mystep)
+ if sys.version_info >= (2, 6): # doesn't work in 2.5
+ assert slice(start, stop, step).indices(length) == (
+ mystart, mystop, mystep)
class AppTest_SliceObject:
def test_new(self):
diff --git a/pypy/objspace/std/test/test_stdobjspace.py b/pypy/objspace/std/test/test_stdobjspace.py
--- a/pypy/objspace/std/test/test_stdobjspace.py
+++ b/pypy/objspace/std/test/test_stdobjspace.py
@@ -50,6 +50,8 @@
def test_fastpath_isinstance(self):
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.intobject import W_IntObject
+ from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
+ from pypy.objspace.std.iterobject import W_SeqIterObject
space = self.space
assert space._get_interplevel_cls(space.w_str) is W_StringObject
@@ -62,9 +64,13 @@
assert space.isinstance_w(X(), space.w_str)
+ w_sequenceiterator = space.gettypefor(W_SeqIterObject)
+ cls = space._get_interplevel_cls(w_sequenceiterator)
+ assert cls is W_AbstractSeqIterObject
+
def test_withstrbuf_fastpath_isinstance(self):
- from pypy.objspace.std.stringobject import W_StringObject
+ from pypy.objspace.std.stringobject import W_AbstractStringObject
- space = gettestobjspace(withstrbuf=True)
- assert space._get_interplevel_cls(space.w_str) is W_StringObject
-
+ space = gettestobjspace(withstrbuf=True)
+ cls = space._get_interplevel_cls(space.w_str)
+ assert cls is W_AbstractStringObject
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -9,7 +9,10 @@
from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
-class W_TupleObject(W_Object):
+class W_AbstractTupleObject(W_Object):
+ __slots__ = ()
+
+class W_TupleObject(W_AbstractTupleObject):
from pypy.objspace.std.tupletype import tuple_typedef as typedef
_immutable_fields_ = ['wrappeditems[*]']
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -19,7 +19,10 @@
from pypy.objspace.std.formatting import mod_format
from pypy.objspace.std.stringtype import stringstartswith, stringendswith
-class W_UnicodeObject(W_Object):
+class W_AbstractUnicodeObject(W_Object):
+ __slots__ = ()
+
+class W_UnicodeObject(W_AbstractUnicodeObject):
from pypy.objspace.std.unicodetype import unicode_typedef as typedef
_immutable_fields_ = ['_value']
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -31,6 +31,9 @@
_MAC_OS = platform.name == "darwin"
_FREEBSD_7 = platform.name == "freebsd7"
+_LITTLE_ENDIAN = sys.byteorder == 'little'
+_BIG_ENDIAN = sys.byteorder == 'big'
+
if _WIN32:
from pypy.rlib import rwin32
@@ -339,15 +342,38 @@
cast_type_to_ffitype._annspecialcase_ = 'specialize:memo'
def push_arg_as_ffiptr(ffitp, arg, ll_buf):
- # this is for primitive types. For structures and arrays
- # would be something different (more dynamic)
+ # This is for primitive types. Note that the exact type of 'arg' may be
+ # different from the expected 'c_size'. To cope with that, we fall back
+ # to a byte-by-byte copy.
TP = lltype.typeOf(arg)
TP_P = lltype.Ptr(rffi.CArray(TP))
- buf = rffi.cast(TP_P, ll_buf)
- buf[0] = arg
+ TP_size = rffi.sizeof(TP)
+ c_size = intmask(ffitp.c_size)
+ # if both types have the same size, we can directly write the
+ # value to the buffer
+ if c_size == TP_size:
+ buf = rffi.cast(TP_P, ll_buf)
+ buf[0] = arg
+ else:
+ # needs byte-by-byte copying. Make sure 'arg' is an integer type.
+ # Note that this won't work for rffi.FLOAT/rffi.DOUBLE.
+ assert TP is not rffi.FLOAT and TP is not rffi.DOUBLE
+ if TP_size <= rffi.sizeof(lltype.Signed):
+ arg = rffi.cast(lltype.Unsigned, arg)
+ else:
+ arg = rffi.cast(lltype.UnsignedLongLong, arg)
+ if _LITTLE_ENDIAN:
+ for i in range(c_size):
+ ll_buf[i] = chr(arg & 0xFF)
+ arg >>= 8
+ elif _BIG_ENDIAN:
+ for i in range(c_size-1, -1, -1):
+ ll_buf[i] = chr(arg & 0xFF)
+ arg >>= 8
+ else:
+ raise AssertionError
push_arg_as_ffiptr._annspecialcase_ = 'specialize:argtype(1)'
-
# type defs for callback and closure userdata
USERDATA_P = lltype.Ptr(lltype.ForwardReference())
CALLBACK_TP = lltype.Ptr(lltype.FuncType([rffi.VOIDPP, rffi.VOIDP, USERDATA_P],
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -234,7 +234,7 @@
# It is important that there is no other operation in the middle, else
# the optimizer will fail to recognize the pattern and won't turn it
# into a fast CALL. Note that "arg = arg.next" is optimized away,
- # assuming that archain is completely virtual.
+ # assuming that argchain is completely virtual.
self = jit.promote(self)
if argchain.numargs != len(self.argtypes):
raise TypeError, 'Wrong number of arguments: %d expected, got %d' %\
diff --git a/pypy/rlib/test/test_libffi.py b/pypy/rlib/test/test_libffi.py
--- a/pypy/rlib/test/test_libffi.py
+++ b/pypy/rlib/test/test_libffi.py
@@ -179,6 +179,17 @@
res = self.call(func, [chr(20), 22], rffi.LONG)
assert res == 42
+ def test_char_args(self):
+ """
+ char sum_args(char a, char b) {
+ return a + b;
+ }
+ """
+ libfoo = self.get_libfoo()
+ func = (libfoo, 'sum_args', [types.schar, types.schar], types.schar)
+ res = self.call(func, [123, 43], rffi.CHAR)
+ assert res == chr(166)
+
def test_unsigned_short_args(self):
"""
unsigned short sum_xy_us(unsigned short x, unsigned short y)
diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -1178,10 +1178,14 @@
value = value.adr
if isinstance(value, llmemory.fakeaddress):
value = value.ptr or 0
+ if isinstance(value, r_singlefloat):
+ value = float(value)
TYPE1 = lltype.typeOf(value)
cvalue = lltype2ctypes(value)
cresulttype = get_ctypes_type(RESTYPE)
- if isinstance(TYPE1, lltype.Ptr):
+ if RESTYPE == TYPE1:
+ return value
+ elif isinstance(TYPE1, lltype.Ptr):
if isinstance(RESTYPE, lltype.Ptr):
# shortcut: ptr->ptr cast
cptr = ctypes.cast(cvalue, cresulttype)
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -126,6 +126,7 @@
canraise=False,
random_effects_on_gcobjs=
random_effects_on_gcobjs,
+ calling_conv=calling_conv,
**kwds)
if isinstance(_callable, ll2ctypes.LL2CtypesCallable):
_callable.funcptr = funcptr
@@ -865,11 +866,12 @@
try:
unsigned = not tp._type.SIGNED
except AttributeError:
- if tp in [lltype.Char, lltype.Float, lltype.Signed] or\
- isinstance(tp, lltype.Ptr):
+ if (not isinstance(tp, lltype.Primitive) or
+ tp in (FLOAT, DOUBLE) or
+ cast(lltype.SignedLongLong, cast(tp, -1)) < 0):
unsigned = False
else:
- unsigned = False
+ unsigned = True
return size, unsigned
def sizeof(tp):
diff --git a/pypy/rpython/lltypesystem/test/test_rffi.py b/pypy/rpython/lltypesystem/test/test_rffi.py
--- a/pypy/rpython/lltypesystem/test/test_rffi.py
+++ b/pypy/rpython/lltypesystem/test/test_rffi.py
@@ -18,6 +18,7 @@
from pypy.conftest import option
from pypy.objspace.flow.model import summary
from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rlib.rarithmetic import r_singlefloat
class BaseTestRffi:
def test_basic(self):
@@ -704,6 +705,14 @@
res = cast(lltype.Signed, 42.5)
assert res == 42
+ res = cast(lltype.SingleFloat, 12.3)
+ assert res == r_singlefloat(12.3)
+ res = cast(lltype.SingleFloat, res)
+ assert res == r_singlefloat(12.3)
+
+ res = cast(lltype.Float, r_singlefloat(12.))
+ assert res == 12.
+
def test_rffi_sizeof(self):
try:
import ctypes
@@ -733,7 +742,7 @@
assert sizeof(ll) == ctypes.sizeof(ctp)
assert sizeof(lltype.Typedef(ll, 'test')) == sizeof(ll)
assert not size_and_sign(lltype.Signed)[1]
- assert not size_and_sign(lltype.Char)[1]
+ assert size_and_sign(lltype.Char) == (1, True)
assert not size_and_sign(lltype.UniChar)[1]
assert size_and_sign(UINT)[1]
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -356,6 +356,32 @@
return extdef([int, str, [str]], int, llimpl=spawnv_llimpl,
export_name="ll_os.ll_os_spawnv")
+ @registering_if(os, 'spawnve')
+ def register_os_spawnve(self):
+ os_spawnve = self.llexternal('spawnve',
+ [rffi.INT, rffi.CCHARP, rffi.CCHARPP,
+ rffi.CCHARPP],
+ rffi.INT)
+
+ def spawnve_llimpl(mode, path, args, env):
+ envstrs = []
+ for item in env.iteritems():
+ envstrs.append("%s=%s" % item)
+
+ mode = rffi.cast(rffi.INT, mode)
+ l_args = rffi.liststr2charpp(args)
+ l_env = rffi.liststr2charpp(envstrs)
+ childpid = os_spawnve(mode, path, l_args, l_env)
+ rffi.free_charpp(l_env)
+ rffi.free_charpp(l_args)
+ if childpid == -1:
+ raise OSError(rposix.get_errno(), "os_spawnve failed")
+ return rffi.cast(lltype.Signed, childpid)
+
+ return extdef([int, str, [str], {str: str}], int,
+ llimpl=spawnve_llimpl,
+ export_name="ll_os.ll_os_spawnve")
+
@registering(os.dup)
def register_os_dup(self):
os_dup = self.llexternal(underscore_on_windows+'dup', [rffi.INT], rffi.INT)
diff --git a/pypy/translator/c/test/test_extfunc.py b/pypy/translator/c/test/test_extfunc.py
--- a/pypy/translator/c/test/test_extfunc.py
+++ b/pypy/translator/c/test/test_extfunc.py
@@ -818,6 +818,24 @@
func()
assert open(filename).read() == "2"
+if hasattr(posix, 'spawnve'):
+ def test_spawnve():
+ filename = str(udir.join('test_spawnve.txt'))
+ progname = str(sys.executable)
+ scriptpath = udir.join('test_spawnve.py')
+ scriptpath.write('import os\n' +
+ 'f=open(%r,"w")\n' % filename +
+ 'f.write(os.environ["FOOBAR"])\n' +
+ 'f.close\n')
+ scriptname = str(scriptpath)
+ def does_stuff():
+ l = [progname, scriptname]
+ pid = os.spawnve(os.P_NOWAIT, progname, l, {'FOOBAR': '42'})
+ os.waitpid(pid, 0)
+ func = compile(does_stuff, [])
+ func()
+ assert open(filename).read() == "42"
+
def test_utime():
path = str(udir.ensure("test_utime.txt"))
from time import time, sleep
diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py
--- a/pypy/translator/platform/__init__.py
+++ b/pypy/translator/platform/__init__.py
@@ -42,6 +42,8 @@
so_prefixes = ('',)
+ extra_libs = ()
+
def __init__(self, cc):
if self.__class__ is Platform:
raise TypeError("You should not instantiate Platform class directly")
@@ -181,7 +183,8 @@
link_files = self._linkfiles(eci.link_files)
export_flags = self._exportsymbols_link_flags(eci)
return (library_dirs + list(self.link_flags) + export_flags +
- link_files + list(eci.link_extra) + libraries)
+ link_files + list(eci.link_extra) + libraries +
+ list(self.extra_libs))
def _exportsymbols_link_flags(self, eci, relto=None):
if eci.export_symbols:
diff --git a/pypy/translator/platform/linux.py b/pypy/translator/platform/linux.py
--- a/pypy/translator/platform/linux.py
+++ b/pypy/translator/platform/linux.py
@@ -6,7 +6,8 @@
class BaseLinux(BasePosix):
name = "linux"
- link_flags = ('-pthread', '-lrt')
+ link_flags = ('-pthread',)
+ extra_libs = ('-lrt',)
cflags = ('-O3', '-pthread', '-fomit-frame-pointer',
'-Wall', '-Wno-unused')
standalone_only = ()
diff --git a/pypy/translator/platform/posix.py b/pypy/translator/platform/posix.py
--- a/pypy/translator/platform/posix.py
+++ b/pypy/translator/platform/posix.py
@@ -140,7 +140,7 @@
('DEFAULT_TARGET', exe_name.basename),
('SOURCES', rel_cfiles),
('OBJECTS', rel_ofiles),
- ('LIBS', self._libs(eci.libraries)),
+ ('LIBS', self._libs(eci.libraries) + list(self.extra_libs)),
('LIBDIRS', self._libdirs(rel_libdirs)),
('INCLUDEDIRS', self._includedirs(rel_includedirs)),
('CFLAGS', cflags),
diff --git a/pypy/translator/platform/test/test_posix.py b/pypy/translator/platform/test/test_posix.py
--- a/pypy/translator/platform/test/test_posix.py
+++ b/pypy/translator/platform/test/test_posix.py
@@ -41,6 +41,7 @@
if self.strict_on_stderr:
assert res.err == ''
assert res.returncode == 0
+ assert '-lrt' in tmpdir.join("Makefile").read()
def test_link_files(self):
tmpdir = udir.join('link_files' + self.__class__.__name__).ensure(dir=1)
diff --git a/pypy/translator/test/test_simplify.py b/pypy/translator/test/test_simplify.py
--- a/pypy/translator/test/test_simplify.py
+++ b/pypy/translator/test/test_simplify.py
@@ -42,24 +42,6 @@
assert graph.startblock.operations[0].opname == 'int_mul_ovf'
assert graph.startblock.operations[1].opname == 'int_sub'
-def test_remove_ovfcheck_lshift():
- # check that ovfcheck_lshift() is handled
- from pypy.rlib.rarithmetic import ovfcheck_lshift
- def f(x):
- try:
- return ovfcheck_lshift(x, 2)
- except OverflowError:
- return -42
- graph, _ = translate(f, [int])
- assert len(graph.startblock.operations) == 1
- assert graph.startblock.operations[0].opname == 'int_lshift_ovf'
- assert len(graph.startblock.operations[0].args) == 2
- assert len(graph.startblock.exits) == 2
- assert [link.exitcase for link in graph.startblock.exits] == \
- [None, OverflowError]
- assert [link.target.operations for link in graph.startblock.exits] == \
- [(), ()]
-
def test_remove_ovfcheck_floordiv():
# check that ovfcheck() is handled even if the operation raises
# and catches another exception too, here ZeroDivisionError
More information about the pypy-commit
mailing list