Author: Maciej Fijalkowski <[email protected]>
Branch: vmprof
Changeset: r74968:060eabccb5b8
Date: 2014-12-17 14:01 +0100
http://bitbucket.org/pypy/pypy/changeset/060eabccb5b8/
Log: merge default
diff too long, truncating to 2000 out of 2100 lines
diff --git a/lib-python/2.7/sqlite3/test/dbapi.py
b/lib-python/2.7/sqlite3/test/dbapi.py
--- a/lib-python/2.7/sqlite3/test/dbapi.py
+++ b/lib-python/2.7/sqlite3/test/dbapi.py
@@ -478,6 +478,29 @@
except TypeError:
pass
+ def CheckCurDescription(self):
+ self.cu.execute("select * from test")
+
+ actual = self.cu.description
+ expected = [
+ ('id', None, None, None, None, None, None),
+ ('name', None, None, None, None, None, None),
+ ('income', None, None, None, None, None, None),
+ ]
+ self.assertEqual(expected, actual)
+
+ def CheckCurDescriptionVoidStatement(self):
+ self.cu.execute("insert into test(name) values (?)", ("foo",))
+ self.assertIsNone(self.cu.description)
+
+ def CheckCurDescriptionWithoutStatement(self):
+ cu = self.cx.cursor()
+ try:
+ self.assertIsNone(cu.description)
+ finally:
+ cu.close()
+
+
@unittest.skipUnless(threading, 'This test requires threading.')
class ThreadTests(unittest.TestCase):
def setUp(self):
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -1175,8 +1175,9 @@
try:
return self.__description
except AttributeError:
- self.__description = self.__statement._get_description()
- return self.__description
+ if self.__statement:
+ self.__description = self.__statement._get_description()
+ return self.__description
description = property(__get_description)
def __get_lastrowid(self):
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -125,6 +125,8 @@
else:
return self.space.builtin
+ _NO_CELLS = []
+
@jit.unroll_safe
def initialize_frame_scopes(self, outer_func, code):
# regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
@@ -143,7 +145,7 @@
nfreevars = len(code.co_freevars)
if not nfreevars:
if not ncellvars:
- self.cells = []
+ self.cells = self._NO_CELLS
return # no self.cells needed - fast path
elif outer_func is None:
space = self.space
diff --git a/pypy/module/cpyext/frameobject.py
b/pypy/module/cpyext/frameobject.py
--- a/pypy/module/cpyext/frameobject.py
+++ b/pypy/module/cpyext/frameobject.py
@@ -58,7 +58,7 @@
w_globals = from_ref(space, py_frame.c_f_globals)
frame = space.FrameClass(space, code, w_globals, outer_func=None)
- frame.f_lineno = py_frame.c_f_lineno
+ frame.f_lineno = rffi.getintfield(py_frame, 'c_f_lineno')
w_obj = space.wrap(frame)
track_reference(space, py_obj, w_obj)
return w_obj
diff --git a/pypy/module/micronumpy/flagsobj.py
b/pypy/module/micronumpy/flagsobj.py
--- a/pypy/module/micronumpy/flagsobj.py
+++ b/pypy/module/micronumpy/flagsobj.py
@@ -5,46 +5,26 @@
from pypy.interpreter.gateway import interp2app
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.module.micronumpy import constants as NPY
-
+from pypy.module.micronumpy.strides import is_c_contiguous, is_f_contiguous
def enable_flags(arr, flags):
arr.flags |= flags
-
def clear_flags(arr, flags):
arr.flags &= ~flags
-
[email protected]_safe
def _update_contiguous_flags(arr):
- shape = arr.shape
- strides = arr.strides
-
- is_c_contig = True
- sd = arr.dtype.elsize
- for i in range(len(shape) - 1, -1, -1):
- dim = shape[i]
- if strides[i] != sd:
- is_c_contig = False
- break
- if dim == 0:
- break
- sd *= dim
+ is_c_contig = is_c_contiguous(arr)
if is_c_contig:
enable_flags(arr, NPY.ARRAY_C_CONTIGUOUS)
else:
clear_flags(arr, NPY.ARRAY_C_CONTIGUOUS)
- sd = arr.dtype.elsize
- for i in range(len(shape)):
- dim = shape[i]
- if strides[i] != sd:
- clear_flags(arr, NPY.ARRAY_F_CONTIGUOUS)
- return
- if dim == 0:
- break
- sd *= dim
- enable_flags(arr, NPY.ARRAY_F_CONTIGUOUS)
+ is_f_contig = is_f_contiguous(arr)
+ if is_f_contig:
+ enable_flags(arr, NPY.ARRAY_F_CONTIGUOUS)
+ else:
+ clear_flags(arr, NPY.ARRAY_F_CONTIGUOUS)
class W_FlagsObject(W_Root):
diff --git a/pypy/module/micronumpy/ndarray.py
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -19,7 +19,7 @@
order_converter, shape_converter, searchside_converter
from pypy.module.micronumpy.flagsobj import W_FlagsObject
from pypy.module.micronumpy.strides import get_shape_from_iterable, \
- shape_agreement, shape_agreement_multiple
+ shape_agreement, shape_agreement_multiple, is_c_contiguous, is_f_contiguous
def _match_dot_shapes(space, left, right):
@@ -837,7 +837,15 @@
raise OperationError(space.w_ValueError, space.wrap(
"new type not compatible with array."))
else:
- if dims == 1 or impl.get_strides()[0] < impl.get_strides()[-1]:
+ if not is_c_contiguous(impl) and not is_f_contiguous(impl):
+ if old_itemsize != new_itemsize:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "new type not compatible with array."))
+ # Strides, shape does not change
+ v = impl.astype(space, dtype)
+ return wrap_impl(space, w_type, self, v)
+ strides = impl.get_strides()
+ if dims == 1 or strides[0] <strides[-1]:
# Column-major, resize first dimension
if new_shape[0] * old_itemsize % new_itemsize != 0:
raise OperationError(space.w_ValueError, space.wrap(
diff --git a/pypy/module/micronumpy/strides.py
b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -429,3 +429,35 @@
n_old_elems_to_use *= old_shape[oldI]
assert len(new_strides) == len(new_shape)
return new_strides[:]
+
[email protected]_safe
+def is_c_contiguous(arr):
+ shape = arr.get_shape()
+ strides = arr.get_strides()
+ ret = True
+ sd = arr.dtype.elsize
+ for i in range(len(shape) - 1, -1, -1):
+ dim = shape[i]
+ if strides[i] != sd:
+ ret = False
+ break
+ if dim == 0:
+ break
+ sd *= dim
+ return ret
+
[email protected]_safe
+def is_f_contiguous(arr):
+ shape = arr.get_shape()
+ strides = arr.get_strides()
+ ret = True
+ sd = arr.dtype.elsize
+ for i in range(len(shape)):
+ dim = shape[i]
+ if strides[i] != sd:
+ ret = False
+ break
+ if dim == 0:
+ break
+ sd *= dim
+ return ret
diff --git a/pypy/module/micronumpy/test/test_iterators.py
b/pypy/module/micronumpy/test/test_iterators.py
--- a/pypy/module/micronumpy/test/test_iterators.py
+++ b/pypy/module/micronumpy/test/test_iterators.py
@@ -13,6 +13,11 @@
self.strides = strides
self.start = start
+ def get_shape(self):
+ return self.shape
+
+ def get_strides(self):
+ return self.strides
class TestIterDirect(object):
def test_iterator_basic(self):
diff --git a/pypy/module/micronumpy/test/test_ndarray.py
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -1807,6 +1807,17 @@
x = array([], dtype=[('a', 'int8'), ('b', 'int8')])
y = x.view(dtype='int16')
+ def test_view_of_slice(self):
+ from numpy import empty
+ x = empty([6], 'uint32')
+ x.fill(0xdeadbeef)
+ s = x[::3]
+ exc = raises(ValueError, s.view, 'uint8')
+ assert exc.value[0] == 'new type not compatible with array.'
+ s[...] = 2
+ v = s.view(x.__class__)
+ assert (v == 2).all()
+
def test_tolist_scalar(self):
from numpy import dtype
int32 = dtype('int32').type
@@ -2912,11 +2923,7 @@
a = empty(10, dtype=[(_, int) for _ in 'abcde'])
a.fill(123)
for i in a:
- import sys
- if '__pypy__' in sys.builtin_module_names:
- assert tuple(i) == (123,) + (0,) * 4
- else:
- assert tuple(i) == (123,) * 5
+ assert tuple(i) == (123,) * 5
a = zeros(3, dtype=dtype(complex).newbyteorder())
a.fill(1.5+2.5j)
@@ -3846,7 +3853,7 @@
a = np.array([b, b, b], dtype=dt)
assert a.shape == (3, 2)
for i in a.flat:
- assert tuple(i) == (True, False)
+ assert tuple(i) == (True, True)
dt = np.dtype([('A', '<i8'), ('B', '<f8'), ('C', '<c16')])
b = np.array((999999, 1e+20, 1e+20+0j), dtype=dt)
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -311,26 +311,26 @@
BoxType = boxes.W_BoolBox
format_code = "?"
- True = BoxType(True)
- False = BoxType(False)
+ _True = BoxType(True)
+ _False = BoxType(False)
@specialize.argtype(1)
def box(self, value):
box = Primitive.box(self, value)
if box.value:
- return self.True
+ return self._True
else:
- return self.False
+ return self._False
@specialize.argtype(1, 2)
def box_complex(self, real, imag):
box = Primitive.box(self, real)
if box.value:
- return self.True
+ return self._True
box = Primitive.box(self, imag)
if box.value:
- return self.True
- return self.False
+ return self._True
+ return self._False
def coerce_subtype(self, space, w_subtype, w_item):
# Doesn't return subclasses so it can return the constants.
@@ -1869,7 +1869,7 @@
items_w = space.fixedview(w_item.get_scalar_value())
else:
# XXX support initializing from readable buffers
- items_w = [w_item]
+ items_w = [w_item] * len(dtype.fields)
else:
items_w = [None] * len(dtype.fields)
arr = VoidBoxStorage(dtype.elsize, dtype)
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
@@ -415,9 +415,12 @@
self.match_descr(op.descr, exp_descr)
- def _next_op(self, iter_ops, assert_raises=False):
+ def _next_op(self, iter_ops, assert_raises=False, ignore_ops=set()):
try:
- op = iter_ops.next()
+ while True:
+ op = iter_ops.next()
+ if op.name not in ignore_ops:
+ break
except StopIteration:
self._assert(assert_raises, "not enough operations")
return
@@ -454,9 +457,7 @@
else:
assert 0, "'{{{' not followed by '}}}'"
while exp_ops:
- op = self._next_op(iter_ops)
- if op.name in ignore_ops:
- continue
+ op = self._next_op(iter_ops, ignore_ops=ignore_ops)
# match 'op' against any of the exp_ops; the first successful
# match is kept, and the exp_op gets removed from the list
for i, exp_op in enumerate(exp_ops):
@@ -491,10 +492,7 @@
self.match_any_order(iter_exp_ops, iter_ops, ignore_ops)
continue
else:
- while True:
- op = self._next_op(iter_ops)
- if op.name not in ignore_ops:
- break
+ op = self._next_op(iter_ops, ignore_ops=ignore_ops)
self.match_op(op, exp_op)
except InvalidMatch, e:
if type(exp_op) is not str and exp_op[4] is False: #
optional operation
@@ -504,7 +502,7 @@
raise
#
# make sure we exhausted iter_ops
- self._next_op(iter_ops, assert_raises=True)
+ self._next_op(iter_ops, assert_raises=True, ignore_ops=ignore_ops)
def match(self, expected_src, ignore_ops=[]):
def format(src, opindex=None):
diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
@@ -318,6 +318,16 @@
jump(i4, descr=...)
"""
assert self.match(loop, expected, ignore_ops=['force_token'])
+ #
+ loop = """
+ [i0]
+ i1 = int_add(i0, 1)
+ i4 = force_token()
+ """
+ expected = """
+ i1 = int_add(i0, 1)
+ """
+ assert self.match(loop, expected, ignore_ops=['force_token'])
def test_match_dots_in_arguments(self):
loop = """
diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py
b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
--- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
@@ -342,9 +342,9 @@
guard_false(i114, descr=...)
--TICK--
i119 = call(ConstClass(_ll_1_raw_malloc_varsize__Signed), 6,
descr=<Calli . i EF=4 OS=110>)
- raw_store(i119, 0, i112, descr=<ArrayS 2>)
- raw_store(i119, 2, i112, descr=<ArrayS 2>)
- raw_store(i119, 4, i112, descr=<ArrayS 2>)
+ raw_store(i119, 0, i160, descr=<ArrayS 2>)
+ raw_store(i119, 2, i160, descr=<ArrayS 2>)
+ raw_store(i119, 4, i160, descr=<ArrayS 2>)
setfield_gc(p167, i119, descr=<FieldU
pypy.module._cffi_backend.cdataobj.W_CData.inst__cdata .+>)
i123 = arraylen_gc(p67, descr=<ArrayP .>)
jump(..., descr=...)
diff --git a/pypy/module/test_lib_pypy/test_datetime.py
b/pypy/module/test_lib_pypy/test_datetime.py
--- a/pypy/module/test_lib_pypy/test_datetime.py
+++ b/pypy/module/test_lib_pypy/test_datetime.py
@@ -3,6 +3,7 @@
from __future__ import absolute_import
import py
+
class BaseTestDatetime:
def test_repr(self):
print datetime
@@ -210,11 +211,13 @@
naive == aware
assert str(e.value) == "can't compare offset-naive and offset-aware
times"
-class TestDatetimeCPython(BaseTestDatetime):
+
+class TestDatetimeHost(BaseTestDatetime):
def setup_class(cls):
global datetime
import datetime
+
class TestDatetimePyPy(BaseTestDatetime):
def setup_class(cls):
global datetime
diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py
b/pypy/module/test_lib_pypy/test_sqlite3.py
--- a/pypy/module/test_lib_pypy/test_sqlite3.py
+++ b/pypy/module/test_lib_pypy/test_sqlite3.py
@@ -1,267 +1,285 @@
# -*- coding: utf-8 -*-
"""Tests for _sqlite3.py"""
-import pytest, sys
+from __future__ import absolute_import
+import pytest
+import sys
-if sys.version_info < (2, 7):
- pytest.skip("_sqlite3 requires Python 2.7")
-try:
- import _cffi_backend
-except ImportError:
- # On CPython, "pip install cffi". On old PyPy's, no chance
- pytest.skip("_sqlite3 requires _cffi_backend to be installed")
-
-from lib_pypy import _sqlite3
def pytest_funcarg__con(request):
con = _sqlite3.connect(':memory:')
request.addfinalizer(lambda: con.close())
return con
-def test_list_ddl(con):
- """From issue996. Mostly just looking for lack of exceptions."""
- cursor = con.cursor()
- cursor.execute('CREATE TABLE foo (bar INTEGER)')
- result = list(cursor)
- assert result == []
- cursor.execute('INSERT INTO foo (bar) VALUES (42)')
- result = list(cursor)
- assert result == []
- cursor.execute('SELECT * FROM foo')
- result = list(cursor)
- assert result == [(42,)]
-def test_connect_takes_same_positional_args_as_Connection(con):
- from inspect import getargspec
- clsargs = getargspec(_sqlite3.Connection.__init__).args[1:] # ignore self
- conargs = getargspec(_sqlite3.connect).args
- assert clsargs == conargs
+class BaseTestSQLite:
+ def test_list_ddl(self, con):
+ """From issue996. Mostly just looking for lack of exceptions."""
+ cursor = con.cursor()
+ cursor.execute('CREATE TABLE foo (bar INTEGER)')
+ result = list(cursor)
+ assert result == []
+ cursor.execute('INSERT INTO foo (bar) VALUES (42)')
+ result = list(cursor)
+ assert result == []
+ cursor.execute('SELECT * FROM foo')
+ result = list(cursor)
+ assert result == [(42,)]
-def test_total_changes_after_close(con):
- con.close()
- pytest.raises(_sqlite3.ProgrammingError, "con.total_changes")
+ def test_connect_takes_same_positional_args_as_Connection(self, con):
+ if not hasattr(_sqlite3, '_ffi'):
+ pytest.skip("only works for lib_pypy _sqlite3")
+ from inspect import getargspec
+ clsargs = getargspec(_sqlite3.Connection.__init__).args[1:] # ignore
self
+ conargs = getargspec(_sqlite3.connect).args
+ assert clsargs == conargs
-def test_connection_check_init():
- class Connection(_sqlite3.Connection):
- def __init__(self, name):
+ def test_total_changes_after_close(self, con):
+ con.close()
+ pytest.raises(_sqlite3.ProgrammingError, "con.total_changes")
+
+ def test_connection_check_init(self):
+ class Connection(_sqlite3.Connection):
+ def __init__(self, name):
+ pass
+
+ con = Connection(":memory:")
+ e = pytest.raises(_sqlite3.ProgrammingError, "con.cursor()")
+ assert '__init__' in e.value.message
+
+ def test_cursor_check_init(self, con):
+ class Cursor(_sqlite3.Cursor):
+ def __init__(self, name):
+ pass
+
+ cur = Cursor(con)
+ e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')")
+ assert '__init__' in e.value.message
+
+ def test_connection_after_close(self, con):
+ pytest.raises(TypeError, "con()")
+ con.close()
+ # raises ProgrammingError because should check closed before check args
+ pytest.raises(_sqlite3.ProgrammingError, "con()")
+
+ def test_cursor_iter(self, con):
+ cur = con.cursor()
+ with pytest.raises(StopIteration):
+ next(cur)
+
+ cur.execute('select 1')
+ next(cur)
+ with pytest.raises(StopIteration):
+ next(cur)
+
+ cur.execute('select 1')
+ con.commit()
+ next(cur)
+ with pytest.raises(StopIteration):
+ next(cur)
+
+ with pytest.raises(_sqlite3.ProgrammingError):
+ cur.executemany('select 1', [])
+ with pytest.raises(StopIteration):
+ next(cur)
+
+ cur.execute('select 1')
+ cur.execute('create table test(ing)')
+ with pytest.raises(StopIteration):
+ next(cur)
+
+ cur.execute('select 1')
+ cur.execute('insert into test values(1)')
+ con.commit()
+ with pytest.raises(StopIteration):
+ next(cur)
+
+ def test_cursor_after_close(self, con):
+ cur = con.execute('select 1')
+ cur.close()
+ con.close()
+ pytest.raises(_sqlite3.ProgrammingError, "cur.close()")
+ # raises ProgrammingError because should check closed before check args
+ pytest.raises(_sqlite3.ProgrammingError, "cur.execute(1,2,3,4,5)")
+ pytest.raises(_sqlite3.ProgrammingError, "cur.executemany(1,2,3,4,5)")
+
+ @pytest.mark.skipif("not hasattr(sys, 'pypy_translation_info')")
+ def test_connection_del(self, tmpdir):
+ """For issue1325."""
+ import os
+ import gc
+ try:
+ import resource
+ except ImportError:
+ pytest.skip("needs resource module")
+
+ limit = resource.getrlimit(resource.RLIMIT_NOFILE)
+ try:
+ fds = 0
+ while True:
+ fds += 1
+ resource.setrlimit(resource.RLIMIT_NOFILE, (fds, limit[1]))
+ try:
+ for p in os.pipe(): os.close(p)
+ except OSError:
+ assert fds < 100
+ else:
+ break
+
+ def open_many(cleanup):
+ con = []
+ for i in range(3):
+ con.append(_sqlite3.connect(str(tmpdir.join('test.db'))))
+ if cleanup:
+ con[i] = None
+ gc.collect(); gc.collect()
+
+ pytest.raises(_sqlite3.OperationalError, open_many, False)
+ gc.collect(); gc.collect()
+ open_many(True)
+ finally:
+ resource.setrlimit(resource.RLIMIT_NOFILE, limit)
+
+ def test_on_conflict_rollback_executemany(self, con):
+ major, minor, micro = _sqlite3.sqlite_version.split('.')[:3]
+ if (int(major), int(minor), int(micro)) < (3, 2, 2):
+ pytest.skip("requires sqlite3 version >= 3.2.2")
+ con.execute("create table foo(x, unique(x) on conflict rollback)")
+ con.execute("insert into foo(x) values (1)")
+ try:
+ con.executemany("insert into foo(x) values (?)", [[1]])
+ except _sqlite3.DatabaseError:
pass
+ con.execute("insert into foo(x) values (2)")
+ try:
+ con.commit()
+ except _sqlite3.OperationalError:
+ pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK")
- con = Connection(":memory:")
- e = pytest.raises(_sqlite3.ProgrammingError, "con.cursor()")
- assert '__init__' in e.value.message
+ def test_statement_arg_checking(self, con):
+ with pytest.raises(_sqlite3.Warning) as e:
+ con(123)
+ assert str(e.value) == 'SQL is of wrong type. Must be string or
unicode.'
+ with pytest.raises(ValueError) as e:
+ con.execute(123)
+ assert str(e.value) == 'operation parameter must be str or unicode'
+ with pytest.raises(ValueError) as e:
+ con.executemany(123, 123)
+ assert str(e.value) == 'operation parameter must be str or unicode'
+ with pytest.raises(ValueError) as e:
+ con.executescript(123)
+ assert str(e.value) == 'script argument must be unicode or string.'
-def test_cursor_check_init(con):
- class Cursor(_sqlite3.Cursor):
- def __init__(self, name):
- pass
+ def test_statement_param_checking(self, con):
+ con.execute('create table foo(x)')
+ con.execute('insert into foo(x) values (?)', [2])
+ con.execute('insert into foo(x) values (?)', (2,))
+ class seq(object):
+ def __len__(self):
+ return 1
+ def __getitem__(self, key):
+ return 2
+ con.execute('insert into foo(x) values (?)', seq())
+ del seq.__len__
+ with pytest.raises(_sqlite3.ProgrammingError):
+ con.execute('insert into foo(x) values (?)', seq())
+ with pytest.raises(_sqlite3.ProgrammingError):
+ con.execute('insert into foo(x) values (?)', {2:2})
+ with pytest.raises(ValueError) as e:
+ con.execute('insert into foo(x) values (?)', 2)
+ assert str(e.value) == 'parameters are of unsupported type'
- cur = Cursor(con)
- e = pytest.raises(_sqlite3.ProgrammingError, "cur.execute('select 1')")
- assert '__init__' in e.value.message
+ def test_explicit_begin(self, con):
+ con.execute('BEGIN')
+ con.execute('BEGIN ')
+ con.execute('BEGIN')
+ con.commit()
+ con.execute('BEGIN')
+ con.commit()
-def test_connection_after_close(con):
- pytest.raises(TypeError, "con()")
- con.close()
- # raises ProgrammingError because should check closed before check args
- pytest.raises(_sqlite3.ProgrammingError, "con()")
+ def test_row_factory_use(self, con):
+ con.row_factory = 42
+ con.execute('select 1')
-def test_cursor_iter(con):
- cur = con.cursor()
- with pytest.raises(StopIteration):
- next(cur)
+ def test_returning_blob_must_own_memory(self, con):
+ import gc
+ con.create_function("returnblob", 0, lambda: buffer("blob"))
+ cur = con.execute("select returnblob()")
+ val = cur.fetchone()[0]
+ for i in range(5):
+ gc.collect()
+ got = (val[0], val[1], val[2], val[3])
+ assert got == ('b', 'l', 'o', 'b')
+ # in theory 'val' should be a read-write buffer
+ # but it's not right now
+ if not hasattr(_sqlite3, '_ffi'):
+ val[1] = 'X'
+ got = (val[0], val[1], val[2], val[3])
+ assert got == ('b', 'X', 'o', 'b')
- cur.execute('select 1')
- next(cur)
- with pytest.raises(StopIteration):
- next(cur)
+ def test_description_after_fetchall(self, con):
+ cur = con.cursor()
+ assert cur.description is None
+ cur.execute("select 42").fetchall()
+ assert cur.description is not None
- cur.execute('select 1')
- con.commit()
- next(cur)
- with pytest.raises(StopIteration):
- next(cur)
+ def test_executemany_lastrowid(self, con):
+ cur = con.cursor()
+ cur.execute("create table test(a)")
+ cur.executemany("insert into test values (?)", [[1], [2], [3]])
+ assert cur.lastrowid is None
- with pytest.raises(_sqlite3.ProgrammingError):
- cur.executemany('select 1', [])
- with pytest.raises(StopIteration):
- next(cur)
+ def test_authorizer_bad_value(self, con):
+ def authorizer_cb(action, arg1, arg2, dbname, source):
+ return 42
+ con.set_authorizer(authorizer_cb)
+ with pytest.raises(_sqlite3.OperationalError) as e:
+ con.execute('select 123')
+ major, minor, micro = _sqlite3.sqlite_version.split('.')[:3]
+ if (int(major), int(minor), int(micro)) >= (3, 6, 14):
+ assert str(e.value) == 'authorizer malfunction'
+ else:
+ assert str(e.value) == \
+ ("illegal return value (1) from the authorization function - "
+ "should be SQLITE_OK, SQLITE_IGNORE, or SQLITE_DENY")
- cur.execute('select 1')
- cur.execute('create table test(ing)')
- with pytest.raises(StopIteration):
- next(cur)
+ def test_issue1573(self, con):
+ cur = con.cursor()
+ cur.execute(u'SELECT 1 as méil')
+ assert cur.description[0][0] == u"méil".encode('utf-8')
- cur.execute('select 1')
- cur.execute('insert into test values(1)')
- con.commit()
- with pytest.raises(StopIteration):
- next(cur)
+ def test_adapter_exception(self, con):
+ def cast(obj):
+ raise ZeroDivisionError
-def test_cursor_after_close(con):
- cur = con.execute('select 1')
- cur.close()
- con.close()
- pytest.raises(_sqlite3.ProgrammingError, "cur.close()")
- # raises ProgrammingError because should check closed before check args
- pytest.raises(_sqlite3.ProgrammingError, "cur.execute(1,2,3,4,5)")
- pytest.raises(_sqlite3.ProgrammingError, "cur.executemany(1,2,3,4,5)")
+ _sqlite3.register_adapter(int, cast)
+ try:
+ cur = con.cursor()
+ cur.execute("select ?", (4,))
+ val = cur.fetchone()[0]
+ # Adapter error is ignored, and parameter is passed as is.
+ assert val == 4
+ assert type(val) is int
+ finally:
+ del _sqlite3.adapters[(int, _sqlite3.PrepareProtocol)]
[email protected]("not hasattr(sys, 'pypy_translation_info')")
-def test_connection_del(tmpdir):
- """For issue1325."""
- import os
- import gc
- try:
- import resource
- except ImportError:
- pytest.skip("needs resource module")
- limit = resource.getrlimit(resource.RLIMIT_NOFILE)
- try:
- fds = 0
- while True:
- fds += 1
- resource.setrlimit(resource.RLIMIT_NOFILE, (fds, limit[1]))
- try:
- for p in os.pipe(): os.close(p)
- except OSError:
- assert fds < 100
- else:
- break
- def open_many(cleanup):
- con = []
- for i in range(3):
- con.append(_sqlite3.connect(str(tmpdir.join('test.db'))))
- if cleanup:
- con[i] = None
- gc.collect(); gc.collect()
+class TestSQLiteHost(BaseTestSQLite):
+ def setup_class(cls):
+ global _sqlite3
+ import _sqlite3
- pytest.raises(_sqlite3.OperationalError, open_many, False)
- gc.collect(); gc.collect()
- open_many(True)
- finally:
- resource.setrlimit(resource.RLIMIT_NOFILE, limit)
-def test_on_conflict_rollback_executemany(con):
- major, minor, micro = _sqlite3.sqlite_version.split('.')[:3]
- if (int(major), int(minor), int(micro)) < (3, 2, 2):
- pytest.skip("requires sqlite3 version >= 3.2.2")
- con.execute("create table foo(x, unique(x) on conflict rollback)")
- con.execute("insert into foo(x) values (1)")
- try:
- con.executemany("insert into foo(x) values (?)", [[1]])
- except _sqlite3.DatabaseError:
- pass
- con.execute("insert into foo(x) values (2)")
- try:
- con.commit()
- except _sqlite3.OperationalError:
- pytest.fail("_sqlite3 knew nothing about the implicit ROLLBACK")
+class TestSQLitePyPy(BaseTestSQLite):
+ def setup_class(cls):
+ if sys.version_info < (2, 7):
+ pytest.skip("_sqlite3 requires Python 2.7")
-def test_statement_arg_checking(con):
- with pytest.raises(_sqlite3.Warning) as e:
- con(123)
- assert str(e.value) == 'SQL is of wrong type. Must be string or unicode.'
- with pytest.raises(ValueError) as e:
- con.execute(123)
- assert str(e.value) == 'operation parameter must be str or unicode'
- with pytest.raises(ValueError) as e:
- con.executemany(123, 123)
- assert str(e.value) == 'operation parameter must be str or unicode'
- with pytest.raises(ValueError) as e:
- con.executescript(123)
- assert str(e.value) == 'script argument must be unicode or string.'
+ try:
+ import _cffi_backend
+ except ImportError:
+ # On CPython, "pip install cffi". On old PyPy's, no chance
+ pytest.skip("_sqlite3 requires _cffi_backend to be installed")
-def test_statement_param_checking(con):
- con.execute('create table foo(x)')
- con.execute('insert into foo(x) values (?)', [2])
- con.execute('insert into foo(x) values (?)', (2,))
- class seq(object):
- def __len__(self):
- return 1
- def __getitem__(self, key):
- return 2
- con.execute('insert into foo(x) values (?)', seq())
- del seq.__len__
- with pytest.raises(_sqlite3.ProgrammingError):
- con.execute('insert into foo(x) values (?)', seq())
- with pytest.raises(_sqlite3.ProgrammingError):
- con.execute('insert into foo(x) values (?)', {2:2})
- with pytest.raises(ValueError) as e:
- con.execute('insert into foo(x) values (?)', 2)
- assert str(e.value) == 'parameters are of unsupported type'
-
-def test_explicit_begin(con):
- con.execute('BEGIN')
- con.execute('BEGIN ')
- con.execute('BEGIN')
- con.commit()
- con.execute('BEGIN')
- con.commit()
-
-def test_row_factory_use(con):
- con.row_factory = 42
- con.execute('select 1')
-
-def test_returning_blob_must_own_memory(con):
- import gc
- con.create_function("returnblob", 0, lambda: buffer("blob"))
- cur = con.execute("select returnblob()")
- val = cur.fetchone()[0]
- for i in range(5):
- gc.collect()
- got = (val[0], val[1], val[2], val[3])
- assert got == ('b', 'l', 'o', 'b')
- # in theory 'val' should be a read-write buffer
- # but it's not right now
- pytest.skip("in theory 'val' should be a read-write buffer")
- val[1] = 'X'
- got = (val[0], val[1], val[2], val[3])
- assert got == ('b', 'X', 'o', 'b')
-
-def test_description_after_fetchall(con):
- cur = con.cursor()
- cur.execute("select 42").fetchall()
- assert cur.description is not None
-
-def test_executemany_lastrowid(con):
- cur = con.cursor()
- cur.execute("create table test(a)")
- cur.executemany("insert into test values (?)", [[1], [2], [3]])
- assert cur.lastrowid is None
-
-
-def test_authorizer_bad_value(con):
- def authorizer_cb(action, arg1, arg2, dbname, source):
- return 42
- con.set_authorizer(authorizer_cb)
- with pytest.raises(_sqlite3.OperationalError) as e:
- con.execute('select 123')
- major, minor, micro = _sqlite3.sqlite_version.split('.')[:3]
- if (int(major), int(minor), int(micro)) >= (3, 6, 14):
- assert str(e.value) == 'authorizer malfunction'
- else:
- assert str(e.value) == \
- ("illegal return value (1) from the authorization function - "
- "should be SQLITE_OK, SQLITE_IGNORE, or SQLITE_DENY")
-
-
-def test_issue1573(con):
- cur = con.cursor()
- cur.execute(u'SELECT 1 as méil')
- assert cur.description[0][0] == u"méil".encode('utf-8')
-
-def test_adapter_exception(con):
- def cast(obj):
- raise ZeroDivisionError
-
- _sqlite3.register_adapter(int, cast)
- try:
- cur = con.cursor()
- cur.execute("select ?", (4,))
- val = cur.fetchone()[0]
- # Adapter error is ignored, and parameter is passed as is.
- assert val == 4
- assert type(val) is int
- finally:
- del _sqlite3.adapters[(int, _sqlite3.PrepareProtocol)]
+ global _sqlite3
+ from lib_pypy import _sqlite3
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -366,8 +366,12 @@
tup = w_self._lookup_where(name)
return tup
name = promote_string(name)
- w_class, w_value = w_self._pure_lookup_where_with_method_cache(name,
version_tag)
- return w_class, unwrap_cell(space, w_value)
+ tup_w = w_self._pure_lookup_where_with_method_cache(name, version_tag)
+ w_class, w_value = tup_w
+ if (space.config.objspace.std.withtypeversion and
+ isinstance(w_value, TypeCell)):
+ return w_class, w_value.w_value
+ return tup_w # don't make a new tuple, reuse the old one
def _pure_lookup_where_possibly_with_method_cache(w_self, name,
version_tag):
if w_self.space.config.objspace.std.withmethodcache:
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -19,7 +19,7 @@
from rpython.annotator import description
from rpython.annotator.signature import annotationoftype
from rpython.annotator.argument import simple_args
-from rpython.rlib.objectmodel import r_dict, Symbolic
+from rpython.rlib.objectmodel import r_dict, r_ordereddict, Symbolic
from rpython.tool.algo.unionfind import UnionFind
from rpython.rtyper import extregistry
@@ -260,21 +260,23 @@
result.listdef.generalize(self.immutablevalue(e))
result.const_box = key
return result
- elif tp is dict or tp is r_dict or tp is SomeOrderedDict.knowntype:
- if tp is SomeOrderedDict.knowntype:
- cls = SomeOrderedDict
- else:
- cls = SomeDict
+ elif (tp is dict or tp is r_dict or
+ tp is SomeOrderedDict.knowntype or tp is r_ordereddict):
key = Constant(x)
try:
return self.immutable_cache[key]
except KeyError:
+ if tp is SomeOrderedDict.knowntype or tp is r_ordereddict:
+ cls = SomeOrderedDict
+ else:
+ cls = SomeDict
+ is_r_dict = issubclass(tp, r_dict)
result = cls(DictDef(self,
s_ImpossibleValue,
s_ImpossibleValue,
- is_r_dict = tp is r_dict))
+ is_r_dict = is_r_dict))
self.immutable_cache[key] = result
- if tp is r_dict:
+ if is_r_dict:
s_eqfn = self.immutablevalue(x.key_eq)
s_hashfn = self.immutablevalue(x.key_hash)
result.dictdef.dictkey.update_rdict_annotations(s_eqfn,
diff --git a/rpython/jit/metainterp/compile.py
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -74,7 +74,6 @@
# for a CALL_ASSEMBLER: record it as a potential jump.
if descr is not original_jitcell_token:
original_jitcell_token.record_jump_to(descr)
- descr.exported_state = None
op.cleardescr() # clear reference, mostly for tests
elif isinstance(descr, TargetToken):
# for a JUMP: record it as a potential jump.
@@ -84,10 +83,6 @@
if descr.original_jitcell_token is not original_jitcell_token:
assert descr.original_jitcell_token is not None
original_jitcell_token.record_jump_to(descr.original_jitcell_token)
- # exported_state is clear by optimizeopt when the short preamble is
- # constrcucted. if that did not happen the label should not show up
- # in a trace that will be used
- assert descr.exported_state is None
if not we_are_translated():
op._descr_wref = weakref.ref(op._descr)
op.cleardescr() # clear reference to prevent the history.Stats
@@ -133,7 +128,7 @@
[ResOperation(rop.LABEL, jumpargs, None,
descr=jitcell_token)]
try:
- optimize_trace(metainterp_sd, part, enable_opts)
+ start_state = optimize_trace(metainterp_sd, part, enable_opts)
except InvalidLoop:
return None
target_token = part.operations[0].getdescr()
@@ -146,7 +141,7 @@
loop.quasi_immutable_deps = {}
if part.quasi_immutable_deps:
loop.quasi_immutable_deps.update(part.quasi_immutable_deps)
- while part.operations[-1].getopnum() == rop.LABEL:
+ if part.operations[-1].getopnum() == rop.LABEL:
inliner = Inliner(inputargs, jumpargs)
part.quasi_immutable_deps = None
part.operations = [part.operations[-1]] + \
@@ -160,13 +155,15 @@
jumpargs = part.operations[-1].getarglist()
try:
- optimize_trace(metainterp_sd, part, enable_opts)
+ optimize_trace(metainterp_sd, part, enable_opts,
+ start_state=start_state)
except InvalidLoop:
return None
loop.operations = loop.operations[:-1] + part.operations
if part.quasi_immutable_deps:
loop.quasi_immutable_deps.update(part.quasi_immutable_deps)
+ assert part.operations[-1].getopnum() != rop.LABEL
if not loop.quasi_immutable_deps:
loop.quasi_immutable_deps = None
@@ -186,7 +183,7 @@
def compile_retrace(metainterp, greenkey, start,
inputargs, jumpargs,
- partial_trace, resumekey):
+ partial_trace, resumekey, start_state):
"""Try to compile a new procedure by closing the current history back
to the first operation.
"""
@@ -211,18 +208,19 @@
orignial_label = label.clone()
assert label.getopnum() == rop.LABEL
try:
- optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts)
+ optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts,
+ start_state=start_state)
except InvalidLoop:
# Fall back on jumping to preamble
target_token = label.getdescr()
assert isinstance(target_token, TargetToken)
- assert target_token.exported_state
part.operations = [orignial_label] + \
[ResOperation(rop.JUMP, inputargs[:],
None, descr=loop_jitcell_token)]
try:
- optimize_trace(metainterp_sd, part,
jitdriver_sd.warmstate.enable_opts,
- inline_short_preamble=False)
+ optimize_trace(metainterp_sd, part,
+ jitdriver_sd.warmstate.enable_opts,
+ inline_short_preamble=False,
start_state=start_state)
except InvalidLoop:
return None
assert part.operations[-1].getopnum() != rop.LABEL
@@ -791,7 +789,7 @@
else:
inline_short_preamble = True
try:
- optimize_trace(metainterp_sd, new_trace, state.enable_opts,
inline_short_preamble)
+ state = optimize_trace(metainterp_sd, new_trace, state.enable_opts,
inline_short_preamble)
except InvalidLoop:
debug_print("compile_new_bridge: got an InvalidLoop")
# XXX I am fairly convinced that optimize_bridge cannot actually raise
@@ -807,7 +805,7 @@
record_loop_or_bridge(metainterp_sd, new_trace)
return target_token
else:
- metainterp.retrace_needed(new_trace)
+ metainterp.retrace_needed(new_trace, state)
return None
# ____________________________________________________________
diff --git a/rpython/jit/metainterp/history.py
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -617,7 +617,6 @@
self.original_jitcell_token = None
self.virtual_state = None
- self.exported_state = None
self.short_preamble = None
def repr_of_descr(self):
diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py
--- a/rpython/jit/metainterp/logger.py
+++ b/rpython/jit/metainterp/logger.py
@@ -178,13 +178,6 @@
fail_args = ''
return s_offset + res + op.getopname() + '(' + args + ')' + fail_args
- def _log_inputarg_setup_ops(self, op):
- target_token = op.getdescr()
- if isinstance(target_token, TargetToken):
- if target_token.exported_state:
- for op in target_token.exported_state.inputarg_setup_ops:
- debug_print(' ' + self.repr_of_resop(op))
-
def _log_operations(self, inputargs, operations, ops_offset):
if not have_debug_prints():
return
@@ -194,10 +187,10 @@
args = ", ".join([self.repr_of_arg(arg) for arg in inputargs])
debug_print('[' + args + ']')
for i in range(len(operations)):
- op = operations[i]
+ #op = operations[i]
debug_print(self.repr_of_resop(operations[i], ops_offset))
- if op.getopnum() == rop.LABEL:
- self._log_inputarg_setup_ops(op)
+ #if op.getopnum() == rop.LABEL:
+ # self._log_inputarg_setup_ops(op)
if ops_offset and None in ops_offset:
offset = ops_offset[None]
debug_print("+%d: --end of the loop--" % offset)
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py
b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -47,7 +47,8 @@
return optimizations, unroll
-def optimize_trace(metainterp_sd, loop, enable_opts,
inline_short_preamble=True):
+def optimize_trace(metainterp_sd, loop, enable_opts,
+ inline_short_preamble=True, start_state=None):
"""Optimize loop.operations to remove internal overheadish operations.
"""
@@ -57,7 +58,8 @@
loop.operations)
optimizations, unroll = build_opt_chain(metainterp_sd, enable_opts)
if unroll:
- optimize_unroll(metainterp_sd, loop, optimizations,
inline_short_preamble)
+ return optimize_unroll(metainterp_sd, loop, optimizations,
+ inline_short_preamble, start_state)
else:
optimizer = Optimizer(metainterp_sd, loop, optimizations)
optimizer.propagate_all_forward()
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py
b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -42,8 +42,9 @@
oldop = self.pure_operations.get(args, None)
if oldop is not None and oldop.getdescr() is op.getdescr():
assert oldop.getopnum() == op.getopnum()
- self.optimizer.make_equal_to(op.result,
self.getvalue(oldop.result),
- True)
+ self.optimizer.make_equal_to(op.result,
+ self.getvalue(oldop.result),
+ True)
return
else:
self.pure_operations[args] = op
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_multilabel.py
b/rpython/jit/metainterp/optimizeopt/test/test_multilabel.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_multilabel.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_multilabel.py
@@ -32,6 +32,7 @@
if op.getopnum()==rop.LABEL]
prv = 0
last_label = []
+ state = None
for nxt in labels + [len(loop.operations)]:
assert prv != nxt
operations = last_label + loop.operations[prv:nxt]
@@ -44,7 +45,7 @@
part.operations = operations
self.add_guard_future_condition(part)
- self._do_optimize_loop(part, None)
+ state = self._do_optimize_loop(part, None, state)
if part.operations[-1].getopnum() == rop.LABEL:
last_label = [part.operations.pop()]
else:
@@ -496,7 +497,7 @@
class BaseTestOptimizerRenamingBoxes(BaseTestMultiLabel):
- def _do_optimize_loop(self, loop, call_pure_results):
+ def _do_optimize_loop(self, loop, call_pure_results, state):
from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll
from rpython.jit.metainterp.optimizeopt.util import args_dict
from rpython.jit.metainterp.optimizeopt.pure import OptPure
@@ -504,7 +505,7 @@
self.loop = loop
loop.call_pure_results = args_dict()
metainterp_sd = FakeMetaInterpStaticData(self.cpu)
- optimize_unroll(metainterp_sd, loop, [OptRewrite(), OptRenameStrlen(),
OptHeap(), OptPure()], True)
+ return optimize_unroll(metainterp_sd, loop, [OptRewrite(),
OptRenameStrlen(), OptHeap(), OptPure()], True, state)
def test_optimizer_renaming_boxes1(self):
ops = """
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -390,7 +390,7 @@
assert equaloplists(optimized.operations,
expected.operations, False, remap, text_right)
- def _do_optimize_loop(self, loop, call_pure_results):
+ def _do_optimize_loop(self, loop, call_pure_results, start_state=None):
from rpython.jit.metainterp.optimizeopt import optimize_trace
from rpython.jit.metainterp.optimizeopt.util import args_dict
@@ -405,7 +405,8 @@
if hasattr(self, 'callinfocollection'):
metainterp_sd.callinfocollection = self.callinfocollection
#
- optimize_trace(metainterp_sd, loop, self.enable_opts)
+ return optimize_trace(metainterp_sd, loop, self.enable_opts,
+ start_state=start_state)
def unroll_and_optimize(self, loop, call_pure_results=None):
self.add_guard_future_condition(loop)
@@ -425,7 +426,7 @@
preamble.operations = [ResOperation(rop.LABEL, inputargs, None,
descr=TargetToken(token))] + \
operations + \
[ResOperation(rop.LABEL, jump_args, None,
descr=token)]
- self._do_optimize_loop(preamble, call_pure_results)
+ start_state = self._do_optimize_loop(preamble, call_pure_results)
assert preamble.operations[-1].getopnum() == rop.LABEL
@@ -439,7 +440,7 @@
assert loop.operations[0].getopnum() == rop.LABEL
loop.inputargs = loop.operations[0].getarglist()
- self._do_optimize_loop(loop, call_pure_results)
+ self._do_optimize_loop(loop, call_pure_results, start_state)
extra_same_as = []
while loop.operations[0].getopnum() != rop.LABEL:
extra_same_as.append(loop.operations[0])
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
@@ -15,10 +15,11 @@
# FIXME: Introduce some VirtualOptimizer super class instead
-def optimize_unroll(metainterp_sd, loop, optimizations,
inline_short_preamble=True):
+def optimize_unroll(metainterp_sd, loop, optimizations,
+ inline_short_preamble=True, start_state=None):
opt = UnrollOptimizer(metainterp_sd, loop, optimizations)
opt.inline_short_preamble = inline_short_preamble
- opt.propagate_all_forward()
+ return opt.propagate_all_forward(start_state)
class UnrollableOptimizer(Optimizer):
@@ -69,7 +70,7 @@
prev = self.fix_snapshot(jump_args, snapshot.prev)
return Snapshot(prev, new_snapshot_args)
- def propagate_all_forward(self):
+ def propagate_all_forward(self, starting_state):
loop = self.optimizer.loop
self.optimizer.clear_newoperations()
@@ -94,7 +95,7 @@
else:
jumpop = None
- self.import_state(start_label)
+ self.import_state(start_label, starting_state)
self.optimizer.propagate_all_forward(clear=False)
if not jumpop:
@@ -147,8 +148,9 @@
KillHugeIntBounds(self.optimizer).apply()
loop.operations = self.optimizer.get_newoperations()
- self.export_state(stop_label)
+ final_state = self.export_state(stop_label)
loop.operations.append(stop_label)
+ return final_state
def jump_to_start_label(self, start_label, stop_label):
if not start_label or not stop_label:
@@ -202,10 +204,9 @@
box = op.result
exported_values[box] = self.optimizer.getvalue(box)
- target_token.exported_state = ExportedState(short_boxes,
inputarg_setup_ops,
- exported_values)
+ return ExportedState(short_boxes, inputarg_setup_ops, exported_values)
- def import_state(self, targetop):
+ def import_state(self, targetop, exported_state):
if not targetop: # Trace did not start with a label
self.inputargs = self.optimizer.loop.inputargs
self.short = None
@@ -215,7 +216,6 @@
self.inputargs = targetop.getarglist()
target_token = targetop.getdescr()
assert isinstance(target_token, TargetToken)
- exported_state = target_token.exported_state
if not exported_state:
# No state exported, construct one without virtuals
self.short = None
@@ -413,7 +413,6 @@
if op.result:
op.result.forget_value()
target_token.short_preamble = self.short
- target_token.exported_state = None
def ensure_short_op_emitted(self, op, optimizer, seen):
if op is None:
@@ -561,7 +560,9 @@
try:
# NB: the short_preamble ends with a jump
- self._inline_short_preamble(target.short_preamble, inliner,
patchguardop, target.assumed_classes)
+ self._inline_short_preamble(target.short_preamble, inliner,
+ patchguardop,
+ target.assumed_classes)
except InvalidLoop:
#debug_print("Inlining failed unexpectedly",
# "jumping to preamble instead")
@@ -572,7 +573,8 @@
debug_stop('jit-log-virtualstate')
return False
- def _inline_short_preamble(self, short_preamble, inliner, patchguardop,
assumed_classes):
+ def _inline_short_preamble(self, short_preamble, inliner, patchguardop,
+ assumed_classes):
i = 1
# XXX this is intentiontal :-(. short_preamble can change during the
# loop in some cases
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py
b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -585,13 +585,13 @@
class ShortBoxes(object):
- def __init__(self, optimizer, surviving_boxes, availible_boxes=None):
+ def __init__(self, optimizer, surviving_boxes, available_boxes=None):
self.potential_ops = {}
self.alternatives = {}
self.synthetic = {}
self.rename = {}
self.optimizer = optimizer
- self.availible_boxes = availible_boxes
+ self.available_boxes = available_boxes
self.assumed_classes = {}
if surviving_boxes is not None:
@@ -663,7 +663,7 @@
return
if box in self.short_boxes_in_production:
raise BoxNotProducable
- if self.availible_boxes is not None and box not in
self.availible_boxes:
+ if self.available_boxes is not None and box not in
self.available_boxes:
raise BoxNotProducable
self.short_boxes_in_production[box] = None
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -1730,6 +1730,7 @@
class MetaInterp(object):
portal_call_depth = 0
cancel_count = 0
+ exported_state = None
def __init__(self, staticdata, jitdriver_sd):
self.staticdata = staticdata
@@ -1750,9 +1751,10 @@
self.call_ids = []
self.current_call_id = 0
- def retrace_needed(self, trace):
+ def retrace_needed(self, trace, exported_state):
self.partial_trace = trace
self.retracing_from = len(self.history.operations) - 1
+ self.exported_state = exported_state
self.heapcache.reset()
@@ -2249,7 +2251,9 @@
raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP) # For
now
# Found! Compile it as a loop.
# raises in case it works -- which is the common case
- self.compile_loop(original_boxes, live_arg_boxes, start)
+ self.compile_loop(original_boxes, live_arg_boxes, start,
+ exported_state=self.exported_state)
+ self.exported_state = None
# creation of the loop was cancelled!
self.cancel_count += 1
if self.staticdata.warmrunnerdesc:
@@ -2363,7 +2367,7 @@
return token
def compile_loop(self, original_boxes, live_arg_boxes, start,
- try_disabling_unroll=False):
+ try_disabling_unroll=False, exported_state=None):
num_green_args = self.jitdriver_sd.num_green_args
greenkey = original_boxes[:num_green_args]
if not self.partial_trace:
@@ -2377,7 +2381,8 @@
original_boxes[num_green_args:],
live_arg_boxes[num_green_args:],
self.partial_trace,
- self.resumekey)
+ self.resumekey,
+ exported_state)
else:
target_token = compile.compile_loop(self, greenkey, start,
original_boxes[num_green_args:],
diff --git a/rpython/rlib/test/test_objectmodel.py
b/rpython/rlib/test/test_objectmodel.py
--- a/rpython/rlib/test/test_objectmodel.py
+++ b/rpython/rlib/test/test_objectmodel.py
@@ -329,6 +329,18 @@
res = self.interpret(g, [3])
assert res == 42 # "did not crash"
+ def test_prepare_dict_update_2(self):
+ try:
+ from collections import OrderedDict
+ except ImportError: # Python 2.6
+ py.test.skip("requires collections.OrderedDict")
+ def g(n):
+ d = OrderedDict()
+ prepare_dict_update(d, n)
+ return 42
+ res = self.interpret(g, [3])
+ assert res == 42 # "did not crash"
+
def test_compute_hash(self):
class Foo(object):
pass
diff --git a/rpython/rtyper/lltypesystem/rdict.py
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -669,6 +669,7 @@
d.num_items = 0
d.resize_counter = DICT_INITSIZE * 2
return d
+DictRepr.ll_newdict = staticmethod(ll_newdict)
def ll_newdict_size(DICT, length_estimate):
length_estimate = (length_estimate // 2) * 3
@@ -692,26 +693,6 @@
pass
-def rtype_r_dict(hop, i_force_non_null=None):
- r_dict = hop.r_result
- if not r_dict.custom_eq_hash:
- raise TyperError("r_dict() call does not return an r_dict instance")
- v_eqfn = hop.inputarg(r_dict.r_rdict_eqfn, arg=0)
- v_hashfn = hop.inputarg(r_dict.r_rdict_hashfn, arg=1)
- if i_force_non_null is not None:
- assert i_force_non_null == 2
- hop.inputarg(lltype.Void, arg=2)
- cDICT = hop.inputconst(lltype.Void, r_dict.DICT)
- hop.exception_cannot_occur()
- v_result = hop.gendirectcall(ll_newdict, cDICT)
- if r_dict.r_rdict_eqfn.lowleveltype != lltype.Void:
- cname = hop.inputconst(lltype.Void, 'fnkeyeq')
- hop.genop('setfield', [v_result, cname, v_eqfn])
- if r_dict.r_rdict_hashfn.lowleveltype != lltype.Void:
- cname = hop.inputconst(lltype.Void, 'fnkeyhash')
- hop.genop('setfield', [v_result, cname, v_hashfn])
- return v_result
-
# ____________________________________________________________
#
# Iteration.
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py
b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -156,7 +156,7 @@
def __init__(self, rtyper, key_repr, value_repr, dictkey, dictvalue,
custom_eq_hash=None, force_non_null=False):
- assert not force_non_null
+ #assert not force_non_null
self.rtyper = rtyper
self.finalized = False
self.DICT = lltype.GcForwardReference()
@@ -232,6 +232,7 @@
raise TypeError("No prebuilt dicts of address keys")
r_value = self.value_repr
if isinstance(dictobj, objectmodel.r_dict):
+
if self.r_rdict_eqfn.lowleveltype != lltype.Void:
l_fn = self.r_rdict_eqfn.convert_const(dictobj.key_eq)
l_dict.fnkeyeq = l_fn
@@ -289,6 +290,11 @@
hop.exception_cannot_occur()
return hop.gendirectcall(ll_dict_update, v_dic1, v_dic2)
+ def rtype_method__prepare_dict_update(self, hop):
+ v_dict, v_num = hop.inputargs(self, lltype.Signed)
+ hop.exception_cannot_occur()
+ hop.gendirectcall(ll_prepare_dict_update, v_dict, v_num)
+
def _rtype_method_kvi(self, hop, ll_func):
v_dic, = hop.inputargs(self)
r_list = hop.r_result
@@ -594,10 +600,12 @@
else:
newitems = d.entries
#
- ENTRY = lltype.typeOf(d).TO.entries.TO.OF
+ ENTRIES = lltype.typeOf(d).TO.entries.TO
+ ENTRY = ENTRIES.OF
isrc = 0
idst = 0
- while isrc < len(d.entries):
+ isrclimit = d.num_used_items
+ while isrc < isrclimit:
if d.entries.valid(isrc):
src = d.entries[isrc]
dst = newitems[idst]
@@ -610,9 +618,21 @@
dst.f_valid = True
idst += 1
isrc += 1
- d.entries = newitems
assert d.num_items == idst
d.num_used_items = idst
+ if ((ENTRIES.must_clear_key or ENTRIES.must_clear_value) and
+ d.entries == newitems):
+ # must clear the extra entries: they may contain valid pointers
+ # which would create a temporary memory leak
+ while idst < isrclimit:
+ entry = newitems[idst]
+ if ENTRIES.must_clear_key:
+ entry.key = lltype.nullptr(ENTRY.key.TO)
+ if ENTRIES.must_clear_value:
+ entry.value = lltype.nullptr(ENTRY.value.TO)
+ idst += 1
+ else:
+ d.entries = newitems
ll_dict_reindex(d, _ll_len_of_d_indexes(d))
@@ -653,11 +673,14 @@
# make a 'new_size' estimate and shrink it if there are many
# deleted entry markers. See CPython for why it is a good idea to
# quadruple the dictionary size as long as it's not too big.
- num_items = d.num_items
- if num_items > 50000:
- new_estimate = num_items * 2
- else:
- new_estimate = num_items * 4
+ # (Quadrupling comes from '(d.num_items + d.num_items + 1) * 2'
+ # as long as num_items is not too large.)
+ num_extra = min(d.num_items + 1, 30000)
+ _ll_dict_resize_to(d, num_extra)
+ll_dict_resize.oopspec = 'odict.resize(d)'
+
+def _ll_dict_resize_to(d, num_extra):
+ new_estimate = (d.num_items + num_extra) * 2
new_size = DICT_INITSIZE
while new_size <= new_estimate:
new_size *= 2
@@ -666,7 +689,6 @@
ll_dict_remove_deleted_items(d)
else:
ll_dict_reindex(d, new_size)
-ll_dict_resize.oopspec = 'odict.resize(d)'
def ll_dict_reindex(d, new_size):
ll_malloc_indexes_and_choose_lookup(d, new_size)
@@ -831,6 +853,7 @@
d.num_used_items = 0
d.resize_counter = DICT_INITSIZE * 2
return d
+OrderedDictRepr.ll_newdict = staticmethod(ll_newdict)
def ll_newdict_size(DICT, orig_length_estimate):
length_estimate = (orig_length_estimate // 2) * 3
@@ -856,23 +879,6 @@
pass
-def rtype_r_dict(hop):
- r_dict = hop.r_result
- if not r_dict.custom_eq_hash:
- raise TyperError("r_dict() call does not return an r_dict instance")
- v_eqfn = hop.inputarg(r_dict.r_rdict_eqfn, arg=0)
- v_hashfn = hop.inputarg(r_dict.r_rdict_hashfn, arg=1)
- cDICT = hop.inputconst(lltype.Void, r_dict.DICT)
- hop.exception_cannot_occur()
- v_result = hop.gendirectcall(ll_newdict, cDICT)
- if r_dict.r_rdict_eqfn.lowleveltype != lltype.Void:
- cname = hop.inputconst(lltype.Void, 'fnkeyeq')
- hop.genop('setfield', [v_result, cname, v_eqfn])
- if r_dict.r_rdict_hashfn.lowleveltype != lltype.Void:
- cname = hop.inputconst(lltype.Void, 'fnkeyhash')
- hop.genop('setfield', [v_result, cname, v_hashfn])
- return v_result
-
# ____________________________________________________________
#
# Iteration.
@@ -981,6 +987,9 @@
ll_dict_clear.oopspec = 'odict.clear(d)'
def ll_dict_update(dic1, dic2):
+ if dic1 == dic2:
+ return
+ ll_prepare_dict_update(dic1, dic2.num_items)
i = 0
while i < dic2.num_used_items:
entries = dic2.entries
@@ -994,6 +1003,22 @@
i += 1
ll_dict_update.oopspec = 'odict.update(dic1, dic2)'
+def ll_prepare_dict_update(d, num_extra):
+ # Prescale 'd' for 'num_extra' items, assuming that most items don't
+ # collide. If this assumption is false, 'd' becomes too large by at
+ # most 'num_extra'. The logic is based on:
+ # (d.resize_counter - 1) // 3 = room left in d
+ # so, if num_extra == 1, we need d.resize_counter > 3
+ # if num_extra == 2, we need d.resize_counter > 6 etc.
+ # Note however a further hack: if num_extra <= d.num_items,
+ # we avoid calling _ll_dict_resize_to here. This is to handle
+ # the case where dict.update() actually has a lot of collisions.
+ # If num_extra is much greater than d.num_items the conditional_call
+ # will trigger anyway, which is really the goal.
+ x = num_extra - d.num_items
+ jit.conditional_call(d.resize_counter <= x * 3,
+ _ll_dict_resize_to, d, num_extra)
+
# this is an implementation of keys(), values() and items()
# in a single function.
# note that by specialization on func, three different
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -724,15 +724,16 @@
raise TyperError("hasattr is only suported on a constant")
@typer_for(annmodel.SomeOrderedDict.knowntype)
+@typer_for(objectmodel.r_dict)
@typer_for(objectmodel.r_ordereddict)
-def rtype_ordered_dict(hop):
- from rpython.rtyper.lltypesystem.rordereddict import ll_newdict
-
+def rtype_dict_constructor(hop, i_force_non_null=None):
+ # 'i_force_non_null' is ignored here; if it has any effect, it
+ # has already been applied to 'hop.r_result'
hop.exception_cannot_occur()
r_dict = hop.r_result
cDICT = hop.inputconst(lltype.Void, r_dict.DICT)
- v_result = hop.gendirectcall(ll_newdict, cDICT)
- if hasattr(r_dict, 'r_dict_eqfn'):
+ v_result = hop.gendirectcall(r_dict.ll_newdict, cDICT)
+ if r_dict.custom_eq_hash:
v_eqfn = hop.inputarg(r_dict.r_rdict_eqfn, arg=0)
v_hashfn = hop.inputarg(r_dict.r_rdict_hashfn, arg=1)
if r_dict.r_rdict_eqfn.lowleveltype != lltype.Void:
@@ -743,9 +744,6 @@
hop.genop('setfield', [v_result, cname, v_hashfn])
return v_result
-from rpython.rtyper.lltypesystem.rdict import rtype_r_dict
-typer_for(objectmodel.r_dict)(rtype_r_dict)
-
# _________________________________________________________________
# weakrefs
diff --git a/rpython/rtyper/rdict.py b/rpython/rtyper/rdict.py
--- a/rpython/rtyper/rdict.py
+++ b/rpython/rtyper/rdict.py
@@ -57,11 +57,10 @@
def rtype_newdict(hop):
- from rpython.rtyper.lltypesystem.rdict import ll_newdict
hop.inputargs() # no arguments expected
r_dict = hop.r_result
cDICT = hop.inputconst(lltype.Void, r_dict.DICT)
- v_result = hop.gendirectcall(ll_newdict, cDICT)
+ v_result = hop.gendirectcall(r_dict.ll_newdict, cDICT)
return v_result
diff --git a/rpython/rtyper/test/test_rdict.py
b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -878,6 +878,81 @@
res = self.interpret(func, [])
assert lltype.typeOf(res.item0) == lltype.typeOf(res.item1)
+ def test_r_dict(self):
+ class FooError(Exception):
+ pass
+ def myeq(n, m):
+ return n == m
+ def myhash(n):
+ if n < 0:
+ raise FooError
+ return -n
+ def f(n):
+ d = self.new_r_dict(myeq, myhash)
+ for i in range(10):
+ d[i] = i*i
+ try:
+ value1 = d[n]
+ except FooError:
+ value1 = 99
+ try:
+ value2 = n in d
+ except FooError:
+ value2 = 99
+ try:
+ value3 = d[-n]
+ except FooError:
+ value3 = 99
+ try:
+ value4 = (-n) in d
+ except FooError:
+ value4 = 99
+ return (value1 * 1000000 +
+ value2 * 10000 +
+ value3 * 100 +
+ value4)
+ res = self.interpret(f, [5])
+ assert res == 25019999
+
+ def test_r_dict_popitem_hash(self):
+ def deq(n, m):
+ return n == m
+ def dhash(n):
+ return ~n
+ def func():
+ d = self.new_r_dict(deq, dhash)
+ d[5] = 2
+ d[6] = 3
+ k1, v1 = d.popitem()
+ assert len(d) == 1
+ k2, v2 = d.popitem()
+ try:
+ d.popitem()
+ except KeyError:
+ pass
+ else:
+ assert 0, "should have raised KeyError"
+ assert len(d) == 0
+ return k1*1000 + v1*100 + k2*10 + v2
+
+ res = self.interpret(func, [])
+ assert res in [5263, 6352]
+
+ def test_prebuilt_r_dict(self):
+ def deq(n, m):
+ return (n & 3) == (m & 3)
+ def dhash(n):
+ return n & 3
+ d = self.new_r_dict(deq, dhash)
+ d[0x123] = "abcd"
+ d[0x231] = "efgh"
+ def func():
+ return d[0x348973] + d[0x12981]
+
+ res = self.interpret(func, [])
+ res = self.ll_to_string(res)
+ assert res == "abcdefgh"
+
class TestRDict(BaseTestRDict):
@staticmethod
@@ -888,6 +963,10 @@
def newdict2():
return {}
+ @staticmethod
+ def new_r_dict(myeq, myhash):
+ return r_dict(myeq, myhash)
+
def test_two_dicts_with_different_value_types(self):
def func(i):
d1 = {}
@@ -1043,66 +1122,6 @@
assert lltype.typeOf(res.item1) == lltype.typeOf(res.item2)
assert lltype.typeOf(res.item1) == lltype.typeOf(res.item3)
- def test_r_dict(self):
- class FooError(Exception):
- pass
- def myeq(n, m):
- return n == m
- def myhash(n):
- if n < 0:
- raise FooError
- return -n
- def f(n):
- d = r_dict(myeq, myhash)
- for i in range(10):
- d[i] = i*i
- try:
- value1 = d[n]
- except FooError:
- value1 = 99
- try:
- value2 = n in d
- except FooError:
- value2 = 99
- try:
- value3 = d[-n]
- except FooError:
- value3 = 99
- try:
- value4 = (-n) in d
- except FooError:
- value4 = 99
- return (value1 * 1000000 +
- value2 * 10000 +
- value3 * 100 +
- value4)
- res = self.interpret(f, [5])
- assert res == 25019999
-
- def test_dict_popitem_hash(self):
- def deq(n, m):
- return n == m
- def dhash(n):
- return ~n
- def func():
- d = r_dict(deq, dhash)
- d[5] = 2
- d[6] = 3
- k1, v1 = d.popitem()
- assert len(d) == 1
- k2, v2 = d.popitem()
- try:
- d.popitem()
- except KeyError:
- pass
- else:
- assert 0, "should have raised KeyError"
- assert len(d) == 0
- return k1*1000 + v1*100 + k2*10 + v2
-
- res = self.interpret(func, [])
- assert res in [5263, 6352]
-
def test_nonnull_hint(self):
def eq(a, b):
return a == b
diff --git a/rpython/rtyper/test/test_rordereddict.py
b/rpython/rtyper/test/test_rordereddict.py
--- a/rpython/rtyper/test/test_rordereddict.py
+++ b/rpython/rtyper/test/test_rordereddict.py
@@ -251,6 +251,16 @@
assert rordereddict.ll_dict_pop_default(ll_d, llstr("k"), 40) == 40
assert rordereddict.ll_dict_pop_default(ll_d, llstr("j"), 39) == 39
+ def test_bug_remove_deleted_items(self):
+ DICT = self._get_str_dict()
+ ll_d = rordereddict.ll_newdict(DICT)
+ for i in range(15):
+ rordereddict.ll_dict_setitem(ll_d, llstr(chr(i)), 5)
+ for i in range(15):
+ rordereddict.ll_dict_delitem(ll_d, llstr(chr(i)))
+ rordereddict.ll_prepare_dict_update(ll_d, 7)
+ # used to get UninitializedMemoryAccess
+
class TestRDictDirectDummyKey(TestRDictDirect):
class dummykeyobj:
ll_dummy_value = llstr("dupa")
@@ -268,6 +278,10 @@
def newdict2():
return OrderedDict()
+ @staticmethod
+ def new_r_dict(myeq, myhash):
+ return objectmodel.r_ordereddict(myeq, myhash)
+
def test_two_dicts_with_different_value_types(self):
def func(i):
d1 = OrderedDict()
@@ -285,62 +299,124 @@
py.test.skip("I don't want to edit this file on two branches")
- def test_r_dict(self):
- class FooError(Exception):
- pass
- def myeq(n, m):
- return n == m
- def myhash(n):
- if n < 0:
- raise FooError
- return -n
- def f(n):
- d = objectmodel.r_ordereddict(myeq, myhash)
- for i in range(10):
- d[i] = i*i
- try:
- value1 = d[n]
- except FooError:
- value1 = 99
- try:
- value2 = n in d
- except FooError:
- value2 = 99
- try:
- value3 = d[-n]
- except FooError:
- value3 = 99
- try:
- value4 = (-n) in d
- except FooError:
- value4 = 99
- return (value1 * 1000000 +
- value2 * 10000 +
- value3 * 100 +
- value4)
- res = self.interpret(f, [5])
- assert res == 25019999
+class TestStress:
- def test_dict_popitem_hash(self):
- def deq(n, m):
- return n == m
- def dhash(n):
- return ~n
- def func():
- d = objectmodel.r_ordereddict(deq, dhash)
- d[5] = 2
- d[6] = 3
- k1, v1 = d.popitem()
- assert len(d) == 1
- k2, v2 = d.popitem()
- try:
- d.popitem()
- except KeyError:
- pass
+ def test_stress(self):
+ from rpython.annotator.dictdef import DictKey, DictValue
+ from rpython.annotator import model as annmodel
+ from rpython.rtyper import rint
+ from rpython.rtyper.test.test_rdict import not_really_random
+ rodct = rordereddict
+ dictrepr = rodct.OrderedDictRepr(
+ None, rint.signed_repr, rint.signed_repr,
+ DictKey(None, annmodel.SomeInteger()),
+ DictValue(None, annmodel.SomeInteger()))
+ dictrepr.setup()
+ l_dict = rodct.ll_newdict(dictrepr.DICT)
+ referencetable = [None] * 400
+ referencelength = 0
+ value = 0
+
+ def complete_check():
+ for n, refvalue in zip(range(len(referencetable)), referencetable):
+ try:
+ gotvalue = rodct.ll_dict_getitem(l_dict, n)
+ except KeyError:
+ assert refvalue is None
+ else:
+ assert gotvalue == refvalue
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit