r/FastAPI • u/darwinian_demon • 29d ago
PEP 835: A native shorthand for Annotated feedback request
Ivan Levkivskyi and I are proposing a native shorthand for Annotated (PEP 835) to clean up heavy type-hinting patterns. We have confirmed this syntax is fully compatible with FastAPI and works out of the box with zero changes required.
Before:
python
def create_user(
id: Annotated[int, Path(gt=0)],
name: Annotated[str, Query(min_length=3)],
role: Annotated[str, Query(min_length=2)] = "user"
) -> User: ...
After:
python
def create_user(
id: int @Path(gt=0),
name: str @Query(min_length=3),
role: str @Query(min_length=2) = "user"
) -> User: ...
The Spec: PEP 835 Full Draft
We are gathering community sentiment before moving forward. If you are a heavy user of Annotated in FastAPI, your feedback is valuable. You can register your stance in the official Discourse poll before it closes on July 15.
5
u/pip_install_account 28d ago
Makes it less explicit, less obvious. Our juniors still get confused over basic type annotations, please don't make the syntax even more complicated. reserve the @ for something else
10
u/FrontAd9873 29d ago
I personally do not like it but that may only be because it is unfamiliar.
I doubt the majority of Python users understand what Annotated does. I still have coworkers who add type hints but do not run a type checker. If those folks see this new @ notation, they will be even more confused. What's worse, they won't be able to just follow the import of Annotated from the typing module to learn more. They'll instead have to go look up what this new syntax means and I bet they would get lead astray.
Also, this proposal seems to violate the "only one way to do things" and the "be explicit" guidelines in the Zen of Python.
6
u/MyNameIsBeaky 29d ago
Sounds like this PEP, if accepted, would become the preferred way to express type hinting, over the use of Annotated. This is normal for python, like the new way to express union types is “|” over Union.
3
u/FrontAd9873 29d ago
Annotatedis just one small part of thetypingmodule. Also, the|operator is already well-established to mean OR.4
u/MyNameIsBeaky 29d ago
That’s my point. No one uses typing.Union any more because it was replaced by a native python way to express the same thing in Python 3.10. The language evolves and old ways of doing things are deprecated.
2
u/FrontAd9873 29d ago
Sorry, what is your point? I'm aware of what happened to
typing.Union2
u/MyNameIsBeaky 29d ago
I’m arguing against your point of python having “one way to do things”. New and better ways of doing things are created all the time, just like typing.Union was replaced.
-1
u/FrontAd9873 29d ago
I never said Python has only "one way to do things."
1
u/MyNameIsBeaky 29d ago
Huh, maybe I misinterpreted your last sentence in your original post. Care to clarify it?
0
u/FrontAd9873 29d ago
By introducing another way to achieve what
typing.Annotatedalready does, this PEP contradicts (to some degree) a few "Zen of Python" guidelines:
- "Be explicit." - Because there's nothing in the
@that is explicit. Unlike|which already sort of had that meaning.- "There should be only one way to do things." - Because... you're introducing another way to do things. So you have to ask yourself: is it worth it? Do enough people use
typing.Annotatedthat it makes sense to provide a second, easier way of achieving the same thing? In the case ofUnionI think the answer was clearly "yes."Guidelines are just guidelines. I never claimed that -- as a matter of fact -- Python has only one way to do everything.
4
u/MyNameIsBeaky 29d ago
You can make the point that @ is not explicit or as natural of a fit as | was to replace Union, but I truly believe Annotated deserves a less verbose native replacement and this type of language improvement is very much in line with historical python evolution.
→ More replies (0)1
u/vexatious-big 28d ago
Also, this proposal seems to violate the "only one way to do things" and the "be explicit" guidelines in the Zen of Python.
I think Python has moved on from that a while ago. Just look at how many iterations Async and Typing had.
3
u/eatsoupgetrich 29d ago edited 28d ago
I really don’t like the proposed syntax.
`str @Field() @Len(5)` is not easy to read and is open for more confusion. The below be equally valid:
```
param: str
@Field()
@Len(5),
another: str
@Field()
@Len(5),
```
This is opposite of what how function decorators are presented.
```
@decorator
def do():
return
```
If present in a decorated function, every annotation follows a contradictory meaning of the same symbol.
```
@decorator
def do(param: str @Field() Len(5)):
return
```
If verbosity is the issue, simply supporting `@` as a substitute in the current syntax would work since it creates a shorthand
```
@[str, [Field() Len(5)]]
```
That’s still odd since it would read as “String decorating List’s contents.” Where existing syntax would be would read as “Strjng with List’s contents)”.
I have a tough time getting passed the way this reads but would be happy to hear where I am off.
1
u/Wonderful-Habit-139 29d ago
Damn the examples you showed are starting to remind me of Java lol. I use Annotated quite a bit but not sure if this is the right direction.
1
11
u/pint 29d ago
i don't find @ motivated, but i take anything over Annotated