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:

Reply via email to