Type annotations, imho, are actually useful and not really hard to read.
Type annotations, imho, are actually useful and not really hard to read.
Walrus is...fine. I don't use it much, but I defo see how it's one more thing.
Python's biggest complexity, imho, is its almost unrivaled dynamicism. There's just too many degrees of freedom at times.
The import system continues to be a nuclear footgun. I consider myself a python expert with 15 years under my belt and today I was still fighting with imports in a pytest suite. Like wtf.
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 :)
FYI: You can use strings as a workaround, or the
from __future__ import annotations
trick.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.
Do you keep the value on the left, the value on the right, error out, try merging the values (if so: how?), add a parameter allowing the user to make that choice, require the user to pass a lambda?
I don’t think there’s a ‘best’ answer here, but if you want to make one of them easier to write as a|b, you can only support one.
>>> {1} | {1.0} | {True}
{1}
But the behavior for dicts is surprising even in that light: >>> {1: 1} | {1.0: 1.0} | {True: True}
{1: True} >>> {1: 1, 1.0: 1.0, True: True}
{1: True}
So `|` between dictionaries behaves just as you'd expect, if your expectations about creating a dictionary are correct. I think that's very reasonable.I’d be cool with a statically typed flavor that wouldn’t allow for the type gymnastics.
But that’s gross with the None situation where you’d have to fall back to magic values vs ‘nil’ or similar concepts. None was one of my favorite things back when other languages didn’t address it.
And a lot of my opinion is probably based on the fact that I came to the language in the late 90s from a Pascal/C background. Probably just getting to old :).