diff --git a/build/pkgs/cython/checksums.ini b/build/pkgs/cython/checksums.ini index b06052c59aa..175914867ed 100644 --- a/build/pkgs/cython/checksums.ini +++ b/build/pkgs/cython/checksums.ini @@ -1,5 +1,5 @@ tarball=Cython-VERSION.tar.gz -sha1=015b737107304a5777f5c6552ffb12713684c924 -md5=91c36ea86c00adcc5c1c11cf48b733c0 -cksum=1793363471 +sha1=762987c737acfe7532cb3da38b450fb6e0cf1d7b +md5=a4d0f9fbc9c137f1a88937cd40e8c5ee +cksum=2260471737 upstream_url=https://pypi.io/packages/source/C/Cython/Cython-VERSION.tar.gz diff --git a/build/pkgs/cython/package-version.txt b/build/pkgs/cython/package-version.txt index babe4be9be1..5232b0aaea8 100644 --- a/build/pkgs/cython/package-version.txt +++ b/build/pkgs/cython/package-version.txt @@ -1 +1 @@ -0.29.32.p2 +0.29.36 diff --git a/build/pkgs/cython/patches/trashcan.patch b/build/pkgs/cython/patches/0001-cython.trashcan-directive-to-enable-the-Python-trash.patch similarity index 55% rename from build/pkgs/cython/patches/trashcan.patch rename to build/pkgs/cython/patches/0001-cython.trashcan-directive-to-enable-the-Python-trash.patch index e1e88ebe465..0cd3f35df32 100644 --- a/build/pkgs/cython/patches/trashcan.patch +++ b/build/pkgs/cython/patches/0001-cython.trashcan-directive-to-enable-the-Python-trash.patch @@ -9,10 +9,10 @@ Date: Thu Feb 14 10:02:41 2019 +0100 @cython.trashcan directive to enable the Python trashcan for deallocations diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py -index d5742de..27fcad6 100644 +index 56845330d..3a3e8a956 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py -@@ -1426,6 +1426,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): +@@ -1443,6 +1443,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): is_final_type = scope.parent_type.is_final_type needs_gc = scope.needs_gc() @@ -20,7 +20,7 @@ index d5742de..27fcad6 100644 weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None if weakref_slot not in scope.var_entries: -@@ -1464,6 +1465,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): +@@ -1481,6 +1482,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): # running this destructor. code.putln("PyObject_GC_UnTrack(o);") @@ -32,7 +32,7 @@ index d5742de..27fcad6 100644 # call the user's __dealloc__ self.generate_usr_dealloc_call(scope, code) -@@ -1537,6 +1543,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): +@@ -1554,6 +1560,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("(*Py_TYPE(o)->tp_free)(o);") if freelist_size: code.putln("}") @@ -44,18 +44,20 @@ index d5742de..27fcad6 100644 "}") diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py -index d859c19..19d96f1 100644 +index d03119fca..539629926 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py -@@ -313,6 +313,7 @@ directive_types = { +@@ -319,7 +319,8 @@ directive_types = { 'freelist': int, 'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'), 'c_string_encoding': normalise_encoding_name, +- 'cpow': bool ++ 'cpow': bool, + 'trashcan': bool, } for key, val in _directive_defaults.items(): -@@ -355,6 +356,7 @@ directive_scopes = { # defaults to available everywhere +@@ -362,6 +363,7 @@ directive_scopes = { # defaults to available everywhere 'np_pythran': ('module',), 'fast_gil': ('module',), 'iterable_coroutine': ('module', 'function'), @@ -64,10 +66,10 @@ index d859c19..19d96f1 100644 diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py -index 3b572d6..f200c5f 100644 +index c309bd04b..9231130b5 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py -@@ -1136,6 +1136,7 @@ class PyObjectType(PyrexType): +@@ -1129,6 +1129,7 @@ class PyObjectType(PyrexType): is_extern = False is_subclassed = False is_gc_simple = False @@ -75,7 +77,7 @@ index 3b572d6..f200c5f 100644 def __str__(self): return "Python object" -@@ -1190,10 +1191,14 @@ class PyObjectType(PyrexType): +@@ -1183,10 +1184,14 @@ class PyObjectType(PyrexType): builtin_types_that_cannot_create_refcycles = set([ @@ -91,7 +93,7 @@ index 3b572d6..f200c5f 100644 class BuiltinObjectType(PyObjectType): # objstruct_cname string Name of PyObject struct -@@ -1218,6 +1223,7 @@ class BuiltinObjectType(PyObjectType): +@@ -1211,6 +1216,7 @@ class BuiltinObjectType(PyObjectType): self.typeptr_cname = "(&%s)" % cname self.objstruct_cname = objstruct_cname self.is_gc_simple = name in builtin_types_that_cannot_create_refcycles @@ -100,10 +102,19 @@ index 3b572d6..f200c5f 100644 # Special case the type type, as many C API calls (and other # libraries) actually expect a PyTypeObject* for type arguments. diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py -index f7443cb..d44484d 100644 +index 7361a55ae..f0c311ba6 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py -@@ -2085,6 +2085,22 @@ class CClassScope(ClassScope): +@@ -2043,7 +2043,7 @@ class PyClassScope(ClassScope): + class CClassScope(ClassScope): + # Namespace of an extension type. + # +- # parent_type CClassType ++ # parent_type PyExtensionType + # #typeobj_cname string or None + # #objstruct_cname string + # method_table_cname string +@@ -2087,6 +2087,22 @@ class CClassScope(ClassScope): return not self.parent_type.is_gc_simple return False @@ -127,10 +138,10 @@ index f7443cb..d44484d 100644 """ Do we need to generate an implementation for the tp_clear slot? Can diff --git a/Cython/Utility/ExtensionTypes.c b/Cython/Utility/ExtensionTypes.c -index 50d0e21..ca2adbe 100644 +index dc187ab49..f359165df 100644 --- a/Cython/Utility/ExtensionTypes.c +++ b/Cython/Utility/ExtensionTypes.c -@@ -74,6 +74,54 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { +@@ -119,6 +119,54 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) { return r; } @@ -185,3 +196,160 @@ index 50d0e21..ca2adbe 100644 /////////////// CallNextTpDealloc.proto /////////////// static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc); +diff --git a/tests/run/trashcan.pyx b/tests/run/trashcan.pyx +new file mode 100644 +index 000000000..93a501ff8 +--- /dev/null ++++ b/tests/run/trashcan.pyx +@@ -0,0 +1,148 @@ ++# mode: run ++ ++cimport cython ++ ++ ++# Count number of times an object was deallocated twice. This should remain 0. ++cdef int double_deallocations = 0 ++def assert_no_double_deallocations(): ++ global double_deallocations ++ err = double_deallocations ++ double_deallocations = 0 ++ assert not err ++ ++ ++# Compute x = f(f(f(...(None)...))) nested n times and throw away the result. ++# The real test happens when exiting this function: then a big recursive ++# deallocation of x happens. We are testing two things in the tests below: ++# that Python does not crash and that no double deallocation happens. ++# See also https://github.com/python/cpython/pull/11841 ++def recursion_test(f, int n=2**20): ++ x = None ++ cdef int i ++ for i in range(n): ++ x = f(x) ++ ++ ++@cython.trashcan(True) ++cdef class Recurse: ++ """ ++ >>> recursion_test(Recurse) ++ >>> assert_no_double_deallocations() ++ """ ++ cdef public attr ++ cdef int deallocated ++ ++ def __init__(self, x): ++ self.attr = x ++ ++ def __dealloc__(self): ++ # Check that we're not being deallocated twice ++ global double_deallocations ++ double_deallocations += self.deallocated ++ self.deallocated = 1 ++ ++ ++cdef class RecurseSub(Recurse): ++ """ ++ >>> recursion_test(RecurseSub) ++ >>> assert_no_double_deallocations() ++ """ ++ cdef int subdeallocated ++ ++ def __dealloc__(self): ++ # Check that we're not being deallocated twice ++ global double_deallocations ++ double_deallocations += self.subdeallocated ++ self.subdeallocated = 1 ++ ++ ++@cython.freelist(4) ++@cython.trashcan(True) ++cdef class RecurseFreelist: ++ """ ++ >>> recursion_test(RecurseFreelist) ++ >>> recursion_test(RecurseFreelist, 1000) ++ >>> assert_no_double_deallocations() ++ """ ++ cdef public attr ++ cdef int deallocated ++ ++ def __init__(self, x): ++ self.attr = x ++ ++ def __dealloc__(self): ++ # Check that we're not being deallocated twice ++ global double_deallocations ++ double_deallocations += self.deallocated ++ self.deallocated = 1 ++ ++ ++# Subclass of list => uses trashcan by default ++# As long as https://github.com/python/cpython/pull/11841 is not fixed, ++# this does lead to double deallocations, so we skip that check. ++cdef class RecurseList(list): ++ """ ++ >>> RecurseList(42) ++ [42] ++ >>> recursion_test(RecurseList) ++ """ ++ def __init__(self, x): ++ super().__init__((x,)) ++ ++ ++# Some tests where the trashcan is NOT used. When the trashcan is not used ++# in a big recursive deallocation, the __dealloc__s of the base classs are ++# only run after the __dealloc__s of the subclasses. ++# We use this to detect trashcan usage. ++cdef int base_deallocated = 0 ++cdef int trashcan_used = 0 ++def assert_no_trashcan_used(): ++ global base_deallocated, trashcan_used ++ err = trashcan_used ++ trashcan_used = base_deallocated = 0 ++ assert not err ++ ++ ++cdef class Base: ++ def __dealloc__(self): ++ global base_deallocated ++ base_deallocated = 1 ++ ++ ++# Trashcan disabled by default ++cdef class Sub1(Base): ++ """ ++ >>> recursion_test(Sub1, 100) ++ >>> assert_no_trashcan_used() ++ """ ++ cdef public attr ++ ++ def __init__(self, x): ++ self.attr = x ++ ++ def __dealloc__(self): ++ global base_deallocated, trashcan_used ++ trashcan_used += base_deallocated ++ ++ ++@cython.trashcan(True) ++cdef class Middle(Base): ++ cdef public foo ++ ++ ++# Trashcan disabled explicitly ++@cython.trashcan(False) ++cdef class Sub2(Middle): ++ """ ++ >>> recursion_test(Sub2, 1000) ++ >>> assert_no_trashcan_used() ++ """ ++ cdef public attr ++ ++ def __init__(self, x): ++ self.attr = x ++ ++ def __dealloc__(self): ++ global base_deallocated, trashcan_used ++ trashcan_used += base_deallocated +-- +2.37.1 (Apple Git-137.1) + diff --git a/build/pkgs/cython/patches/4918.patch b/build/pkgs/cython/patches/0001-rebased-PR2946.patch similarity index 60% rename from build/pkgs/cython/patches/4918.patch rename to build/pkgs/cython/patches/0001-rebased-PR2946.patch index a9dbb0a4a0c..36764e7291e 100644 --- a/build/pkgs/cython/patches/4918.patch +++ b/build/pkgs/cython/patches/0001-rebased-PR2946.patch @@ -1,22 +1,21 @@ -From 0dade9353e06b052d0da5e512cdc2ce04061904a Mon Sep 17 00:00:00 2001 -From: Matthias Koeppe -Date: Sat, 23 Jul 2022 10:53:49 -0700 -Subject: [PATCH 1/3] Add PEP420 namespace support +From 0b69e95aa702fb9f52b285360d5c5ae5e7fbb745 Mon Sep 17 00:00:00 2001 +From: Dima Pasechnik +Date: Thu, 16 Mar 2023 22:35:09 +0000 +Subject: [PATCH] rebased PR2946 -Backport of https://github.com/cython/cython/pull/2946 to 0.29.x --- Cython/Compiler/Main.py | 44 +++++++++++++++---- - Cython/Utils.py | 26 ++++++++--- + Cython/Utils.py | 22 +++++++--- runtests.py | 1 + .../build/cythonize_pep420_namespace.srctree | 44 +++++++++++++++++++ - 4 files changed, 99 insertions(+), 16 deletions(-) + 4 files changed, 96 insertions(+), 15 deletions(-) create mode 100644 tests/build/cythonize_pep420_namespace.srctree diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py -index dc4add541e..2be7a06a1c 100644 +index 9c57452ba..1143ecf03 100644 --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py -@@ -801,32 +801,58 @@ def search_include_directories(dirs, qualified_name, suffix, pos, include=False) +@@ -809,32 +809,58 @@ def search_include_directories(dirs, qualified_name, suffix, pos, include=False) else: dirs = (Utils.find_root_package_dir(file_desc.filename),) + dirs @@ -85,14 +84,12 @@ index dc4add541e..2be7a06a1c 100644 diff --git a/Cython/Utils.py b/Cython/Utils.py -index d59d67d78b..305ebf8412 100644 +index 69563794c..77a48fbd7 100644 --- a/Cython/Utils.py +++ b/Cython/Utils.py -@@ -134,16 +134,21 @@ def find_root_package_dir(file_path): - else: +@@ -135,15 +135,19 @@ def find_root_package_dir(file_path): return dir -+ @cached_function -def check_package_dir(dir, package_names): +def check_package_dir(dir_path, package_names): @@ -110,19 +107,17 @@ index d59d67d78b..305ebf8412 100644 + namespace = False + return dir_path, namespace --@cached_function + @cached_function -def is_package_dir(dir_path): -+ +def contains_init(dir_path): for filename in ("__init__.py", "__init__.pyc", "__init__.pyx", -@@ -152,6 +157,13 @@ def is_package_dir(dir_path): +@@ -152,6 +156,12 @@ def is_package_dir(dir_path): if path_exists(path): return 1 + -+@cached_function +def is_package_dir(dir_path): + if contains_init(dir_path): + return 1 @@ -132,10 +127,10 @@ index d59d67d78b..305ebf8412 100644 def path_exists(path): # try on the filesystem first diff --git a/runtests.py b/runtests.py -index 91a0dd2570..7d04463846 100755 +index 91a0dd257..7d0446384 100755 --- a/runtests.py +++ b/runtests.py -@@ -415,6 +415,7 @@ def get_openmp_compiler_flags(language): +@@ -415,6 +415,7 @@ VER_DEP_MODULES = { 'run.special_methods_T561_py2' ]), (3,3) : (operator.lt, lambda x: x in ['build.package_compilation', @@ -145,7 +140,7 @@ index 91a0dd2570..7d04463846 100755 ]), diff --git a/tests/build/cythonize_pep420_namespace.srctree b/tests/build/cythonize_pep420_namespace.srctree new file mode 100644 -index 0000000000..6a031e4170 +index 000000000..6a031e417 --- /dev/null +++ b/tests/build/cythonize_pep420_namespace.srctree @@ -0,0 +1,44 @@ @@ -193,95 +188,6 @@ index 0000000000..6a031e4170 + +a = A() +b = B() +-- +2.37.1 (Apple Git-137.1) -From fcd3e7bd1351a0964704f2921ae33b4b57250668 Mon Sep 17 00:00:00 2001 -From: Fedor Alekseev -Date: Mon, 9 Nov 2020 14:34:01 +0300 -Subject: [PATCH 2/3] Support namespace packages inside regular packages - ---- - Cython/Utils.py | 4 +--- - tests/build/cythonize_pep420_namespace.srctree | 17 ++++++++++++++++- - 2 files changed, 17 insertions(+), 4 deletions(-) - -diff --git a/Cython/Utils.py b/Cython/Utils.py -index 305ebf8412..f21d5cddba 100644 ---- a/Cython/Utils.py -+++ b/Cython/Utils.py -@@ -141,9 +141,7 @@ def check_package_dir(dir_path, package_names): - for dirname in package_names: - dir_path = os.path.join(dir_path, dirname) - has_init = contains_init(dir_path) -- if not namespace and not has_init: -- return None, False -- elif has_init: -+ if has_init: - namespace = False - return dir_path, namespace - -diff --git a/tests/build/cythonize_pep420_namespace.srctree b/tests/build/cythonize_pep420_namespace.srctree -index 6a031e4170..04013a3004 100644 ---- a/tests/build/cythonize_pep420_namespace.srctree -+++ b/tests/build/cythonize_pep420_namespace.srctree -@@ -10,7 +10,8 @@ from distutils.core import setup, Extension - setup( - ext_modules=cythonize([ - Extension("nsp.m1.a", ["nsp/m1/a.pyx"]), -- Extension("nsp.m2.b", ["nsp/m2/b.pyx"]) -+ Extension("nsp.m2.b", ["nsp/m2/b.pyx"]), -+ Extension("nsp.m3.c.d", ["nsp/m3/c/d.pyx"]) - ]), - ) - -@@ -31,14 +32,28 @@ cdef class A: - ######## nsp/m2/b.pyx ######## - - from nsp.m1.a cimport A -+from nsp.m3.c.d cimport D - - cdef class B(A): - pass - -+######## nsp/m3/__init__.py ######## -+ -+######## nsp/m3/c/d.pyx ######## -+ -+cdef class D: -+ pass -+ -+######## nsp/m3/c/d.pxd ######## -+ -+cdef class D: -+ pass -+ - ######## runner.py ######## - - from nsp.m1.a import A - from nsp.m2.b import B -+from nsp.m3.c.d import D - - a = A() - b = B() - -From 9d61b95a6a71a4c88a51ab8f30d5b3a8b93998b8 Mon Sep 17 00:00:00 2001 -From: scoder -Date: Sat, 14 Nov 2020 09:42:09 +0100 -Subject: [PATCH 3/3] Anticipate future changes. - ---- - tests/build/cythonize_pep420_namespace.srctree | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/build/cythonize_pep420_namespace.srctree b/tests/build/cythonize_pep420_namespace.srctree -index 04013a3004..99649376a3 100644 ---- a/tests/build/cythonize_pep420_namespace.srctree -+++ b/tests/build/cythonize_pep420_namespace.srctree -@@ -11,7 +11,7 @@ setup( - ext_modules=cythonize([ - Extension("nsp.m1.a", ["nsp/m1/a.pyx"]), - Extension("nsp.m2.b", ["nsp/m2/b.pyx"]), -- Extension("nsp.m3.c.d", ["nsp/m3/c/d.pyx"]) -+ Extension("nsp.m3.c.d", ["nsp/m3/c/d.pyx"]), - ]), - ) -