From 64b8add768fce939410ae1754856a43dce3be19d Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Fri, 9 Jan 2026 18:42:12 +0200 Subject: [PATCH 1/2] [xmltodict] Fix false positive for namespaces with None values Signed-off-by: Emmanuel Ferdman --- stubs/xmltodict/@tests/test_cases/check_namespaces.py | 6 ++++++ stubs/xmltodict/xmltodict.pyi | 11 ++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 stubs/xmltodict/@tests/test_cases/check_namespaces.py diff --git a/stubs/xmltodict/@tests/test_cases/check_namespaces.py b/stubs/xmltodict/@tests/test_cases/check_namespaces.py new file mode 100644 index 000000000000..e58eda2bbea3 --- /dev/null +++ b/stubs/xmltodict/@tests/test_cases/check_namespaces.py @@ -0,0 +1,6 @@ +from __future__ import annotations + +import xmltodict + +ns: dict[str, None] = {"http://example.com/": None} +xmltodict.parse("", namespaces=ns) diff --git a/stubs/xmltodict/xmltodict.pyi b/stubs/xmltodict/xmltodict.pyi index 654c1ccc5860..591ea58aea2b 100644 --- a/stubs/xmltodict/xmltodict.pyi +++ b/stubs/xmltodict/xmltodict.pyi @@ -8,6 +8,7 @@ class ParsingInterrupted(Exception): ... # dict as attribute value is exclusive to xmlns: https://github.com/bigpick/xmltodict/commit/22541b4874365cb8d2397f23087a866b3081fd9c _AttrValue: TypeAlias = str | dict[str, str] _AttrDict: TypeAlias = dict[str, _AttrValue] +_Namespaces: TypeAlias = dict[str, str] | dict[str, None] | dict[str, str | None] class _DictSAXHandler: path: list[tuple[str, _AttrDict | None]] @@ -25,7 +26,7 @@ class _DictSAXHandler: dict_constructor: type strip_whitespace: bool namespace_separator: str - namespaces: dict[str, str] | None + namespaces: _Namespaces | None namespace_declarations: dict[str, str] force_list: bool | Container[str] | Callable[[tuple[str, _AttrDict | None], str, str], bool] | None comment_key: str @@ -42,7 +43,7 @@ class _DictSAXHandler: dict_constructor: type = ..., strip_whitespace: bool = True, namespace_separator: str = ":", - namespaces: dict[str, str] | None = None, + namespaces: _Namespaces | None = None, force_list: bool | Container[str] | Callable[[tuple[str, _AttrDict | None], str, str], bool] | None = None, comment_key: str = "#comment", ) -> None: ... @@ -72,7 +73,7 @@ def parse( postprocessor: Callable[[list[tuple[str, _AttrDict | None]], str, _AttrValue], tuple[str, _AttrValue]] | None = None, dict_constructor: type = ..., strip_whitespace: bool = True, - namespaces: dict[str, str] | None = None, + namespaces: _Namespaces | None = None, force_list: bool | Container[str] | Callable[[tuple[str, _AttrDict | None], str, str], bool] | None = None, comment_key: str = "#comment", ) -> dict[str, Any]: ... @@ -95,7 +96,7 @@ def unparse( newl: str = "\n", indent: str | int = "\t", namespace_separator: str = ":", - namespaces: Mapping[str, str] | None = None, + namespaces: Mapping[str, str | None] | None = None, expand_iter: str | None = None, ) -> None: ... @overload @@ -117,6 +118,6 @@ def unparse( newl: str = "\n", indent: str | int = "\t", namespace_separator: str = ":", - namespaces: Mapping[str, str] | None = None, + namespaces: Mapping[str, str | None] | None = None, expand_iter: str | None = None, ) -> str: ... From d56dea5ce828dd7f7b90419a51659ec2895723aa Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Sat, 10 Jan 2026 13:06:07 +0200 Subject: [PATCH 2/2] [xmltodict] Fix false positive for namespaces with None values Signed-off-by: Emmanuel Ferdman --- stubs/xmltodict/xmltodict.pyi | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/stubs/xmltodict/xmltodict.pyi b/stubs/xmltodict/xmltodict.pyi index 591ea58aea2b..937db619e499 100644 --- a/stubs/xmltodict/xmltodict.pyi +++ b/stubs/xmltodict/xmltodict.pyi @@ -8,7 +8,6 @@ class ParsingInterrupted(Exception): ... # dict as attribute value is exclusive to xmlns: https://github.com/bigpick/xmltodict/commit/22541b4874365cb8d2397f23087a866b3081fd9c _AttrValue: TypeAlias = str | dict[str, str] _AttrDict: TypeAlias = dict[str, _AttrValue] -_Namespaces: TypeAlias = dict[str, str] | dict[str, None] | dict[str, str | None] class _DictSAXHandler: path: list[tuple[str, _AttrDict | None]] @@ -26,7 +25,7 @@ class _DictSAXHandler: dict_constructor: type strip_whitespace: bool namespace_separator: str - namespaces: _Namespaces | None + namespaces: Mapping[str, str | None] | None namespace_declarations: dict[str, str] force_list: bool | Container[str] | Callable[[tuple[str, _AttrDict | None], str, str], bool] | None comment_key: str @@ -43,7 +42,7 @@ class _DictSAXHandler: dict_constructor: type = ..., strip_whitespace: bool = True, namespace_separator: str = ":", - namespaces: _Namespaces | None = None, + namespaces: Mapping[str, str | None] | None = None, force_list: bool | Container[str] | Callable[[tuple[str, _AttrDict | None], str, str], bool] | None = None, comment_key: str = "#comment", ) -> None: ... @@ -73,7 +72,7 @@ def parse( postprocessor: Callable[[list[tuple[str, _AttrDict | None]], str, _AttrValue], tuple[str, _AttrValue]] | None = None, dict_constructor: type = ..., strip_whitespace: bool = True, - namespaces: _Namespaces | None = None, + namespaces: Mapping[str, str | None] | None = None, force_list: bool | Container[str] | Callable[[tuple[str, _AttrDict | None], str, str], bool] | None = None, comment_key: str = "#comment", ) -> dict[str, Any]: ...