Imported Upstream version 0.29.15 upstream/0.29.15
authorDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 31 Dec 2020 03:05:58 +0000 (12:05 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Thu, 31 Dec 2020 03:05:58 +0000 (12:05 +0900)
17 files changed:
.travis.yml
CHANGES.rst
Cython/Build/Dependencies.py
Cython/Build/IpythonMagic.py
Cython/Build/Tests/TestIpythonMagic.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
Cython/Shadow.py
Cython/Utility/ExtensionTypes.c
Cython/Utility/Overflow.c
runtests.py
tests/run/async_def.pyx [new file with mode: 0644]
tests/run/generators.pyx
tests/run/libcpp_algo.pyx
tests/run/py3k_super.pyx
tests/run/pyclass_dynamic_bases.pyx
tests/run/test_coroutines_pep492.pyx

index 433745cab8426316b9b55bc435841932e2d4e4bf..1e80e2f4e3c94adc29267427abcc17df4bc5e4f5 100644 (file)
@@ -67,9 +67,14 @@ matrix:
       env: BACKEND=c
     - python: 3.6
       env: BACKEND=cpp
-    - python: 3.8-dev
+    - python: 3.8
       dist: xenial    # Required for Python 3.7
       sudo: required  # travis-ci/travis-ci#9069
+      env: BACKEND=c
+    - python: 3.8
+      dist: xenial    # Required for Python 3.7
+      sudo: required  # travis-ci/travis-ci#9069
+      env: BACKEND=cpp
     - os: osx
       osx_image: xcode6.4
       env: PY=2
@@ -95,9 +100,6 @@ matrix:
   allow_failures:
     - python: pypy
     - python: pypy3
-    - python: 3.8-dev
-    - env: STACKLESS=true BACKEND=c PY=2
-    #- env: STACKLESS=true BACKEND=c PY=3
 
 branches:
   only:
@@ -138,7 +140,7 @@ before_install:
 
 install:
   - python -c 'import sys; print("Python %s" % (sys.version,))'
-  - if [ -n "${TRAVIS_PYTHON_VERSION##*-dev}" -a -n "${TRAVIS_PYTHON_VERSION##2.6*}" ]; then pip install -r test-requirements.txt $( [ -z "${TRAVIS_PYTHON_VERSION##pypy*}" -o -z "${TRAVIS_PYTHON_VERSION##3.7*}" ] || echo " -r test-requirements-cpython.txt" ) ; fi
+  - if [ -n "${TRAVIS_PYTHON_VERSION##*-dev}" -a -n "${TRAVIS_PYTHON_VERSION##2.6*}" ]; then pip install -r test-requirements.txt $( [ -z "${TRAVIS_PYTHON_VERSION##pypy*}" -o -z "${TRAVIS_PYTHON_VERSION##3.[478]*}" ] || echo " -r test-requirements-cpython.txt" ) ; fi
 #  - CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build
 
 before_script: ccache -s || true
index 95f20739a7ace21390560edddc3c1bd786f810b6..3c249e66e2691afddc4aebc6e164e01880b714a0 100644 (file)
@@ -2,6 +2,31 @@
 Cython Changelog
 ================
 
+0.29.15 (2020-02-06)
+====================
+
+* Crash when returning a temporary Python object from an async-def function.
+  (Github issue #3337)
+
+* Crash when using ``**kwargs`` in generators.
+  Patch by David Woods.  (Github issue #3265)
+
+* Double reference free in ``__class__`` cell handling for ``super()`` calls.
+  (Github issue #3246)
+
+* Compile error when using ``*args`` as Python class bases.
+  (Github issue #3338)
+
+* Import failure in IPython 7.11.
+  (Github issue #3297)
+
+* Fixed C name collision in the auto-pickle code.
+  Patch by ThePrez.  (Github issue #3238)
+
+* Deprecated import failed in Python 3.9.
+  (Github issue #3266)
+
+
 0.29.14 (2019-11-01)
 ====================
 
@@ -9,7 +34,7 @@ Bugs fixed
 ----------
 
 * The generated code failed to initialise the ``tp_print`` slot in CPython 3.8.
-  Patches by Pablo Galindo and Orivej Desh (Github issues #3171, #3201).
+  Patches by Pablo Galindo and Orivej Desh.  (Github issues #3171, #3201)
 
 * ``?`` for ``bool`` was missing from the supported NumPy dtypes.
   Patch by Max Klein.  (Github issue #2675)
index a4e5c60bee67c181ef8828cf8bd96baa4b5a8d7c..eb03004e247603cc0f5b1d22ba5b11620fc5ab21 100644 (file)
@@ -18,6 +18,11 @@ from distutils.extension import Extension
 from distutils.util import strtobool
 import zipfile
 
+try:
+    from collections.abc import Iterable
+except ImportError:
+    from collections import Iterable
+
 try:
     import gzip
     gzip_open = gzip.open
@@ -749,7 +754,7 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet=
         exclude = []
     if patterns is None:
         return [], {}
-    elif isinstance(patterns, basestring) or not isinstance(patterns, collections.Iterable):
+    elif isinstance(patterns, basestring) or not isinstance(patterns, Iterable):
         patterns = [patterns]
     explicit_modules = set([m.name for m in patterns if isinstance(m, Extension)])
     seen = set()
index 2743423eef5980e39ff10fe29aea733acd3f8f24..7abb97ec70a2b3aa00bc08e8303f401a0b56fc66 100644 (file)
@@ -56,6 +56,8 @@ import copy
 import distutils.log
 import textwrap
 
+IO_ENCODING = sys.getfilesystemencoding()
+IS_PY2 = sys.version_info[0] < 3
 
 try:
     reload
@@ -73,7 +75,6 @@ from distutils.command.build_ext import build_ext
 from IPython.core import display
 from IPython.core import magic_arguments
 from IPython.core.magic import Magics, magics_class, cell_magic
-from IPython.utils import py3compat
 try:
     from IPython.paths import get_ipython_cache_dir
 except ImportError:
@@ -101,6 +102,14 @@ PGO_CONFIG = {
 PGO_CONFIG['mingw32'] = PGO_CONFIG['gcc']
 
 
+if IS_PY2:
+    def encode_fs(name):
+        return name if isinstance(name, bytes) else name.encode(IO_ENCODING)
+else:
+    def encode_fs(name):
+        return name
+
+
 @magics_class
 class CythonMagics(Magics):
 
@@ -306,7 +315,7 @@ class CythonMagics(Magics):
             key += (time.time(),)
 
         if args.name:
-            module_name = py3compat.unicode_to_str(args.name)
+            module_name = str(args.name)  # no-op in Py3
         else:
             module_name = "_cython_magic_" + hashlib.md5(str(key).encode('utf-8')).hexdigest()
         html_file = os.path.join(lib_dir, module_name + '.html')
@@ -406,7 +415,7 @@ class CythonMagics(Magics):
 
     def _cythonize(self, module_name, code, lib_dir, args, quiet=True):
         pyx_file = os.path.join(lib_dir, module_name + '.pyx')
-        pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding())
+        pyx_file = encode_fs(pyx_file)
 
         c_include_dirs = args.include
         c_src_files = list(map(str, args.src))
@@ -526,10 +535,10 @@ class CythonMagics(Magics):
         build_extension = _build_ext(dist)
         build_extension.finalize_options()
         if temp_dir:
-            temp_dir = py3compat.cast_bytes_py2(temp_dir, encoding=sys.getfilesystemencoding())
+            temp_dir = encode_fs(temp_dir)
             build_extension.build_temp = temp_dir
         if lib_dir:
-            lib_dir = py3compat.cast_bytes_py2(lib_dir, encoding=sys.getfilesystemencoding())
+            lib_dir = encode_fs(lib_dir)
             build_extension.build_lib = lib_dir
         if extension is not None:
             build_extension.extensions = [extension]
index fc8a84af7325613d552b58067e5b622863686011..d9d8322a874fd4daf036b863a1df9e892d498990 100644 (file)
@@ -13,15 +13,8 @@ from Cython.TestUtils import CythonTest
 
 try:
     import IPython.testing.globalipapp
-    from IPython.utils import py3compat
 except ImportError:
     # Disable tests and fake helpers for initialisation below.
-    class _py3compat(object):
-        def str_to_unicode(self, s):
-            return s
-
-    py3compat = _py3compat()
-
     def skip_if_not_installed(_):
         return None
 else:
@@ -35,24 +28,24 @@ try:
 except ImportError:
     pass
 
-code = py3compat.str_to_unicode("""\
+code = u"""\
 def f(x):
     return 2*x
-""")
+"""
 
-cython3_code = py3compat.str_to_unicode("""\
+cython3_code = u"""\
 def f(int x):
     return 2 / x
 
 def call(x):
     return f(*(x,))
-""")
+"""
 
-pgo_cython3_code = cython3_code + py3compat.str_to_unicode("""\
+pgo_cython3_code = cython3_code + u"""\
 def main():
     for _ in range(100): call(5)
 main()
-""")
+"""
 
 
 if sys.platform == 'win32':
@@ -161,10 +154,10 @@ class TestIPythonMagic(CythonTest):
     @skip_win32('Skip on Windows')
     def test_extlibs(self):
         ip = self._ip
-        code = py3compat.str_to_unicode("""
+        code = u"""
 from libc.math cimport sin
 x = sin(0.0)
-        """)
+        """
         ip.user_ns['x'] = 1
         ip.run_cell_magic('cython', '-l m', code)
         self.assertEqual(ip.user_ns['x'], 0)
index 424a939654b615ba4d0d79663d3196f4d038b34f..ecbbb694f1895bdcafb1268177e61744b66afd98 100644 (file)
@@ -8938,12 +8938,11 @@ class ClassNode(ExprNode, ModuleNameMixin):
     #  a name, tuple of bases and class dictionary.
     #
     #  name         EncodedString      Name of the class
-    #  bases        ExprNode           Base class tuple
-    #  dict         ExprNode           Class dict (not owned by this node)
+    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
     #  doc          ExprNode or None   Doc string
     #  module_name  EncodedString      Name of defining module
 
-    subexprs = ['bases', 'doc']
+    subexprs = ['doc']
     type = py_object_type
     is_temp = True
 
@@ -8952,7 +8951,6 @@ class ClassNode(ExprNode, ModuleNameMixin):
         return py_object_type
 
     def analyse_types(self, env):
-        self.bases = self.bases.analyse_types(env)
         if self.doc:
             self.doc = self.doc.analyse_types(env)
             self.doc = self.doc.coerce_to_pyobject(env)
@@ -8965,12 +8963,13 @@ class ClassNode(ExprNode, ModuleNameMixin):
     gil_message = "Constructing Python class"
 
     def generate_result_code(self, code):
+        class_def_node = self.class_def_node
         cname = code.intern_identifier(self.name)
 
         if self.doc:
             code.put_error_if_neg(self.pos,
                 'PyDict_SetItem(%s, %s, %s)' % (
-                    self.dict.py_result(),
+                    class_def_node.dict.py_result(),
                     code.intern_identifier(
                         StringEncoding.EncodedString("__doc__")),
                     self.doc.py_result()))
@@ -8979,8 +8978,8 @@ class ClassNode(ExprNode, ModuleNameMixin):
         code.putln(
             '%s = __Pyx_CreateClass(%s, %s, %s, %s, %s); %s' % (
                 self.result(),
-                self.bases.py_result(),
-                self.dict.py_result(),
+                class_def_node.bases.py_result(),
+                class_def_node.dict.py_result(),
                 cname,
                 qualname,
                 py_mod_name,
@@ -8994,8 +8993,8 @@ class Py3ClassNode(ExprNode):
     #  a name, tuple of bases and class dictionary.
     #
     #  name         EncodedString      Name of the class
-    #  dict         ExprNode           Class dict (not owned by this node)
     #  module_name  EncodedString      Name of defining module
+    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
     #  calculate_metaclass  bool       should call CalculateMetaclass()
     #  allow_py2_metaclass  bool       should look for Py2 metaclass
 
@@ -9018,12 +9017,10 @@ class Py3ClassNode(ExprNode):
     def generate_result_code(self, code):
         code.globalstate.use_utility_code(UtilityCode.load_cached("Py3ClassCreate", "ObjectHandling.c"))
         cname = code.intern_identifier(self.name)
-        if self.mkw:
-            mkw = self.mkw.py_result()
-        else:
-            mkw = 'NULL'
-        if self.metaclass:
-            metaclass = self.metaclass.py_result()
+        class_def_node = self.class_def_node
+        mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL'
+        if class_def_node.metaclass:
+            metaclass = class_def_node.metaclass.py_result()
         else:
             metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
         code.putln(
@@ -9031,8 +9028,8 @@ class Py3ClassNode(ExprNode):
                 self.result(),
                 metaclass,
                 cname,
-                self.bases.py_result(),
-                self.dict.py_result(),
+                class_def_node.bases.py_result(),
+                class_def_node.dict.py_result(),
                 mkw,
                 self.calculate_metaclass,
                 self.allow_py2_metaclass,
@@ -9043,8 +9040,7 @@ class Py3ClassNode(ExprNode):
 class PyClassMetaclassNode(ExprNode):
     # Helper class holds Python3 metaclass object
     #
-    #  bases        ExprNode           Base class tuple (not owned by this node)
-    #  mkw          ExprNode           Class keyword arguments (not owned by this node)
+    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
 
     subexprs = []
 
@@ -9057,38 +9053,38 @@ class PyClassMetaclassNode(ExprNode):
         return True
 
     def generate_result_code(self, code):
-        if self.mkw:
+        bases = self.class_def_node.bases
+        mkw = self.class_def_node.mkw
+        if mkw:
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("Py3MetaclassGet", "ObjectHandling.c"))
             call = "__Pyx_Py3MetaclassGet(%s, %s)" % (
-                self.bases.result(),
-                self.mkw.result())
+                bases.result(),
+                mkw.result())
         else:
             code.globalstate.use_utility_code(
                 UtilityCode.load_cached("CalculateMetaclass", "ObjectHandling.c"))
             call = "__Pyx_CalculateMetaclass(NULL, %s)" % (
-                self.bases.result())
+                bases.result())
         code.putln(
             "%s = %s; %s" % (
                 self.result(), call,
                 code.error_goto_if_null(self.result(), self.pos)))
         code.put_gotref(self.py_result())
 
+
 class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
     # Helper class holds Python3 namespace object
     #
     # All this are not owned by this node
-    #  metaclass    ExprNode           Metaclass object
-    #  bases        ExprNode           Base class tuple
-    #  mkw          ExprNode           Class keyword arguments
+    #  class_def_node  PyClassDefNode  PyClassDefNode defining this class
     #  doc          ExprNode or None   Doc string (owned)
 
     subexprs = ['doc']
 
     def analyse_types(self, env):
         if self.doc:
-            self.doc = self.doc.analyse_types(env)
-            self.doc = self.doc.coerce_to_pyobject(env)
+            self.doc = self.doc.analyse_types(env).coerce_to_pyobject(env)
         self.type = py_object_type
         self.is_temp = 1
         return self
@@ -9100,23 +9096,16 @@ class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
         cname = code.intern_identifier(self.name)
         py_mod_name = self.get_py_mod_name(code)
         qualname = self.get_py_qualified_name(code)
-        if self.doc:
-            doc_code = self.doc.result()
-        else:
-            doc_code = '(PyObject *) NULL'
-        if self.mkw:
-            mkw = self.mkw.py_result()
-        else:
-            mkw = '(PyObject *) NULL'
-        if self.metaclass:
-            metaclass = self.metaclass.py_result()
-        else:
-            metaclass = "(PyObject *) NULL"
+        class_def_node = self.class_def_node
+        null = "(PyObject *) NULL"
+        doc_code = self.doc.result() if self.doc else null
+        mkw = class_def_node.mkw.py_result() if class_def_node.mkw else null
+        metaclass = class_def_node.metaclass.py_result() if class_def_node.metaclass else null
         code.putln(
             "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s, %s); %s" % (
                 self.result(),
                 metaclass,
-                self.bases.result(),
+                class_def_node.bases.result(),
                 cname,
                 qualname,
                 mkw,
@@ -9136,21 +9125,20 @@ class ClassCellInjectorNode(ExprNode):
     def analyse_expressions(self, env):
         return self
 
-    def generate_evaluation_code(self, code):
-        if self.is_active:
-            self.allocate_temp_result(code)
-            code.putln(
-                '%s = PyList_New(0); %s' % (
-                    self.result(),
-                    code.error_goto_if_null(self.result(), self.pos)))
-            code.put_gotref(self.result())
+    def generate_result_code(self, code):
+        assert self.is_active
+        code.putln(
+            '%s = PyList_New(0); %s' % (
+                self.result(),
+                code.error_goto_if_null(self.result(), self.pos)))
+        code.put_gotref(self.result())
 
     def generate_injection_code(self, code, classobj_cname):
-        if self.is_active:
-            code.globalstate.use_utility_code(
-                UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c"))
-            code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % (
-                self.result(), classobj_cname))
+        assert self.is_active
+        code.globalstate.use_utility_code(
+            UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c"))
+        code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % (
+            self.result(), classobj_cname))
 
 
 class ClassCellNode(ExprNode):
index 4bae6a331786d500d672c368ea69e7dc060f6968..e2b4d63a5ff63671b16eea355ffcce744d9c3c0e 100644 (file)
@@ -3232,8 +3232,14 @@ class DefNode(FuncDefNode):
         def put_into_closure(entry):
             if entry.in_closure:
                 code.putln('%s = %s;' % (entry.cname, entry.original_cname))
-                code.put_var_incref(entry)
-                code.put_var_giveref(entry)
+                if entry.xdecref_cleanup:
+                    # mostly applies to the starstar arg - this can sometimes be NULL
+                    # so must be xincrefed instead
+                    code.put_var_xincref(entry)
+                    code.put_var_xgiveref(entry)
+                else:
+                    code.put_var_incref(entry)
+                    code.put_var_giveref(entry)
         for arg in self.args:
             put_into_closure(arg.entry)
         for arg in self.star_arg, self.starstar_arg:
@@ -4497,26 +4503,22 @@ class PyClassDefNode(ClassDefNode):
                     pass  # no base classes => no inherited metaclass
                 else:
                     self.metaclass = ExprNodes.PyClassMetaclassNode(
-                        pos, mkw=mkdict, bases=self.bases)
+                        pos, class_def_node=self)
                 needs_metaclass_calculation = False
             else:
                 needs_metaclass_calculation = True
 
             self.dict = ExprNodes.PyClassNamespaceNode(
-                pos, name=name, doc=doc_node,
-                metaclass=self.metaclass, bases=self.bases, mkw=self.mkw)
+                pos, name=name, doc=doc_node, class_def_node=self)
             self.classobj = ExprNodes.Py3ClassNode(
-                pos, name=name,
-                bases=self.bases, dict=self.dict, doc=doc_node,
-                metaclass=self.metaclass, mkw=self.mkw,
+                pos, name=name, class_def_node=self, doc=doc_node,
                 calculate_metaclass=needs_metaclass_calculation,
                 allow_py2_metaclass=allow_py2_metaclass)
         else:
             # no bases, no metaclass => old style class creation
             self.dict = ExprNodes.DictNode(pos, key_value_pairs=[])
             self.classobj = ExprNodes.ClassNode(
-                pos, name=name,
-                bases=bases, dict=self.dict, doc=doc_node)
+                pos, name=name, class_def_node=self, doc=doc_node)
 
         self.target = ExprNodes.NameNode(pos, name=name)
         self.class_cell = ExprNodes.ClassCellInjectorNode(self.pos)
@@ -4534,7 +4536,7 @@ class PyClassDefNode(ClassDefNode):
                              visibility='private',
                              module_name=None,
                              class_name=self.name,
-                             bases=self.classobj.bases or ExprNodes.TupleNode(self.pos, args=[]),
+                             bases=self.bases or ExprNodes.TupleNode(self.pos, args=[]),
                              decorators=self.decorators,
                              body=self.body,
                              in_pxd=False,
@@ -4558,6 +4560,10 @@ class PyClassDefNode(ClassDefNode):
                     args=[class_result])
             self.decorators = None
         self.class_result = class_result
+        if self.bases:
+            self.bases.analyse_declarations(env)
+        if self.mkw:
+            self.mkw.analyse_declarations(env)
         self.class_result.analyse_declarations(env)
         self.target.analyse_target_declaration(env)
         cenv = self.create_scope(env)
@@ -4568,10 +4574,10 @@ class PyClassDefNode(ClassDefNode):
     def analyse_expressions(self, env):
         if self.bases:
             self.bases = self.bases.analyse_expressions(env)
-        if self.metaclass:
-            self.metaclass = self.metaclass.analyse_expressions(env)
         if self.mkw:
             self.mkw = self.mkw.analyse_expressions(env)
+        if self.metaclass:
+            self.metaclass = self.metaclass.analyse_expressions(env)
         self.dict = self.dict.analyse_expressions(env)
         self.class_result = self.class_result.analyse_expressions(env)
         cenv = self.scope
@@ -4596,12 +4602,22 @@ class PyClassDefNode(ClassDefNode):
             self.metaclass.generate_evaluation_code(code)
         self.dict.generate_evaluation_code(code)
         cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
-        self.class_cell.generate_evaluation_code(code)
+
+        class_cell = self.class_cell
+        if class_cell is not None and not class_cell.is_active:
+            class_cell = None
+
+        if class_cell is not None:
+            class_cell.generate_evaluation_code(code)
         self.body.generate_execution_code(code)
         self.class_result.generate_evaluation_code(code)
-        self.class_cell.generate_injection_code(
-            code, self.class_result.result())
-        self.class_cell.generate_disposal_code(code)
+        if class_cell is not None:
+            class_cell.generate_injection_code(
+                code, self.class_result.result())
+        if class_cell is not None:
+            class_cell.generate_disposal_code(code)
+            class_cell.free_temps(code)
+
         cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
         self.target.generate_assignment_code(self.class_result, code)
         self.dict.generate_disposal_code(code)
@@ -5980,6 +5996,7 @@ class ReturnStatNode(StatNode):
                     rhs=value,
                     code=code,
                     have_gil=self.in_nogil_context)
+                value.generate_post_assignment_code(code)
             elif self.in_generator:
                 # return value == raise StopIteration(value), but uncatchable
                 code.globalstate.use_utility_code(
@@ -5993,7 +6010,7 @@ class ReturnStatNode(StatNode):
                 code.putln("%s = %s;" % (
                     Naming.retval_cname,
                     value.result_as(self.return_type)))
-            value.generate_post_assignment_code(code)
+                value.generate_post_assignment_code(code)
             value.free_temps(code)
         else:
             if self.return_type.is_pyobject:
index 40d91a0ce93d648c49e830df5eb73d0e0364a0e5..a7401d5dbb73322e8fa03e66a9fee411b0cfb39d 100644 (file)
@@ -1,7 +1,7 @@
 # cython.* namespace for pure mode.
 from __future__ import absolute_import
 
-__version__ = "0.29.14"
+__version__ = "0.29.15"
 
 try:
     from __builtin__ import basestring
index fc11fafa7315c05183692e0b57d146b2f19a28a5..4107b9143dfb5fce584c90bf895453f814e3b42c 100644 (file)
@@ -166,49 +166,49 @@ static int __Pyx_setup_reduce(PyObject* type_obj) {
     PyObject *setstate_cython = NULL;
 
 #if CYTHON_USE_PYTYPE_LOOKUP
-    if (_PyType_Lookup((PyTypeObject*)type_obj, PYIDENT("__getstate__"))) goto GOOD;
+    if (_PyType_Lookup((PyTypeObject*)type_obj, PYIDENT("__getstate__"))) goto __PYX_GOOD;
 #else
-    if (PyObject_HasAttr(type_obj, PYIDENT("__getstate__"))) goto GOOD;
+    if (PyObject_HasAttr(type_obj, PYIDENT("__getstate__"))) goto __PYX_GOOD;
 #endif
 
 #if CYTHON_USE_PYTYPE_LOOKUP
-    object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, PYIDENT("__reduce_ex__")); if (!object_reduce_ex) goto BAD;
+    object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, PYIDENT("__reduce_ex__")); if (!object_reduce_ex) goto __PYX_BAD;
 #else
-    object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, PYIDENT("__reduce_ex__")); if (!object_reduce_ex) goto BAD;
+    object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, PYIDENT("__reduce_ex__")); if (!object_reduce_ex) goto __PYX_BAD;
 #endif
 
-    reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce_ex__")); if (unlikely(!reduce_ex)) goto BAD;
+    reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce_ex__")); if (unlikely(!reduce_ex)) goto __PYX_BAD;
     if (reduce_ex == object_reduce_ex) {
 
 #if CYTHON_USE_PYTYPE_LOOKUP
-        object_reduce = _PyType_Lookup(&PyBaseObject_Type, PYIDENT("__reduce__")); if (!object_reduce) goto BAD;
+        object_reduce = _PyType_Lookup(&PyBaseObject_Type, PYIDENT("__reduce__")); if (!object_reduce) goto __PYX_BAD;
 #else
-        object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, PYIDENT("__reduce__")); if (!object_reduce) goto BAD;
+        object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, PYIDENT("__reduce__")); if (!object_reduce) goto __PYX_BAD;
 #endif
-        reduce = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce__")); if (unlikely(!reduce)) goto BAD;
+        reduce = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce__")); if (unlikely(!reduce)) goto __PYX_BAD;
 
         if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, PYIDENT("__reduce_cython__"))) {
-            reduce_cython = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce_cython__")); if (unlikely(!reduce_cython)) goto BAD;
-            ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce__"), reduce_cython); if (unlikely(ret < 0)) goto BAD;
-            ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce_cython__")); if (unlikely(ret < 0)) goto BAD;
+            reduce_cython = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__reduce_cython__")); if (unlikely(!reduce_cython)) goto __PYX_BAD;
+            ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce__"), reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+            ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__reduce_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
 
             setstate = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__setstate__"));
             if (!setstate) PyErr_Clear();
             if (!setstate || __Pyx_setup_reduce_is_named(setstate, PYIDENT("__setstate_cython__"))) {
-                setstate_cython = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__setstate_cython__")); if (unlikely(!setstate_cython)) goto BAD;
-                ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate__"), setstate_cython); if (unlikely(ret < 0)) goto BAD;
-                ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate_cython__")); if (unlikely(ret < 0)) goto BAD;
+                setstate_cython = __Pyx_PyObject_GetAttrStr(type_obj, PYIDENT("__setstate_cython__")); if (unlikely(!setstate_cython)) goto __PYX_BAD;
+                ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate__"), setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD;
+                ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, PYIDENT("__setstate_cython__")); if (unlikely(ret < 0)) goto __PYX_BAD;
             }
             PyType_Modified((PyTypeObject*)type_obj);
         }
     }
-    goto GOOD;
+    goto __PYX_GOOD;
 
-BAD:
+__PYX_BAD:
     if (!PyErr_Occurred())
         PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name);
     ret = -1;
-GOOD:
+__PYX_GOOD:
 #if !CYTHON_USE_PYTYPE_LOOKUP
     Py_XDECREF(object_reduce);
     Py_XDECREF(object_reduce_ex);
index 8629bafaea8578fc9cb0c301b6e7bfc3deb1e7fb..6dff81cc1e29072dd9579f6520a9adb72fc11b09 100644 (file)
@@ -20,10 +20,10 @@ TODO: Conditionally support 128-bit with intmax_t?
 /////////////// Common.proto ///////////////
 
 static int __Pyx_check_twos_complement(void) {
-    if (-1 != ~0) {
+    if ((-1 != ~0)) {
         PyErr_SetString(PyExc_RuntimeError, "Two's complement required for overflow checks.");
         return 1;
-    } else if (sizeof(short) == sizeof(int)) {
+    } else if ((sizeof(short) == sizeof(int))) {
         PyErr_SetString(PyExc_RuntimeError, "sizeof(short) < sizeof(int) required for overflow checks.");
         return 1;
     } else {
@@ -31,11 +31,11 @@ static int __Pyx_check_twos_complement(void) {
     }
 }
 
-#define __PYX_IS_UNSIGNED(type) (((type) -1) > 0)
-#define __PYX_SIGN_BIT(type)    (((unsigned type) 1) << (sizeof(type) * 8 - 1))
-#define __PYX_HALF_MAX(type)    (((type) 1) << (sizeof(type) * 8 - 2))
-#define __PYX_MIN(type)         (__PYX_IS_UNSIGNED(type) ? (type) 0 : 0 - __PYX_HALF_MAX(type) - __PYX_HALF_MAX(type))
-#define __PYX_MAX(type)         (~__PYX_MIN(type))
+#define __PYX_IS_UNSIGNED(type) ((((type) -1) > 0))
+#define __PYX_SIGN_BIT(type)    ((((unsigned type) 1) << (sizeof(type) * 8 - 1)))
+#define __PYX_HALF_MAX(type)    ((((type) 1) << (sizeof(type) * 8 - 2)))
+#define __PYX_MIN(type)         ((__PYX_IS_UNSIGNED(type) ? (type) 0 : 0 - __PYX_HALF_MAX(type) - __PYX_HALF_MAX(type)))
+#define __PYX_MAX(type)         ((~__PYX_MIN(type)))
 
 #define __Pyx_add_no_overflow(a, b, overflow) ((a) + (b))
 #define __Pyx_add_const_no_overflow(a, b, overflow) ((a) + (b))
@@ -82,13 +82,13 @@ static CYTHON_INLINE {{UINT}} __Pyx_sub_{{NAME}}_checking_overflow({{UINT}} a, {
 }
 
 static CYTHON_INLINE {{UINT}} __Pyx_mul_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow) {
-    if (sizeof({{UINT}}) < sizeof(unsigned long)) {
+    if ((sizeof({{UINT}}) < sizeof(unsigned long))) {
         unsigned long big_r = ((unsigned long) a) * ((unsigned long) b);
         {{UINT}} r = ({{UINT}}) big_r;
         *overflow |= big_r != r;
         return r;
 #ifdef HAVE_LONG_LONG
-    } else if (sizeof({{UINT}}) < sizeof(unsigned PY_LONG_LONG)) {
+    } else if ((sizeof({{UINT}}) < sizeof(unsigned PY_LONG_LONG))) {
         unsigned PY_LONG_LONG big_r = ((unsigned PY_LONG_LONG) a) * ((unsigned PY_LONG_LONG) b);
         {{UINT}} r = ({{UINT}}) big_r;
         *overflow |= big_r != r;
@@ -138,13 +138,13 @@ static CYTHON_INLINE {{INT}} __Pyx_mul_const_{{NAME}}_checking_overflow({{INT}}
 /////////////// BaseCaseSigned ///////////////
 
 static CYTHON_INLINE {{INT}} __Pyx_add_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) {
-    if (sizeof({{INT}}) < sizeof(long)) {
+    if ((sizeof({{INT}}) < sizeof(long))) {
         long big_r = ((long) a) + ((long) b);
         {{INT}} r = ({{INT}}) big_r;
         *overflow |= big_r != r;
         return r;
 #ifdef HAVE_LONG_LONG
-    } else if (sizeof({{INT}}) < sizeof(PY_LONG_LONG)) {
+    } else if ((sizeof({{INT}}) < sizeof(PY_LONG_LONG))) {
         PY_LONG_LONG big_r = ((PY_LONG_LONG) a) + ((PY_LONG_LONG) b);
         {{INT}} r = ({{INT}}) big_r;
         *overflow |= big_r != r;
@@ -184,13 +184,13 @@ static CYTHON_INLINE {{INT}} __Pyx_sub_const_{{NAME}}_checking_overflow({{INT}}
 }
 
 static CYTHON_INLINE {{INT}} __Pyx_mul_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) {
-    if (sizeof({{INT}}) < sizeof(long)) {
+    if ((sizeof({{INT}}) < sizeof(long))) {
         long big_r = ((long) a) * ((long) b);
         {{INT}} r = ({{INT}}) big_r;
         *overflow |= big_r != r;
         return ({{INT}}) r;
 #ifdef HAVE_LONG_LONG
-    } else if (sizeof({{INT}}) < sizeof(PY_LONG_LONG)) {
+    } else if ((sizeof({{INT}}) < sizeof(PY_LONG_LONG))) {
         PY_LONG_LONG big_r = ((PY_LONG_LONG) a) * ((PY_LONG_LONG) b);
         {{INT}} r = ({{INT}}) big_r;
         *overflow |= big_r != r;
@@ -240,11 +240,11 @@ if (unlikely(__Pyx_check_sane_{{NAME}}())) {
 /////////////// SizeCheck.proto ///////////////
 
 static int __Pyx_check_sane_{{NAME}}(void) {
-    if (sizeof({{TYPE}}) <= sizeof(int) ||
+    if (((sizeof({{TYPE}}) <= sizeof(int)) ||
 #ifdef HAVE_LONG_LONG
-            sizeof({{TYPE}}) == sizeof(PY_LONG_LONG) ||
+            (sizeof({{TYPE}}) == sizeof(PY_LONG_LONG)) ||
 #endif
-            sizeof({{TYPE}}) == sizeof(long)) {
+            (sizeof({{TYPE}}) == sizeof(long)))) {
         return 0;
     } else {
         PyErr_Format(PyExc_RuntimeError, \
@@ -261,27 +261,27 @@ static CYTHON_INLINE {{TYPE}} __Pyx_{{BINOP}}_{{NAME}}_checking_overflow({{TYPE}
 /////////////// Binop ///////////////
 
 static CYTHON_INLINE {{TYPE}} __Pyx_{{BINOP}}_{{NAME}}_checking_overflow({{TYPE}} a, {{TYPE}} b, int *overflow) {
-    if (sizeof({{TYPE}}) < sizeof(int)) {
+    if ((sizeof({{TYPE}}) < sizeof(int))) {
         return __Pyx_{{BINOP}}_no_overflow(a, b, overflow);
     } else if (__PYX_IS_UNSIGNED({{TYPE}})) {
-        if (sizeof({{TYPE}}) == sizeof(unsigned int)) {
+        if ((sizeof({{TYPE}}) == sizeof(unsigned int))) {
             return __Pyx_{{BINOP}}_unsigned_int_checking_overflow(a, b, overflow);
-        } else if (sizeof({{TYPE}}) == sizeof(unsigned long)) {
+        } else if ((sizeof({{TYPE}}) == sizeof(unsigned long))) {
             return __Pyx_{{BINOP}}_unsigned_long_checking_overflow(a, b, overflow);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof({{TYPE}}) == sizeof(unsigned PY_LONG_LONG)) {
+        } else if ((sizeof({{TYPE}}) == sizeof(unsigned PY_LONG_LONG))) {
             return __Pyx_{{BINOP}}_unsigned_long_long_checking_overflow(a, b, overflow);
 #endif
         } else {
             abort(); return 0; /* handled elsewhere */
         }
     } else {
-        if (sizeof({{TYPE}}) == sizeof(int)) {
+        if ((sizeof({{TYPE}}) == sizeof(int))) {
             return __Pyx_{{BINOP}}_int_checking_overflow(a, b, overflow);
-        } else if (sizeof({{TYPE}}) == sizeof(long)) {
+        } else if ((sizeof({{TYPE}}) == sizeof(long))) {
             return __Pyx_{{BINOP}}_long_checking_overflow(a, b, overflow);
 #ifdef HAVE_LONG_LONG
-        } else if (sizeof({{TYPE}}) == sizeof(PY_LONG_LONG)) {
+        } else if ((sizeof({{TYPE}}) == sizeof(PY_LONG_LONG))) {
             return __Pyx_{{BINOP}}_long_long_checking_overflow(a, b, overflow);
 #endif
         } else {
index d37f988fe1972e1e93c50d4500740f53ab318594..5d3e30eba0a1be34d89df409936b8c554da0d8c5 100755 (executable)
@@ -1913,13 +1913,13 @@ threads_seen = []
 def check_thread_termination(ignore_seen=True):
     if threading is None: # no threading enabled in CPython
         return
-    current = threading.currentThread()
+    current = threading.current_thread()
     blocking_threads = []
     for t in threading.enumerate():
-        if not t.isAlive() or t == current or t.name == 'time_stamper':
+        if not t.is_alive() or t == current or t.name == 'time_stamper':
             continue
         t.join(timeout=2)
-        if t.isAlive():
+        if t.is_alive():
             if not ignore_seen:
                 blocking_threads.append(t)
                 continue
diff --git a/tests/run/async_def.pyx b/tests/run/async_def.pyx
new file mode 100644 (file)
index 0000000..ac0b8a5
--- /dev/null
@@ -0,0 +1,35 @@
+# cython: language_level=3, binding=True
+# mode: run
+# tag: pep492, await, gh3337
+
+"""
+Cython specific tests in addition to "test_coroutines_pep492.pyx"
+(which is copied from CPython).
+"""
+
+import sys
+
+
+def run_async(coro):
+    #assert coro.__class__ is types.GeneratorType
+    assert coro.__class__.__name__ in ('coroutine', '_GeneratorWrapper'), coro.__class__.__name__
+
+    buffer = []
+    result = None
+    while True:
+        try:
+            buffer.append(coro.send(None))
+        except StopIteration as ex:
+            result = ex.value if sys.version_info >= (3, 5) else ex.args[0] if ex.args else None
+            break
+    return buffer, result
+
+
+async def test_async_temp_gh3337(x, y):
+    """
+    >>> run_async(test_async_temp_gh3337(2, 3))
+    ([], -1)
+    >>> run_async(test_async_temp_gh3337(3, 2))
+    ([], 0)
+    """
+    return min(x - y, 0)
index 8bf35767d694273ea1ad1032f73dafe5a71d8087..b8a79542865fe69bc6b02d838b7e86080ab76f5f 100644 (file)
@@ -1,5 +1,5 @@
 # mode: run
-# tag: generators
+# tag: generators, gh3265
 
 try:
     import backports_abc
@@ -502,3 +502,42 @@ def test_generator_abc():
     True
     """
     yield 1
+
+
+# GH Issue 3265 - **kwds could cause a crash in some cases due to not
+# handling NULL pointers (in testing it shows as a REFNANNY error).
+# This was on creation of the generator and
+# doesn't really require it to be iterated through:
+
+def some_function():
+    return 0
+
+
+def test_generator_kwds1(**kwargs):
+    """
+    >>> for a in test_generator_kwds1():
+    ...     print(a)
+    0
+    """
+    yield some_function(**kwargs)
+
+
+def test_generator_kwds2(**kwargs):
+    """
+    >>> for a in test_generator_kwds2():
+    ...     print(a)
+    0
+    """
+    yield 0
+
+
+def test_generator_kwds3(**kwargs):
+    """
+    This didn't actually crash before but is still worth a try
+    >>> len(list(test_generator_kwds3()))
+    0
+    >>> for a in test_generator_kwds3(a=1):
+    ...    print(a)
+    a
+    """
+    yield from kwargs.keys()
index 2b0a352fecfdfa7d1012d84573021097eb1e736d..40285cbd105dfd89fdfff22478b821f3bb0e6be7 100644 (file)
@@ -20,8 +20,8 @@ def heapsort(l, bool reverse=False):
     cdef vector[int] v = l
 
     if reverse:
-        make_heap(v.begin(), v.end(), greater)
-        sort_heap(v.begin(), v.end(), greater)
+        make_heap(v.begin(), v.end(), &greater)
+        sort_heap(v.begin(), v.end(), &greater)
     else:
         make_heap(v.begin(), v.end())
         sort_heap(v.begin(), v.end())
@@ -38,7 +38,7 @@ def partialsort(l, int k, reverse=False):
     """
     cdef vector[int] v = l
     if reverse:
-        partial_sort(v.begin(), v.begin() + k, v.end(), greater)
+        partial_sort(v.begin(), v.begin() + k, v.end(), &greater)
     else:
         partial_sort(v.begin(), v.begin() + k, v.end())
     return v
@@ -53,7 +53,7 @@ def stdsort(l, reverse=False):
     """
     cdef vector[int] v = l
     if reverse:
-        sort(v.begin(), v.end(), greater)
+        sort(v.begin(), v.end(), &greater)
     else:
         sort(v.begin(), v.end())
     return v
index 97ff3de149e5ac62993051c3682396ee8dda2bc5..2968b99b2ae146b755f9e362de5fb4a49d65b9f4 100644 (file)
@@ -1,5 +1,5 @@
 # mode: run
-# tag: py3k_super
+# tag: py3k_super, gh3246
 
 class A(object):
     def method(self):
@@ -89,3 +89,21 @@ cdef class CClassSub(CClassBase):
 #         return super().method_cp()
 #     cdef method_c(self):
 #         return super().method_c()
+
+
+def freeing_class_cell_temp_gh3246():
+    # https://github.com/cython/cython/issues/3246
+    """
+    >>> abc = freeing_class_cell_temp_gh3246()
+    >>> abc().a
+    1
+    """
+    class SimpleBase(object):
+        def __init__(self):
+            self.a = 1
+
+    class ABC(SimpleBase):
+        def __init__(self):
+            super().__init__()
+
+    return ABC
index f83798d097e19ec7f4d2d994017a75d509fb1752..575a3382060a0039448c3a2b74ae0ab08412edeb 100644 (file)
@@ -24,3 +24,22 @@ def cond_if_bases(x):
     class PyClass(A if x else B):
         p = 5
     return PyClass
+
+
+def make_subclass(*bases):
+    """
+    >>> cls = make_subclass(list)
+    >>> issubclass(cls, list) or cls.__mro__
+    True
+
+    >>> class Cls(object): pass
+    >>> cls = make_subclass(Cls, list)
+    >>> issubclass(cls, list) or cls.__mro__
+    True
+    >>> issubclass(cls, Cls) or cls.__mro__
+    True
+    """
+    # GH-3338
+    class MadeClass(*bases):
+        pass
+    return MadeClass
index 09a3853d56b9889e1fd76558e71de4c7a77c78c2..a010b701f0400528c15607adc3c8df021ff2b67d 100644 (file)
@@ -2,6 +2,11 @@
 # mode: run
 # tag: pep492, pep530, asyncfor, await
 
+###########
+# This file is a copy of the corresponding test file in CPython.
+# Please keep in sync and do not add non-upstream tests.
+###########
+
 import re
 import gc
 import sys