release: 0.20.0

This commit is contained in:
David Hewitt 2023-10-11 08:05:02 +01:00
parent b03c4cb33c
commit c77deee18e
64 changed files with 87 additions and 71 deletions

View File

@ -10,6 +10,72 @@ To see unreleased changes, please see the [CHANGELOG on the main branch guide](h
<!-- towncrier release notes start --> <!-- towncrier release notes start -->
## [0.20.0] - 2023-10-11
### Packaging
- Dual-license PyO3 under either the Apache 2.0 OR the MIT license. This makes the project GPLv2 compatible. [#3108](https://github.com/PyO3/pyo3/pull/3108)
- Update MSRV to Rust 1.56. [#3208](https://github.com/PyO3/pyo3/pull/3208)
- Bump `indoc` dependency to 2.0 and `unindent` dependency to 0.2. [#3237](https://github.com/PyO3/pyo3/pull/3237)
- Bump `syn` dependency to 2.0. [#3239](https://github.com/PyO3/pyo3/pull/3239)
- Drop support for debug builds of Python 3.7. [#3387](https://github.com/PyO3/pyo3/pull/3387)
- Bump `chrono` optional dependency to require 0.4.25 or newer. [#3427](https://github.com/PyO3/pyo3/pull/3427)
- Support Python 3.12. [#3488](https://github.com/PyO3/pyo3/pull/3488)
### Added
- Support `__lt__`, `__le__`, `__eq__`, `__ne__`, `__gt__` and `__ge__` in `#[pymethods]`. [#3203](https://github.com/PyO3/pyo3/pull/3203)
- Add FFI definition `Py_GETENV`. [#3336](https://github.com/PyO3/pyo3/pull/3336)
- Add `as_ptr` and `into_ptr` inherent methods for `Py`, `PyAny`, `PyRef`, and `PyRefMut`. [#3359](https://github.com/PyO3/pyo3/pull/3359)
- Implement `DoubleEndedIterator` for `PyTupleIterator` and `PyListIterator`. [#3366](https://github.com/PyO3/pyo3/pull/3366)
- Add `#[pyclass(rename_all = "...")]` option: this allows renaming all getters and setters of a struct, or all variants of an enum. Available renaming rules are: `"camelCase"`, `"kebab-case"`, `"lowercase"`, `"PascalCase"`, `"SCREAMING-KEBAB-CASE"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"UPPERCASE"`. [#3384](https://github.com/PyO3/pyo3/pull/3384)
- Add FFI definitions `PyObject_GC_IsTracked` and `PyObject_GC_IsFinalized` on Python 3.9 and up (PyPy 3.10 and up). [#3403](https://github.com/PyO3/pyo3/pull/3403)
- Add types for `None`, `Ellipsis`, and `NotImplemented`. [#3408](https://github.com/PyO3/pyo3/pull/3408)
- Add FFI definitions for the `Py_mod_multiple_interpreters` constant and its possible values. [#3494](https://github.com/PyO3/pyo3/pull/3494)
- Add FFI definitions for `PyInterpreterConfig` struct, its constants and `Py_NewInterpreterFromConfig`. [#3502](https://github.com/PyO3/pyo3/pull/3502)
### Changed
- Change `PySet::discard` to return `PyResult<bool>` (previously returned nothing). [#3281](https://github.com/PyO3/pyo3/pull/3281)
- Optimize implmentation of `IntoPy` for Rust tuples to Python tuples. [#3321](https://github.com/PyO3/pyo3/pull/3321)
- Change `PyDict::get_item` to no longer suppress arbitrary exceptions (the return type is now `PyResult<Option<&PyAny>>` instead of `Option<&PyAny>`), and deprecate `PyDict::get_item_with_error`. [#3330](https://github.com/PyO3/pyo3/pull/3330)
- Deprecate FFI definitions which are deprecated in Python 3.12. [#3336](https://github.com/PyO3/pyo3/pull/3336)
- `AsPyPointer` is now an `unsafe trait`. [#3358](https://github.com/PyO3/pyo3/pull/3358)
- Accept all `os.PathLike` values in implementation of `FromPyObject` for `PathBuf`. [#3374](https://github.com/PyO3/pyo3/pull/3374)
- Add `__builtins__` to globals in `py.run()` and `py.eval()` if they're missing. [#3378](https://github.com/PyO3/pyo3/pull/3378)
- Optimize implementation of `FromPyObject` for `BigInt` and `BigUint`. [#3379](https://github.com/PyO3/pyo3/pull/3379)
- `PyIterator::from_object` and `PyByteArray::from` now take a single argument of type `&PyAny` (previously took two arguments `Python` and `AsPyPointer`). [#3389](https://github.com/PyO3/pyo3/pull/3389)
- Replace `AsPyPointer` with `AsRef<PyAny>` as a bound in the blanket implementation of `From<&T> for PyObject`. [#3391](https://github.com/PyO3/pyo3/pull/3391)
- Replace blanket `impl IntoPy<PyObject> for &T where T: AsPyPointer` with implementations of `impl IntoPy<PyObject>` for `&PyAny`, `&T where T: AsRef<PyAny>`, and `&Py<T>`. [#3393](https://github.com/PyO3/pyo3/pull/3393)
- Preserve `std::io::Error` kind in implementation of `From<std::io::IntoInnerError>` for `PyErr` [#3396](https://github.com/PyO3/pyo3/pull/3396)
- Try to select a relevant `ErrorKind` in implementation of `From<PyErr>` for `OSError` subclass. [#3397](https://github.com/PyO3/pyo3/pull/3397)
- Retrieve the original `PyErr` in implementation of `From<std::io::Error>` for `PyErr` if the `std::io::Error` has been built using a Python exception (previously would create a new exception wrapping the `std::io::Error`). [#3402](https://github.com/PyO3/pyo3/pull/3402)
- `#[pymodule]` will now return the same module object on repeated import by the same Python interpreter, on Python 3.9 and up. [#3446](https://github.com/PyO3/pyo3/pull/3446)
- Truncate leap-seconds and warn when converting `chrono` types to Python `datetime` types (`datetime` cannot represent leap-seconds). [#3458](https://github.com/PyO3/pyo3/pull/3458)
- `Err` returned from `#[pyfunction]` will now have a non-None `__context__` if called from inside a `catch` block. [#3455](https://github.com/PyO3/pyo3/pull/3455)
- Deprecate undocumented `#[__new__]` form of `#[new]` attribute. [#3505](https://github.com/PyO3/pyo3/pull/3505)
### Removed
- Remove all functionality deprecated in PyO3 0.18, including `#[args]` attribute for `#[pymethods]`. [#3232](https://github.com/PyO3/pyo3/pull/3232)
- Remove `IntoPyPointer` trait in favour of `into_ptr` inherent methods. [#3385](https://github.com/PyO3/pyo3/pull/3385)
### Fixed
- Handle exceptions properly in `PySet::discard`. [#3281](https://github.com/PyO3/pyo3/pull/3281)
- The `PyTupleIterator` type returned by `PyTuple::iter` is now public and hence can be named by downstream crates. [#3366](https://github.com/PyO3/pyo3/pull/3366)
- Linking of `PyOS_FSPath` on PyPy. [#3374](https://github.com/PyO3/pyo3/pull/3374)
- Fix memory leak in `PyTypeBuilder::build`. [#3401](https://github.com/PyO3/pyo3/pull/3401)
- Disable removed FFI definitions `_Py_GetAllocatedBlocks`, `_PyObject_GC_Malloc`, and `_PyObject_GC_Calloc` on Python 3.11 and up. [#3403](https://github.com/PyO3/pyo3/pull/3403)
- Fix `ResourceWarning` and crashes related to GC when running with debug builds of CPython. [#3404](https://github.com/PyO3/pyo3/pull/3404)
- Some-wrapping of `Option<T>` default arguments will no longer re-wrap `Some(T)` or expressions evaluating to `None`. [#3461](https://github.com/PyO3/pyo3/pull/3461)
- Fix `IterNextOutput::Return` not returning a value on PyPy. [#3471](https://github.com/PyO3/pyo3/pull/3471)
- Emit compile errors instead of ignoring macro invocations inside `#[pymethods]` blocks. [#3491](https://github.com/PyO3/pyo3/pull/3491)
- Emit error on invalid arguments to `#[new]`, `#[classmethod]`, `#[staticmethod]`, and `#[classattr]`. [#3484](https://github.com/PyO3/pyo3/pull/3484)
- Disable `PyMarshal_WriteObjectToString` from `PyMarshal_ReadObjectFromString` with the `abi3` feature. [#3490](https://github.com/PyO3/pyo3/pull/3490)
- Fix FFI definitions for `_PyFrameEvalFunction` on Python 3.11 and up (it now receives a `_PyInterpreterFrame` opaque struct). [#3500](https://github.com/PyO3/pyo3/pull/3500)
## [0.19.2] - 2023-08-01 ## [0.19.2] - 2023-08-01
### Added ### Added
@ -1533,7 +1599,8 @@ Yanked
- Initial release - Initial release
[Unreleased]: https://github.com/pyo3/pyo3/compare/v0.19.2...HEAD [Unreleased]: https://github.com/pyo3/pyo3/compare/v0.20.0...HEAD
[0.20.0]: https://github.com/pyo3/pyo3/compare/v0.19.2...v0.20.0
[0.19.2]: https://github.com/pyo3/pyo3/compare/v0.19.1...v0.19.2 [0.19.2]: https://github.com/pyo3/pyo3/compare/v0.19.1...v0.19.2
[0.19.1]: https://github.com/pyo3/pyo3/compare/v0.19.0...v0.19.1 [0.19.1]: https://github.com/pyo3/pyo3/compare/v0.19.0...v0.19.1
[0.19.0]: https://github.com/pyo3/pyo3/compare/v0.18.3...v0.19.0 [0.19.0]: https://github.com/pyo3/pyo3/compare/v0.18.3...v0.19.0

View File

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3" name = "pyo3"
version = "0.19.2" version = "0.20.0"
description = "Bindings to Python interpreter" description = "Bindings to Python interpreter"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
readme = "README.md" readme = "README.md"
@ -21,10 +21,10 @@ parking_lot = ">= 0.11, < 0.13"
memoffset = "0.9" memoffset = "0.9"
# ffi bindings to the python interpreter, split into a separate crate so they can be used independently # ffi bindings to the python interpreter, split into a separate crate so they can be used independently
pyo3-ffi = { path = "pyo3-ffi", version = "=0.19.2" } pyo3-ffi = { path = "pyo3-ffi", version = "=0.20.0" }
# support crates for macros feature # support crates for macros feature
pyo3-macros = { path = "pyo3-macros", version = "=0.19.2", optional = true } pyo3-macros = { path = "pyo3-macros", version = "=0.20.0", optional = true }
indoc = { version = "2.0.1", optional = true } indoc = { version = "2.0.1", optional = true }
unindent = { version = "0.2.1", optional = true } unindent = { version = "0.2.1", optional = true }
@ -56,7 +56,7 @@ rust_decimal = { version = "1.8.0", features = ["std"] }
widestring = "0.5.1" widestring = "0.5.1"
[build-dependencies] [build-dependencies]
pyo3-build-config = { path = "pyo3-build-config", version = "0.19.2", features = ["resolve-config"] } pyo3-build-config = { path = "pyo3-build-config", version = "0.20.0", features = ["resolve-config"] }
[features] [features]
default = ["macros"] default = ["macros"]

View File

@ -68,7 +68,7 @@ name = "string_sum"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
pyo3 = { version = "0.19.2", features = ["extension-module"] } pyo3 = { version = "0.20.0", features = ["extension-module"] }
``` ```
**`src/lib.rs`** **`src/lib.rs`**
@ -137,7 +137,7 @@ Start a new project with `cargo new` and add `pyo3` to the `Cargo.toml` like th
```toml ```toml
[dependencies.pyo3] [dependencies.pyo3]
version = "0.19.2" version = "0.20.0"
features = ["auto-initialize"] features = ["auto-initialize"]
``` ```

View File

@ -5,7 +5,7 @@ publish = false
edition = "2021" edition = "2021"
[dev-dependencies] [dev-dependencies]
pyo3 = { version = "0.19.2", path = "..", features = ["auto-initialize", "extension-module"] } pyo3 = { version = "0.20.0", path = "..", features = ["auto-initialize", "extension-module"] }
[[example]] [[example]]
name = "decorator" name = "decorator"

View File

@ -1,4 +1,4 @@
variable::set("PYO3_VERSION", "0.19.2"); variable::set("PYO3_VERSION", "0.20.0");
file::rename(".template/Cargo.toml", "Cargo.toml"); file::rename(".template/Cargo.toml", "Cargo.toml");
file::rename(".template/pyproject.toml", "pyproject.toml"); file::rename(".template/pyproject.toml", "pyproject.toml");
file::delete(".template"); file::delete(".template");

View File

@ -1,4 +1,4 @@
variable::set("PYO3_VERSION", "0.19.2"); variable::set("PYO3_VERSION", "0.20.0");
file::rename(".template/Cargo.toml", "Cargo.toml"); file::rename(".template/Cargo.toml", "Cargo.toml");
file::rename(".template/pyproject.toml", "pyproject.toml"); file::rename(".template/pyproject.toml", "pyproject.toml");
file::delete(".template"); file::delete(".template");

View File

@ -1,4 +1,4 @@
variable::set("PYO3_VERSION", "0.19.2"); variable::set("PYO3_VERSION", "0.20.0");
file::rename(".template/Cargo.toml", "Cargo.toml"); file::rename(".template/Cargo.toml", "Cargo.toml");
file::rename(".template/plugin_api/Cargo.toml", "plugin_api/Cargo.toml"); file::rename(".template/plugin_api/Cargo.toml", "plugin_api/Cargo.toml");
file::delete(".template"); file::delete(".template");

View File

@ -1,4 +1,4 @@
variable::set("PYO3_VERSION", "0.19.2"); variable::set("PYO3_VERSION", "0.20.0");
file::rename(".template/Cargo.toml", "Cargo.toml"); file::rename(".template/Cargo.toml", "Cargo.toml");
file::rename(".template/setup.cfg", "setup.cfg"); file::rename(".template/setup.cfg", "setup.cfg");
file::delete(".template"); file::delete(".template");

View File

@ -1,3 +1,3 @@
variable::set("PYO3_VERSION", "0.19.2"); variable::set("PYO3_VERSION", "0.20.0");
file::rename(".template/Cargo.toml", "Cargo.toml"); file::rename(".template/Cargo.toml", "Cargo.toml");
file::delete(".template"); file::delete(".template");

View File

@ -1 +0,0 @@
Dual-license PyO3 under either the Apache 2.0 OR the MIT license. This makes the project GPLv2 compatible.

View File

@ -1 +0,0 @@
Support `__lt__`, `__le__`, `__eq__`, `__ne__`, `__gt__` and `__ge__` in `#[pymethods]`

View File

@ -1 +0,0 @@
Update MSRV to Rust 1.56.

View File

@ -1 +0,0 @@
Simple getitem example showing type-check for possible attribute types

View File

@ -1 +0,0 @@
Remove all functionality deprecated in PyO3 0.18, including `#[args]` attribute for `#[pymethods]`.

View File

@ -1 +0,0 @@
Bump `indoc` dependency to 2.0 and `unindent` to 0.2.

View File

@ -1 +0,0 @@
Switched from syn 1.x to syn 2.x

View File

@ -1 +0,0 @@
Change `PySet::discard` to return `PyResult<bool>` (previously returned nothing).

View File

@ -1 +0,0 @@
Handle exceptions properly in `PySet::discard`.

View File

@ -1 +0,0 @@
Optimize conversion of Rust tuples to Python tuples.

View File

@ -1 +0,0 @@
Change `PyDict::get_item` to no longer suppress arbitrary exceptions (the return type is now `PyResult<Option<&PyAny>>` instead of `Option<&PyAny>`), and deprecate `PyDict::get_item_with_error`.

View File

@ -1 +0,0 @@
Add FFI symbol `Py_GETENV`.

View File

@ -1 +0,0 @@
Deprecate FFI definitions which are deprecated in Python 3.12.

View File

@ -1 +0,0 @@
`AsPyPointer` is now `unsafe trait`.

View File

@ -1 +0,0 @@
Add `as_ptr` and `into_ptr` inherent methods for `Py`, `PyAny`, `PyRef`, and `PyRefMut`.

View File

@ -1 +0,0 @@
Add implementations `DoubleEndedIterator` for `PyTupleIterator` and `PyListIterator`.

View File

@ -1 +0,0 @@
The `PyTupleIterator` type returned by `PyTuple::iter` is now public and hence can be named by downstream crates.

View File

@ -1 +0,0 @@
`PathBuf` `FromPyObject` implementation now works on all `os.PathLike` values.

View File

@ -1 +0,0 @@
Linking of `PyOS_FSPath` on PyPy.

View File

@ -1 +0,0 @@
Add `__builtins__` to globals in `py.run()` and `py.eval()` if they're missing.

View File

@ -1 +0,0 @@
Sped up FromPyObject::extract for BigInt and BigUint by up to 43% (although mileage may vary depending on int size and sign)

View File

@ -1 +0,0 @@
`#[pyclass]` now accepts `rename_all = "renaming_rule"`: this allows renaming all getters and setters of a struct, or all variants of an enum. Available renaming rules are: `"camelCase"`, `"kebab-case"`, `"lowercase"`, `"PascalCase"`, `"SCREAMING-KEBAB-CASE"`, `"SCREAMING_SNAKE_CASE"`, `"snake_case"`, `"UPPERCASE"`.

View File

@ -1 +0,0 @@
Removed `IntoPyPointer` trait, `into_ptr` is now an inherent method on most types representing Python objects

View File

@ -1 +0,0 @@
Drop support for debug builds of Python 3.7.

View File

@ -1 +0,0 @@
`PyIterator::from_object` and `PyByteArray::from` now take a single argument of type `&PyAny`, rather than two arguments, `Python` and `AsPyPointer`

View File

@ -1 +0,0 @@
Replace `AsPyPointer` with `AsRef<PyAny>` as a bound in the blanket implementation of `From<&T> for PyObject`

View File

@ -1 +0,0 @@
Replace blanket `impl IntoPy<PyObject> for &T where T: AsPyPointer` with implementations of `impl IntoPy<PyObject>` for `&PyAny`, `&T where T: AsRef<PyAny>`, and `&Py<T>`.

View File

@ -1 +0,0 @@
Reuses `std::io::Error` conversion code when converting `std::io::IntoInnerError` to `PyErr`

View File

@ -1 +0,0 @@
Pick a relevant `ErrorKind` when building an `io::Error` from a `OSError` subclass.

View File

@ -1 +0,0 @@
Fix memory leak in `PyTypeBuilder::build`.

View File

@ -1 +0,0 @@
`std::io::Error` cast: Reuses the underlying `PyErr` Python error instead of wrapping it again if the `io::Error` has been built using a Python exception

View File

@ -1 +0,0 @@
Add FFI definitions `PyObject_GC_IsTracked` and `PyObject_GC_IsFinalized` on Python 3.9 and up (PyPy 3.10 and up).

View File

@ -1 +0,0 @@
Disable removed FFI definitions `_Py_GetAllocatedBlocks`, `_PyObject_GC_Malloc`, and `_PyObject_GC_Calloc` on Python 3.11 and up.

View File

@ -1 +0,0 @@
Fix `ResourceWarning` and crashes related to GC when running with debug builds of CPython.

View File

@ -1 +0,0 @@
Fix compile warning for unreachable expression on debug builds before 3.12.

View File

@ -1 +0,0 @@
Add types for `None`, `Ellipsis`, and `NotImplemented`

View File

@ -1 +0,0 @@
Bump `chrono` optional dependency to require 0.4.25 or newer.

View File

@ -1 +0,0 @@
`#[pymodule]` will now return the same module object on repeated import by the same Python interpreter, on Python 3.9 and up.

View File

@ -1 +0,0 @@
`Err` returned from `#[pyfunction]` will now have a non-None `__context__` if called from inside a `catch` block.

View File

@ -1 +0,0 @@
Truncate leap-seconds and warn when converting `chrono` types to Python `datetime` types (`datetime` cannot represent leap-seconds).

View File

@ -1 +0,0 @@
Some-wrapping of `Option<T>` default arguments will no longer re-wrap `Some(T)` or expressions evaluating to `None`.

View File

@ -1 +0,0 @@
Fix `IterNextOutput::Return` not returning a value on PyPy.

View File

@ -1 +0,0 @@
Emit error on invalid arguments to `#[new]`, `#[classmethod]`, `#[staticmethod]`, and `#[classattr]`.

View File

@ -1 +0,0 @@
Support Python 3.12.

View File

@ -1 +0,0 @@
Disable `PyMarshal_WriteObjectToString` from `PyMarshal_ReadObjectFromString` with the `abi3` feature.

View File

@ -1 +0,0 @@
Emit compile errors instead of ignoring macro invocations inside `#[pymethods]` blocks.

View File

@ -1 +0,0 @@
Added the Py_mod_multiple_interpreters constant and its possible values.

View File

@ -1,2 +0,0 @@
In Python 3.11 the `_PyFrameEvalFunction` receives a `_PyInterpreterFrame` opaque struct.

View File

@ -1 +0,0 @@
Added the `PyInterpreterConfig` struct, its constants and `Py_NewInterpreterFromConfig`.

View File

@ -1 +0,0 @@
Deprecate undocumented `#[__new__]` form of `#[new]` attribute.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3-build-config" name = "pyo3-build-config"
version = "0.19.2" version = "0.20.0"
description = "Build configuration for the PyO3 ecosystem" description = "Build configuration for the PyO3 ecosystem"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"] keywords = ["pyo3", "python", "cpython", "ffi"]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3-ffi" name = "pyo3-ffi"
version = "0.19.2" version = "0.20.0"
description = "Python-API bindings for the PyO3 ecosystem" description = "Python-API bindings for the PyO3 ecosystem"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"] keywords = ["pyo3", "python", "cpython", "ffi"]
@ -38,4 +38,4 @@ generate-import-lib = ["pyo3-build-config/python3-dll-a"]
[build-dependencies] [build-dependencies]
pyo3-build-config = { path = "../pyo3-build-config", version = "0.19.2", features = ["resolve-config"] } pyo3-build-config = { path = "../pyo3-build-config", version = "0.20.0", features = ["resolve-config"] }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3-macros-backend" name = "pyo3-macros-backend"
version = "0.19.2" version = "0.20.0"
description = "Code generation for PyO3 package" description = "Code generation for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"] keywords = ["pyo3", "python", "cpython", "ffi"]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "pyo3-macros" name = "pyo3-macros"
version = "0.19.2" version = "0.20.0"
description = "Proc macros for PyO3 package" description = "Proc macros for PyO3 package"
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"] authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
keywords = ["pyo3", "python", "cpython", "ffi"] keywords = ["pyo3", "python", "cpython", "ffi"]
@ -22,4 +22,4 @@ abi3 = ["pyo3-macros-backend/abi3"]
proc-macro2 = { version = "1", default-features = false } proc-macro2 = { version = "1", default-features = false }
quote = "1" quote = "1"
syn = { version = "2", features = ["full", "extra-traits"] } syn = { version = "2", features = ["full", "extra-traits"] }
pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.19.2" } pyo3-macros-backend = { path = "../pyo3-macros-backend", version = "=0.20.0" }

View File

@ -20,7 +20,7 @@ exclude = '''
[tool.towncrier] [tool.towncrier]
filename = "CHANGELOG.md" filename = "CHANGELOG.md"
version = "0.19.2" version = "0.20.0"
start_string = "<!-- towncrier release notes start -->\n" start_string = "<!-- towncrier release notes start -->\n"
template = ".towncrier.template.md" template = ".towncrier.template.md"
title_format = "## [{version}] - {project_date}" title_format = "## [{version}] - {project_date}"