typing
typing copied to clipboard
advanced SimpleNamespace typing
the same way we now have TypedDict, it would be nice to have typed SimpleNamespace with equivalent semantics, so that nested structures can be easily checked. eg
class MySubType(TypedSimpleNamespace):
bar: int
class MyType(TypedSimpleNamespace):
foo: MySubType
# correct
a: MyType = SimpleNamespace(foo=SimpleNamespace(bar=1))
# incorrect, `bar` should be a number
a: MyType = SimpleNamespace(foo=SimpleNamespace(bar='abc'))
I think Protocol can basically be used as your proposed TypedSimpleNameSpace.
as far as I can tell, protocols can be used to cast the simple namespace into, but it won't help me typechecking SimpleNamespce, like in my example snippet. can you provide an example when using protocols where the correct line would succeed and the wrong line would file? I don't believe it's possible without adding a specific SimpleNamespace type
I think
Protocolcan basically be used as your proposedTypedSimpleNameSpace.
Almost, but not completely. IIUC auto-generated __init__() signature is important. On the other hand, the latter can be added when support for key types is added.
the latter can be added when support for key types is added.
thanks @ilevkivskyi can you link to related resources about it?
We don't have a "centralized" issues to track this, but you can watch https://github.com/python/mypy/issues/7856 and/or https://github.com/python/mypy/issues/7790
I expect this to work:
from typing import Protocol
from types import SimpleNamespace
class Person(Protocol):
@property
def name(self) -> str: ...
@property
def age(self) -> int: ...
def get_person() -> Person:
return SimpleNamespace(
name="Alice",
age=40
)
But I am not getting any type checking whatsoever.
I use SimpleNamespace for one-off cases where specifying a dataclass or Protocol would be unnecessary boilerplate. I'd like to be able to type SimpleNamespace as a generic:
def returns_namespace() -> SimpleNamespace[int]:
return SimpleNamespace(a=1, b=2)
This is not possible at the moment as SimpleNamespace accepts no type arguments, but it'll be nice to have this as a first step before TypedDict-level typing.
def returns_namespace() -> SimpleNamespace[int]: return SimpleNamespace(a=1, b=2)
That should be -> SimpleNamespace[[int, int]] (cf. Callable)
Documentation of SimpleNamespace mentions:
However, for a structured record type use namedtuple() instead.
Shouldn't that cover the usecases brought up here?