# What changed in cython

> 38 changes in cython 3 from its official release notes, upgrade guides and advisories: 2 breaking, 1 security, 6 new APIs and options. Each one cited. Sources checked 2026-11-13. HTML: https://unstale.sh/pypi/cython/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## cython 3

### Breaking changes

- Unpickling object pickle data with instance dict state into an object that has no __dict__ is now an error. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Instantiating internal types used by Cython is now prohibited. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)

### Security

- Expressions use a slightly safer scheme when unpacking Python integers. (3.1.5) — [release notes](https://github.com/cython/cython/releases/tag/3.1.5)

### New APIs and options

- Declarations for C++ condition variables were added. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- The new --embed-modules option lists extension modules to statically link into the generated extension module so they are initialised on application start. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- The C macro configures whether some object constants are marked immortal to speed reference counting in recent CPython versions. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Some GIL-safe C-API wrappers were added to the libc and libcpp declarations. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Cython's setup.py now accepts the desired Limited API version through --cython-limited-api. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- T-strings are implemented according to PEP-750, backporting the template classes while preferring separately installed backports. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)

### Performance

- bool(c_int), bool(c_float) and bool(c_ptr) avoid passing through Python objects. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Runtime Python dispatch for fused functions is substantially faster. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Looping over literal sequences and strings now uses efficient C array looping when possible. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Imports quickly check whether a module is already imported, speeding up reimports. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Type checks on union types such as int | None are optimised into separate checks. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)

### Behavior and default changes

- 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. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Builtin exception types are now inferred. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Mixed operations use less code and are more streamlined for Python 3.12 and later. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- F-string syntax was extended according to PEP-701. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Assignments accept any suitable Python number and automatically convert it to a Python float. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Freelists are now used with the Limited API and extension type specs, including freelists declared with a cdef class decorator and internally used types. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- NaN is now supported as an exception return value. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Variables assigned inside prange loops can now be initialised outside the loop. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- 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. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Unknown return type annotations using -> now produce warnings instead of being rejected; -> None is also allowed. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Unicode 16.0.0 is now used to parse identifiers. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)

### Tooling

- Cython tools and frontend scripts now use python3 instead of python in their shebang line. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)

### Fixes and other changes

- Fixed cases where indexing bytes failed to optimise. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- cython.critical_section now works with PyMutex, as it already did with Python objects. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Extension arguments defined for the shared code module are no longer ignored. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Fixed embedsignatures failing when lambda was used in function default arguments. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Several improvements were made in freethreaded Python code. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Several improvements were made for the Limited API. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Fixed a crash when iterating over temporary memoryviews. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Fixed an incorrect call to PyList_GetItemRef in PyPy and GraalPython before Python 3.13. (3.2.0) — [release notes](https://github.com/cython/cython/releases/tag/3.2.0)
- Value conversion errors no longer fail tracing C return statements; tracing falls back to reporting None returns. (3.1.5) — [release notes](https://github.com/cython/cython/releases/tag/3.1.5)
- Conversion now validates the length of C++ strings longer than PY_SSIZE_T_MAX. (3.1.5) — [release notes](https://github.com/cython/cython/releases/tag/3.1.5)
- Generated header files no longer use some non-Limited API code. (3.1.5) — [release notes](https://github.com/cython/cython/releases/tag/3.1.5)
- Empty return statements are now reported consistently when tracing. (3.1.5) — [release notes](https://github.com/cython/cython/releases/tag/3.1.5)
