Alternative type-first annotation syntax: type: name = value

Title: Alternative type-first annotation syntax: type: name = value

Body:

Summary

I’d like to propose an alternative syntax for variable type annotations where the type precedes the variable name, as an optional complement to PEP 526’s existing name: type = value form:

str: name = "Laura"  
int: age = 20  
float: height = 1.90  
bool: is_developer = True  

This would be semantically identical to today’s:

name: str = "Laura"  
age: int = 20  
height: float = 1.90  
is_developer: bool = True  

Motivation

Developers coming from C, Java, or Go are used to reading the type first when scanning a declaration (String name = "Laura";). Putting the type first could make declarations easier to scan visually, especially in code with many annotated variables, and could make columns of type-aligned declarations easier to skim in editors.

Known problems I’m aware of

  • This directly conflicts with PEP 20 (“There should be one — and preferably only one — obvious way to do it”). I’d like to hear whether the community thinks the readability gain is worth having two syntaxes for the same thing.
  • There’s a real grammar ambiguity concern: a statement starting with str: name could be confused with a dict literal key ({str: name}) or other existing uses of : in expression context. I haven’t worked out whether this is resolvable without breaking existing valid code — happy to hear from people who know the CPython grammar/parser better than I do.
  • Tooling cost: black, ruff, mypy, pylint, and every IDE would need to support both forms, which could fragment style across the ecosystem.

Alternatives already considered

  • Just using formatters (black/ruff) to visually align existing PEP 526 annotations instead of changing syntax.
  • Implementing this as a linter/formatter plugin or stub-file convention rather than a runtime/grammar change.

I’m posting here first (rather than drafting a full PEP) specifically to get feedback on whether this is worth pursuing further, and especially on the grammar ambiguity issue. Genuinely open to being told this isn’t a good idea — I’d rather find that out here than after writing a full PEP.


I don’t think this will ever be accepted. A different syntax for something we already have syntax for that’s offers nothing on top is a hard if not impossible sell. One could also argue against this with the same argument: People coming from Rust, TypeScript, Kotlin, etc are familiar with name: type = value.

Tangential: I really dislike type name = value. I much prefer Python’s name: type = value (same for Rust, TypeScript, Kotlin, etc)

Welcome @AlensJames.

Apart from (dis)benefits and feasibility and preferences, how would the interpreter, tools, humans and agents discern the new type: name form from the existing name: type form?
Types are not reserved words in Python, so after implementing your proposal int: object = 42 could mean an int instance named object with value 42, or an object-type instance named int, which now is 42 but will be ‘hello’ later.

The syntax is identical to the current one, except for flipped sides. How would Python know, given a : b = c, which is the type and which is the variable? Would it have to check if a or b already exist in scope? Would it be some magic import?

Developers coming from C, Java, or Go are used to reading the type first when scanning a declaration (String name = "Laura";).

Not true for Go. Developers working in multiple languages already have to adjust to various differences (indentation vs braces being the most obvious example). The colon in the current syntax does help distinguish it from the C-style syntax IMO.