[pypy-commit] pypy default: merged upstream
alex_gaynor
noreply at buildbot.pypy.org
Sat Apr 26 20:58:53 CEST 2014
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r71008:bd1d5bf88f29
Date: 2014-04-26 11:58 -0700
http://bitbucket.org/pypy/pypy/changeset/bd1d5bf88f29/
Log: merged upstream
diff --git a/dotviewer/graphserver.py b/dotviewer/graphserver.py
--- a/dotviewer/graphserver.py
+++ b/dotviewer/graphserver.py
@@ -160,15 +160,14 @@
" | instructions in dotviewer/sshgraphserver.py\n")
try:
import pygame
- except ImportError:
+ if isinstance(e, pygame.error):
+ print >> f, help
+ except Exception, e:
f.seek(0)
f.truncate()
- print >> f, "ImportError"
+ print >> f, "%s: %s" % (e.__class__.__name__, e)
print >> f, " | Pygame is not installed; either install it, or"
print >> f, help
- else:
- if isinstance(e, pygame.error):
- print >> f, help
io.sendmsg(msgstruct.MSG_ERROR, f.getvalue())
else:
listen_server(sys.argv[1])
diff --git a/lib-python/2.7/test/test_builtin.py b/lib-python/2.7/test/test_builtin.py
--- a/lib-python/2.7/test/test_builtin.py
+++ b/lib-python/2.7/test/test_builtin.py
@@ -250,14 +250,12 @@
self.assertRaises(TypeError, compile)
self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'badmode')
self.assertRaises(ValueError, compile, 'print 42\n', '<string>', 'single', 0xff)
- if check_impl_detail(cpython=True):
- self.assertRaises(TypeError, compile, chr(0), 'f', 'exec')
+ self.assertRaises(TypeError, compile, chr(0), 'f', 'exec')
self.assertRaises(TypeError, compile, 'pass', '?', 'exec',
mode='eval', source='0', filename='tmp')
if have_unicode:
compile(unicode('print u"\xc3\xa5"\n', 'utf8'), '', 'exec')
- if check_impl_detail(cpython=True):
- self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec')
+ self.assertRaises(TypeError, compile, unichr(0), 'f', 'exec')
self.assertRaises(ValueError, compile, unicode('a = 1'), 'f', 'bad')
diff --git a/lib-python/2.7/test/test_file2k.py b/lib-python/2.7/test/test_file2k.py
--- a/lib-python/2.7/test/test_file2k.py
+++ b/lib-python/2.7/test/test_file2k.py
@@ -479,11 +479,10 @@
def _create_file(self):
if self.use_buffering:
- f = open(self.filename, "w+", buffering=1024*16)
+ self.f = open(self.filename, "w+", buffering=1024*16)
else:
- f = open(self.filename, "w+")
- self.f = f
- self.all_files.append(f)
+ self.f = open(self.filename, "w+")
+ self.all_files.append(self.f)
oldf = self.all_files.pop(0)
if oldf is not None:
oldf.close()
diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py
--- a/lib_pypy/_ctypes_test.py
+++ b/lib_pypy/_ctypes_test.py
@@ -1,4 +1,5 @@
-import imp, os
+import imp
+import os
try:
import cpyext
@@ -17,7 +18,8 @@
output_dir = _pypy_testcapi.get_hashed_dir(os.path.join(thisdir, cfile))
try:
fp, filename, description = imp.find_module('_ctypes_test', path=[output_dir])
- imp.load_module('_ctypes_test', fp, filename, description)
+ with fp:
+ imp.load_module('_ctypes_test', fp, filename, description)
except ImportError:
print('could not find _ctypes_test in %s' % output_dir)
_pypy_testcapi.compile_shared('_ctypes_test.c', '_ctypes_test', output_dir)
diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py
--- a/lib_pypy/_testcapi.py
+++ b/lib_pypy/_testcapi.py
@@ -1,4 +1,5 @@
-import imp, os
+import imp
+import os
try:
import cpyext
@@ -12,6 +13,7 @@
try:
fp, filename, description = imp.find_module('_testcapi', path=[output_dir])
- imp.load_module('_testcapi', fp, filename, description)
+ with fp:
+ imp.load_module('_testcapi', fp, filename, description)
except ImportError:
_pypy_testcapi.compile_shared(cfile, '_testcapi', output_dir)
diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst
--- a/pypy/doc/cppyy.rst
+++ b/pypy/doc/cppyy.rst
@@ -583,7 +583,7 @@
Special care needs to be taken for global operator overloads in C++: first,
make sure that they are actually reflected, especially for the global
overloads for ``operator==`` and ``operator!=`` of STL vector iterators in
- the case of gcc (note that they are not needed to iterator over a vector).
+ the case of gcc (note that they are not needed to iterate over a vector).
Second, make sure that reflection info is loaded in the proper order.
I.e. that these global overloads are available before use.
diff --git a/pypy/interpreter/main.py b/pypy/interpreter/main.py
--- a/pypy/interpreter/main.py
+++ b/pypy/interpreter/main.py
@@ -15,10 +15,11 @@
space.setitem(w_modules, w_main, mainmodule)
return mainmodule
+
def compilecode(space, source, filename, cmd='exec'):
w = space.wrap
- w_code = space.builtin.call('compile',
- w(source), w(filename), w(cmd), w(0), w(0))
+ w_code = space.builtin.call(
+ 'compile', w(source), w(filename), w(cmd), w(0), w(0))
pycode = space.interp_w(eval.Code, w_code)
return pycode
@@ -28,7 +29,7 @@
cmd = 'eval'
else:
cmd = 'exec'
-
+
try:
if space is None:
from pypy.objspace.std import StdObjSpace
@@ -55,18 +56,22 @@
operationerr.record_interpreter_traceback()
raise
+
def run_string(source, filename=None, space=None):
_run_eval_string(source, filename, space, False)
+
def eval_string(source, filename=None, space=None):
return _run_eval_string(source, filename, space, True)
+
def run_file(filename, space=None):
- if __name__=='__main__':
+ if __name__ == '__main__':
print "Running %r with %r" % (filename, space)
istring = open(filename).read()
run_string(istring, filename, space)
+
def run_module(module_name, args, space=None):
"""Implements PEP 338 'Executing modules as scripts', overwriting
sys.argv[1:] using `args` and executing the module `module_name`.
@@ -89,7 +94,6 @@
return space.call_function(w_run_module, w(module_name), space.w_None,
w('__main__'), space.w_True)
-# ____________________________________________________________
def run_toplevel(space, f, verbose=False):
"""Calls f() and handle all OperationErrors.
diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -22,22 +22,6 @@
compile; if absent or zero these statements do influence the compilation,
in addition to any features explicitly specified.
"""
-
- ast_node = None
- w_ast_type = space.gettypeobject(ast.AST.typedef)
- str_ = None
- if space.isinstance_w(w_source, w_ast_type):
- ast_node = space.interp_w(ast.mod, w_source)
- ast_node.sync_app_attrs(space)
- elif space.isinstance_w(w_source, space.w_unicode):
- w_utf_8_source = space.call_method(w_source, "encode",
- space.wrap("utf-8"))
- str_ = space.str_w(w_utf_8_source)
- # This flag tells the parser to reject any coding cookies it sees.
- flags |= consts.PyCF_SOURCE_IS_UTF8
- else:
- str_ = space.str_w(w_source)
-
ec = space.getexecutioncontext()
if flags & ~(ec.compiler.compiler_flags | consts.PyCF_ONLY_AST |
consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8):
@@ -53,14 +37,30 @@
space.wrap("compile() arg 3 must be 'exec' "
"or 'eval' or 'single'"))
- if ast_node is None:
- if flags & consts.PyCF_ONLY_AST:
- mod = ec.compiler.compile_to_ast(str_, filename, mode, flags)
- return space.wrap(mod)
- else:
- code = ec.compiler.compile(str_, filename, mode, flags)
+ w_ast_type = space.gettypeobject(ast.AST.typedef)
+ if space.isinstance_w(w_source, w_ast_type):
+ ast_node = space.interp_w(ast.mod, w_source)
+ ast_node.sync_app_attrs(space)
+ code = ec.compiler.compile_ast(ast_node, filename, mode, flags)
+ return space.wrap(code)
+
+ if space.isinstance_w(w_source, space.w_unicode):
+ w_utf_8_source = space.call_method(w_source, "encode",
+ space.wrap("utf-8"))
+ str_ = space.str_w(w_utf_8_source)
+ # This flag tells the parser to reject any coding cookies it sees.
+ flags |= consts.PyCF_SOURCE_IS_UTF8
else:
- code = ec.compiler.compile_ast(ast_node, filename, mode, flags)
+ str_ = space.readbuf_w(w_source).as_str()
+
+ if '\x00' in str_:
+ raise OperationError(space.w_TypeError, space.wrap(
+ "compile() expected string without null bytes"))
+
+ if flags & consts.PyCF_ONLY_AST:
+ code = ec.compiler.compile_to_ast(str_, filename, mode, flags)
+ else:
+ code = ec.compiler.compile(str_, filename, mode, flags)
return space.wrap(code)
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -351,17 +351,17 @@
self.promote_step = promote_step
def descr_new(space, w_subtype, w_start, w_stop=None, w_step=None):
- start = _toint(space, w_start)
+ start = space.int_w(w_start)
if space.is_none(w_step): # no step argument provided
step = 1
promote_step = True
else:
- step = _toint(space, w_step)
+ step = space.int_w(w_step)
promote_step = False
if space.is_none(w_stop): # only 1 argument provided
start, stop = 0, start
else:
- stop = _toint(space, w_stop)
+ stop = space.int_w(w_stop)
howmany = get_len_of_range(space, start, stop, step)
obj = space.allocate_instance(W_XRange, w_subtype)
W_XRange.__init__(obj, space, start, howmany, step, promote_step)
@@ -425,11 +425,6 @@
minint = -sys.maxint - 1
return minint if last < minint - step else last + step
-def _toint(space, w_obj):
- # this also supports float arguments. CPython still does, too.
- # needs a bit more thinking in general...
- return space.int_w(space.int(w_obj))
-
W_XRange.typedef = TypeDef("xrange",
__new__ = interp2app(W_XRange.descr_new.im_func),
__repr__ = interp2app(W_XRange.descr_repr),
@@ -441,6 +436,7 @@
)
W_XRange.typedef.acceptable_as_base_class = False
+
class W_XRangeIterator(W_Root):
def __init__(self, space, current, remaining, step):
self.space = space
@@ -488,7 +484,10 @@
)
W_XRangeIterator.typedef.acceptable_as_base_class = False
+
class W_XRangeStepOneIterator(W_XRangeIterator):
+ _immutable_fields_ = ['stop']
+
def __init__(self, space, start, stop):
self.space = space
self.current = start
diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -311,14 +311,14 @@
def test_xrange_len(self):
x = xrange(33)
assert len(x) == 33
- x = xrange(33.2)
- assert len(x) == 33
+ exc = raises(TypeError, xrange, 33.2)
+ assert "integer" in str(exc.value)
x = xrange(33,0,-1)
assert len(x) == 33
x = xrange(33,0)
assert len(x) == 0
- x = xrange(33,0.2)
- assert len(x) == 0
+ exc = raises(TypeError, xrange, 33, 0.2)
+ assert "integer" in str(exc.value)
x = xrange(0,33)
assert len(x) == 33
x = xrange(0,33,-1)
@@ -490,6 +490,14 @@
def test_compile(self):
co = compile('1+2', '?', 'eval')
assert eval(co) == 3
+ co = compile(buffer('1+2'), '?', 'eval')
+ assert eval(co) == 3
+ exc = raises(TypeError, compile, chr(0), '?', 'eval')
+ assert str(exc.value) == "compile() expected string without null bytes"
+ exc = raises(TypeError, compile, unichr(0), '?', 'eval')
+ assert str(exc.value) == "compile() expected string without null bytes"
+ exc = raises(TypeError, compile, memoryview('1+2'), '?', 'eval')
+ assert str(exc.value) == "expected a readable buffer object"
compile("from __future__ import with_statement", "<test>", "exec")
raises(SyntaxError, compile, '-', '?', 'eval')
raises(ValueError, compile, '"\\xt"', '?', 'eval')
diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py
--- a/pypy/module/__builtin__/test/test_functional.py
+++ b/pypy/module/__builtin__/test/test_functional.py
@@ -1,5 +1,4 @@
class AppTestMap:
-
def test_trivial_map_one_seq(self):
assert map(lambda x: x+2, [1, 2, 3, 4]) == [3, 4, 5, 6]
@@ -77,6 +76,7 @@
assert result == [(2, 7), (1, 6), (None, 5), (None, 4),
(None, 3), (None, 2), (None, 1)]
+
class AppTestZip:
def test_one_list(self):
assert zip([1,2,3]) == [(1,), (2,), (3,)]
@@ -93,6 +93,7 @@
yield None
assert zip(Foo()) == []
+
class AppTestReduce:
def test_None(self):
raises(TypeError, reduce, lambda x, y: x+y, [1,2,3], None)
@@ -105,6 +106,7 @@
assert reduce(lambda x, y: x-y, [10, 2, 8]) == 0
assert reduce(lambda x, y: x-y, [2, 8], 10) == 0
+
class AppTestFilter:
def test_None(self):
assert filter(None, ['a', 'b', 1, 0, None]) == ['a', 'b', 1]
@@ -125,6 +127,7 @@
return i * 10
assert filter(lambda x: x != 20, T("abcd")) == (0, 10, 30)
+
class AppTestXRange:
def test_xrange(self):
x = xrange(2, 9, 3)
@@ -155,7 +158,8 @@
assert list(xrange(0, 10, A())) == [0, 5]
def test_xrange_float(self):
- assert list(xrange(0.1, 2.0, 1.1)) == [0, 1]
+ exc = raises(TypeError, xrange, 0.1, 2.0, 1.1)
+ assert "integer" in str(exc.value)
def test_xrange_long(self):
import sys
@@ -218,6 +222,7 @@
assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o']
raises(TypeError, reversed, reversed("hello"))
+
class AppTestApply:
def test_apply(self):
def f(*args, **kw):
@@ -228,6 +233,7 @@
assert apply(f, args) == (args, {})
assert apply(f, args, kw) == (args, kw)
+
class AppTestAllAny:
"""
These are copied directly and replicated from the Python 2.5 source code.
@@ -277,6 +283,7 @@
S = [10, 20, 30]
assert any([x > 42 for x in S]) == False
+
class AppTestMinMax:
def test_min(self):
assert min(1, 2) == 1
diff --git a/pypy/module/__pypy__/test/test_bytebuffer.py b/pypy/module/__pypy__/test/test_bytebuffer.py
--- a/pypy/module/__pypy__/test/test_bytebuffer.py
+++ b/pypy/module/__pypy__/test/test_bytebuffer.py
@@ -25,5 +25,6 @@
assert str(b) == "\x00xy" + "\x00" * 7
b[4:8:2] = 'zw'
assert str(b) == "\x00xy\x00z\x00w" + "\x00" * 3
- b[6:10] = u'#'
- assert str(b) == "\x00xy\x00z\x00#" + "\x00" * 3
+ r = str(buffer(u'#'))
+ b[6:6+len(r)] = u'#'
+ assert str(b[:6+len(r)]) == "\x00xy\x00z\x00" + r
diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py
--- a/pypy/module/_codecs/interp_codecs.py
+++ b/pypy/module/_codecs/interp_codecs.py
@@ -679,7 +679,7 @@
if space.isinstance_w(w_string, space.w_unicode):
return space.newtuple([w_string, space.len(w_string)])
- string = space.str_w(w_string)
+ string = space.readbuf_w(w_string).as_str()
if len(string) == 0:
return space.newtuple([space.wrap(u''), space.wrap(0)])
diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py
--- a/pypy/module/_codecs/test/test_codecs.py
+++ b/pypy/module/_codecs/test/test_codecs.py
@@ -276,7 +276,7 @@
assert enc == "a\x00\x00\x00"
def test_unicode_internal_decode(self):
- import sys
+ import sys, _codecs, array
if sys.maxunicode == 65535: # UCS2 build
if sys.byteorder == "big":
bytes = "\x00a"
@@ -291,6 +291,9 @@
bytes2 = "\x98\x00\x01\x00"
assert bytes2.decode("unicode_internal") == u"\U00010098"
assert bytes.decode("unicode_internal") == u"a"
+ assert _codecs.unicode_internal_decode(array.array('c', bytes))[0] == u"a"
+ exc = raises(TypeError, _codecs.unicode_internal_decode, memoryview(bytes))
+ assert str(exc.value) == "expected a readable buffer object"
def test_raw_unicode_escape(self):
assert unicode("\u0663", "raw-unicode-escape") == u"\u0663"
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -460,14 +460,17 @@
space = self.space
self.check_closed()
- w_iterator = space.iter(w_lines)
- while True:
- try:
- w_line = space.next(w_iterator)
- except OperationError, e:
- if not e.match(space, space.w_StopIteration):
- raise
- break # done
+ lines = space.fixedview(w_lines)
+ for i, w_line in enumerate(lines):
+ if not space.isinstance_w(w_line, space.w_str):
+ try:
+ line = w_line.charbuf_w(space)
+ except TypeError:
+ raise OperationError(space.w_TypeError, space.wrap(
+ "writelines() argument must be a sequence of strings"))
+ else:
+ lines[i] = space.wrap(line)
+ for w_line in lines:
self.file_write(w_line)
def file_readinto(self, w_rwbuffer):
diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py
--- a/pypy/module/_file/test/test_file_extra.py
+++ b/pypy/module/_file/test/test_file_extra.py
@@ -386,6 +386,32 @@
assert len(somelines) > 200
assert somelines == lines[:len(somelines)]
+ def test_writelines(self):
+ import array
+ fn = self.temptestfile
+ with file(fn, 'w') as f:
+ f.writelines(['abc'])
+ f.writelines([u'def'])
+ exc = raises(TypeError, f.writelines, [array.array('c', 'ghi')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ exc = raises(TypeError, f.writelines, [memoryview('jkl')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ assert open(fn, 'r').readlines() == ['abcdef']
+
+ with file(fn, 'wb') as f:
+ f.writelines(['abc'])
+ f.writelines([u'def'])
+ exc = raises(TypeError, f.writelines, [array.array('c', 'ghi')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ exc = raises(TypeError, f.writelines, [memoryview('jkl')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ assert open(fn, 'rb').readlines() == ['abcdef']
+
+ with file(fn, 'wb') as f:
+ exc = raises(TypeError, f.writelines, ['abc', memoryview('def')])
+ assert str(exc.value) == "writelines() argument must be a sequence of strings"
+ assert open(fn, 'rb').readlines() == []
+
def test_nasty_writelines(self):
# The stream lock should be released between writes
fn = self.temptestfile
diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py
--- a/pypy/module/_rawffi/array.py
+++ b/pypy/module/_rawffi/array.py
@@ -193,7 +193,7 @@
def setslice(self, space, w_slice, w_value):
start, stop = self.decodeslice(space, w_slice)
- value = space.bufferstr_w(w_value)
+ value = space.str_w(w_value)
if start + len(value) != stop:
raise OperationError(space.w_ValueError,
space.wrap("cannot resize array"))
diff --git a/pypy/module/_winreg/interp_winreg.py b/pypy/module/_winreg/interp_winreg.py
--- a/pypy/module/_winreg/interp_winreg.py
+++ b/pypy/module/_winreg/interp_winreg.py
@@ -2,7 +2,7 @@
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from pypy.interpreter.error import OperationError, wrap_windowserror
+from pypy.interpreter.error import OperationError, wrap_windowserror, oefmt
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib import rwinreg, rwin32
from rpython.rlib.rarithmetic import r_uint, intmask
@@ -327,7 +327,14 @@
buf = lltype.malloc(rffi.CCHARP.TO, 1, flavor='raw')
buf[0] = '\0'
else:
- value = space.bufferstr_w(w_value)
+ try:
+ value = w_value.readbuf_w(space)
+ except TypeError:
+ raise oefmt(space.w_TypeError,
+ "Objects of type '%T' can not be used as binary "
+ "registry values", w_value)
+ else:
+ value = value.as_str()
buflen = len(value)
buf = rffi.str2charp(value)
diff --git a/pypy/module/_winreg/test/test_winreg.py b/pypy/module/_winreg/test/test_winreg.py
--- a/pypy/module/_winreg/test/test_winreg.py
+++ b/pypy/module/_winreg/test/test_winreg.py
@@ -137,11 +137,15 @@
assert 0, "Did not raise"
def test_SetValueEx(self):
- from _winreg import CreateKey, SetValueEx
+ from _winreg import CreateKey, SetValueEx, REG_BINARY
key = CreateKey(self.root_key, self.test_key_name)
sub_key = CreateKey(key, "sub_key")
for name, value, type in self.test_data:
SetValueEx(sub_key, name, 0, type, value)
+ exc = raises(TypeError, SetValueEx, sub_key, 'test_name', None,
+ REG_BINARY, memoryview('abc'))
+ assert str(exc.value) == ("Objects of type 'memoryview' can not "
+ "be used as binary registry values")
def test_readValues(self):
from _winreg import OpenKey, EnumValue, QueryValueEx, EnumKey
diff --git a/pypy/module/cppyy/__init__.py b/pypy/module/cppyy/__init__.py
--- a/pypy/module/cppyy/__init__.py
+++ b/pypy/module/cppyy/__init__.py
@@ -25,6 +25,7 @@
'_init_pythonify' : 'pythonify._init_pythonify',
'load_reflection_info' : 'pythonify.load_reflection_info',
'add_pythonization' : 'pythonify.add_pythonization',
+ 'Template' : 'pythonify.CppyyTemplateType',
}
def __init__(self, space, *args):
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -63,7 +63,7 @@
def get_rawbuffer(space, w_obj):
# raw buffer
try:
- buf = space.buffer_w(w_obj, space.BUF_SIMPLE)
+ buf = space.getarg_w('s*', w_obj)
return rffi.cast(rffi.VOIDP, buf.get_raw_address())
except Exception:
pass
@@ -163,7 +163,7 @@
def to_memory(self, space, w_obj, w_value, offset):
# copy the full array (uses byte copy for now)
address = rffi.cast(rffi.CCHARP, self._get_raw_address(space, w_obj, offset))
- buf = space.buffer_w(w_value, space.BUF_SIMPLE)
+ buf = space.getarg_w('s*', w_value)
# TODO: report if too many items given?
for i in range(min(self.size*self.typesize, buf.getlength())):
address[i] = buf.getitem(i)
@@ -204,7 +204,7 @@
# copy only the pointer value
rawobject = get_rawobject_nonnull(space, w_obj)
byteptr = rffi.cast(rffi.CCHARPP, capi.direct_ptradd(rawobject, offset))
- buf = space.buffer_w(w_value, space.BUF_SIMPLE)
+ buf = space.getarg_w('s*', w_value)
try:
byteptr[0] = buf.get_raw_address()
except ValueError:
diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -450,8 +450,8 @@
class CPPConstructor(CPPMethod):
"""Method dispatcher that constructs new objects. This method can not have
- a fast path, a the allocation of the object is currently left to the
- reflection layer only, b/c the C++ class may have an overloaded operator
+ a fast path, as the allocation of the object is currently left to the
+ reflection layer only, since the C++ class may have an overloaded operator
new, disallowing malloc here."""
_immutable_ = True
@@ -460,8 +460,18 @@
# TODO: these casts are very, very un-pretty; need to find a way of
# re-using CPPMethod's features w/o these roundabouts
vscope = rffi.cast(capi.C_OBJECT, self.scope.handle)
- w_result = CPPMethod.call(self, vscope, args_w)
+ cppinstance = None
+ try:
+ cppinstance = self.space.interp_w(W_CPPInstance, args_w[0], can_be_None=False)
+ use_args_w = args_w[1:]
+ except (OperationError, TypeError), e:
+ use_args_w = args_w
+ w_result = CPPMethod.call(self, vscope, use_args_w)
newthis = rffi.cast(capi.C_OBJECT, self.space.int_w(w_result))
+ if cppinstance:
+ cppinstance._rawobject = newthis
+ memory_regulator.register(cppinstance)
+ return args_w[0]
return wrap_cppobject(self.space, newthis, self.scope,
do_cast=False, python_owns=True, fresh=True)
@@ -1141,10 +1151,14 @@
self.objects = rweakref.RWeakValueDictionary(int, W_CPPInstance)
def register(self, obj):
+ if not obj._rawobject:
+ return
int_address = int(rffi.cast(rffi.LONG, obj._rawobject))
self.objects.set(int_address, obj)
def unregister(self, obj):
+ if not obj._rawobject:
+ return
int_address = int(rffi.cast(rffi.LONG, obj._rawobject))
self.objects.set(int_address, None)
@@ -1194,7 +1208,7 @@
w_pycppclass = get_pythonized_cppclass(space, cppclass.handle)
# try to recycle existing object if this one is not newly created
- if not fresh:
+ if not fresh and rawobject:
obj = memory_regulator.retrieve(rawobject)
if obj is not None and obj.cppclass is cppclass:
return obj
diff --git a/pypy/module/cppyy/pythonify.py b/pypy/module/cppyy/pythonify.py
--- a/pypy/module/cppyy/pythonify.py
+++ b/pypy/module/cppyy/pythonify.py
@@ -25,9 +25,12 @@
# class CppyyClass defined in _init_pythonify()
class CppyyTemplateType(object):
- def __init__(self, scope, name):
- self._scope = scope
+ def __init__(self, name, scope=None):
self._name = name
+ if scope is None:
+ self._scope = gbl
+ else:
+ self._scope = scope
def _arg_to_str(self, arg):
if arg == str:
@@ -143,7 +146,12 @@
raise TypeError(msg)
else:
def __new__(cls, *args):
- return constructor_overload.call(None, *args)
+ # create a place-holder only as there may be a derived class defined
+ import cppyy
+ instance = cppyy.bind_object(0, class_name, True)
+ if not instance.__class__ is cls:
+ instance.__class__ = cls # happens for derived class
+ return instance
return __new__
def make_pycppclass(scope, class_name, final_class_name, cppclass):
@@ -206,7 +214,7 @@
return pycppclass
def make_cpptemplatetype(scope, template_name):
- return CppyyTemplateType(scope, template_name)
+ return CppyyTemplateType(template_name, scope)
def get_pycppitem(scope, name):
@@ -424,7 +432,9 @@
__metaclass__ = CppyyClassMeta
def __init__(self, *args, **kwds):
- pass # ignored, for the C++ backend, ctor == __new__ + __init__
+ # self is only a placeholder; now create the actual C++ object
+ args = (self,) + args
+ self._cpp_proxy.get_overload(self._cpp_proxy.type_name).call(None, *args)
# class generator callback
cppyy._set_class_generator(clgen_callback)
diff --git a/pypy/module/cppyy/src/dummy_backend.cxx b/pypy/module/cppyy/src/dummy_backend.cxx
--- a/pypy/module/cppyy/src/dummy_backend.cxx
+++ b/pypy/module/cppyy/src/dummy_backend.cxx
@@ -3,12 +3,23 @@
#include <map>
#include <string>
+#include <sstream>
#include <vector>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+// add example01.cxx code
+int globalAddOneToInt(int a);
+
+namespace dummy {
+#include "example01.cxx"
+}
+
+int globalAddOneToInt(int a) {
+ return dummy::globalAddOneToInt(a);
+}
/* pseudo-reflection data ------------------------------------------------- */
namespace {
@@ -38,28 +49,16 @@
typedef std::map<cppyy_scope_t, Cppyy_PseudoClassInfo> Scopes_t;
static Scopes_t s_scopes;
-class PseudoExample01 {
-public:
- PseudoExample01() : m_somedata(-99) {}
- PseudoExample01(int a) : m_somedata(a) {}
- PseudoExample01(const PseudoExample01& e) : m_somedata(e.m_somedata) {}
- PseudoExample01& operator=(const PseudoExample01& e) {
- if (this != &e) m_somedata = e.m_somedata;
- return *this;
- }
- virtual ~PseudoExample01() {}
-
-public:
- int m_somedata;
-};
-
static int example01_last_static_method = 0;
static int example01_last_constructor = 0;
+static int payload_methods_offset = 0;
struct Cppyy_InitPseudoReflectionInfo {
Cppyy_InitPseudoReflectionInfo() {
// class example01 --
static long s_scope_id = 0;
+
+ { // class example01 --
s_handles["example01"] = (cppyy_scope_t)++s_scope_id;
std::vector<Cppyy_PseudoMethodInfo> methods;
@@ -115,14 +114,81 @@
// cut-off is used in cppyy_is_constructor
example01_last_constructor = methods.size();
- // (12) double addDataToDouble(double a)
+ // (12) int addDataToInt(int a)
+ argtypes.clear();
+ argtypes.push_back("int");
+ methods.push_back(Cppyy_PseudoMethodInfo("addDataToInt", argtypes, "int"));
+
+ // (13) int addDataToIntConstRef(const int& a)
+ argtypes.clear();
+ argtypes.push_back("const int&");
+ methods.push_back(Cppyy_PseudoMethodInfo("addDataToIntConstRef", argtypes, "int"));
+
+ // (14) int overloadedAddDataToInt(int a, int b)
+ argtypes.clear();
+ argtypes.push_back("int");
+ argtypes.push_back("int");
+ methods.push_back(Cppyy_PseudoMethodInfo("overloadedAddDataToInt", argtypes, "int"));
+
+ // (15) int overloadedAddDataToInt(int a)
+ // (16) int overloadedAddDataToInt(int a, int b, int c)
+ argtypes.clear();
+ argtypes.push_back("int");
+ methods.push_back(Cppyy_PseudoMethodInfo("overloadedAddDataToInt", argtypes, "int"));
+
+ argtypes.push_back("int");
+ argtypes.push_back("int");
+ methods.push_back(Cppyy_PseudoMethodInfo("overloadedAddDataToInt", argtypes, "int"));
+
+ // (17) double addDataToDouble(double a)
argtypes.clear();
argtypes.push_back("double");
methods.push_back(Cppyy_PseudoMethodInfo("addDataToDouble", argtypes, "double"));
+ // (18) int addDataToAtoi(const char* str)
+ // (19) char* addToStringValue(const char* str)
+ argtypes.clear();
+ argtypes.push_back("const char*");
+ methods.push_back(Cppyy_PseudoMethodInfo("addDataToAtoi", argtypes, "int"));
+ methods.push_back(Cppyy_PseudoMethodInfo("addToStringValue", argtypes, "char*"));
+
+ // (20) void setPayload(payload* p)
+ // (21) payload* cyclePayload(payload* p)
+ // (22) payload copyCyclePayload(payload* p)
+ argtypes.clear();
+ argtypes.push_back("payload*");
+ methods.push_back(Cppyy_PseudoMethodInfo("setPayload", argtypes, "void"));
+ methods.push_back(Cppyy_PseudoMethodInfo("cyclePayload", argtypes, "payload*"));
+ methods.push_back(Cppyy_PseudoMethodInfo("copyCyclePayload", argtypes, "payload"));
+
+ payload_methods_offset = methods.size();
+
Cppyy_PseudoClassInfo info(methods);
s_scopes[(cppyy_scope_t)s_scope_id] = info;
- // -- class example01
+ } // -- class example01
+
+ { // class payload --
+ s_handles["payload"] = (cppyy_scope_t)++s_scope_id;
+
+ std::vector<Cppyy_PseudoMethodInfo> methods;
+
+ // (23) payload(double d = 0.)
+ std::vector<std::string> argtypes;
+ argtypes.push_back("double");
+ methods.push_back(Cppyy_PseudoMethodInfo("payload", argtypes, "constructor"));
+
+ // (24) double getData()
+ argtypes.clear();
+ methods.push_back(Cppyy_PseudoMethodInfo("getData", argtypes, "double"));
+
+ // (25) void setData(double d)
+ argtypes.clear();
+ argtypes.push_back("double");
+ methods.push_back(Cppyy_PseudoMethodInfo("setData", argtypes, "void"));
+
+ Cppyy_PseudoClassInfo info(methods);
+ s_scopes[(cppyy_scope_t)s_scope_id] = info;
+ } // -- class payload
}
} _init;
@@ -150,36 +216,69 @@
return s_handles[scope_name]; // lookup failure will return 0 (== error)
}
+cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t /* obj */) {
+ return klass;
+}
+
/* memory management ------------------------------------------------------ */
void cppyy_destruct(cppyy_type_t handle, cppyy_object_t self) {
if (handle == s_handles["example01"])
- delete (PseudoExample01*)self;
+ delete (dummy::example01*)self;
}
/* method/function dispatching -------------------------------------------- */
+void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
+ switch ((long)method) {
+ case 5: // static void example01:;staticSetPayload(payload* p, double d)
+ assert(!self && nargs == 2);
+ dummy::example01::staticSetPayload((dummy::payload*)(*(long*)&((CPPYY_G__value*)args)[0]),
+ ((CPPYY_G__value*)args)[1].obj.d);
+ break;
+ case 9: // static void example01::setCount(int)
+ assert(!self && nargs == 1);
+ dummy::example01::setCount(((CPPYY_G__value*)args)[0].obj.in);
+ break;
+ case 20: // void example01::setPayload(payload* p);
+ assert(self && nargs == 1);
+ ((dummy::example01*)self)->setPayload((dummy::payload*)(*(long*)&((CPPYY_G__value*)args)[0]));
+ break;
+ default:
+ assert(!"method unknown in cppyy_call_v");
+ break;
+ }
+}
+
int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
int result = 0;
switch ((long)method) {
- case 1: // static int staticAddOneToInt(int)
+ case 1: // static int example01::staticAddOneToInt(int)
assert(!self && nargs == 1);
- result = ((CPPYY_G__value*)args)[0].obj.in + 1;
+ result = dummy::example01::staticAddOneToInt(((CPPYY_G__value*)args)[0].obj.in);
break;
- case 2: // static int staticAddOneToInt(int, int)
+ case 2: // static int example01::staticAddOneToInt(int, int)
assert(!self && nargs == 2);
- result = ((CPPYY_G__value*)args)[0].obj.in + ((CPPYY_G__value*)args)[1].obj.in + 1;
+ result = dummy::example01::staticAddOneToInt(
+ ((CPPYY_G__value*)args)[0].obj.in, ((CPPYY_G__value*)args)[1].obj.in);
break;
- case 3: // static int staticAtoi(const char* str)
+ case 3: // static int example01::staticAtoi(const char* str)
assert(!self && nargs == 1);
- result = ::atoi((const char*)(*(long*)&((CPPYY_G__value*)args)[0]));
+ result = dummy::example01::staticAtoi((const char*)(*(long*)&((CPPYY_G__value*)args)[0]));
break;
- case 8: // static int getCount()
- assert(!self && nargs == 0);
- // can't actually call this method (would need to resolve example01::count), but
- // other than the memory tests, most tests just check for 0 at the end
- result = 0;
- break;
+ case 8: // static int example01::getCount()
+ assert(!self && nargs == 0);
+ result = dummy::example01::getCount();
+ break;
+ case 12: // int example01::addDataToInt(int a)
+ assert(self && nargs == 1);
+ result = ((dummy::example01*)self)->addDataToInt(((CPPYY_G__value*)args)[0].obj.in);
+ break;
+ case 18: // int example01::addDataToAtoi(const char* str)
+ assert(self && nargs == 1);
+ result = ((dummy::example01*)self)->addDataToAtoi(
+ (const char*)(*(long*)&((CPPYY_G__value*)args)[0]));
+ break;
default:
assert(!"method unknown in cppyy_call_i");
break;
@@ -188,26 +287,50 @@
}
long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
- if ((long)method == 4) { // static char* staticStrcpy(const char* strin)
- const char* strin = (const char*)(*(long*)&((CPPYY_G__value*)args)[0]);
- char* strout = (char*)malloc(::strlen(strin)+1);
- ::strcpy(strout, strin);
- return (long)strout;
+ long result = 0;
+ switch ((long)method) {
+ case 4: // static char* example01::staticStrcpy(const char* strin)
+ assert(!self && nargs == 1);
+ result = (long)dummy::example01::staticStrcpy(
+ (const char*)(*(long*)&((CPPYY_G__value*)args)[0]));
+ break;
+ case 6: // static payload* example01::staticCyclePayload(payload* p, double d)
+ assert(!self && nargs == 2);
+ result = (long)dummy::example01::staticCyclePayload(
+ (dummy::payload*)(*(long*)&((CPPYY_G__value*)args)[0]),
+ ((CPPYY_G__value*)args)[1].obj.d);
+ break;
+ case 19: // char* example01::addToStringValue(const char* str)
+ assert(self && nargs == 1);
+ result = (long)((dummy::example01*)self)->addToStringValue(
+ (const char*)(*(long*)&((CPPYY_G__value*)args)[0]));
+ break;
+ case 21: // payload* example01::cyclePayload(payload* p)
+ assert(self && nargs == 1);
+ result = (long)((dummy::example01*)self)->cyclePayload(
+ (dummy::payload*)(*(long*)&((CPPYY_G__value*)args)[0]));
+ break;
+ default:
+ assert(!"method unknown in cppyy_call_l");
+ break;
}
- assert(!"method unknown in cppyy_call_l");
- return 0;
+ return result;
}
double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
double result = 0.;
switch ((long)method) {
- case 0: // static double staticAddToDouble(double)
+ case 0: // static double example01::staticAddToDouble(double)
assert(!self && nargs == 1);
- result = ((CPPYY_G__value*)args)[0].obj.d + 0.01;
+ result = dummy::example01::staticAddToDouble(((CPPYY_G__value*)args)[0].obj.d);
break;
- case 12: // double addDataToDouble(double a)
+ case 17: // double example01::addDataToDouble(double a)
assert(self && nargs == 1);
- result = ((PseudoExample01*)self)->m_somedata + ((CPPYY_G__value*)args)[0].obj.d;
+ result = ((dummy::example01*)self)->addDataToDouble(((CPPYY_G__value*)args)[0].obj.d);
+ break;
+ case 24: // double payload::getData()
+ assert(self && nargs == 0);
+ result = ((dummy::payload*)self)->getData();
break;
default:
assert(!"method unknown in cppyy_call_d");
@@ -217,11 +340,17 @@
}
char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
- // char* staticStrcpy(const char* strin)
- const char* strin = (const char*)(*(long*)&((CPPYY_G__value*)args)[0]);
- char* strout = (char*)malloc(::strlen(strin)+1);
- ::strcpy(strout, strin);
- return strout;
+ char* result = 0;
+ switch ((long)method) {
+ case 4: // static char* example01::staticStrcpy(const char* strin)
+ assert(!self && nargs == 1);
+ result = dummy::example01::staticStrcpy((const char*)(*(long*)&((CPPYY_G__value*)args)[0]));
+ break;
+ default:
+ assert(!"method unknown in cppyy_call_s");
+ break;
+ }
+ return result;
}
cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t handle, int nargs, void* args) {
@@ -230,17 +359,27 @@
switch ((long)method) {
case 10:
assert(nargs == 0);
- result = new PseudoExample01;
+ result = new dummy::example01;
break;
case 11:
assert(nargs == 1);
- result = new PseudoExample01(((CPPYY_G__value*)args)[0].obj.in);
+ result = new dummy::example01(((CPPYY_G__value*)args)[0].obj.in);
break;
default:
- assert(!"method unknown in cppyy_constructor");
+ assert(!"method of example01 unknown in cppyy_constructor");
break;
}
- }
+ } else if (handle == s_handles["payload"]) {
+ switch ((long)method) {
+ case 23:
+ if (nargs == 0) result = new dummy::payload;
+ else if (nargs == 1) result = new dummy::payload(((CPPYY_G__value*)args)[0].obj.d);
+ break;
+ default:
+ assert(!"method payload unknown in cppyy_constructor");
+ break;
+ }
+ }
return (cppyy_object_t)result;
}
@@ -346,8 +485,13 @@
return 0;
}
-cppyy_method_t cppyy_get_method(cppyy_scope_t /* handle */, cppyy_index_t method_index) {
- return (cppyy_method_t)method_index;
+cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t method_index) {
+ if (handle == s_handles["example01"])
+ return (cppyy_method_t)method_index;
+ else if (handle == s_handles["payload"])
+ return (cppyy_method_t)((long)method_index + payload_methods_offset);
+ assert(!"unknown class in cppyy_get_method");
+ return (cppyy_method_t)0;
}
@@ -356,12 +500,16 @@
if (handle == s_handles["example01"])
return example01_last_static_method <= method_index
&& method_index < example01_last_constructor;
+ else if (handle == s_handles["payload"])
+ return (long)method_index == 0;
return 0;
}
int cppyy_is_staticmethod(cppyy_type_t handle, cppyy_index_t method_index) {
if (handle == s_handles["example01"])
return method_index < example01_last_static_method ? 1 : 0;
+ if (handle == s_handles["payload"])
+ return 0;
return 1;
}
diff --git a/pypy/module/cppyy/test/conftest.py b/pypy/module/cppyy/test/conftest.py
--- a/pypy/module/cppyy/test/conftest.py
+++ b/pypy/module/cppyy/test/conftest.py
@@ -8,13 +8,18 @@
# run only tests that are covered by the dummy backend and tests
# that do not rely on reflex
if not ('test_helper.py' in item.location[0] or \
- 'test_cppyy.py' in item.location[0]):
+ 'test_cppyy.py' in item.location[0] or \
+ 'test_pythonify.py' in item.location[0]):
py.test.skip("genreflex is not installed")
import re
- if 'test_cppyy.py' in item.location[0] and \
- not re.search("test0[1-36]", item.location[2]):
+ if 'test_pythonify.py' in item.location[0] and \
+ not re.search("AppTestPYTHONIFY.test0[1-6]", item.location[2]):
py.test.skip("genreflex is not installed")
+def pytest_ignore_collect(path, config):
+ if py.path.local.sysfind('genreflex') is None and config.option.runappdirect:
+ return True # "can't run dummy tests in -A"
+
def pytest_configure(config):
if py.path.local.sysfind('genreflex') is None:
import pypy.module.cppyy.capi.loadable_capi as lcapi
@@ -22,6 +27,9 @@
import ctypes
ctypes.CDLL(lcapi.reflection_library)
except Exception, e:
+ if config.option.runappdirect:
+ return # "can't run dummy tests in -A"
+
# build dummy backend (which has reflex info and calls hard-wired)
import os
from rpython.translator.tool.cbuild import ExternalCompilationInfo
@@ -32,10 +40,11 @@
pkgpath = py.path.local(__file__).dirpath().join(os.pardir)
srcpath = pkgpath.join('src')
incpath = pkgpath.join('include')
+ tstpath = pkgpath.join('test')
eci = ExternalCompilationInfo(
separate_module_files=[srcpath.join('dummy_backend.cxx')],
- include_dirs=[incpath],
+ include_dirs=[incpath, tstpath],
use_cpp_linker=True,
)
diff --git a/pypy/module/cppyy/test/example01.cxx b/pypy/module/cppyy/test/example01.cxx
--- a/pypy/module/cppyy/test/example01.cxx
+++ b/pypy/module/cppyy/test/example01.cxx
@@ -1,4 +1,3 @@
-#include <iostream>
#include <sstream>
#include <string>
#include <stdlib.h>
diff --git a/pypy/module/cppyy/test/test_pythonify.py b/pypy/module/cppyy/test/test_pythonify.py
--- a/pypy/module/cppyy/test/test_pythonify.py
+++ b/pypy/module/cppyy/test/test_pythonify.py
@@ -321,7 +321,7 @@
e = cppyy.gbl.example01(2)
assert 5 == meth(e, 3)
- def test01_installable_function(self):
+ def test15_installable_function(self):
"""Test installing and calling global C++ function as python method"""
import cppyy
@@ -332,6 +332,33 @@
assert 2 == e.fresh(1)
assert 3 == e.fresh(2)
+ def test16_subclassing(self):
+ """A sub-class on the python side should have that class as type"""
+
+ import cppyy
+ example01 = cppyy.gbl.example01
+
+ o = example01()
+ assert type(o) == example01
+
+ class MyClass1(example01):
+ def myfunc(self):
+ return 1
+
+ o = MyClass1()
+ assert type(o) == MyClass1
+ assert isinstance(o, example01)
+ assert o.myfunc() == 1
+
+ class MyClass2(example01):
+ def __init__(self, what):
+ example01.__init__(self)
+ self.what = what
+
+ o = MyClass2('hi')
+ assert type(o) == MyClass2
+ assert o.what == 'hi'
+
class AppTestPYTHONIFY_UI:
spaceconfig = dict(usemodules=['cppyy', '_rawffi', 'itertools'])
diff --git a/pypy/module/cppyy/test/test_stltypes.py b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -477,3 +477,29 @@
assert b1 == e2
assert b1 != b2
assert b1 == e2
+
+
+class AppTestTEMPLATE_UI:
+ spaceconfig = dict(usemodules=['cppyy', '_rawffi', 'itertools'])
+
+ def setup_class(cls):
+ cls.w_test_dct = cls.space.wrap(test_dct)
+ cls.w_stlstring = cls.space.appexec([], """():
+ import cppyy, sys
+ return cppyy.load_reflection_info(%r)""" % (test_dct, ))
+
+ def test01_explicit_templates(self):
+ """Explicit use of Template class"""
+
+ import cppyy
+
+ vector = cppyy.Template('vector', cppyy.gbl.std)
+ assert vector[int] == vector(int)
+
+ v = vector[int]()
+
+ N = 10
+ v += range(N)
+ assert len(v) == N
+ for i in range(N):
+ assert v[i] == i
diff --git a/pypy/module/cppyy/test/test_zjit.py b/pypy/module/cppyy/test/test_zjit.py
--- a/pypy/module/cppyy/test/test_zjit.py
+++ b/pypy/module/cppyy/test/test_zjit.py
@@ -132,7 +132,7 @@
return w_obj
interp_w._annspecialcase_ = 'specialize:arg(1)'
- def buffer_w(self, w_obj):
+ def getarg_w(self, code, w_obj): # for retrieving buffers
return FakeBuffer(w_obj)
def exception_match(self, typ, sub):
diff --git a/pypy/module/pypyjit/test_pypy_c/test_buffers.py b/pypy/module/pypyjit/test_pypy_c/test_buffers.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/pypyjit/test_pypy_c/test_buffers.py
@@ -0,0 +1,27 @@
+from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
+
+
+class TestBuffers(BaseTestPyPyC):
+ def test_re_match(self):
+ def main(n):
+ import re
+ import array
+ p = re.compile('.+')
+ a = array.array('c', 'test' * 1000)
+ i = 0
+ while i < n:
+ i += 1
+ p.match(a) # ID: match
+ return i
+ log = self.run(main, [1000])
+ assert log.result == 1000
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match_by_id('match', """
+ guard_not_invalidated(descr=...)
+ i65 = getfield_gc(p18, descr=...)
+ i67 = int_gt(0, i65)
+ guard_false(i67, descr=...)
+ i69 = int_gt(., i65)
+ guard_true(i69, descr=...)
+ --TICK--
+ """)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_weakref.py b/pypy/module/pypyjit/test_pypy_c/test_weakref.py
--- a/pypy/module/pypyjit/test_pypy_c/test_weakref.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_weakref.py
@@ -20,8 +20,7 @@
loop, = log.loops_by_filename(self.filepath)
assert loop.match("""
i58 = getfield_gc(p18, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current .>)
- i59 = getfield_gc(p18, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeStepOneIterator.inst_stop \d+>)
- i60 = int_lt(i58, i59)
+ i60 = int_lt(i58, i31)
guard_true(i60, descr=...)
i61 = int_add(i58, 1)
p62 = getfield_gc(ConstPtr(ptr37), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>)
diff --git a/pypy/module/termios/interp_termios.py b/pypy/module/termios/interp_termios.py
--- a/pypy/module/termios/interp_termios.py
+++ b/pypy/module/termios/interp_termios.py
@@ -4,7 +4,7 @@
"""
from pypy.interpreter.gateway import unwrap_spec
-from pypy.interpreter.error import wrap_oserror
+from pypy.interpreter.error import wrap_oserror, OperationError
from rpython.rlib import rtermios
import termios
@@ -19,6 +19,10 @@
@unwrap_spec(when=int)
def tcsetattr(space, w_fd, when, w_attributes):
fd = space.c_filedescriptor_w(w_fd)
+ if not space.isinstance_w(w_attributes, space.w_list) or \
+ space.len_w(w_attributes) != 7:
+ raise OperationError(space.w_TypeError, space.wrap(
+ "tcsetattr, arg 3: must be 7 element list"))
w_iflag, w_oflag, w_cflag, w_lflag, w_ispeed, w_ospeed, w_cc = \
space.unpackiterable(w_attributes, expected_length=7)
w_builtin = space.getbuiltinmodule('__builtin__')
diff --git a/pypy/module/termios/test/test_termios.py b/pypy/module/termios/test/test_termios.py
--- a/pypy/module/termios/test/test_termios.py
+++ b/pypy/module/termios/test/test_termios.py
@@ -86,7 +86,7 @@
child.expect('ok!')
def test_ioctl_termios(self):
- source = py.code.Source("""
+ source = py.code.Source(r"""
import termios
import fcntl
lgt = len(fcntl.ioctl(2, termios.TIOCGWINSZ, '\000'*8))
@@ -149,4 +149,7 @@
def test_error_tcsetattr(self):
import termios
- raises(ValueError, termios.tcsetattr, 0, 1, (1, 2))
+ exc = raises(TypeError, termios.tcsetattr, 0, 1, (1, 2))
+ assert str(exc.value) == "tcsetattr, arg 3: must be 7 element list"
+ exc = raises(TypeError, termios.tcsetattr, 0, 1, (1, 2, 3, 4, 5, 6, 7))
+ assert str(exc.value) == "tcsetattr, arg 3: must be 7 element list"
diff --git a/pypy/objspace/std/bufferobject.py b/pypy/objspace/std/bufferobject.py
--- a/pypy/objspace/std/bufferobject.py
+++ b/pypy/objspace/std/bufferobject.py
@@ -3,13 +3,12 @@
"""
import operator
-from rpython.rlib.buffer import Buffer, StringBuffer, SubBuffer
+from rpython.rlib.buffer import Buffer, SubBuffer
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
from rpython.rlib.objectmodel import compute_hash
-from rpython.rlib.rstring import StringBuilder
class W_Buffer(W_Root):
diff --git a/pypy/objspace/std/memoryobject.py b/pypy/objspace/std/memoryobject.py
--- a/pypy/objspace/std/memoryobject.py
+++ b/pypy/objspace/std/memoryobject.py
@@ -6,7 +6,7 @@
from rpython.rlib.buffer import Buffer, SubBuffer
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.gateway import interp2app
from pypy.interpreter.typedef import TypeDef, GetSetProperty
diff --git a/pypy/sandbox/pypy_interact.py b/pypy/sandbox/pypy_interact.py
--- a/pypy/sandbox/pypy_interact.py
+++ b/pypy/sandbox/pypy_interact.py
@@ -21,7 +21,7 @@
"""
import sys, os
-sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..', '..')))
+sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..', '..')))
from rpython.translator.sandbox.sandlib import SimpleIOSandboxedProc
from rpython.translator.sandbox.sandlib import VirtualizedSandboxedProc
from rpython.translator.sandbox.vfs import Dir, RealDir, RealFile
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -5884,6 +5884,25 @@
"""
self.optimize_loop(ops, expected)
+ def test_bug_unroll_with_immutables(self):
+ ops = """
+ [p0]
+ i2 = getfield_gc_pure(p0, descr=immut_intval)
+ p1 = new_with_vtable(ConstClass(intobj_immut_vtable))
+ setfield_gc(p1, 1242, descr=immut_intval)
+ jump(p1)
+ """
+ preamble = """
+ [p0]
+ i2 = getfield_gc_pure(p0, descr=immut_intval)
+ jump()
+ """
+ expected = """
+ []
+ jump()
+ """
+ self.optimize_loop(ops, expected, preamble)
+
def test_immutable_constantfold_recursive(self):
ops = """
[]
@@ -8356,6 +8375,31 @@
"""
self.optimize_loop(ops, ops)
+ def test_unroll_failargs(self):
+ ops = """
+ [p0, i1]
+ p1 = getfield_gc(p0, descr=valuedescr)
+ i2 = int_add(i1, 1)
+ i3 = int_le(i2, 13)
+ guard_true(i3) [p1]
+ jump(p0, i2)
+ """
+ expected = """
+ [p0, i1, p1]
+ i2 = int_add(i1, 1)
+ i3 = int_le(i2, 13)
+ guard_true(i3) [p1]
+ jump(p0, i2, p1)
+ """
+ preamble = """
+ [p0, i1]
+ p1 = getfield_gc(p0, descr=valuedescr)
+ i2 = int_add(i1, 1)
+ i3 = int_le(i2, 13)
+ guard_true(i3) [p1]
+ jump(p0, i2, p1)
+ """
+ self.optimize_loop(ops, expected, preamble)
class TestLLtype(OptimizeOptTest, LLtypeMixin):
pass
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -180,10 +180,11 @@
self.optimizer.clear_newoperations()
for i in range(len(original_jump_args)):
+ srcbox = jump_args[i]
if values[i].is_virtual():
- values[i].force_box(self.optimizer)
- if original_jump_args[i] is not jump_args[i]:
- op = ResOperation(rop.SAME_AS, [jump_args[i]], original_jump_args[i])
+ srcbox = values[i].force_box(self.optimizer)
+ if original_jump_args[i] is not srcbox:
+ op = ResOperation(rop.SAME_AS, [srcbox], original_jump_args[i])
self.optimizer.emit_operation(op)
inputarg_setup_ops = self.optimizer.get_newoperations()
diff --git a/rpython/jit/metainterp/test/test_string.py b/rpython/jit/metainterp/test/test_string.py
--- a/rpython/jit/metainterp/test/test_string.py
+++ b/rpython/jit/metainterp/test/test_string.py
@@ -654,3 +654,23 @@
self.check_resops(call_pure=0, unicodesetitem=0, call=2,
newunicode=0, unicodegetitem=0,
copyunicodecontent=0)
+
+ def test_string_interpolation(self):
+ def f(x, y):
+ return len('<%d %d>' % (x, y))
+ res = self.interp_operations(f, [222, 3333])
+ assert res == 10
+
+ def test_string_interpolation_constants(self):
+ jitdriver = JitDriver(greens=['x', 'y'], reds=['z'])
+ def f(x, y):
+ z = 0
+ while z < 10:
+ jitdriver.jit_merge_point(x=x, y=y, z=z)
+ if len('<%d %d>' % (x, y)) != 10:
+ raise Exception
+ z += 1
+ return 0
+ self.meta_interp(f, [222, 3333])
+ self.check_simple_loop({'guard_true': 1, 'int_add': 1,
+ 'int_lt': 1, 'jump': 1})
diff --git a/rpython/translator/platform/test/test_posix.py b/rpython/translator/platform/test/test_posix.py
--- a/rpython/translator/platform/test/test_posix.py
+++ b/rpython/translator/platform/test/test_posix.py
@@ -9,13 +9,8 @@
res = host.execute('echo', '42 24')
assert res.out == '42 24\n'
- if sys.platform == 'win32':
- # echo is a shell builtin on Windows
- res = host.execute('cmd', ['/c', 'echo', '42', '24'])
- assert res.out == '42 24\n'
- else:
- res = host.execute('echo', ['42', '24'])
- assert res.out == '42 24\n'
+ res = host.execute('echo', ['42', '24'])
+ assert res.out == '42 24\n'
class TestMakefile(object):
platform = host
@@ -61,8 +56,13 @@
finally:
del os.environ['PYPY_LOCALBASE']
Makefile = tmpdir.join('Makefile').read()
- assert 'INCLUDEDIRS = -I/foo/baz/include' in Makefile
- assert 'LIBDIRS = -L/foo/baz/lib' in Makefile
+ include_prefix = '-I'
+ lib_prefix = '-L'
+ if self.platform.name == 'msvc':
+ include_prefix = '/I'
+ lib_prefix = '/LIBPATH:'
+ assert 'INCLUDEDIRS = %s/foo/baz/include' % include_prefix in Makefile
+ assert 'LIBDIRS = %s/foo/baz/lib' % lib_prefix in Makefile
class TestMaemo(TestMakefile):
strict_on_stderr = False
diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -292,7 +292,10 @@
rel_ofiles = [rel_cfile[:rel_cfile.rfind('.')]+'.obj' for rel_cfile in rel_cfiles]
m.cfiles = rel_cfiles
- rel_includedirs = [rpyrel(incldir) for incldir in eci.include_dirs]
+ rel_includedirs = [rpyrel(incldir) for incldir in
+ self.preprocess_include_dirs(eci.include_dirs)]
+ rel_libdirs = [rpyrel(libdir) for libdir in
+ self.preprocess_library_dirs(eci.library_dirs)]
m.comment('automatically generated makefile')
definitions = [
@@ -302,7 +305,7 @@
('SOURCES', rel_cfiles),
('OBJECTS', rel_ofiles),
('LIBS', self._libs(eci.libraries)),
- ('LIBDIRS', self._libdirs(eci.library_dirs)),
+ ('LIBDIRS', self._libdirs(rel_libdirs)),
('INCLUDEDIRS', self._includedirs(rel_includedirs)),
('CFLAGS', self.cflags),
('CFLAGSEXTRA', list(eci.compile_extra)),
diff --git a/rpython/translator/sandbox/rsandbox.py b/rpython/translator/sandbox/rsandbox.py
--- a/rpython/translator/sandbox/rsandbox.py
+++ b/rpython/translator/sandbox/rsandbox.py
@@ -3,6 +3,10 @@
trampolines that marshal their input arguments, dump them to STDOUT,
and wait for an answer on STDIN. Enable with 'translate.py --sandbox'.
"""
+import sys
+if sys.platform == 'win32':
+ raise TypeError("sandbox not supported on windows")
+
import py
from rpython.rlib import rmarshal, types
diff --git a/rpython/translator/sandbox/test/test_sandbox.py b/rpython/translator/sandbox/test/test_sandbox.py
--- a/rpython/translator/sandbox/test/test_sandbox.py
+++ b/rpython/translator/sandbox/test/test_sandbox.py
@@ -25,7 +25,20 @@
check_str_without_nul=True)
return str(t.compile())
+unsupported_platform = ('False', '')
+if sys.platform == 'win32':
+ unsupported_platform = ('True', 'sandbox not supported on this platform')
+ def test_unavailable():
+ def entry_point(argv):
+ fd = os.open("/tmp/foobar", os.O_RDONLY, 0777)
+ os.close(fd)
+ return 0
+ exc = py.test.raises(TypeError, compile, entry_point)
+ assert str(exc).find('not supported') >= 0
+supported = py.test.mark.skipif(unsupported_platform[0], reason=unsupported_platform[1])
+
+ at supported
def test_open_dup():
def entry_point(argv):
fd = os.open("/tmp/foobar", os.O_RDONLY, 0777)
@@ -43,6 +56,7 @@
f.close()
assert tail == ""
+ at supported
def test_read_write():
def entry_point(argv):
fd = os.open("/tmp/foobar", os.O_RDONLY, 0777)
@@ -65,6 +79,7 @@
f.close()
assert tail == ""
+ at supported
def test_dup2_access():
def entry_point(argv):
os.dup2(34, 56)
@@ -80,6 +95,7 @@
f.close()
assert tail == ""
+ at supported
def test_stat_ftruncate():
from rpython.translator.sandbox.sandlib import RESULTTYPE_STATRESULT
from rpython.rlib.rarithmetic import r_longlong
@@ -101,6 +117,7 @@
f.close()
assert tail == ""
+ at supported
def test_time():
def entry_point(argv):
t = time.time()
@@ -116,6 +133,7 @@
f.close()
assert tail == ""
+ at supported
def test_getcwd():
def entry_point(argv):
t = os.getcwd()
@@ -131,6 +149,7 @@
f.close()
assert tail == ""
+ at supported
def test_oserror():
def entry_point(argv):
try:
@@ -148,6 +167,7 @@
f.close()
assert tail == ""
+ at supported
def test_hybrid_gc():
def entry_point(argv):
l = []
@@ -172,6 +192,7 @@
rescode = pipe.wait()
assert rescode == 0
+ at supported
def test_segfault_1():
class A:
def __init__(self, m):
@@ -194,6 +215,7 @@
e.close()
assert 'Invalid RPython operation' in errors
+ at supported
def test_segfault_2():
py.test.skip("hum, this is one example, but we need to be very careful")
class Base:
@@ -226,6 +248,7 @@
e.close()
assert '...think what kind of errors to get...' in errors
+ at supported
def test_safe_alloc():
from rpython.rlib.rmmap import alloc, free
@@ -246,6 +269,7 @@
rescode = pipe.wait()
assert rescode == 0
+ at supported
def test_unsafe_mmap():
py.test.skip("Since this stuff is unimplemented, it won't work anyway "
"however, the day it starts working, it should pass test")
@@ -271,6 +295,7 @@
rescode = pipe.wait()
assert rescode == 0
+ at supported
class TestPrintedResults:
def run(self, entry_point, args, expected):
diff --git a/rpython/translator/sandbox/test/test_sandlib.py b/rpython/translator/sandbox/test/test_sandlib.py
--- a/rpython/translator/sandbox/test/test_sandlib.py
+++ b/rpython/translator/sandbox/test/test_sandlib.py
@@ -6,10 +6,10 @@
from rpython.translator.sandbox.sandlib import SimpleIOSandboxedProc
from rpython.translator.sandbox.sandlib import VirtualizedSandboxedProc
from rpython.translator.sandbox.sandlib import VirtualizedSocketProc
-from rpython.translator.sandbox.test.test_sandbox import compile
+from rpython.translator.sandbox.test.test_sandbox import compile, supported
from rpython.translator.sandbox.vfs import Dir, File, RealDir, RealFile
-
+ at supported
class MockSandboxedProc(SandboxedProc):
"""A sandbox process wrapper that replays expected syscalls."""
@@ -35,7 +35,7 @@
do_ll_os__ll_os_write = _make_method("write")
do_ll_os__ll_os_close = _make_method("close")
-
+ at supported
def test_lib():
def entry_point(argv):
fd = os.open("/tmp/foobar", os.O_RDONLY, 0777)
@@ -63,6 +63,7 @@
proc.handle_forever()
assert proc.seen == len(proc.expected)
+ at supported
def test_foobar():
py.test.skip("to be updated")
foobar = rffi.llexternal("foobar", [rffi.CCHARP], rffi.LONG)
@@ -79,6 +80,7 @@
proc.handle_forever()
assert proc.seen == len(proc.expected)
+ at supported
def test_simpleio():
def entry_point(argv):
print "Please enter a number:"
@@ -100,6 +102,7 @@
assert output == "Please enter a number:\nThe double is: 42\n"
assert error == ""
+ at supported
def test_socketio():
class SocketProc(VirtualizedSocketProc, SimpleIOSandboxedProc):
def build_virtual_root(self):
@@ -116,6 +119,7 @@
output, error = proc.communicate("")
assert output.startswith('HTTP/1.0 503 Service Unavailable')
+ at supported
def test_oserror():
def entry_point(argv):
try:
@@ -133,6 +137,7 @@
assert proc.seen == len(proc.expected)
+ at supported
class SandboxedProcWithFiles(VirtualizedSandboxedProc, SimpleIOSandboxedProc):
"""A sandboxed process with a simple virtualized filesystem.
@@ -145,6 +150,7 @@
'this.pyc': RealFile(__file__),
})
+ at supported
def test_too_many_opens():
def entry_point(argv):
try:
@@ -186,6 +192,7 @@
assert output == "All ok!\n"
assert error == ""
+ at supported
def test_fstat():
def compare(a, b, i):
if a != b:
@@ -219,6 +226,7 @@
assert output == "All ok!\n"
assert error == ""
+ at supported
def test_lseek():
def char_should_be(c, should):
if c != should:
@@ -248,6 +256,7 @@
assert output == "All ok!\n"
assert error == ""
+ at supported
def test_getuid():
def entry_point(argv):
import os
diff --git a/rpython/translator/sandbox/test/test_vfs.py b/rpython/translator/sandbox/test/test_vfs.py
--- a/rpython/translator/sandbox/test/test_vfs.py
+++ b/rpython/translator/sandbox/test/test_vfs.py
@@ -2,10 +2,13 @@
import sys, stat, os
from rpython.translator.sandbox.vfs import *
from rpython.tool.udir import udir
+from rpython.translator.sandbox.test.test_sandbox import unsupported_platform
HASLINK = hasattr(os, 'symlink')
def setup_module(mod):
+ if unsupported_platform[0] == 'True':
+ py.test.skip(unsupported_platform[1])
d = udir.ensure('test_vfs', dir=1)
d.join('file1').write('somedata1')
d.join('file2').write('somelongerdata2')
More information about the pypy-commit
mailing list