my main issue with the typing is circular imports, and how ultimately for a lot of configurations the best solution is to just skip the typing that one time. Even "if type_checking:" often simply can't cut it
I want to be able to use typing everywhere if I'm going to use it, it really grinds when I have to selectively not use it.
That being said, im glad typing is in the language :)
Configuration hoisting and library layout to avoid circulars is tricky. The way I structure my libs, lets say ./foo is my main lib, I'll have ./foo/types/.py with most of my primary schema models (I use Pydantic heavily). Then ./foo/config/.py manages application config. Basically everything is pulled in with env vars / config files - I rarely use CLI flags for application-level global configuration - the rest are passed in to entry point functions.
What this means is I can import my AppConfig class anywhere (except types and config submodules) without circular imports, construct them, and they will be initialized with the configs from the env.
Occasionally I have to bust out ForwardRef annotations and model.update_forward_refs() but that's pretty rare. Basically, the imports are structured so that it's as close to a DAG as possible.
Definitely check out pydantic, it makes it really easy to do 12-factor style application config.
I haven't done a lot with CLI-flag global config, but if I had to, I'd use something like dependency-injectors to wire it all together.
I want to be able to use typing everywhere if I'm going to use it, it really grinds when I have to selectively not use it.
That being said, im glad typing is in the language :)