I’ve been acquainting myself with Python’s type annotations (after way too long being stuck with much older versions of Python), and they have inspired a lot of exciting applications in my code (in my case the codebase is the backend for a medium-sized commercial web application).
Here’s one example that came up recently. I have a simple enumeration class inspired by StrEnum but with different behavior. It’s implemented with a metaclass just like StrEnum. In my case I need a way to specify one of the enumerated params as the default. Type annotations have let me do it this way:
class SearchType(EnumParam):
NAME = 'Name'
USER_ID: Annotated[str, Default] = 'User ID'
BIRTHDAY = 'Birthday'
This works really well, and the exciting thing for me is that type annotations let you say something about a variable without repeating its name. It lets you say that thing where the variable is defined, which is the most natural place. The alternative approaches lack the simplicity of the above (e.g. class SearchType(EnumParam, default='USER_ID') or USER_ID = default('User ID'), etc).
So far so good, but what I’d really like is something like this:
class SearchType(EnumParam):
NAME = 'Name'
USER_ID: Default = 'User ID'
BIRTHDAY = 'Birthday'
The problem is that type annotations currently require you to specify a type when adding annotations. I don’t want to specify types in this case - that’s a much longer discussion but I’ve run into trouble trying to strictly type throughout my code base (I come from a C++ background so the idea had very strong appeal to me! I just ran into some practical challenges with it). More to the point - it’s always been crystal clear that type annotations will never be forced on a Python developer nor will they be enforced at runtime.
So my idea is simply a way to annotate variables without being forced to specify a type. This could be a single-argument form of Annotated that just has an annotation, or perhaps a new member of the typing module with a different name. I haven’t contributed to python’s implementation but I have to imagine that this is a pretty trivial addition, and the only requirement outside Python itself would be that static type checkers know to ignore these annotations entirely. Just like with Annotated, any tooling which doesn’t recognize the form of an annotation would ignore it.
I understand that there hasn’t been much enthusiasm for non-type applications of Python’s type annotations. I looked into FastAPI’s use of Annotated to specify things like ranges for variables. In these cases Annotated is saying something beyond an object’s type - something that further specifies its behavior or allowed values. I see this as an elegant application of Annotated but my question is why Python forces the developer to specify a type in order to be allowed to state these other things about the variable?
Type hints have managed to sit elegantly on top of Python without affecting those who opt out of using static type analysis. I think it would be consistent with that philosophy to allow the annotation of variables as described above without being forced to also specify a type (and thus change the behavior of linting and auto-complete in the IDE for example). This is all toward making the definition of variables more expressive which helps make code both clear and concise.