Skip to content

Commit 76191ac

Browse files
author
Release Manager
committed
gh-35084: build/pkgs/cython: Update to 0.29.36 <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes #1234" use "Introduce new method to calculate 1+1" --> ### 📚 Description <!-- Describe your changes here in detail --> Update to latest in 0.x series https://cython.readthedocs.io/en/latest/src/changes.html#id35 <!-- Why is this change required? What problem does it solve? --> Preparation for Python 3.12 <!-- If it resolves an open issue, please link to the issue here. For example "Closes #1337" --> Fixes #34897 ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] I have made sure that the title is self-explanatory and the description concisely explains the PR. - [x] I have linked an issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open pull requests that this PR logically depends on --> <!-- - #xyz: short description why this is a dependency - #abc: ... --> URL: #35084 Reported by: Matthias Köppe Reviewer(s): Dima Pasechnik
2 parents 04232a4 + 057d0d5 commit 76191ac

File tree

4 files changed

+204
-130
lines changed

4 files changed

+204
-130
lines changed

build/pkgs/cython/checksums.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tarball=Cython-VERSION.tar.gz
2-
sha1=015b737107304a5777f5c6552ffb12713684c924
3-
md5=91c36ea86c00adcc5c1c11cf48b733c0
4-
cksum=1793363471
2+
sha1=762987c737acfe7532cb3da38b450fb6e0cf1d7b
3+
md5=a4d0f9fbc9c137f1a88937cd40e8c5ee
4+
cksum=2260471737
55
upstream_url=https://pypi.io/packages/source/C/Cython/Cython-VERSION.tar.gz
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.29.32.p2
1+
0.29.36

build/pkgs/cython/patches/trashcan.patch renamed to build/pkgs/cython/patches/0001-cython.trashcan-directive-to-enable-the-Python-trash.patch

Lines changed: 183 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@ Date: Thu Feb 14 10:02:41 2019 +0100
99
@cython.trashcan directive to enable the Python trashcan for deallocations
1010

1111
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
12-
index d5742de..27fcad6 100644
12+
index 56845330d..3a3e8a956 100644
1313
--- a/Cython/Compiler/ModuleNode.py
1414
+++ b/Cython/Compiler/ModuleNode.py
15-
@@ -1426,6 +1426,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
15+
@@ -1443,6 +1443,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
1616

1717
is_final_type = scope.parent_type.is_final_type
1818
needs_gc = scope.needs_gc()
1919
+ needs_trashcan = scope.needs_trashcan()
2020

2121
weakref_slot = scope.lookup_here("__weakref__") if not scope.is_closure_class_scope else None
2222
if weakref_slot not in scope.var_entries:
23-
@@ -1464,6 +1465,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
23+
@@ -1481,6 +1482,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
2424
# running this destructor.
2525
code.putln("PyObject_GC_UnTrack(o);")
2626

@@ -32,7 +32,7 @@ index d5742de..27fcad6 100644
3232
# call the user's __dealloc__
3333
self.generate_usr_dealloc_call(scope, code)
3434

35-
@@ -1537,6 +1543,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
35+
@@ -1554,6 +1560,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
3636
code.putln("(*Py_TYPE(o)->tp_free)(o);")
3737
if freelist_size:
3838
code.putln("}")
@@ -44,18 +44,20 @@ index d5742de..27fcad6 100644
4444
"}")
4545

4646
diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py
47-
index d859c19..19d96f1 100644
47+
index d03119fca..539629926 100644
4848
--- a/Cython/Compiler/Options.py
4949
+++ b/Cython/Compiler/Options.py
50-
@@ -313,6 +313,7 @@ directive_types = {
50+
@@ -319,7 +319,8 @@ directive_types = {
5151
'freelist': int,
5252
'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'),
5353
'c_string_encoding': normalise_encoding_name,
54+
- 'cpow': bool
55+
+ 'cpow': bool,
5456
+ 'trashcan': bool,
5557
}
5658

5759
for key, val in _directive_defaults.items():
58-
@@ -355,6 +356,7 @@ directive_scopes = { # defaults to available everywhere
60+
@@ -362,6 +363,7 @@ directive_scopes = { # defaults to available everywhere
5961
'np_pythran': ('module',),
6062
'fast_gil': ('module',),
6163
'iterable_coroutine': ('module', 'function'),
@@ -64,18 +66,18 @@ index d859c19..19d96f1 100644
6466

6567

6668
diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py
67-
index 3b572d6..f200c5f 100644
69+
index c309bd04b..9231130b5 100644
6870
--- a/Cython/Compiler/PyrexTypes.py
6971
+++ b/Cython/Compiler/PyrexTypes.py
70-
@@ -1136,6 +1136,7 @@ class PyObjectType(PyrexType):
72+
@@ -1129,6 +1129,7 @@ class PyObjectType(PyrexType):
7173
is_extern = False
7274
is_subclassed = False
7375
is_gc_simple = False
7476
+ builtin_trashcan = False # builtin type using trashcan
7577

7678
def __str__(self):
7779
return "Python object"
78-
@@ -1190,10 +1191,14 @@ class PyObjectType(PyrexType):
80+
@@ -1183,10 +1184,14 @@ class PyObjectType(PyrexType):
7981

8082

8183
builtin_types_that_cannot_create_refcycles = set([
@@ -91,7 +93,7 @@ index 3b572d6..f200c5f 100644
9193

9294
class BuiltinObjectType(PyObjectType):
9395
# objstruct_cname string Name of PyObject struct
94-
@@ -1218,6 +1223,7 @@ class BuiltinObjectType(PyObjectType):
96+
@@ -1211,6 +1216,7 @@ class BuiltinObjectType(PyObjectType):
9597
self.typeptr_cname = "(&%s)" % cname
9698
self.objstruct_cname = objstruct_cname
9799
self.is_gc_simple = name in builtin_types_that_cannot_create_refcycles
@@ -100,10 +102,19 @@ index 3b572d6..f200c5f 100644
100102
# Special case the type type, as many C API calls (and other
101103
# libraries) actually expect a PyTypeObject* for type arguments.
102104
diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py
103-
index f7443cb..d44484d 100644
105+
index 7361a55ae..f0c311ba6 100644
104106
--- a/Cython/Compiler/Symtab.py
105107
+++ b/Cython/Compiler/Symtab.py
106-
@@ -2085,6 +2085,22 @@ class CClassScope(ClassScope):
108+
@@ -2043,7 +2043,7 @@ class PyClassScope(ClassScope):
109+
class CClassScope(ClassScope):
110+
# Namespace of an extension type.
111+
#
112+
- # parent_type CClassType
113+
+ # parent_type PyExtensionType
114+
# #typeobj_cname string or None
115+
# #objstruct_cname string
116+
# method_table_cname string
117+
@@ -2087,6 +2087,22 @@ class CClassScope(ClassScope):
107118
return not self.parent_type.is_gc_simple
108119
return False
109120

@@ -127,10 +138,10 @@ index f7443cb..d44484d 100644
127138
"""
128139
Do we need to generate an implementation for the tp_clear slot? Can
129140
diff --git a/Cython/Utility/ExtensionTypes.c b/Cython/Utility/ExtensionTypes.c
130-
index 50d0e21..ca2adbe 100644
141+
index dc187ab49..f359165df 100644
131142
--- a/Cython/Utility/ExtensionTypes.c
132143
+++ b/Cython/Utility/ExtensionTypes.c
133-
@@ -74,6 +74,54 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) {
144+
@@ -119,6 +119,54 @@ static int __Pyx_PyType_Ready(PyTypeObject *t) {
134145
return r;
135146
}
136147

@@ -185,3 +196,160 @@ index 50d0e21..ca2adbe 100644
185196
/////////////// CallNextTpDealloc.proto ///////////////
186197

187198
static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc);
199+
diff --git a/tests/run/trashcan.pyx b/tests/run/trashcan.pyx
200+
new file mode 100644
201+
index 000000000..93a501ff8
202+
--- /dev/null
203+
+++ b/tests/run/trashcan.pyx
204+
@@ -0,0 +1,148 @@
205+
+# mode: run
206+
+
207+
+cimport cython
208+
+
209+
+
210+
+# Count number of times an object was deallocated twice. This should remain 0.
211+
+cdef int double_deallocations = 0
212+
+def assert_no_double_deallocations():
213+
+ global double_deallocations
214+
+ err = double_deallocations
215+
+ double_deallocations = 0
216+
+ assert not err
217+
+
218+
+
219+
+# Compute x = f(f(f(...(None)...))) nested n times and throw away the result.
220+
+# The real test happens when exiting this function: then a big recursive
221+
+# deallocation of x happens. We are testing two things in the tests below:
222+
+# that Python does not crash and that no double deallocation happens.
223+
+# See also https://github.com/python/cpython/pull/11841
224+
+def recursion_test(f, int n=2**20):
225+
+ x = None
226+
+ cdef int i
227+
+ for i in range(n):
228+
+ x = f(x)
229+
+
230+
+
231+
+@cython.trashcan(True)
232+
+cdef class Recurse:
233+
+ """
234+
+ >>> recursion_test(Recurse)
235+
+ >>> assert_no_double_deallocations()
236+
+ """
237+
+ cdef public attr
238+
+ cdef int deallocated
239+
+
240+
+ def __init__(self, x):
241+
+ self.attr = x
242+
+
243+
+ def __dealloc__(self):
244+
+ # Check that we're not being deallocated twice
245+
+ global double_deallocations
246+
+ double_deallocations += self.deallocated
247+
+ self.deallocated = 1
248+
+
249+
+
250+
+cdef class RecurseSub(Recurse):
251+
+ """
252+
+ >>> recursion_test(RecurseSub)
253+
+ >>> assert_no_double_deallocations()
254+
+ """
255+
+ cdef int subdeallocated
256+
+
257+
+ def __dealloc__(self):
258+
+ # Check that we're not being deallocated twice
259+
+ global double_deallocations
260+
+ double_deallocations += self.subdeallocated
261+
+ self.subdeallocated = 1
262+
+
263+
+
264+
+@cython.freelist(4)
265+
+@cython.trashcan(True)
266+
+cdef class RecurseFreelist:
267+
+ """
268+
+ >>> recursion_test(RecurseFreelist)
269+
+ >>> recursion_test(RecurseFreelist, 1000)
270+
+ >>> assert_no_double_deallocations()
271+
+ """
272+
+ cdef public attr
273+
+ cdef int deallocated
274+
+
275+
+ def __init__(self, x):
276+
+ self.attr = x
277+
+
278+
+ def __dealloc__(self):
279+
+ # Check that we're not being deallocated twice
280+
+ global double_deallocations
281+
+ double_deallocations += self.deallocated
282+
+ self.deallocated = 1
283+
+
284+
+
285+
+# Subclass of list => uses trashcan by default
286+
+# As long as https://github.com/python/cpython/pull/11841 is not fixed,
287+
+# this does lead to double deallocations, so we skip that check.
288+
+cdef class RecurseList(list):
289+
+ """
290+
+ >>> RecurseList(42)
291+
+ [42]
292+
+ >>> recursion_test(RecurseList)
293+
+ """
294+
+ def __init__(self, x):
295+
+ super().__init__((x,))
296+
+
297+
+
298+
+# Some tests where the trashcan is NOT used. When the trashcan is not used
299+
+# in a big recursive deallocation, the __dealloc__s of the base classs are
300+
+# only run after the __dealloc__s of the subclasses.
301+
+# We use this to detect trashcan usage.
302+
+cdef int base_deallocated = 0
303+
+cdef int trashcan_used = 0
304+
+def assert_no_trashcan_used():
305+
+ global base_deallocated, trashcan_used
306+
+ err = trashcan_used
307+
+ trashcan_used = base_deallocated = 0
308+
+ assert not err
309+
+
310+
+
311+
+cdef class Base:
312+
+ def __dealloc__(self):
313+
+ global base_deallocated
314+
+ base_deallocated = 1
315+
+
316+
+
317+
+# Trashcan disabled by default
318+
+cdef class Sub1(Base):
319+
+ """
320+
+ >>> recursion_test(Sub1, 100)
321+
+ >>> assert_no_trashcan_used()
322+
+ """
323+
+ cdef public attr
324+
+
325+
+ def __init__(self, x):
326+
+ self.attr = x
327+
+
328+
+ def __dealloc__(self):
329+
+ global base_deallocated, trashcan_used
330+
+ trashcan_used += base_deallocated
331+
+
332+
+
333+
+@cython.trashcan(True)
334+
+cdef class Middle(Base):
335+
+ cdef public foo
336+
+
337+
+
338+
+# Trashcan disabled explicitly
339+
+@cython.trashcan(False)
340+
+cdef class Sub2(Middle):
341+
+ """
342+
+ >>> recursion_test(Sub2, 1000)
343+
+ >>> assert_no_trashcan_used()
344+
+ """
345+
+ cdef public attr
346+
+
347+
+ def __init__(self, x):
348+
+ self.attr = x
349+
+
350+
+ def __dealloc__(self):
351+
+ global base_deallocated, trashcan_used
352+
+ trashcan_used += base_deallocated
353+
--
354+
2.37.1 (Apple Git-137.1)
355+

0 commit comments

Comments
 (0)