Python: Best way to require a key value pair (with invalid key identifier)?
The requirements for the ingestion of this dict payload are are: 1. there is a valid identifier 'a', with type int that is required 2. there is an invalid identifier '1req' with type string that is required 3. additional properties can be passed in with any string keys different from the above two and value list 4. all input types must be included so TypedDict will not work because it does not capture item 3 5. in the real life use case the payload can contain n invalidly named identifiers 6 in real life there can be other known keys like b: float that are optional and are not the same as item 3 additional properties. They are not the same because the value type is different, and this key is a known literal (like 'b') but item 3 keys are strings but their value is unknown
Options that I know are: 1. use a function and move the invalid arg value into a union in kwargs `def some_fun(, a: int, *kwargs: typing.Union[list, str]):` - pro can pass in unpacked dict - con: no requirement on invalid required key name
2. use a function and use args to define the values for the invalidly named parameter `def some_fun(a: int, args: str, *kwargs: list):` - pro: required args not shown in kwargs - con: arguments must be passed in specific order - con: missing required arg key definition
3. Use a frozenset of tuples to require that the required args are passed first, then the optional args: ``` OptionalDictPair = typing.Tuple[typing_extensions.LiteralString, list]
RequiredDictPairs = typing.Union[ typing.Tuple[typing_extensions.Literal['a'], int], typing.Tuple[typing_extensions.Literal['1req'], int] ]
_T_co = typing.TypeVar("_T_co", covariant=True)
class frozenset_with_length(frozenset[_T_co]): def __new__( cls, required_1: RequiredDictPairs, required_2: RequiredDictPairs, args: OptionalDictPair) -> FrozensetInputType: req_args = (required_1, required_2) if not args: return super().__new__(cls, req_args) # type: ignore all_args = tuple(req_args) all_args.extend(args) return super().__new__(cls, all_args) # type: ignore
tuple_items = frozenset_with_length(*( ('a', 1), ('1req', 1), ('otherReq', None), )) ``` - pro: all required keys must be present, values checked too - con: required parameters must come first, then optional ones
Which do people prefer? Or are there other preferred options?
2 comments
[ 2.6 ms ] story [ 13.4 ms ] thread