Author: mattip <[email protected]>
Branch:
Changeset: r62318:5929d5aa6cd8
Date: 2013-03-12 08:10 -0700
http://bitbucket.org/pypy/pypy/changeset/5929d5aa6cd8/
Log: merge heads
diff --git a/dotviewer/graphclient.py b/dotviewer/graphclient.py
--- a/dotviewer/graphclient.py
+++ b/dotviewer/graphclient.py
@@ -130,10 +130,10 @@
if hasattr(sys, 'pypy_objspaceclass'):
# if 'python' is actually PyPy, e.g. in a virtualenv, then
# try hard to find a real CPython
- for python in ['/usr/local/bin/python', '/usr/bin/python']:
- if os.path.exists(python):
- break
- else:
+ try:
+ python = subprocess.check_output(
+ 'env -i $SHELL -l -c "which python"', shell=True).strip()
+ except subprocess.CalledProcessError:
# did not work, fall back to 'python'
python = 'python'
else:
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -480,8 +480,6 @@
@_check_thread_wrap
@_check_closed_wrap
def __call__(self, sql):
- if not isinstance(sql, basestring):
- raise Warning("SQL is of wrong type. Must be string or unicode.")
return self._statement_cache.get(sql, self.row_factory)
def cursor(self, factory=None):
@@ -878,9 +876,6 @@
if self.__statement._kind == Statement._DQL and ret ==
_lib.SQLITE_ROW:
self.__statement._build_row_cast_map()
self.__statement._readahead(self)
- else:
- self.__statement._item = None
- self.__statement._exhausted = True
if self.__statement._kind == Statement._DML:
if self.__rowcount == -1:
@@ -1007,7 +1002,7 @@
self.__con = connection
if not isinstance(sql, basestring):
- raise ValueError("sql must be a string")
+ raise Warning("SQL is of wrong type. Must be string or unicode.")
first_word = self._statement_kind = sql.lstrip().split(" ")[0].upper()
if first_word in ("INSERT", "UPDATE", "DELETE", "REPLACE"):
self._kind = Statement._DML
@@ -1017,7 +1012,6 @@
self._kind = Statement._DDL
self._in_use = False
- self._exhausted = False
self._row_factory = None
if isinstance(sql, unicode):
@@ -1055,7 +1049,6 @@
if self._in_use and self._statement:
_lib.sqlite3_reset(self._statement)
self._in_use = False
- self._exhausted = False
if sys.version_info[0] < 3:
def __check_decodable(self, param):
@@ -1220,20 +1213,19 @@
self._item = row
def _next(self, cursor):
- if self._exhausted:
+ try:
+ item = self._item
+ except AttributeError:
raise StopIteration
- item = self._item
+ del self._item
ret = _lib.sqlite3_step(self._statement)
- if ret == _lib.SQLITE_DONE:
- self._exhausted = True
- self._item = None
- elif ret != _lib.SQLITE_ROW:
- exc = self.__con._get_exception(ret)
+ if ret not in (_lib.SQLITE_DONE, _lib.SQLITE_ROW):
_lib.sqlite3_reset(self._statement)
- raise exc
+ raise self.__con._get_exception(ret)
+ elif ret == _lib.SQLITE_ROW:
+ self._readahead(cursor)
- self._readahead(cursor)
return item
def _get_description(self):
diff --git a/pypy/module/cpyext/test/test_cpyext.py
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -85,6 +85,8 @@
"""Base class for all cpyext tests."""
spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array',
'itertools', 'rctime', 'binascii'])
+ spaceconfig['std.withmethodcache'] = True
+
enable_leak_checking = True
@staticmethod
diff --git a/pypy/module/cpyext/test/test_typeobject.py
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -288,7 +288,38 @@
class C(object):
pass
assert module.name_by_heaptype(C) == "C"
-
+
+ def test_type_dict(self):
+ foo = self.import_module("foo")
+ module = self.import_extension('test', [
+ ("hack_tp_dict", "METH_O",
+ '''
+ PyTypeObject *type = args->ob_type;
+ PyObject *a1 = PyLong_FromLong(1);
+ PyObject *a2 = PyLong_FromLong(2);
+ PyObject *value;
+
+ if (PyDict_SetItemString(type->tp_dict, "a",
+ a1) < 0)
+ return NULL;
+ Py_DECREF(a1);
+ PyType_Modified(type);
+ value = PyObject_GetAttrString(type, "a");
+ Py_DECREF(value);
+
+ if (PyDict_SetItemString(type->tp_dict, "a",
+ a2) < 0)
+ return NULL;
+ Py_DECREF(a2);
+ PyType_Modified(type);
+ value = PyObject_GetAttrString(type, "a");
+ return value;
+ '''
+ )
+ ])
+ obj = foo.new()
+ assert module.hack_tp_dict(obj) == 2
+
class TestTypes(BaseApiTest):
def test_type_attributes(self, space, api):
@@ -326,7 +357,7 @@
w_obj = api._PyType_Lookup(w_type, space.wrap("__invalid"))
assert w_obj is None
assert api.PyErr_Occurred() is None
-
+
class AppTestSlots(AppTestCpythonExtensionBase):
def test_some_slots(self):
module = self.import_extension('foo', [
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -729,6 +729,9 @@
subtypes. This function must be called after any manual
modification of the attributes or base classes of the type.
"""
- # PyPy already takes care of direct modifications to type.__dict__
- # (which is a W_DictProxyObject).
- pass
+ # Invalidate the type cache in case of a builtin type.
+ if not isinstance(w_obj, W_TypeObject):
+ return
+ if w_obj.is_cpytype():
+ w_obj.mutated(None)
+
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
@@ -57,11 +57,34 @@
cur = con.cursor()
with pytest.raises(StopIteration):
next(cur)
- cur = con.execute('select 1')
+
+ 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():
con = _sqlite3.connect(':memory:')
cur = con.execute('select 1')
diff --git a/pypy/objspace/std/complexobject.py
b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -9,7 +9,7 @@
from rpython.rlib.rfloat import (
formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
from rpython.rlib import jit, rcomplex
-from rpython.rlib.rarithmetic import intmask
+from rpython.rlib.rarithmetic import intmask, r_ulonglong
import math
@@ -41,7 +41,7 @@
real = space.float_w(space.getattr(self, space.wrap("real")))
imag = space.float_w(space.getattr(self, space.wrap("imag")))
real_b = rbigint.fromrarith_int(float2longlong(real))
- imag_b = rbigint.fromrarith_int(float2longlong(imag))
+ imag_b = rbigint.fromrarith_int(r_ulonglong(float2longlong(imag)))
val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag))
return space.newlong_from_rbigint(val)
diff --git a/pypy/objspace/std/dictmultiobject.py
b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -106,15 +106,13 @@
for w_k, w_v in list_pairs_w:
w_self.setitem(w_k, w_v)
- def view_as_kwargs(self):
- return self.strategy.view_as_kwargs(self)
-
def _add_indirections():
dict_methods = "setitem setitem_str getitem \
getitem_str delitem length \
clear w_keys values \
items iterkeys itervalues iteritems setdefault \
- popitem listview_str listview_unicode listview_int".split()
+ popitem listview_str listview_unicode listview_int \
+ view_as_kwargs".split()
def make_method(method):
def f(self, *args):
@@ -122,9 +120,6 @@
f.func_name = method
return f
- def view_as_kwargs(self):
- return self.strategy.view_as_kwargs(self)
-
for method in dict_methods:
setattr(W_DictMultiObject, method, make_method(method))
diff --git a/pypy/objspace/std/dictproxyobject.py
b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -54,10 +54,11 @@
raise
if not w_type.is_cpytype():
raise
- # xxx obscure workaround: allow cpyext to write to type->tp_dict
- # xxx even in the case of a builtin type.
- # xxx like CPython, we assume that this is only done early after
- # xxx the type is created, and we don't invalidate any cache.
+ # Allow cpyext to write to type->tp_dict even in the case
+ # of a builtin type.
+ # Like CPython, we assume that this is only done early
+ # after the type is created, and we don't invalidate any
+ # cache. User code shoud call PyType_Modified().
w_type.dict_w[key] = w_value
def setdefault(self, w_dict, w_key, w_default):
@@ -81,7 +82,7 @@
def length(self, w_dict):
return len(self.unerase(w_dict.dstorage).dict_w)
- def keys(self, w_dict):
+ def w_keys(self, w_dict):
space = self.space
return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys())
diff --git a/pypy/objspace/std/test/test_obj.py
b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -203,7 +203,9 @@
l.append(i + sys.maxint)
l.append(i - sys.maxint)
l.append(i + 1j)
+ l.append(i - 1j)
l.append(1 + i * 1j)
+ l.append(1 - i * 1j)
s = str(i)
l.append(s)
u = unicode(s)
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
@@ -161,7 +161,7 @@
generic mutation.
"""
space = w_self.space
- assert w_self.is_heaptype()
+ assert w_self.is_heaptype() or w_self.is_cpytype()
if (not space.config.objspace.std.withtypeversion and
not space.config.objspace.std.getattributeshortcut and
not space.config.objspace.std.withidentitydict and
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -143,13 +143,9 @@
# XXX HACK HACK HACK
bk = getbookkeeper()
if bk is not None: # for testing
+ op = bk._find_current_op("is_", 2)
knowntypedata = {}
- fn, block, i = bk.position_key
-
annotator = bk.annotator
- op = block.operations[i]
- assert op.opname == "is_"
- assert len(op.args) == 2
def bind(src_obj, tgt_obj, tgt_arg):
if hasattr(tgt_obj, 'is_type_of') and src_obj.is_constant():
@@ -319,11 +315,7 @@
rarithmetic.signedtype(int2.knowntype)):
return r
knowntypedata = {}
- # XXX HACK HACK HACK
- fn, block, i = getbookkeeper().position_key
- op = block.operations[i]
- assert op.opname == opname
- assert len(op.args) == 2
+ op = getbookkeeper()._find_current_op(opname=opname, arity=2)
def tointtype(int0):
if int0.knowntype is bool:
return int
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -693,6 +693,20 @@
if emulate_enter:
self.leave()
+ def _find_current_op(self, opname=None, arity=None, pos=None, s_type=None):
+ """ Find operation that is currently being annotated. Do some
+ sanity checks to see whether the correct op was found."""
+ # XXX XXX HACK HACK HACK
+ fn, block, i = self.position_key
+ op = block.operations[i]
+ if opname is not None:
+ assert op.opname == opname or op.opname in opname
+ if arity is not None:
+ assert len(op.args) == arity
+ if pos is not None:
+ assert self.annotator.binding(op.args[pos]) == s_type
+ return op
+
def build_args(self, op, args_s):
space = RPythonCallsSpace()
if op == "simple_call":
diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py
--- a/rpython/annotator/builtin.py
+++ b/rpython/annotator/builtin.py
@@ -178,15 +178,9 @@
# from bool to int, notice
that isinstance( , bool|int)
# is quite border case for
RPython
r.const = False
- # XXX HACK HACK HACK
- # XXX HACK HACK HACK
- # XXX HACK HACK HACK
bk = getbookkeeper()
if variables is None:
- fn, block, i = bk.position_key
- op = block.operations[i]
- assert op.opname == "simple_call"
- assert len(op.args) == 3
+ op = bk._find_current_op("simple_call", 3)
assert op.args[0] == Constant(isinstance)
variables = [op.args[1]]
for variable in variables:
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -233,6 +233,9 @@
def nonnoneify(self):
return self.__class__(can_be_None=False, no_nul=self.no_nul)
+ def nonnulify(self):
+ return self.__class__(can_be_None=self.can_be_None, no_nul=True)
+
class SomeString(SomeStringOrUnicode):
"Stands for an object which is known to be a string."
knowntype = str
diff --git a/rpython/annotator/test/test_annrpython.py
b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -446,6 +446,25 @@
s_item = s.listdef.listitem.s_value
assert s_item.no_nul
+ def test_str_split_nul(self):
+ def f(n):
+ return n.split('\0')[0]
+ a = self.RPythonAnnotator()
+ a.translator.config.translation.check_str_without_nul = True
+ s = a.build_types(f, [annmodel.SomeString(no_nul=False,
can_be_None=False)])
+ assert isinstance(s, annmodel.SomeString)
+ assert not s.can_be_None
+ assert s.no_nul
+
+ def g(n):
+ return n.split('\0', 1)[0]
+ a = self.RPythonAnnotator()
+ a.translator.config.translation.check_str_without_nul = True
+ s = a.build_types(g, [annmodel.SomeString(no_nul=False,
can_be_None=False)])
+ assert isinstance(s, annmodel.SomeString)
+ assert not s.can_be_None
+ assert not s.no_nul
+
def test_str_splitlines(self):
a = self.RPythonAnnotator()
def f(a_str):
@@ -3762,6 +3781,19 @@
assert isinstance(s, annmodel.SomeString)
assert not s.can_be_None
+ def test_contains_no_nul(self):
+ def f(i):
+ if "\0" in i:
+ return None
+ else:
+ return i
+ a = self.RPythonAnnotator()
+ a.translator.config.translation.check_str_without_nul = True
+ s = a.build_types(f, [annmodel.SomeString(no_nul=False)])
+ assert isinstance(s, annmodel.SomeString)
+ assert s.can_be_None
+ assert s.no_nul
+
def test_no___call__(self):
class X(object):
def __call__(self):
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -43,12 +43,7 @@
raise Exception, 'type() called with more than one argument'
r = SomeType()
bk = getbookkeeper()
- fn, block, i = bk.position_key
- annotator = bk.annotator
- op = block.operations[i]
- assert op.opname == "type"
- assert len(op.args) == 1
- assert annotator.binding(op.args[0]) == obj
+ op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=obj)
r.is_type_of = [op.args[0]]
return r
@@ -79,10 +74,7 @@
bk = getbookkeeper()
knowntypedata = {}
- fn, block, i = bk.position_key
- op = block.operations[i]
- assert op.opname == "is_true" or op.opname == "nonzero"
- assert len(op.args) == 1
+ op = bk._find_current_op(opname=("is_true", "nonzero"), arity=1)
arg = op.args[0]
s_nonnone_obj = s_obj
if s_obj.can_be_none():
@@ -504,7 +496,11 @@
def method_split(str, patt, max=-1):
getbookkeeper().count("str_split", str, patt)
- s_item = str.basestringclass(no_nul=str.no_nul)
+ if max == -1 and patt.is_constant() and patt.const == "\0":
+ no_nul = True
+ else:
+ no_nul = str.no_nul
+ s_item = str.basestringclass(no_nul=no_nul)
return getbookkeeper().newlist(s_item)
def method_rsplit(str, patt, max=-1):
@@ -520,6 +516,20 @@
result = str.basestringclass(no_nul=str.no_nul)
return result
+ def op_contains(str, s_element):
+ if s_element.is_constant() and s_element.const == "\0":
+ r = SomeBool()
+ bk = getbookkeeper()
+ op = bk._find_current_op(opname="contains", arity=2, pos=0,
s_type=str)
+ knowntypedata = {}
+ add_knowntypedata(knowntypedata, False, [op.args[0]],
str.nonnulify())
+ r.set_knowntypedata(knowntypedata)
+ return r
+ else:
+ return SomeObject.op_contains(str, s_element)
+ op_contains.can_only_throw = []
+
+
class __extend__(SomeUnicodeString):
def method_encode(uni, s_enc):
if not s_enc.is_constant():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit