pypi / cython
cython
What changed in cython 3, from its official release notes, upgrade guides and advisories. Sources checked 2026-11-13.
2 breaking1 security6 new APIs and options5 performance11 behavior and defaults1 tooling12 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initcython 338 changes
Breaking changes 2
Unpickling object pickle data with instance dict state into an object that has no __dict__ is now an error.
Instantiating internal types used by Cython is now prohibited.
Security 1
Expressions use a slightly safer scheme when unpacking Python integers.
New APIs and options 6
Declarations for C++ condition variables were added.
The new --embed-modules option lists extension modules to statically link into the generated extension module so they are initialised on application start.
The C macro configures whether some object constants are marked immortal to speed reference counting in recent CPython versions.
Some GIL-safe C-API wrappers were added to the libc and libcpp declarations.
Cython's setup.py now accepts the desired Limited API version through --cython-limited-api.
T-strings are implemented according to PEP-750, backporting the template classes while preferring separately installed backports.
Performance 5
bool(c_int), bool(c_float) and bool(c_ptr) avoid passing through Python objects.
Runtime Python dispatch for fused functions is substantially faster.
Looping over literal sequences and strings now uses efficient C array looping when possible.
Imports quickly check whether a module is already imported, speeding up reimports.
Type checks on union types such as int | None are optimised into separate checks.
Behavior and default changes 11
Some lesser-used platforms now use Python 3.9 abi3 wheels instead of Python-version-specific wheels; an abi3 wheel was also added for armv7l.
Builtin exception types are now inferred.
Mixed operations use less code and are more streamlined for Python 3.12 and later.
F-string syntax was extended according to PEP-701.
Assignments accept any suitable Python number and automatically convert it to a Python float.
Freelists are now used with the Limited API and extension type specs, including freelists declared with a cdef class decorator and internally used types.
NaN is now supported as an exception return value.
Variables assigned inside prange loops can now be initialised outside the loop.
The known, inferred and optimised builtin list changed: range is now considered a type, and ascii, bin, format, hex and oct are added as functions.
Unknown return type annotations using -> now produce warnings instead of being rejected; -> None is also allowed.
Unicode 16.0.0 is now used to parse identifiers.
Tooling 1
Cython tools and frontend scripts now use python3 instead of python in their shebang line.
Fixes and other changes 12
Fixed cases where indexing bytes failed to optimise.
cython.critical_section now works with PyMutex, as it already did with Python objects.
Extension arguments defined for the shared code module are no longer ignored.
Fixed embedsignatures failing when lambda was used in function default arguments.
Several improvements were made in freethreaded Python code.
Several improvements were made for the Limited API.
Fixed a crash when iterating over temporary memoryviews.
Fixed an incorrect call to PyList_GetItemRef in PyPy and GraalPython before Python 3.13.
Value conversion errors no longer fail tracing C return statements; tracing falls back to reporting None returns.
Conversion now validates the length of C++ strings longer than PY_SSIZE_T_MAX.
Generated header files no longer use some non-Limited API code.
Empty return statements are now reported consistently when tracing.