diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index cba2f2149c02..6fc81bc8e4a2 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -500,7 +500,6 @@ types.MethodType.__closure__ # read-only but not actually a property; stubtest types.MethodType.__defaults__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.ModuleType.__dict__ # read-only but not actually a property; stubtest thinks it's a mutable attribute. types.ModuleType.__getattr__ # this doesn't exist at runtime -types.SimpleNamespace.__init__ # class doesn't accept positional arguments but has default C signature # sys attributes that are not always defined sys.gettotalrefcount # Available on python debug builds diff --git a/stdlib/@tests/stubtest_allowlists/py310.txt b/stdlib/@tests/stubtest_allowlists/py310.txt index 25e238c547c4..8e77280791fa 100644 --- a/stdlib/@tests/stubtest_allowlists/py310.txt +++ b/stdlib/@tests/stubtest_allowlists/py310.txt @@ -249,6 +249,7 @@ pkgutil.ImpImporter\..* pkgutil.ImpLoader\..* types.CodeType.replace # stubtest thinks default values are None but None doesn't work at runtime +types.SimpleNamespace.__init__ # class doesn't accept positional arguments but has default C signature # These enums derive from (str, Enum) pstats.SortKey.__new__ diff --git a/stdlib/@tests/stubtest_allowlists/py311.txt b/stdlib/@tests/stubtest_allowlists/py311.txt index 25a12ada6c2b..aac0d4820b62 100644 --- a/stdlib/@tests/stubtest_allowlists/py311.txt +++ b/stdlib/@tests/stubtest_allowlists/py311.txt @@ -135,6 +135,7 @@ inspect._ParameterKind.description # Still exists, but stubtest can't see it os.PathLike.__class_getitem__ # PathLike is a protocol; we don't expect all PathLike classes to implement class_getitem poplib.POP3_SSL.stls # bad declaration of inherited function. See poplib.pyi types.GenericAlias.__call__ # Would be complicated to fix properly, Any could silence problems. #6392 +types.SimpleNamespace.__init__ # class doesn't accept positional arguments but has default C signature types.GenericAlias.__getattr__ types.GenericAlias.__mro_entries__ weakref.ProxyType.__reversed__ # Doesn't really exist diff --git a/stdlib/@tests/stubtest_allowlists/py312.txt b/stdlib/@tests/stubtest_allowlists/py312.txt index 469efb38be4a..616fe8cf620e 100644 --- a/stdlib/@tests/stubtest_allowlists/py312.txt +++ b/stdlib/@tests/stubtest_allowlists/py312.txt @@ -184,6 +184,9 @@ typing.ParamSpecKwargs.__mro_entries__ typing.TypeVar.__mro_entries__ typing.TypeVarTuple.__mro_entries__ +# class doesn't accept positional arguments but has default C signature +types.SimpleNamespace.__init__ + # TODO: mypy should infer that this attribute is inherited from builtins.type; # why doesn't it infer this? typing.SupportsAbs.__type_params__ diff --git a/stdlib/@tests/stubtest_allowlists/py38.txt b/stdlib/@tests/stubtest_allowlists/py38.txt index cb1b23328a35..893efaae4a38 100644 --- a/stdlib/@tests/stubtest_allowlists/py38.txt +++ b/stdlib/@tests/stubtest_allowlists/py38.txt @@ -206,6 +206,7 @@ types.GetSetDescriptorType.__get__ types.MemberDescriptorType.__get__ types.MethodDescriptorType.__get__ types.WrapperDescriptorType.__get__ +types.SimpleNamespace.__init__ # class doesn't accept positional arguments but has default C signature multiprocessing.managers.DictProxy.clear multiprocessing.managers.DictProxy.popitem diff --git a/stdlib/@tests/stubtest_allowlists/py39.txt b/stdlib/@tests/stubtest_allowlists/py39.txt index ceac9d170702..5203888299e9 100644 --- a/stdlib/@tests/stubtest_allowlists/py39.txt +++ b/stdlib/@tests/stubtest_allowlists/py39.txt @@ -223,6 +223,7 @@ pkgutil.ImpImporter\..* pkgutil.ImpLoader\..* types.CodeType.replace # stubtest thinks default values are None but None doesn't work at runtime +types.SimpleNamespace.__init__ # class doesn't accept positional arguments but has default C signature # These enums derive from (str, Enum) pstats.SortKey.__new__ diff --git a/stdlib/@tests/test_cases/check_types.py b/stdlib/@tests/test_cases/check_types.py new file mode 100644 index 000000000000..3654ca86447a --- /dev/null +++ b/stdlib/@tests/test_cases/check_types.py @@ -0,0 +1,27 @@ +import sys +import types +from collections import UserDict + +# test `types.SimpleNamespace` + +# Valid: +types.SimpleNamespace() +types.SimpleNamespace(x=1, y=2) + +if sys.version_info >= (3, 13): + types.SimpleNamespace(()) + types.SimpleNamespace([]) + types.SimpleNamespace([("x", "y"), ("z", 1)]) + types.SimpleNamespace({}) + types.SimpleNamespace(UserDict({"x": 1, "y": 2})) + + +# Invalid: +types.SimpleNamespace(1) # type: ignore +types.SimpleNamespace([1]) # type: ignore +types.SimpleNamespace([["x"]]) # type: ignore +types.SimpleNamespace(**{1: 2}) # type: ignore +types.SimpleNamespace({1: 2}) # type: ignore +types.SimpleNamespace([[1, 2]]) # type: ignore +types.SimpleNamespace(UserDict({1: 2})) # type: ignore +types.SimpleNamespace([[[], 2]]) # type: ignore diff --git a/stdlib/types.pyi b/stdlib/types.pyi index df2d853a630c..a569b55efa23 100644 --- a/stdlib/types.pyi +++ b/stdlib/types.pyi @@ -312,7 +312,11 @@ class MappingProxyType(Mapping[_KT, _VT_co]): class SimpleNamespace: __hash__: ClassVar[None] # type: ignore[assignment] - def __init__(self, **kwargs: Any) -> None: ... + if sys.version_info >= (3, 13): + def __init__(self, mapping_or_iterable: Mapping[str, Any] | Iterable[tuple[str, Any]] = (), /, **kwargs: Any) -> None: ... + else: + def __init__(self, **kwargs: Any) -> None: ... + def __eq__(self, value: object, /) -> bool: ... def __getattribute__(self, name: str, /) -> Any: ... def __setattr__(self, name: str, value: Any, /) -> None: ...