Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-Cython for openSUSE:Factory checked in at 2025-09-25 18:44:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Cython (Old) and /work/SRC/openSUSE:Factory/.python-Cython.new.11973 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Cython" Thu Sep 25 18:44:08 2025 rev:89 rq:1306743 version:3.1.4 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Cython/python-Cython.changes 2025-08-15 21:51:16.550162792 +0200 +++ /work/SRC/openSUSE:Factory/.python-Cython.new.11973/python-Cython.changes 2025-09-25 18:44:40.308605296 +0200 @@ -1,0 +2,18 @@ +Mon Sep 22 12:31:13 UTC 2025 - Markéta Machová <[email protected]> + +- Update to 3.1.4 + * Declarations for the new PyUnstable_*() refcounting C-API functions in Py3.14 + were added. + * The monitoring code could crash on tracing. + * Initialising the monitoring code could fail with a CPython exception. + * Optimised integer shifting triggered undefined behaviour in C. + * Deallocating objects that inherit from external types defined in pxd files + could run into an infinite loop. + * A reference to metaclasses could be leaked on instantiation. + * (Unlikely) error handling during empty builtin container tests was ineffective. + * Generated *_api.h files used potentially unknown Cython configuration macros. + * cythonize() avoids parallel compiler runs on systems using spawn() in + multiprocessing. + * The @cython.ufunc decorator was missing in type checker stubs. + +------------------------------------------------------------------- Old: ---- cython-3.1.3.tar.gz New: ---- cython-3.1.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Cython.spec ++++++ --- /var/tmp/diff_new_pack.K4hFLo/_old 2025-09-25 18:44:40.852628066 +0200 +++ /var/tmp/diff_new_pack.K4hFLo/_new 2025-09-25 18:44:40.856628233 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-Cython # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ %endif %{?sle15_python_module_pythons} Name: python-Cython -Version: 3.1.3 +Version: 3.1.4 Release: 0 Summary: The Cython compiler for writing C extensions for the Python language License: Apache-2.0 ++++++ cython-3.1.3.tar.gz -> cython-3.1.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/.gitrev new/cython-3.1.4/.gitrev --- old/cython-3.1.3/.gitrev 2025-08-13 06:30:35.126921000 +0200 +++ new/cython-3.1.4/.gitrev 2025-09-16 08:36:11.190519300 +0200 @@ -1 +1 @@ -8a1b3c10260fa9f9a91475819d737bce59b1a3d0 +236e4a3ccd24d4e24c9d7c40a8580d359663832c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/CHANGES.rst new/cython-3.1.4/CHANGES.rst --- old/cython-3.1.3/CHANGES.rst 2025-08-13 06:30:25.725922000 +0200 +++ new/cython-3.1.4/CHANGES.rst 2025-09-16 08:36:01.223351500 +0200 @@ -2,6 +2,47 @@ Cython Changelog ================ +3.1.4 (2025-09-16) +================== + +Features added +-------------- + +* Declarations for the new ``PyUnstable_*()`` refcounting C-API functions in Py3.14 were added. + (Github issue :issue:`6836`) + +Bugs fixed +---------- + +* The monitoring code could crash on tracing. + (Github issue :issue:`7050`) + +* Initialising the monitoring code could fail with a CPython exception. + See https://github.com/nedbat/coveragepy/issues/1790#issuecomment-3257410149 + +* Optimised integer shifting triggered undefined behaviour in C. + (Github issue :issue:`7089`) + +* Deallocating objects that inherit from external types defined in pxd files + could run into an infinite loop. + (Github issue :issue:`7143`) + +* A reference to metaclasses could be leaked on instantiation. + (Github issue :issue:`7130`) + +* (Unlikely) error handling during empty builtin container tests was ineffective. + (Github issue :issue:`7190`) + +* Generated ``*_api.h`` files used potentially unknown Cython configuration macros. + (Github issue :issue:`7108`) + +* ``cythonize()`` avoids parallel compiler runs on systems using ``spawn()`` in multiprocessing. + Patch by Marcel Bargull. (Github issue :issue:`3262`) + +* The ``@cython.ufunc`` decorator was missing in type checker stubs. + Patch by jayClean. (Github issue :issue:`7109`) + + 3.1.3 (2025-08-13) ================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Build/Dependencies.py new/cython-3.1.4/Cython/Build/Dependencies.py --- old/cython-3.1.3/Cython/Build/Dependencies.py 2025-08-13 06:30:25.726922300 +0200 +++ new/cython-3.1.4/Cython/Build/Dependencies.py 2025-09-16 08:36:01.224351400 +0200 @@ -1131,6 +1131,11 @@ nthreads = 0 if nthreads: import multiprocessing + if multiprocessing.get_start_method() == 'spawn': + print('Disabling parallel cythonization for "spawn" process start method.') + nthreads = 0 + if nthreads: + import multiprocessing pool = multiprocessing.Pool( nthreads, initializer=_init_multiprocessing_helper) # This is a bit more involved than it should be, because KeyboardInterrupts diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Compiler/ExprNodes.py new/cython-3.1.4/Cython/Compiler/ExprNodes.py --- old/cython-3.1.3/Cython/Compiler/ExprNodes.py 2025-08-13 06:30:25.730922200 +0200 +++ new/cython-3.1.4/Cython/Compiler/ExprNodes.py 2025-09-16 08:36:01.228351400 +0200 @@ -14682,7 +14682,9 @@ type = PyrexTypes.c_bint_type - # Note that all of these need a check if CYTHON_ASSUME_SAFE_MACROS is false + # Note that all of these need a check if CYTHON_ASSUME_SAFE_SIZE is false. + # They should also all return something compatible with Py_ssize_t + # (i.e. Py_ssize_t or a smaller int type). _special_builtins = { Builtin.list_type: '__Pyx_PyList_GET_SIZE', Builtin.tuple_type: '__Pyx_PyTuple_GET_SIZE', @@ -14718,11 +14720,18 @@ return test_func = self._special_builtins.get(self.arg.type) if test_func is not None: - checks = ["(%s != Py_None)" % self.arg.py_result()] if self.arg.may_be_none() else [] - checks.append("(%s(%s) != 0)" % (test_func, self.arg.py_result())) - code.putln("%s = %s;" % (self.result(), '&&'.join(checks))) + if self.arg.may_be_none(): + code.putln(f"if ({self.arg.py_result()} == Py_None) {self.result()} = 0;") + code.putln("else") + code.putln("{") + # Be aware that __Pyx_PyUnicode_IS_TRUE isn't strictly returning a size (but it does + # return an int which fits into a Py_ssize_t). + code.putln(f"Py_ssize_t {Naming.quick_temp_cname} = {test_func}({self.arg.py_result()});") code.putln(code.error_goto_if( - "((!CYTHON_ASSUME_SAFE_MACROS) && %s < 0)" % self.result(), self.pos)) + f"((!CYTHON_ASSUME_SAFE_SIZE) && {Naming.quick_temp_cname} < 0)", self.pos)) + code.putln(f"{self.result()} = ({Naming.quick_temp_cname} != 0);") + code.putln("}") + code.putln() else: code.putln( "%s = __Pyx_PyObject_IsTrue(%s); %s" % ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Compiler/Scanning.py new/cython-3.1.4/Cython/Compiler/Scanning.py --- old/cython-3.1.3/Cython/Compiler/Scanning.py 2025-08-13 06:30:25.737922200 +0200 +++ new/cython-3.1.4/Cython/Compiler/Scanning.py 2025-09-16 08:36:01.235351600 +0200 @@ -209,22 +209,15 @@ # we cache the lines only the second time this is called, in # order to save memory when they are only used once key = (encoding, error_handling) - try: - lines = self._lines[key] - if lines is not None: - return lines - except KeyError: - pass + lines = self._lines.get(key) + if lines is not None: + return lines with self.get_file_object(encoding=encoding, error_handling=error_handling) as f: lines = f.readlines() - if key in self._lines: - self._lines[key] = lines - else: - # do not cache the first access, but remember that we - # already read it once - self._lines[key] = None + # Do not cache the first access, but add the key to remember that we already read it once. + self._lines[key] = lines if key in self._lines else None return lines def get_file_object(self, encoding=None, error_handling=None): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Compiler/Symtab.py new/cython-3.1.4/Cython/Compiler/Symtab.py --- old/cython-3.1.3/Cython/Compiler/Symtab.py 2025-08-13 06:30:25.737922200 +0200 +++ new/cython-3.1.4/Cython/Compiler/Symtab.py 2025-09-16 08:36:01.235351600 +0200 @@ -1194,7 +1194,7 @@ def _emit_class_private_warning(self, pos, name): warning(pos, "Global name %s matched from within class scope " - "in contradiction to to Python 'class private name' rules. " + "in contradiction to Python 'class private name' rules. " "This may change in a future release." % name, 1) def use_utility_code(self, new_code): @@ -2445,6 +2445,9 @@ # C attributes, then it needs to participate in GC. if self.has_cyclic_pyobject_attrs and not self.directives.get('no_gc', False): return True + if self.parent_type.is_external and not self.parent_type.is_builtin_type: + # It's impossible to really know - external types are often incomplete. + return True base_type = self.parent_type.base_type if base_type and base_type.scope is not None: return base_type.scope.needs_gc() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Compiler/TypeSlots.py new/cython-3.1.4/Cython/Compiler/TypeSlots.py --- old/cython-3.1.3/Cython/Compiler/TypeSlots.py 2025-08-13 06:30:25.739922300 +0200 +++ new/cython-3.1.4/Cython/Compiler/TypeSlots.py 2025-09-16 08:36:01.236351500 +0200 @@ -424,7 +424,9 @@ InternalMethodSlot.__init__(self, slot_name, **kargs) def slot_code(self, scope): - if not scope.needs_gc(): + # We treat external types as needing gc, but don't generate a slot code + # because we don't know it to be able to call it directly. + if not scope.needs_gc() or scope.parent_type.is_external: return "0" if not scope.has_cyclic_pyobject_attrs: # if the type does not have GC relevant object attributes, it can @@ -479,16 +481,10 @@ # delegate GC methods to its parent - iff the parent # functions are defined in the same module slot_code = self._parent_slot_function(scope) - return slot_code or '0' + if slot_code is not None: + return slot_code return InternalMethodSlot.slot_code(self, scope) - def spec_value(self, scope): - slot_function = self.slot_code(scope) - if self.slot_name == "tp_dealloc" and slot_function != scope.mangle_internal("tp_dealloc"): - # Not used => inherit from base type. - return "0" - return slot_function - def generate_dynamic_init_code(self, scope, code): if self.slot_code(scope) != '0': return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Includes/cpython/ref.pxd new/cython-3.1.4/Cython/Includes/cpython/ref.pxd --- old/cython-3.1.3/Cython/Includes/cpython/ref.pxd 2025-08-13 06:30:25.743922200 +0200 +++ new/cython-3.1.4/Cython/Includes/cpython/ref.pxd 2025-09-16 08:36:01.240351700 +0200 @@ -1,4 +1,5 @@ -from .object cimport PyObject, PyTypeObject, Py_TYPE # legacy imports for re-export +from .object cimport PyObject +from .object cimport PyTypeObject, Py_TYPE # legacy imports for re-export cdef extern from "Python.h": ##################################################################### @@ -65,3 +66,76 @@ # This is useful when it would be awkward to create an owned reference just # to get the reference count. See the note for Py_REFCNT above about the # accuracy of reference counts. + + int PyUnstable_Object_EnableDeferredRefcount(object o) + # Enable deferred reference counting on obj, if supported by the runtime. + # In the free-threaded build, this allows the interpreter to avoid reference count + # adjustments to obj, which may improve multi-threaded performance. + # The tradeoff is that obj will only be deallocated by the tracing garbage collector, + # and not when the interpreter no longer has any references to it. + # + # This function returns 1 if deferred reference counting is enabled on obj, + # and 0 if deferred reference counting is not supported or if the hint was ignored + # by the interpreter, such as when deferred reference counting is already enabled on obj. + # This function is thread-safe, and cannot fail. + # + # This function does nothing on builds with the GIL enabled, which do not support + # deferred reference counting. This also does nothing if obj is not an object tracked + # by the garbage collector (see gc.is_tracked() and PyObject_GC_IsTracked()). + # + # This function is intended to be used soon after obj is created, by the code + # that creates it, such as in the object’s tp_new slot. + # + # Added in CPython 3.14. + + int PyUnstable_Object_IsUniqueReferencedTemporary(object o) + # Check if obj is a unique temporary object. + # Returns 1 if obj is known to be a unique temporary object, and 0 otherwise. + # This function cannot fail, but the check is conservative, and may return 0 + # in some cases even if obj is a unique temporary object. + # + # If an object is a unique temporary, it is guaranteed that the current code + # has the only reference to the object. For arguments to C functions, this should + # be used instead of checking if the reference count is 1. + # Starting with Python 3.14, the interpreter internally avoids some reference count + # modifications when loading objects onto the operands stack by borrowing references + # when possible, which means that a reference count of 1 by itself does not guarantee + # that a function argument uniquely referenced. + # + # Added in CPython 3.14. + + int PyUnstable_IsImmortal(object o) + # This function returns non-zero if obj is immortal, and zero otherwise. + # This function cannot fail. + # + # Added in CPython 3.14. + + void PyUnstable_EnableTryIncRef(object o) + # Enables subsequent uses of PyUnstable_TryIncRef() on obj. + # The caller must hold a strong reference to obj when calling this. + # + # Added in CPython 3.14. + + bint PyUnstable_TryIncRef(PyObject *o) + # Increments the reference count of obj if it is not zero. + # Returns 1 if the object’s reference count was successfully incremented. + # Otherwise, this function returns 0. + # + # PyUnstable_EnableTryIncRef() must have been called earlier on obj + # or this function may spuriously return 0 in the free threading build. + # + # Added in CPython 3.14. + + int PyUnstable_Object_IsUniquelyReferenced(object o) + # Determine if op only has one reference. + # + # On GIL-enabled builds, this function is equivalent to Py_REFCNT(op) == 1. + # + # On a free threaded build, this checks if op’s reference count is equal + # to one and additionally checks if op is only used by this thread. + # Py_REFCNT(op) == 1 is not thread-safe on free threaded builds; prefer this function. + # + # The caller must hold an attached thread state, despite the fact that this function + # doesn’t call into the Python interpreter. This function cannot fail. + # + # Added in CPython 3.14. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Shadow.py new/cython-3.1.4/Cython/Shadow.py --- old/cython-3.1.3/Cython/Shadow.py 2025-08-13 06:30:25.747922200 +0200 +++ new/cython-3.1.4/Cython/Shadow.py 2025-09-16 08:36:01.245351600 +0200 @@ -1,7 +1,7 @@ # cython.* namespace for pure mode. # Possible version formats: "3.1.0", "3.1.0a1", "3.1.0a1.dev0" -__version__ = "3.1.3" +__version__ = "3.1.4" # BEGIN shameless copy from Cython/minivect/minitypes.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Shadow.pyi new/cython-3.1.4/Cython/Shadow.pyi --- old/cython-3.1.3/Cython/Shadow.pyi 2025-08-13 06:30:25.747922200 +0200 +++ new/cython-3.1.4/Cython/Shadow.pyi 2025-09-16 08:36:01.245351600 +0200 @@ -38,13 +38,13 @@ _func_deco: _Decorator -cfunc = ccall = compile = _func_deco +cfunc = ccall = compile = ufunc = _func_deco def locals(**kwargs: Any) -> _Decorator: ... def _class_deco(__cls: _TypeT) -> _TypeT: ... -cclass = internal = c_api_binop_methods = type_version_tag = no_gc_clear = no_gc = _class_deco +cclass = internal = c_api_binop_methods = type_version_tag = no_gc_clear = no_gc = total_ordering = _class_deco # May be a bit hard to read but essentially means: # > Returns a callable that takes another callable with these parameters and *some* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Utility/CommonStructures.c new/cython-3.1.4/Cython/Utility/CommonStructures.c --- old/cython-3.1.3/Cython/Utility/CommonStructures.c 2025-08-13 06:30:25.749922300 +0200 +++ new/cython-3.1.4/Cython/Utility/CommonStructures.c 2025-09-16 08:36:01.246351700 +0200 @@ -194,6 +194,7 @@ return -1; } mstate->__pyx_CommonTypesMetaclassType = __Pyx_FetchCommonTypeFromSpec(NULL, module, &__pyx_CommonTypesMetaclass_spec, bases); + Py_DECREF(bases); if (unlikely(mstate->__pyx_CommonTypesMetaclassType == NULL)) { return -1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Utility/ImportExport.c new/cython-3.1.4/Cython/Utility/ImportExport.c --- old/cython-3.1.3/Cython/Utility/ImportExport.c 2025-08-13 06:30:25.750922200 +0200 +++ new/cython-3.1.4/Cython/Utility/ImportExport.c 2025-09-16 08:36:01.248351600 +0200 @@ -472,6 +472,8 @@ /////////////// TypeImport /////////////// //@substitute: naming +// Note that this goes into headers so CYTHON_COMPILING_IN_LIMITED_API isn't available. + #ifndef __PYX_HAVE_RT_ImportType_$cyversion #define __PYX_HAVE_RT_ImportType_$cyversion static PyTypeObject *__Pyx_ImportType_$cyversion(PyObject *module, const char *module_name, const char *class_name, @@ -480,7 +482,7 @@ PyObject *result = 0; Py_ssize_t basicsize; Py_ssize_t itemsize; -#if CYTHON_COMPILING_IN_LIMITED_API +#ifdef Py_LIMITED_API PyObject *py_basicsize; PyObject *py_itemsize; #endif @@ -494,7 +496,7 @@ module_name, class_name); goto bad; } -#if !CYTHON_COMPILING_IN_LIMITED_API +#ifndef Py_LIMITED_API basicsize = ((PyTypeObject *)result)->tp_basicsize; itemsize = ((PyTypeObject *)result)->tp_itemsize; #else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Utility/ModuleSetupCode.c new/cython-3.1.4/Cython/Utility/ModuleSetupCode.c --- old/cython-3.1.3/Cython/Utility/ModuleSetupCode.c 2025-08-13 06:30:25.751922100 +0200 +++ new/cython-3.1.4/Cython/Utility/ModuleSetupCode.c 2025-09-16 08:36:01.248351600 +0200 @@ -2397,8 +2397,7 @@ // PyCode_NewEmpty isn't in the limited API. Therefore the two options are // 1. Python call of the code type with a long list of positional args. // 2. Generate a code object by compiling some trivial code, and customize. - // We use the second because it's less sensitive to changes in the code type - // constructor with version. + // We use the first option here. PyObject *exception_table = NULL; PyObject *types_module=NULL, *code_type=NULL, *result=NULL; #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 @@ -2479,6 +2478,11 @@ PyCode_NewWithPosOnlyArgs #endif (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, EMPTY(bytes)); + + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030c00A1 + if (likely(result)) + result->_co_firsttraceable = 0; + #endif return result; } #elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Utility/Optimize.c new/cython-3.1.4/Cython/Utility/Optimize.c --- old/cython-3.1.3/Cython/Utility/Optimize.c 2025-08-13 06:30:25.751922100 +0200 +++ new/cython-3.1.4/Cython/Utility/Optimize.c 2025-09-16 08:36:01.249351700 +0200 @@ -1237,6 +1237,20 @@ PY_LONG_LONG ll{{ival}}, llx; #endif {{endif}} + {{if op == 'Rshift' or op == 'Lshift'}} +// shifting negative numbers is technically implementation defined on C, and +// C++ before C++20. Most implementation do the right thing though so +// special case ones we know are good. +#if (defined(__cplusplus) && __cplusplus >= 202002L) \ + || (defined(__GNUC__) || (defined(__clang__))) && \ + (defined(__arm__) || defined(__x86_64__) || defined(__i386__)) \ + || (defined(_MSC_VER) && \ + (defined(_M_ARM) || defined(_M_AMD64) || defined(_M_IX86))) + const int negative_shift_works = 1; +#else + const int negative_shift_works = 0; +#endif + {{endif}} // special cases for 0: + - * % / // | ^ & >> << if (unlikely(__Pyx_PyLong_IsZero({{pyval}}))) { @@ -1348,6 +1362,15 @@ x = q; } {{else}} + + {{if op == 'Rshift' or op == 'Lshift'}} + if ((!negative_shift_works) && unlikely(a < 0)) goto fallback; + {{endif}} + {{if op == 'Rshift'}} + if (unlikely(b >= (long) (sizeof(long)*8))) { + x = (a < 0) ? -1 : 0; + } else + {{endif}} x = a {{c_op}} b; {{if op == 'Lshift'}} #ifdef HAVE_LONG_LONG @@ -1379,6 +1402,14 @@ llx = q; } {{else}} + {{if op == 'LShift' or op == 'Rshift'}} + if ((!negative_shift_works) && unlikely(a < 0)) goto fallback; + {{endif}} + {{if op == 'Rshift'}} + if (unlikely(llb >= (long long) (sizeof(long long)*8))) { + llx = (lla < 0) ? -1 : 0; + } else + {{endif}} llx = lla {{c_op}} llb; {{if op == 'Lshift'}} if (likely(lla == llx >> llb)) /* then execute 'return' below */ @@ -1386,6 +1417,9 @@ {{endif}} return PyLong_FromLongLong(llx); #endif +{{if op == 'Lshift' or op == 'Rshift'}} + fallback: +{{endif}} return __Pyx_Fallback_{{cfunc_name}}(op1, op2, inplace); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/Cython/Utility/Profile.c new/cython-3.1.4/Cython/Utility/Profile.c --- old/cython-3.1.3/Cython/Utility/Profile.c 2025-08-13 06:30:25.752922000 +0200 +++ new/cython-3.1.4/Cython/Utility/Profile.c 2025-09-16 08:36:01.249351700 +0200 @@ -157,18 +157,18 @@ if (!__Pyx_PyThreadState_Current->tracing) { \ if (likely($frame_code_cname)) Py_INCREF($frame_code_cname); \ else $frame_code_cname = (PyObject*) __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno); \ - if (unlikely(!$frame_code_cname)) goto_error; \ - ret = __Pyx__TraceStartFunc($monitoring_states_cname, $frame_code_cname, offset, skip_event); \ - } \ + if (unlikely(!$frame_code_cname)) ret = -1; \ + else ret = __Pyx__TraceStartFunc($monitoring_states_cname, $frame_code_cname, offset, skip_event); \ + } else $frame_code_cname = NULL; \ PyGILState_Release(state); \ - } \ + } else $frame_code_cname = NULL; \ } else { \ if (!__Pyx_PyThreadState_Current->tracing) { \ if (likely($frame_code_cname)) Py_INCREF($frame_code_cname); \ else $frame_code_cname = (PyObject*) __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno); \ - if (unlikely(!$frame_code_cname)) goto_error; \ - ret = __Pyx__TraceStartFunc($monitoring_states_cname, $frame_code_cname, offset, skip_event); \ - } \ + if (unlikely(!$frame_code_cname)) ret = -1; \ + else ret = __Pyx__TraceStartFunc($monitoring_states_cname, $frame_code_cname, offset, skip_event); \ + } else $frame_code_cname = NULL; \ } \ if (unlikely(ret == -1)) goto_error; \ } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/PKG-INFO new/cython-3.1.4/PKG-INFO --- old/cython-3.1.3/PKG-INFO 2025-08-13 06:30:35.559920800 +0200 +++ new/cython-3.1.4/PKG-INFO 2025-09-16 08:36:11.637525000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Cython -Version: 3.1.3 +Version: 3.1.4 Summary: The Cython compiler for writing C extensions in the Python language. Home-page: https://cython.org/ Author: Robert Bradshaw, Stefan Behnel, David Woods, Greg Ewing, et al. @@ -66,35 +66,42 @@ .. _Pyrex: https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/ -3.1.3 (2025-08-13) +3.1.4 (2025-09-16) ================== +Features added +-------------- + +* Declarations for the new ``PyUnstable_*()`` refcounting C-API functions in Py3.14 were added. + (Github issue https://github.com/cython/cython/issues/6836) + Bugs fixed ---------- -* Some method calls with 0 or 1 argument failed to use ``PyObject_VectorCallMethod()``. +* The monitoring code could crash on tracing. + (Github issue https://github.com/cython/cython/issues/7050) -* Walrus assignments of literal Python integers could generate invalid C code. - (Github issue https://github.com/cython/cython/issues/6989) +* Initialising the monitoring code could fail with a CPython exception. + See https://github.com/nedbat/coveragepy/issues/1790#issuecomment-3257410149 -* ``cython.pythread_type_lock`` (also used as fallback for ``cython.pymutex``) - could stall on heavily contended locks. - (Github issue https://github.com/cython/cython/issues/6999) +* Optimised integer shifting triggered undefined behaviour in C. + (Github issue https://github.com/cython/cython/issues/7089) -* C string arrays (not pointers) always coerced to the Python default string type, - even on explicit casts to other string types. - (Github issue https://github.com/cython/cython/issues/7020) +* Deallocating objects that inherit from external types defined in pxd files + could run into an infinite loop. + (Github issue https://github.com/cython/cython/issues/7143) -* Unterminated ``\N{}`` character escapes in strings could unrail the parser. - (Github issue https://github.com/cython/cython/issues/7056) +* A reference to metaclasses could be leaked on instantiation. + (Github issue https://github.com/cython/cython/issues/7130) -* An internal C function was not marked as ``static`` and leaked a linker symbol. - (Github issue https://github.com/cython/cython/issues/6957) +* (Unlikely) error handling during empty builtin container tests was ineffective. + (Github issue https://github.com/cython/cython/issues/7190) -* Some Unicode letters were not recognised as lexically valid name parts. - (Github issue https://github.com/cython/cython/issues/7059) +* Generated ``*_api.h`` files used potentially unknown Cython configuration macros. + (Github issue https://github.com/cython/cython/issues/7108) -* Compatibility with PyPy3.8 was lost by accident. +* ``cythonize()`` avoids parallel compiler runs on systems using ``spawn()`` in multiprocessing. + Patch by Marcel Bargull. (Github issue https://github.com/cython/cython/issues/3262) -* The Linux binary wheels of 3.1.2 used SSSE3 CPU instructions which are not available on some CPUs. - (Github issue https://github.com/cython/cython/issues/7038) +* The ``@cython.ufunc`` decorator was missing in type checker stubs. + Patch by jayClean. (Github issue https://github.com/cython/cython/issues/7109) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/docs/examples/tutorial/embedding/embedded_main.c new/cython-3.1.4/docs/examples/tutorial/embedding/embedded_main.c --- old/cython-3.1.3/docs/examples/tutorial/embedding/embedded_main.c 2025-08-13 06:30:25.761922100 +0200 +++ new/cython-3.1.4/docs/examples/tutorial/embedding/embedded_main.c 2025-09-16 08:36:01.259351700 +0200 @@ -32,9 +32,8 @@ If this step fails, it will be a fatal error. */ Py_Initialize(); - /* Optionally import the module; alternatively, - import can be deferred until the embedded script - imports it. */ + /* You must import the module before calling any + function in the module. */ pmodule = PyImport_ImportModule("embedded"); if (!pmodule) { PyErr_Print(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/docs/src/userguide/limited_api.rst new/cython-3.1.4/docs/src/userguide/limited_api.rst --- old/cython-3.1.3/docs/src/userguide/limited_api.rst 2025-08-13 06:30:25.778922000 +0200 +++ new/cython-3.1.4/docs/src/userguide/limited_api.rst 2025-09-16 08:36:01.275352000 +0200 @@ -75,7 +75,7 @@ when running the C compiler. This macro should be set to the version-hex for the minimum Python version that you want to support. Useful version-hexes are: -* ``0x03070000`` - Python 3.7 - the minimum version that Cython supports. +* ``0x03080000`` - Python 3.8 - the minimum version that Cython supports. * ``0x030B0000`` - Python 3.11 - the first version to support typed memoryviews. * ``0x030C0000`` - Python 3.12 - the first version to support vectorcall (performance improvement). @@ -102,7 +102,7 @@ name="cy_code", sources=["cy_code.pyx"], define_macros=[ - ("Py_LIMITED_API", 0x03070000), + ("Py_LIMITED_API", 0x030A0000), ], py_limited_api=True ), @@ -126,7 +126,7 @@ add_library(cy_code MODULE ${cy_code}) python_extension_module(cy_code) - target_compile_definitions(cy_code PUBLIC -DPy_LIMITED_API=0x03070000) + target_compile_definitions(cy_code PUBLIC -DPy_LIMITED_API=0x030A0000) set_target_properties(cy_code PROPERTIES SUFFIX .abi3.so) install(TARGETS cy_code LIBRARY DESTINATION .) @@ -155,10 +155,10 @@ py.extension_module( 'cy_code', 'cy_code.pyx', - limited_api: '3.7' + limited_api: '3.10' ) Again, this example is adapted from `the Meson documentation <https://mesonbuild.com/Cython.html#cython>`_ and more complete -details are available there. The Limited API modification is the argument ``limited_api: '3.7'``, +details are available there. The Limited API modification is the argument ``limited_api: '3.10'``, which both sets the version hex and names the generated module correctly. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/tests/limited_api_bugs.txt new/cython-3.1.4/tests/limited_api_bugs.txt --- old/cython-3.1.3/tests/limited_api_bugs.txt 2025-08-13 06:30:25.801922000 +0200 +++ new/cython-3.1.4/tests/limited_api_bugs.txt 2025-09-16 08:36:01.298352200 +0200 @@ -30,7 +30,8 @@ datetime_cimport datetime_pxd datetime_members -run[.]exttype +run[.]exttype$ +run[.]exttype_gc$ isinstance pycontextvar run[.]pytype diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/tests/run/api_class.srctree new/cython-3.1.4/tests/run/api_class.srctree --- old/cython-3.1.3/tests/run/api_class.srctree 1970-01-01 01:00:00.000000000 +0100 +++ new/cython-3.1.4/tests/run/api_class.srctree 2025-09-16 08:36:01.301352300 +0200 @@ -0,0 +1,55 @@ +PYTHON setup.py build_ext --inplace +PYTHON -c "import useapi; useapi.make_testclass()" + +################# setup.py ###################### + +# The tests in this file are mainly about ensuring that the +# correct utility code is included when needed. +# Therefore, future additions should add new files rather than +# new code in the existing files. + +from setuptools import setup, Extension +from Cython.Build import cythonize + +ext_modules = ( + cythonize("mainmodule.pyx") + + cythonize(Extension("useapi", sources=["useapi.pyx", "use_api_c.c"])) +) + +import sys +print(ext_modules, file=sys.stderr) + +setup(ext_modules=ext_modules) + +################ mainmodule.pyx ################# + +ctypedef api class TestClass [type Test_Type, object TestObject]: + cdef int attr + +############## use_api_c.c ################ + +// This is making sure that mainmodule_api is functional +// when used outside Cython (and with/without the Limited API +// depending on how the tests are run). + +#include "mainmodule_api.h" + +PyObject *make_testclass_c(void) { + if (import_mainmodule() == -1) return NULL; + PyObject *tpl = PyTuple_New(0); + if (!tpl) return NULL; + PyObject *result = PyObject_Call((PyObject*)&Test_Type, tpl, NULL); + Py_DECREF(tpl); + return result; +} + +############## useapi.pyx ####################### + +cdef extern from *: + """ + PyObject *make_testclass_c(void); + """ + object make_testclass_c() + +def make_testclass(): + return make_testclass_c() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/tests/run/exttype_dealloc_pxd.srctree new/cython-3.1.4/tests/run/exttype_dealloc_pxd.srctree --- old/cython-3.1.3/tests/run/exttype_dealloc_pxd.srctree 1970-01-01 01:00:00.000000000 +0100 +++ new/cython-3.1.4/tests/run/exttype_dealloc_pxd.srctree 2025-09-16 08:36:01.320352600 +0200 @@ -0,0 +1,53 @@ +PYTHON setup.py build_ext --inplace +PYTHON -c "import b; b.run()" + +######## setup.py ######## + +from Cython.Build.Dependencies import cythonize +from setuptools import setup + +setup( + ext_modules = cythonize("*.pyx"), +) + +####### a.pxd ######## + +cdef class BaseClass: + pass + +####### a.pyx ######## + +BaseClass_dealloc_calls = 0 + +cdef class BaseClass: + def __dealloc__(self): + global BaseClass_dealloc_calls + BaseClass_dealloc_calls += 1 + +####### b.pyx ######### + +import sys + +cimport a +import a + +cdef class InheritsFromPxd(a.BaseClass): + pass # no dealloc + +derived_class_dealloc_calls = 0 + +cdef class InheritsFromInheritsFromPxd(InheritsFromPxd): + def __dealloc__(self): + global derived_class_dealloc_calls + derived_class_dealloc_calls += 1 + +def run(): + # This is mostly a "no-crash" test, but we do some validation + # (on CPython only, because this won't be reliable with a GC) + x = a.BaseClass() + x = InheritsFromPxd() + x = InheritsFromInheritsFromPxd() + del x + if sys.implementation.name == "cpython": + assert a.BaseClass_dealloc_calls == 3 + assert derived_class_dealloc_calls == 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/tests/run/pyintop.pyx new/cython-3.1.4/tests/run/pyintop.pyx --- old/cython-3.1.3/tests/run/pyintop.pyx 2025-08-13 06:30:25.837922000 +0200 +++ new/cython-3.1.4/tests/run/pyintop.pyx 2025-09-16 08:36:01.333352800 +0200 @@ -3,6 +3,8 @@ cimport cython +from operator import lshift as py_lshift, rshift as py_rshift + def bigint(x): # avoid 'L' postfix in Py2.x @@ -184,6 +186,11 @@ 144115188075855872 >>> bigint(rshift_int(-2**60)) -144115188075855872 + + >>> rshift_int(-1) + -1 + >>> (-1) >> 3 + -1 """ obj1 = obj2 >> 3 return obj1 @@ -703,3 +710,232 @@ """ res = obj2 / 2 return res + + +def negative_rhs_lshift(obj: int): + """ + >>> negative_rhs_lshift(5) + Traceback (most recent call last): + ... + ValueError: negative shift count + """ + return (obj << (-1)) + +def negative_rhs_rshift(obj: int): + """ + >>> negative_rhs_rshift(5) + Traceback (most recent call last): + ... + ValueError: negative shift count + """ + return (obj >> (-1)) + + +def big_lshift(obj): + """ + >>> big_lshift(1) + 1180591620717411303424 + >>> big_lshift(-1) + -1180591620717411303424 + """ + return obj << 70 + +def somewhat_big_lshift(obj): + """ + Note that on MSVC this is bigger than a long + + >>> somewhat_big_lshift(1) + (1099511627776, 4294967296) + >>> somewhat_big_lshift(-1) + (-1099511627776, -4294967296) + """ + return obj << 40, obj << 32 + +def big_rshift(obj): + """ + >>> big_rshift(1) + 0 + >>> big_rshift(-1) + -1 + >>> big_rshift(2**80) + 1024 + >>> big_rshift(-(2**80)) + -1024 + """ + return obj >> 70 + +def somewhat_big_rshift(obj): + """ + Note that on MSVC this is bigger than a long + + >>> somewhat_big_rshift(1) + (0, 0) + >>> somewhat_big_rshift(-1) + (-1, -1) + >>> somewhat_big_rshift(0x6f) + (0, 0) + >>> somewhat_big_rshift(-0x6f) + (-1, -1) + >>> somewhat_big_rshift(2**50) + (1024, 262144) + >>> somewhat_big_rshift(-(2**50)) + (-1024, -262144) + """ + return obj >> 40, obj >> 32 + +cdef compare_lshift(obj, shift, cython_result): + py_result = py_lshift(obj, shift) + assert cython_result == py_result, f"{obj} << {shift} == {cython_result} != {py_result}" + +cdef compare_rshift(obj, shift, cython_result): + py_result = py_rshift(obj, shift) + assert cython_result == py_result, f"{obj} >> {shift} == {cython_result} != {py_result}" + +cdef compare_both_shifts(obj, shift, cython_lresult, cython_rresult): + compare_lshift(obj, shift, cython_lresult) + compare_rshift(obj, shift, cython_rresult) + +def integer_shifts(obj): + """ + >>> integer_shifts(0) + >>> integer_shifts(1) + >>> integer_shifts(-1) + >>> integer_shifts(0xff) + >>> integer_shifts(-0xff) + >>> integer_shifts(0xff00) + >>> integer_shifts(-0xff00) + >>> integer_shifts(0xff0000) + >>> integer_shifts(-0xff0000) + >>> integer_shifts(0xff000000) + >>> integer_shifts(-0xff000000) + """ + compare_both_shifts(obj, 0, obj << 0, obj >> 0) + compare_both_shifts(obj, 1, obj << 1, obj >> 1) + compare_both_shifts(obj, 2, obj << 2, obj >> 2) + compare_both_shifts(obj, 3, obj << 3, obj >> 3) + compare_both_shifts(obj, 4, obj << 4, obj >> 4) + compare_both_shifts(obj, 5, obj << 5, obj >> 5) + compare_both_shifts(obj, 6, obj << 6, obj >> 6) + compare_both_shifts(obj, 7, obj << 7, obj >> 7) + compare_both_shifts(obj, 8, obj << 8, obj >> 8) + compare_both_shifts(obj, 9, obj << 9, obj >> 9) + compare_both_shifts(obj, 10, obj << 10, obj >> 10) + compare_both_shifts(obj, 11, obj << 11, obj >> 11) + compare_both_shifts(obj, 12, obj << 12, obj >> 12) + compare_both_shifts(obj, 13, obj << 13, obj >> 13) + compare_both_shifts(obj, 14, obj << 14, obj >> 14) + compare_both_shifts(obj, 15, obj << 15, obj >> 15) + compare_both_shifts(obj, 16, obj << 16, obj >> 16) + compare_both_shifts(obj, 17, obj << 17, obj >> 17) + compare_both_shifts(obj, 18, obj << 18, obj >> 18) + compare_both_shifts(obj, 19, obj << 19, obj >> 19) + compare_both_shifts(obj, 20, obj << 20, obj >> 20) + compare_both_shifts(obj, 21, obj << 21, obj >> 21) + compare_both_shifts(obj, 22, obj << 22, obj >> 22) + compare_both_shifts(obj, 23, obj << 23, obj >> 23) + compare_both_shifts(obj, 24, obj << 24, obj >> 24) + compare_both_shifts(obj, 25, obj << 25, obj >> 25) + compare_both_shifts(obj, 26, obj << 26, obj >> 26) + compare_both_shifts(obj, 27, obj << 27, obj >> 27) + compare_both_shifts(obj, 28, obj << 28, obj >> 28) + compare_both_shifts(obj, 29, obj << 29, obj >> 29) + compare_both_shifts(obj, 30, obj << 30, obj >> 30) + compare_both_shifts(obj, 31, obj << 31, obj >> 31) + compare_both_shifts(obj, 32, obj << 32, obj >> 32) + compare_both_shifts(obj, 33, obj << 33, obj >> 33) + compare_both_shifts(obj, 34, obj << 34, obj >> 34) + compare_both_shifts(obj, 35, obj << 35, obj >> 35) + compare_both_shifts(obj, 36, obj << 36, obj >> 36) + compare_both_shifts(obj, 37, obj << 37, obj >> 37) + compare_both_shifts(obj, 38, obj << 38, obj >> 38) + compare_both_shifts(obj, 39, obj << 39, obj >> 39) + compare_both_shifts(obj, 40, obj << 40, obj >> 40) + compare_both_shifts(obj, 41, obj << 41, obj >> 41) + compare_both_shifts(obj, 42, obj << 42, obj >> 42) + compare_both_shifts(obj, 43, obj << 43, obj >> 43) + compare_both_shifts(obj, 44, obj << 44, obj >> 44) + compare_both_shifts(obj, 45, obj << 45, obj >> 45) + compare_both_shifts(obj, 46, obj << 46, obj >> 46) + compare_both_shifts(obj, 47, obj << 47, obj >> 47) + compare_both_shifts(obj, 48, obj << 48, obj >> 48) + compare_both_shifts(obj, 49, obj << 49, obj >> 49) + compare_both_shifts(obj, 50, obj << 50, obj >> 50) + compare_both_shifts(obj, 51, obj << 51, obj >> 51) + compare_both_shifts(obj, 52, obj << 52, obj >> 52) + compare_both_shifts(obj, 53, obj << 53, obj >> 53) + compare_both_shifts(obj, 54, obj << 54, obj >> 54) + compare_both_shifts(obj, 55, obj << 55, obj >> 55) + compare_both_shifts(obj, 56, obj << 56, obj >> 56) + compare_both_shifts(obj, 57, obj << 57, obj >> 57) + compare_both_shifts(obj, 58, obj << 58, obj >> 58) + compare_both_shifts(obj, 59, obj << 59, obj >> 59) + compare_both_shifts(obj, 60, obj << 60, obj >> 60) + compare_both_shifts(obj, 61, obj << 61, obj >> 61) + compare_both_shifts(obj, 62, obj << 62, obj >> 62) + compare_both_shifts(obj, 63, obj << 63, obj >> 63) + compare_both_shifts(obj, 64, obj << 64, obj >> 64) + compare_both_shifts(obj, 65, obj << 65, obj >> 65) + compare_both_shifts(obj, 66, obj << 66, obj >> 66) + compare_both_shifts(obj, 67, obj << 67, obj >> 67) + compare_both_shifts(obj, 68, obj << 68, obj >> 68) + compare_both_shifts(obj, 69, obj << 69, obj >> 69) + compare_both_shifts(obj, 70, obj << 70, obj >> 70) + compare_both_shifts(obj, 71, obj << 71, obj >> 71) + compare_both_shifts(obj, 72, obj << 72, obj >> 72) + compare_both_shifts(obj, 73, obj << 73, obj >> 73) + compare_both_shifts(obj, 74, obj << 74, obj >> 74) + compare_both_shifts(obj, 75, obj << 75, obj >> 75) + compare_both_shifts(obj, 76, obj << 76, obj >> 76) + compare_both_shifts(obj, 77, obj << 77, obj >> 77) + compare_both_shifts(obj, 78, obj << 78, obj >> 78) + compare_both_shifts(obj, 79, obj << 79, obj >> 79) + compare_both_shifts(obj, 80, obj << 80, obj >> 80) + compare_both_shifts(obj, 81, obj << 81, obj >> 81) + compare_both_shifts(obj, 82, obj << 82, obj >> 82) + compare_both_shifts(obj, 83, obj << 83, obj >> 83) + compare_both_shifts(obj, 84, obj << 84, obj >> 84) + compare_both_shifts(obj, 85, obj << 85, obj >> 85) + compare_both_shifts(obj, 86, obj << 86, obj >> 86) + compare_both_shifts(obj, 87, obj << 87, obj >> 87) + compare_both_shifts(obj, 88, obj << 88, obj >> 88) + compare_both_shifts(obj, 89, obj << 89, obj >> 89) + compare_both_shifts(obj, 90, obj << 90, obj >> 90) + compare_both_shifts(obj, 91, obj << 91, obj >> 91) + compare_both_shifts(obj, 92, obj << 92, obj >> 92) + compare_both_shifts(obj, 93, obj << 93, obj >> 93) + compare_both_shifts(obj, 94, obj << 94, obj >> 94) + compare_both_shifts(obj, 95, obj << 95, obj >> 95) + compare_both_shifts(obj, 96, obj << 96, obj >> 96) + compare_both_shifts(obj, 97, obj << 97, obj >> 97) + compare_both_shifts(obj, 98, obj << 98, obj >> 98) + compare_both_shifts(obj, 99, obj << 99, obj >> 99) + compare_both_shifts(obj, 100, obj << 100, obj >> 100) + compare_both_shifts(obj, 101, obj << 101, obj >> 101) + compare_both_shifts(obj, 102, obj << 102, obj >> 102) + compare_both_shifts(obj, 103, obj << 103, obj >> 103) + compare_both_shifts(obj, 104, obj << 104, obj >> 104) + compare_both_shifts(obj, 105, obj << 105, obj >> 105) + compare_both_shifts(obj, 106, obj << 106, obj >> 106) + compare_both_shifts(obj, 107, obj << 107, obj >> 107) + compare_both_shifts(obj, 108, obj << 108, obj >> 108) + compare_both_shifts(obj, 109, obj << 109, obj >> 109) + compare_both_shifts(obj, 110, obj << 110, obj >> 110) + compare_both_shifts(obj, 111, obj << 111, obj >> 111) + compare_both_shifts(obj, 112, obj << 112, obj >> 112) + compare_both_shifts(obj, 113, obj << 113, obj >> 113) + compare_both_shifts(obj, 114, obj << 114, obj >> 114) + compare_both_shifts(obj, 115, obj << 115, obj >> 115) + compare_both_shifts(obj, 116, obj << 116, obj >> 116) + compare_both_shifts(obj, 117, obj << 117, obj >> 117) + compare_both_shifts(obj, 118, obj << 118, obj >> 118) + compare_both_shifts(obj, 119, obj << 119, obj >> 119) + compare_both_shifts(obj, 120, obj << 120, obj >> 120) + compare_both_shifts(obj, 121, obj << 121, obj >> 121) + compare_both_shifts(obj, 122, obj << 122, obj >> 122) + compare_both_shifts(obj, 123, obj << 123, obj >> 123) + compare_both_shifts(obj, 124, obj << 124, obj >> 124) + compare_both_shifts(obj, 125, obj << 125, obj >> 125) + compare_both_shifts(obj, 126, obj << 126, obj >> 126) + compare_both_shifts(obj, 127, obj << 127, obj >> 127) + compare_both_shifts(obj, 128, obj << 128, obj >> 128) + compare_both_shifts(obj, 129, obj << 129, obj >> 129) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cython-3.1.3/tests/run/sys_monitoring.py new/cython-3.1.4/tests/run/sys_monitoring.py --- old/cython-3.1.3/tests/run/sys_monitoring.py 2025-08-13 06:30:25.842922200 +0200 +++ new/cython-3.1.4/tests/run/sys_monitoring.py 2025-09-16 08:36:01.338353000 +0200 @@ -363,6 +363,9 @@ >>> smon.free_tool_id(TOOL_ID) + + >>> count_event_inner.__code__ # doctest: +ELLIPSIS + <code object count_event_inner ...> """ @@ -395,6 +398,16 @@ collected_events = {name: dict(values) for name, values in collected_events.items()} [email protected](True) [email protected](True) +def count_event_inner(): + # count_event_inner is deliberately called inside a monitoring event handler + # with profile and linetrace on. It shouldn't appear in any traces (because + # it should know that it's inside an event handler) and it also shouldn't + # cause any crashes. Other than that, it does nothing. + pass + + @contextmanager @cython.profile(False) @cython.linetrace(False) @@ -420,6 +433,7 @@ collected_line_events[offset] += 1 assert offset in (line for line, *_ in code_obj.co_positions()), f"{code_obj.co_name}: {offset} in {list(code_obj.co_positions())}" collected_events[code_obj.co_name][event][offset] += 1 + count_event_inner() try: for event in events:
