Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de>
Branch: py3.7
Changeset: r98554:7212fc31582b
Date: 2020-01-17 22:23 +0100
http://bitbucket.org/pypy/pypy/changeset/7212fc31582b/

Log:    merge py3.6

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,6 @@
 all: pypy-c cffi_imports
 
 PYPY_EXECUTABLE := $(shell which pypy)
-URAM := $(shell python -c "import sys; print 4.5 if sys.maxint>1<<32 else 2.5")
 
 ifeq ($(PYPY_EXECUTABLE),)
 RUNINTERP = python
@@ -10,6 +9,8 @@
 RUNINTERP = $(PYPY_EXECUTABLE)
 endif
 
+URAM := $(shell $(RUNINTERP) -c "import sys; print 4.5 if sys.maxint>1<<32 
else 2.5")
+
 .PHONY: pypy-c cffi_imports
 
 pypy-c:
diff --git a/pypy/TODO b/pypy/TODO
--- a/pypy/TODO
+++ b/pypy/TODO
@@ -3,10 +3,4 @@
 * run coverage against the parser/astbuilder/astcompiler: it's probably full of
 dead code because the grammar changed
 
-* optimize W_UnicodeObject, right now it stores both an unicode and an utf8
-version of the same string
-
-* re-enable BUILD_LIST_FROM_ARG: see the comment in astcompiler/codegen.py in
-ast.ListComp.build_container
-
 * review use of std_decode_utf8, we probably do not want to be using it
diff --git a/pypy/interpreter/astcompiler/codegen.py 
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -111,8 +111,8 @@
 
 class __extend__(ast.GeneratorExp):
 
-    def build_container(self, codegen):
-        pass
+    def build_container_and_load_iter(self, codegen):
+        codegen.comprehension_load_iter()
 
     def get_generators(self):
         return self.generators
@@ -125,12 +125,18 @@
 
 class __extend__(ast.ListComp):
 
-    def build_container(self, codegen):
-        # XXX: this is suboptimal: if we use BUILD_LIST_FROM_ARG it's faster
-        # because it preallocates the list; however, we cannot use it because
-        # at this point we only have the iterator, not the original iterable
-        # object
-        codegen.emit_op_arg(ops.BUILD_LIST, 0)
+    def build_container_and_load_iter(self, codegen):
+        single = False
+        if len(self.generators) == 1:
+            gen, = self.generators
+            if not gen.ifs:
+                single = True
+        if single:
+            codegen.comprehension_load_iter()
+            codegen.emit_op(ops.BUILD_LIST_FROM_ARG)
+        else:
+            codegen.emit_op_arg(ops.BUILD_LIST, 0)
+            codegen.comprehension_load_iter()
 
     def get_generators(self):
         return self.generators
@@ -142,8 +148,9 @@
 
 class __extend__(ast.SetComp):
 
-    def build_container(self, codegen):
+    def build_container_and_load_iter(self, codegen):
         codegen.emit_op_arg(ops.BUILD_SET, 0)
+        codegen.comprehension_load_iter()
 
     def get_generators(self):
         return self.generators
@@ -155,8 +162,9 @@
 
 class __extend__(ast.DictComp):
 
-    def build_container(self, codegen):
+    def build_container_and_load_iter(self, codegen):
         codegen.emit_op_arg(ops.BUILD_MAP, 0)
+        codegen.comprehension_load_iter()
 
     def get_generators(self):
         return self.generators
@@ -1486,10 +1494,7 @@
         anchor = self.new_block()
         gen = generators[gen_index]
         assert isinstance(gen, ast.comprehension)
-        if gen_index == 0:
-            self.argcount = 1
-            self.emit_op_arg(ops.LOAD_FAST, 0)
-        else:
+        if gen_index > 0:
             gen.iter.walkabout(self)
             self.emit_op(ops.GET_ITER)
         self.use_next_block(start)
@@ -1519,10 +1524,7 @@
         b_anchor = self.new_block()
         gen = generators[gen_index]
         assert isinstance(gen, ast.comprehension)
-        if gen_index == 0:
-            self.argcount = 1
-            self.emit_op_arg(ops.LOAD_FAST, 0)
-        else:
+        if gen_index > 0:
             gen.iter.walkabout(self)
             self.emit_op(ops.GET_AITER)
             self.load_const(self.space.w_None)
@@ -1819,12 +1821,16 @@
 class ComprehensionCodeGenerator(AbstractFunctionCodeGenerator):
 
     def _compile(self, node):
+        self.argcount = 1
         assert isinstance(node, ast.expr)
         self.update_position(node.lineno)
-        node.build_container(self)
+        node.build_container_and_load_iter(self)
         self._comp_generator(node, node.get_generators(), 0)
         self._end_comp()
 
+    def comprehension_load_iter(self):
+        self.emit_op_arg(ops.LOAD_FAST, 0)
+
     def _end_comp(self):
         self.emit_op(ops.RETURN_VALUE)
 
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py 
b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1387,15 +1387,24 @@
     # BUILD_LIST_FROM_ARG is PyPy specific
     @py.test.mark.skipif('config.option.runappdirect')
     def test_build_list_from_arg_length_hint(self):
-        py3k_skip('XXX: BUILD_LIST_FROM_ARG list comps are genexps on py3k')
         hint_called = [False]
         class Foo(object):
+            def __iter__(self):
+                return FooIter()
+        class FooIter:
+            def __init__(self):
+                self.i = 0
             def __length_hint__(self):
                 hint_called[0] = True
                 return 5
             def __iter__(self):
-                for i in range(5):
-                    yield i
+                return self
+            def __next__(self):
+                if self.i < 5:
+                    res = self.i
+                    self.i += 1
+                    return res
+                raise StopIteration
         l = [a for a in Foo()]
         assert hint_called[0]
         assert l == list(range(5))
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
@@ -263,6 +263,7 @@
             dict_w[name] = w_descr
             i += 1
 
+WARN_MISSING_SLOTS = False
 missing_slots={}
 def warn_missing_slot(space, method_name, slot_name, w_type):
     if not we_are_translated():
@@ -289,7 +290,8 @@
 
         if not slot_func_helper:
             if not slot_apifunc:
-                warn_missing_slot(space, method_name, slot_name, w_type)
+                if WARN_MISSING_SLOTS:
+                    warn_missing_slot(space, method_name, slot_name, w_type)
                 continue
             slot_func_helper = slot_apifunc.get_llhelper(space)
         fill_slot(space, pto, w_type, slot_names, slot_func_helper)
diff --git a/pypy/module/fcntl/interp_fcntl.py 
b/pypy/module/fcntl/interp_fcntl.py
--- a/pypy/module/fcntl/interp_fcntl.py
+++ b/pypy/module/fcntl/interp_fcntl.py
@@ -77,10 +77,18 @@
     c_flock = external('flock', [rffi.INT, rffi.INT], rffi.INT,
                        save_err=rffi.RFFI_SAVE_ERRNO)
 
-def _get_error(space, funcname):
+def _raise_error_maybe(space, funcname):
+    # wrap_oserror(..., eintr_retry=True) raises an OSError or returns None
+    # when appropriate
     errno = rposix.get_saved_errno()
-    return wrap_oserror(space, OSError(errno, funcname),
-                        exception_name = 'w_IOError', eintr_retry=True)
+    wrap_oserror(space, OSError(errno, funcname),
+                 exception_name = 'w_IOError', eintr_retry=True)
+
+def _raise_error_always(space, funcname):
+    # this variant never returns normally, and doesn't retry if it gets EINTR.
+    errno = rposix.get_saved_errno()
+    raise wrap_oserror(space, OSError(errno, funcname),
+                       exception_name = 'w_IOError', eintr_retry=False)
 
 @unwrap_spec(op=int, w_arg=WrappedDefault(0))
 def fcntl(space, w_fd, op, w_arg):
@@ -109,7 +117,7 @@
             while True:
                 rv = fcntl_str(fd, op, ll_arg)
                 if rv < 0:
-                    _get_error(space, "fcntl")
+                    _raise_error_maybe(space, "fcntl")
                 else:
                     arg = rffi.charpsize2str(ll_arg, len(arg))
                     return space.newbytes(arg)
@@ -119,7 +127,7 @@
     while True:
         rv = fcntl_int(fd, op, intarg)
         if rv < 0:
-            _get_error(space, "fcntl")
+            _raise_error_maybe(space, "fcntl")
         else:
             return space.newint(rv)
 
@@ -137,7 +145,7 @@
         while True:
             rv = c_flock(fd, op)
             if rv < 0:
-                _get_error(space, "flock")
+                _raise_error_maybe(space, "flock")
             else:
                 return
     else:
@@ -191,7 +199,7 @@
         while True:
             rv = fcntl_flock(fd, op, l)
             if rv < 0:
-                _get_error(space, "fcntl")
+                _raise_error_maybe(space, "fcntl")
             else:
                 return
 
@@ -229,7 +237,7 @@
                               rffi.cast(rffi.VOIDP, ll_arg), len(arg))
                 rv = ioctl_str(fd, op, buf.raw)
                 if rv < 0:
-                    raise _get_error(space, "ioctl")
+                    _raise_error_always(space, "ioctl")
                 arg = rffi.charpsize2str(buf.raw, len(arg))
                 if mutate_flag != 0:
                     rwbuffer.setslice(0, arg)
@@ -257,7 +265,7 @@
                               rffi.cast(rffi.VOIDP, ll_arg), len(arg))
                 rv = ioctl_str(fd, op, buf.raw)
                 if rv < 0:
-                    raise _get_error(space, "ioctl")
+                    _raise_error_always(space, "ioctl")
                 arg = rffi.charpsize2str(buf.raw, len(arg))
             return space.newbytes(arg)
         finally:
@@ -267,5 +275,5 @@
     intarg = rffi.cast(rffi.INT, intarg)   # C long => C int
     rv = ioctl_int(fd, op, intarg)
     if rv < 0:
-        raise _get_error(space, "ioctl")
+        _raise_error_always(space, "ioctl")
     return space.newint(rv)
diff --git a/rpython/rtyper/debug.py b/rpython/rtyper/debug.py
--- a/rpython/rtyper/debug.py
+++ b/rpython/rtyper/debug.py
@@ -32,6 +32,12 @@
         return s_x.nonnoneify()
 
     def specialize_call(self, hop):
+        from rpython.annotator import model as annmodel
+        from rpython.rtyper.error import TyperError
+        if annmodel.s_None.contains(hop.args_s[0]):
+            raise TyperError("ll_assert_not_none(None) detected.  This might "
+                             "come from something that annotates as "
+                             "'raise None'.")
         [v0] = hop.inputargs(hop.args_r[0])
         hop.exception_cannot_occur()
         hop.genop('debug_assert_not_none', [v0])
diff --git a/rpython/rtyper/test/test_exception.py 
b/rpython/rtyper/test/test_exception.py
--- a/rpython/rtyper/test/test_exception.py
+++ b/rpython/rtyper/test/test_exception.py
@@ -3,7 +3,7 @@
 from rpython.translator.translator import TranslationContext
 from rpython.rtyper.test.tool import BaseRtypingTest
 from rpython.rtyper.llinterp import LLException
-from rpython.rtyper.error import MissingRTypeOperation
+from rpython.rtyper.error import MissingRTypeOperation, TyperError
 
 
 class MyException(Exception):
@@ -164,3 +164,10 @@
             except OverflowError:
                 return 42
         py.test.raises(MissingRTypeOperation, self.interpret, f, [])
+
+    def test_cannot_raise_something_annotated_as_none(self):
+        def g():
+            return None
+        def f():
+            raise g()
+        py.test.raises(TyperError, rtype, f)
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -218,6 +218,10 @@
             fn = py.path.local(fn)
             if not fn.relto(udir):
                 newname = self.targetdir.join(fn.basename)
+                if newname.check(exists=True):
+                    raise ValueError(
+                        "Cannot have two different separate_module_sources "
+                        "with the same basename, please rename one: %s" % 
fn.basename)
                 fn.copy(newname)
                 fn = newname
             extrafiles.append(fn)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to