From cf1c116f1da9b31c029639974318eb0cff3e848b Mon Sep 17 00:00:00 2001 From: Rogdham Date: Sun, 27 Apr 2025 17:25:43 +0200 Subject: [PATCH] chore: upgrade dev dependecies --- CHANGELOG.md | 1 + dev-requirements.txt | 10 +++++----- pyproject.toml | 4 +--- src/bigxml/__init__.py | 4 ++-- src/bigxml/handle_mgr.py | 2 +- src/bigxml/handler_creator.py | 2 +- src/bigxml/handler_marker.py | 9 ++++----- src/bigxml/stream.py | 6 +++--- src/bigxml/utils.py | 2 +- stubs/defusedxml/ElementTree.pyi | 5 +++-- tests/integration/test_namespaces.py | 4 +++- tests/integration/test_ram_usage.py | 2 +- tests/integration/test_security.py | 12 +++++------- tests/unit/test_handler_creator.py | 10 +++++++--- tests/unit/test_nodes_element_attributes.py | 6 ++++-- tests/unit/test_parser.py | 5 ++++- tests/unit/test_stream.py | 2 +- tests/unit/test_utils_get_mandatory_params.py | 6 ++---- tox.ini | 12 ++++++------ 19 files changed, 55 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b5f504..f89a3dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ For the purpose of determining breaking changes: - Update license metadata as per [PEP 639](https://peps.python.org/pep-0639) - Add tests for PyPy 3.11 +- Upgrade dev dependencies ## [1.1.0] - 2024-10-10 diff --git a/dev-requirements.txt b/dev-requirements.txt index 8e11a56..42d2f91 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,17 +2,17 @@ -e . # build -build==1.2.2 +build==1.3.0 # docs mkdocs==1.6.1 # lint -ruff==0.6.9 +ruff==0.14.1 # tests -pytest==8.3.3 -pytest-cov==5.0.0 +pytest==8.4.2 +pytest-cov==7.0.0 # type -mypy==1.11.2 +mypy==1.18.2 diff --git a/pyproject.toml b/pyproject.toml index d686093..189d680 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,7 +84,7 @@ ignore_missing_imports = false follow_imports = "normal" mypy_path = "stubs" # Platform configuration -python_version = 3.13 +python_version = "3.13" # Disallow dynamic typing disallow_any_unimported = true disallow_any_decorated = true @@ -143,8 +143,6 @@ target-version = "py39" [tool.ruff.lint] select = ["ALL"] ignore = [ - "ANN101", - "ANN102", "C901", "COM812", "D", diff --git a/src/bigxml/__init__.py b/src/bigxml/__init__.py index e5f6690..0133604 100644 --- a/src/bigxml/__init__.py +++ b/src/bigxml/__init__.py @@ -9,9 +9,9 @@ "HandlerTypeHelper", "Parser", "Streamable", - "xml_handle_element", - "xml_handle_text", "XMLElement", "XMLElementAttributes", "XMLText", + "xml_handle_element", + "xml_handle_text", ) diff --git a/src/bigxml/handle_mgr.py b/src/bigxml/handle_mgr.py index ff0ffee..81ddb36 100644 --- a/src/bigxml/handle_mgr.py +++ b/src/bigxml/handle_mgr.py @@ -100,7 +100,7 @@ def iter_from( ], ) -> Iterator[Union["XMLElement", T]]: ... - @overload # type: ignore[misc] + @overload def iter_from( self, *handlers: Any, # noqa: ANN401 diff --git a/src/bigxml/handler_creator.py b/src/bigxml/handler_creator.py index 1b5b285..9e1bdc2 100644 --- a/src/bigxml/handler_creator.py +++ b/src/bigxml/handler_creator.py @@ -135,7 +135,7 @@ def handle( return None @staticmethod - def _handle_from_class( # type: ignore[misc] + def _handle_from_class( klass: type[Any], node: Union["XMLElement", "XMLText"] ) -> Optional[Iterable[object]]: # instantiate class diff --git a/src/bigxml/handler_marker.py b/src/bigxml/handler_marker.py index 5f10811..da37f41 100644 --- a/src/bigxml/handler_marker.py +++ b/src/bigxml/handler_marker.py @@ -19,7 +19,7 @@ class ___xml_handle_xxx_wrapped(Protocol[T_co]): # noqa: N801 # wrapper for classes @overload - def __call__( # type: ignore[misc] + def __call__( self, obj: K, ) -> K: ... @@ -49,22 +49,21 @@ def wrapper(obj: F) -> F: if isinstance(markable, staticmethod): # staticmethod(xml_handle_element(...)) works as expected # xml_handle_element(staticmethod(...)) needs special care - markable = cast(F, markable.__func__) + markable = cast("F", markable.__func__) add_mark(markable, tuple(args)) return obj return cast( - ___xml_handle_xxx_wrapped[XMLElement], + "___xml_handle_xxx_wrapped[XMLElement]", wrapper, ) # @xml_handle_text (for classes) @overload -def xml_handle_text(obj: K, /) -> K: # type: ignore[misc] - ... +def xml_handle_text(obj: K, /) -> K: ... # @xml_handle_text (for functions) diff --git a/src/bigxml/stream.py b/src/bigxml/stream.py index bc40a12..7584a47 100644 --- a/src/bigxml/stream.py +++ b/src/bigxml/stream.py @@ -19,7 +19,7 @@ def _flatten_stream(stream: Streamable) -> Generator[Optional[memoryview], int, # buffer protocol (bytes, etc.) try: # we try-except instead of isinstance(stream, Buffer) for compatibility reasons - yield memoryview(cast(Buffer, stream)) + yield memoryview(cast("Buffer", stream)) return # noqa: TRY300 except TypeError: pass @@ -28,7 +28,7 @@ def _flatten_stream(stream: Streamable) -> Generator[Optional[memoryview], int, if hasattr(stream, "read"): while True: size = yield None - data = cast(SupportsRead[Any], stream).read(size) + data = cast("SupportsRead[Any]", stream).read(size) if not data: break # EOF try: @@ -57,7 +57,7 @@ def _flatten_stream(stream: Streamable) -> Generator[Optional[memoryview], int, # stream iterator (recursive) try: - substreams = iter(cast(Iterable[Streamable], stream)) + substreams = iter(cast("Iterable[Streamable]", stream)) except TypeError: # other types not supported raise TypeError(f"Invalid stream type: {type(stream).__name__}") from None diff --git a/src/bigxml/utils.py b/src/bigxml/utils.py index 0930820..0b1f3bc 100644 --- a/src/bigxml/utils.py +++ b/src/bigxml/utils.py @@ -40,7 +40,7 @@ def __next__(self) -> T: def extract_namespace_name(name: str) -> tuple[str, str]: match = _EXTRACT_NAMESPACE_REGEX.match(name) if match: - return cast(tuple[str, str], match.groups()) + return cast("tuple[str, str]", match.groups()) return ("", name) diff --git a/stubs/defusedxml/ElementTree.pyi b/stubs/defusedxml/ElementTree.pyi index 45d7a93..d6b250e 100644 --- a/stubs/defusedxml/ElementTree.pyi +++ b/stubs/defusedxml/ElementTree.pyi @@ -1,7 +1,8 @@ # ruff: noqa: FBT001 # note: only used items are defined here, with used typing -from typing import Iterator, Optional, Protocol, Sequence, TypeVar +from collections.abc import Iterator, Sequence +from typing import Optional, Protocol, TypeVar from xml.etree.ElementTree import Element, ParseError _T_co = TypeVar("_T_co", covariant=True) @@ -19,4 +20,4 @@ def iterparse( class DefusedXmlException(ValueError): ... # noqa: N818 -__all__ = ("DefusedXmlException", "Element", "iterparse", "ParseError") +__all__ = ("DefusedXmlException", "Element", "ParseError", "iterparse") diff --git a/tests/integration/test_namespaces.py b/tests/integration/test_namespaces.py index a196807..139741c 100644 --- a/tests/integration/test_namespaces.py +++ b/tests/integration/test_namespaces.py @@ -71,7 +71,9 @@ def handle_bbb(node: XMLElement) -> Iterator[tuple[str, str, str]]: ) # note that a warning is emitted if there are attributes with various # namespaces but none without namespace - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, match="Several alternatives for attribute name 'yyy'." + ): # current implementation uses "first" attribute in that case # but you should not rely on it and specify the namespace to use yield ("bbb", "yyy default", node.attributes["yyy"]) diff --git a/tests/integration/test_ram_usage.py b/tests/integration/test_ram_usage.py index 782b536..8239c72 100644 --- a/tests/integration/test_ram_usage.py +++ b/tests/integration/test_ram_usage.py @@ -9,7 +9,7 @@ @pytest.fixture def ram_usage() -> Iterator[Callable[[], float]]: try: - import tracemalloc + import tracemalloc # noqa: PLC0415 except ImportError: # e.g. PyPy pytest.skip("tracemalloc module not available") diff --git a/tests/integration/test_security.py b/tests/integration/test_security.py index e69c451..901d315 100644 --- a/tests/integration/test_security.py +++ b/tests/integration/test_security.py @@ -104,13 +104,11 @@ def test_external_entities(xml: bytes, msg: str) -> None: def test_insecurely_allow_entities() -> None: - xml = ( - b"\n' - b"]>\n" - b"Ω\n" - ) - with pytest.warns(UserWarning): + xml = b']>\nΩ\n' + with pytest.warns( + UserWarning, + match="Using 'insecurely_allow_entities' makes your code vulnerable to some XML attacks.", + ): parser = Parser(xml, insecurely_allow_entities=True) value = parser.return_from(handler_get_text) assert value == "Ω" diff --git a/tests/unit/test_handler_creator.py b/tests/unit/test_handler_creator.py index f6d6ff0..478e45f 100644 --- a/tests/unit/test_handler_creator.py +++ b/tests/unit/test_handler_creator.py @@ -25,7 +25,7 @@ def create_nodes( for node_name in path: # the cast below is wrong but makes our life easier # plus that case is kind of tested in tests below - parents = tuple(cast(list[XMLElement], nodes)) + parents = tuple(cast("list[XMLElement]", nodes)) if node_name == ":text:": node: Union[XMLElement, XMLText] = XMLText(text="text", parents=parents) else: @@ -631,7 +631,9 @@ def handle0(node: XMLElement) -> Iterable[tuple[str, XMLElement]]: nodes = create_nodes("x", "a") handler = create_handler(Handler) - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, match="Items were yielded by some sub-handler of class Handler." + ): items = list(handler(nodes[0])) assert len(items) == 1 assert isinstance(items[0], Handler) @@ -651,7 +653,9 @@ def xml_handler() -> Iterable[tuple[str, None]]: nodes = create_nodes("x", "a") handler = create_handler(Handler) - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, match="Items were yielded by some sub-handler of class Handler." + ): assert list(handler(nodes[0])) == [("end", None)] diff --git a/tests/unit/test_nodes_element_attributes.py b/tests/unit/test_nodes_element_attributes.py index 6e1b9dd..9e20c82 100644 --- a/tests/unit/test_nodes_element_attributes.py +++ b/tests/unit/test_nodes_element_attributes.py @@ -51,7 +51,9 @@ def test_get_without_namespace(key: str, value: str, should_warn: bool) -> None: context: AbstractContextManager[object] = nullcontext() if should_warn: - context = pytest.warns(UserWarning) + context = pytest.warns( + UserWarning, match=f"Several alternatives for attribute name '{key}'." + ) with context: assert XML_ELEMENT_ATTRIBUTES[key] == value @@ -89,5 +91,5 @@ def test_eq() -> None: @pytest.mark.parametrize("key", [r"{aaa", r"{aaa}{bbb"]) def test_invalid_key(key: str) -> None: - with pytest.raises(ValueError, match="Invalid key: '.*'"): + with pytest.raises(ValueError, match=r"Invalid key: '.*'"): XMLElementAttributes({key: "foo"}) diff --git a/tests/unit/test_parser.py b/tests/unit/test_parser.py index 11141bc..e62aebf 100644 --- a/tests/unit/test_parser.py +++ b/tests/unit/test_parser.py @@ -198,7 +198,10 @@ def root_handler( ) -> Iterator[tuple[str, Union[XMLElement, XMLText]]]: yield from node.iter_from(handler) - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, + match="Using 'insecurely_allow_entities' makes your code vulnerable to some XML attacks.", + ): parser = Parser(xml, insecurely_allow_entities=True) assert list(parser.iter_from(root_handler)) == [("handler-yield-0", text_pi_node)] diff --git a/tests/unit/test_stream.py b/tests/unit/test_stream.py index 39c164d..cf2a34e 100644 --- a/tests/unit/test_stream.py +++ b/tests/unit/test_stream.py @@ -119,7 +119,7 @@ def __repr__() -> str: ], ) def test_types_invalid(stream: object, err_message: str) -> None: - stream = StreamChain(cast(Streamable, stream)) + stream = StreamChain(cast("Streamable", stream)) with pytest.raises(TypeError) as excinfo: stream.read(42) diff --git a/tests/unit/test_utils_get_mandatory_params.py b/tests/unit/test_utils_get_mandatory_params.py index b4b683d..0627d5e 100644 --- a/tests/unit/test_utils_get_mandatory_params.py +++ b/tests/unit/test_utils_get_mandatory_params.py @@ -1,5 +1,3 @@ -# ruff: noqa: ARG001 - from typing import Callable import pytest @@ -57,9 +55,9 @@ def fct6( (dict, ()), ], ids=lambda x: str(x.__name__ if callable(x) else x), -) # type: ignore[misc] +) # Typing note: see https://github.com/python/mypy/issues/13436 -def test_mandatory_params( +def test_mandatory_params( # type: ignore[misc] fct: Callable[..., object], expected: tuple[str, ...] ) -> None: assert get_mandatory_params(fct) == expected diff --git a/tox.ini b/tox.ini index 0c3117f..20995d9 100644 --- a/tox.ini +++ b/tox.ini @@ -9,8 +9,8 @@ envlist = package = wheel wheel_build_env = .pkg # reuse same wheel across envs deps = - pytest==8.3.3 - pytest-cov==5.0.0 + pytest==8.4.2 + pytest-cov==7.0.0 passenv = PY_COLORS setenv = COVERAGE_FILE = {toxworkdir}/{envname}/.coverage @@ -22,7 +22,7 @@ commands = [testenv:build] skip_install = true deps = - build==1.2.2 + build==1.3.0 commands = python -m build @@ -35,15 +35,15 @@ commands = [testenv:lint] deps = - ruff==0.6.9 + ruff==0.14.1 commands = ruff check src docs tests ruff format --check src docs tests [testenv:type] deps = - mypy==1.11.2 - pytest==8.3.3 # for typing + mypy==1.18.2 + pytest==8.4.2 # for typing commands = mypy mypy --explicit-package-bases docs tests