Author: mattip <matti.pi...@gmail.com>
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
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to