This PEP proposes the addition of a postfix type declaration syntax toPython. It also specifies a newtypedef statement which is used to createnew mappings between types and declarators.
Its acceptance will greatly enhance the Python user experience as well aseliminate one of the warts that deter users of other programming languages fromswitching to Python.
Python has long suffered from the lack of explicit type declarations. Being oneof the few aspects in which the language deviates from its Zen, this wart hassparked many a discussion between Python heretics and members of the PSU (fora few examples, see[EX1],[EX2] or[EX3]), and it also made it a large-scaleenterprise success unlikely.
However, if one wants to put an end to this misery, a decent Pythonic syntaxmust be found. In almost all languages that have them, type declarations lackthis quality: they are verbose, often needingmultiple words for a singletype, or they are hard to comprehend (e.g., a certain language uses completelyunrelated[1] adjectives likedim for type declaration).
Therefore, this PEP combines the move to type declarations with another boldmove that will once again prove that Python is not only future-proof butfuture-embracing: the introduction of Unicode characters as an integralconstituent of source code.
Unicode makes it possible to express much more with much less characters, whichis in accordance with theZen (“Readability counts.”). Additionally, iteliminates the need for a separate type declaration statement, and last but notleast, it makes Python measure up to Perl 6, which already uses Unicode for itsoperators.[2]
When the type declaration mode is in operation, the grammar is changed so thateachNAME must consist of two parts: a name and a type declarator, which isexactly one Unicode character.
The declarator uniquely specifies the type of the name, and if it occurs on theleft hand side of an expression, this type is enforced: anInquisitionErrorexception is raised if the returned type doesn’t match the declared type.[3]
Also, function call result types have to be specified. If the result of the calldoes not have the declared type, anInquisitionError is raised. Caution: thedeclarator for the result should not be confused with the declarator for thefunction object (see the example below).
Type declarators after names that are only read, not assigned to, are not strictlynecessary but enforced anyway (see the Python Zen: “Explicit is better thanimplicit.”).
The mapping between types and declarators is not static. It can be completelycustomized by the programmer, but for convenience there are some predefinedmappings for some built-in types:
| Type | Declarator |
|---|---|
object | � (REPLACEMENT CHARACTER) |
int | ℕ (DOUBLE-STRUCK CAPITAL N) |
float | ℮ (ESTIMATED SYMBOL) |
bool | ✓ (CHECK MARK) |
complex | ℂ (DOUBLE-STRUCK CAPITAL C) |
str | ✎ (LOWER RIGHT PENCIL) |
unicode | ✒ (BLACK NIB) |
tuple | ⒯ (PARENTHESIZED LATIN SMALL LETTER T) |
list | ♨ (HOT SPRINGS) |
dict | ⧟ (DOUBLE-ENDED MULTIMAP) |
set | ∅ (EMPTY SET) (Note: this is also for full sets) |
frozenset | ☃ (SNOWMAN) |
datetime | ⌚ (WATCH) |
function | ƛ (LATIN SMALL LETTER LAMBDA WITH STROKE) |
generator | ⚛ (ATOM SYMBOL) |
Exception | ⌁ (ELECTRIC ARROW) |
The declarator for theNone type is a zero-width space.
These characters should be obvious and easy to remember and type for everyprogrammer.
Since even in our modern, globalized world there are still some old-fashionedrebels who can’t or don’t want to use Unicode in their source code, and sincePython is a forgiving language, a fallback is provided for those:
Instead of the single Unicode character, they can typename${UNICODENAMEOFTHEDECLARATOR}$. For example, these two function definitions are equivalent:
deffooƛ(xℂ):returnNone
and
def foo${LATIN SMALL LETTER LAMBDA WITH STROKE}$(x${DOUBLE-STRUCK CAPITAL C}$): return None${ZERO WIDTH NO-BREAK SPACE}$This is still easy to read and makes the full power of type-annotated Pythonavailable to ASCII believers.
typedef statementThe mapping between types and declarators can be extended with this new statement.
The syntax is as follows:
typedef_stmt::="typedef"exprDECLARATOR
whereexpr resolves to a type object. For convenience, thetypedef statementcan also be mixed with theclass statement for new classes, like so:
typedef class Foo☺(object�): pass
This is the standardos.path.normpath function, converted to type declarationsyntax:
def normpathƛ(path✎)✎: """Normalize path, eliminating double slashes, etc.""" if path✎ == '': return '.' initial_slashes✓ = path✎.startswithƛ('/')✓ # POSIX allows one or two initial slashes, but treats three or more # as single slash. if (initial_slashes✓ and path✎.startswithƛ('//')✓ and not path✎.startswithƛ('///')✓)✓: initial_slashesℕ = 2 comps♨ = path✎.splitƛ('/')♨ new_comps♨ = []♨ for comp✎ in comps♨: if comp✎ in ('', '.')⒯: continue if (comp✎ != '..' or (not initial_slashesℕ and not new_comps♨)✓ or (new_comps♨ and new_comps♨[-1]✎ == '..')✓)✓: new_comps♨.appendƛ(comp✎) elif new_comps♨: new_comps♨.popƛ()✎ comps♨ = new_comps♨ path✎ = '/'.join(comps♨)✎ if initial_slashesℕ: path✎ = '/'*initial_slashesℕ + path✎ return path✎ or '.'As you can clearly see, the type declarations add expressiveness, while at thesame time they make the code look much more professional.
To enable type declaration mode, one has to write:
from__future__importtype_declarations
which enables Unicode parsing of the source[4], makestypedef a keywordand enforces correct types for all assignments and function calls.
After careful considering, much soul-searching, gnashing of teeth and rendingof garments, it has been decided to reject this PEP.
TypeError is already in use, this name has been chosenfor obvious reasons.from__future__importencoding_hell.Many thanks go to Armin Ronacher, Alexander Schremmer and Marek Kubica who helpedfind the most suitable and mnemonic declarator for built-in types.
Thanks also to the Unicode Consortium for including all those useful charactersin the Unicode standard.
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-3117.rst
Last modified:2025-02-01 08:59:27 GMT