Breaking and important changes
![image showing deprecation warning](https://github.com/user-attachments/assets/6ab30a54-60e7-4e34-932a-2ac2e253c669)
- `pyright` users (and IDE that can make use of `pyright`) will see warning if a single string is supplied where collection of string is expected (`tuple`, `set`, `list` etc). In terms of typing, a single `str` itself is valid as a `Sequence`, so type checkers normally would not raise alarm when using `str` in such function parameters, but can induce unexpected runtime behavior. ([64](https://github.com/abelcheung/types-lxml/issues/64))
- `_ElementTree.write()`, `etree.fromstringlist()`, `etree.tostring()`, `html.soupparser.fromstring()`, `html.soupparser.parse()`
- It is possible to verify release files indeed come from GitHub and not maliciously altered. See [Release file attestation](README.mdrelease-file-attestation) for detail.
- Runtime tests support comparing with `mypy` results, therefore officially making static stub tests obsolete
Bug fixes
- Element tag names, attribute names and attribute values support `bytearray`. This is discovered via `hypothesis` testing, which is intended to be utilized in next release
- Compatibility with `pyright ⩾ 1.1.378`, which imposes additional overload warning for `etree.iterparse()`
- Use relative import in `lxml.ElementInclude`, otherwise `mypy` triggers `--install-type` behavior.
- `ObjectifiedElement` `__getitem()__` and `__setitem()__` should accept `str` as key, which behaves mostly like `__getattr__()` and `__setattr__()`. That means, `elem["foo"]` is equivalent to `elem.foo` for non-repeating subelements.
fixes for etree submodule
- `_Element.tag` property is not just a `str`. It is `str` after initial document or string parsing, but can be set manually to any type supported by tag name and returns the same object.
- When `QName` is initialized with first argument set to `None`, `_Element` can be used as second argument (which is promoted to first argument in implementation)
- Relax single argument usage in `_Element.iter*()` method family, doesn't need `tag=` keyword when argument is `None`
- `FunctionNamespace()` should generate an `_XPathFunctionNamespaceRegistry` object, not its superclass
- For [decorator usage](https://lxml.de/element_classes.html#implementing-namespaces-1) of `_XPathFunctionNamespaceRegistry` and `_ClassNamespaceRegistry`, decorator signature included an extraneous argument, though it doesn't affect any existing correct usage.
- `indent()` first parameter has wrong name
fixes for html submodule
- `soupparser.parse()` should accept `pathlib.Path` object as input
- `.value` property of `SelectElement` can't be set to `bytes`
- `.action` property of `FormElement` can have a value of `None`, and can be set to `None`. They have different meanings though.
Small and internal changes
- Declare python 3.13 support and perform CI tests.
- Separation of `pyright` and `mypy` ignore comments: in previous releases ` type: ignore[code]` was enabled in `pyright` settings. Now it only uses ` pyright: ignore[code]` so `mypy` comment won't affect `pyright` behavior.
- Add `._name` property to `html.FormElement` for form name
- Eliminate `typing.TypeAlias` usage ([declared obsolete](https://docs.python.org/3/library/typing.html#deprecation-timeline-of-major-features), and we can do without it)
Test related changes
- Stub tests migration to runtime:
- Most of remaining `etree._Element` methods, now only `.makeelement()` and `.xpath()` left in stub test
- Runtime test additions:
- `ElementNamespaceClassLookup()`
- `tox` config migrated to `pyproject.toml`, thus requiring `tox ⩾ 4.22`
- Runtime tests are now executed within `test-rt` folder due to python/mypy8400
- Some tests need to be performed conditionally when multi-subclass patch is applied
- Some tests or syntaxes need to be turned off to cope with `mypy` deficiencies
- Usage of [Rust-based `uv`](https://docs.astral.sh/uv/) as well as [related `tox` plugin](https://github.com/tox-dev/tox-uv) to speed up test environment recreation
- Don't force users installing [`tox-gh-actions`](https://github.com/ymyzk/tox-gh-actions) when checkout out repository, it is only useful for GitHub workflows
Docstring additions
- `etree` submodule: `parse()`, `fromstringlist()`, `tostring()`, `indent()`, `iselement()`, `adopt_external_document()`, `DocInfo` properties, `QName`, `CData`, some exception classes
- `html.soupparser` submodule: `fromstring()`, `parse()`, `convert_tree()`