Open anders-kiaer opened 4 years ago
Could not find a simple solution to handle all types, but Union[pathlib.Path, some_nonepath_type]
and possibly Union[List[pathlib.Path], some_nonepath_type]
where paths are prioritized should be possible. In the latter case it would be necessary to decide a behavior when some, but not all, paths exists. Think it would be natural to raise an error?
(Optional actually resolves to a type typing.Union[some_type, NoneType]
and is therefore solved in the same manner)
Plausible solution:
subtypes of typing.Union
have the attributes __origin__
and __args__
. If we check hasattr(expected_type, "__origin__")
, and if so; expected_type.__origin__ == typing.Union
, we can get a tuple of the arguments for typing.Union
with union_args = expected_type.__args__
(from py 3.8 you get functions typing.get_origin
and typing.get_args
).
Then check if pathlib.Path in union_args
and possibly if typing.List[pathlib.Path] in union_args
.
Then check if it is possible to resolve paths that exist, and if not do an isinstance
check of the config argument towards the rest of the union_args
tuple. Could also include a if typing.Any in union_args -> proceed
before the isinstance
check to allow for the generous case of all types allowed.
While waiting on dropping both Python 3.6 and 3.7 support (in quite some time), it probably is cleaner to use this back-port https://pypi.org/project/typing-inspect/ on Python < 3.8
.
Would also be nice if we could support recursion etc.
We should ideally also support overloading (e.g. that plugin authors use https://www.python.org/dev/peps/pep-0484/#function-method-overloading to define different "combinations of arguments"). This could then also be used to further improve both automatic documentation and YAML schema generation.
We can out source the majority of this work to pydantic
- see https://github.com/samuelcolvin/pydantic/issues/2127.
webviz-config
already uses type hint annotations in plugins, to automatically check (at the time of parsing the webviz config file) that the user provided values are consistent with the values expected by the plugin author.Currently we do not support e.g.
Optional(pathlib.Path)
orUnion[dict, pathlib.Path]
.Could we improve on this in a robust way? E.g. if it is
Union[dict, pathlib.Path]
, return absolutepathlib.Path
if input corresponds to a file, otherwise the input in config should be a dict.Optional[...]
should be easy to support.Should aim for as little "special-casing" as possible.