I am defining a class about as follows:
from numbers import Number
from typing import Dict
from typeguard import typechecked
Data = Dict[str, Number]
@typechecked
class Foo:
def __init__(self, data: Data):
self._data = dict(data)
@property
def data(self) -> Data:
return self._data
I am using typeguard. My intention is to restrict the types that can go into the data dictionary. Obviously, typeguard does check the entire dictionary if it is passed into a function or returned from one. If the dictionary is "exposed" directly, it becomes the dictionary's "responsibility" to check types - which does not work, obviously:
bar = Foo({'x': 2, 'y': 3}) # ok
bar = Foo({'x': 2, 'y': 3, 'z': 'not allowed'}) # error as expected
bar.data['z'] = 'should also be not allowed but still is ...' # no error, but should cause one
PEP 589 introduces typed dictionaries, but for a fixed set of keys (similar to struct-like constructs in other languages). In contrast, I need this for a flexible number of arbitrary keys.
My best bad idea is to go "old-school": Sub-classing dict and re-implementing every bit of API through which data can go in (and out) of the dictionary and adding type checks to them:
@typechecked
class TypedDict(dict): # just a sketch
def __init__(
self,
other: Union[Data, None] = None,
**kwargs: Number,
):
pass # TODO
def __setitem__(self, key: str, value: Number):
pass # TODO
# TODO
Is there a valid alternative that does not require the "old-school" approach?
from How to type-hint / type-check a dictionary (at runtime) for an arbitrary number of arbitrary key/value pairs?
No comments:
Post a Comment