PEP 645: New syntax for optional types (#1707)
This commit is contained in:
parent
ed214e8955
commit
e374575f20
|
@ -0,0 +1,158 @@
|
|||
PEP: 645
|
||||
Title: Allow writing optional types as ``x?``
|
||||
Author: Maggie Moss <maggiebmoss@gmail.com>
|
||||
Sponsor: Guido van Rossum <guido@python.org>
|
||||
Status: Draft
|
||||
Type: Process
|
||||
Content-Type: text/x-rst
|
||||
Created: 25-Aug-2020
|
||||
|
||||
|
||||
Abstract
|
||||
========
|
||||
This PEP proposes adding a ``?`` operator for types to allow writing ``int?`` in place of ``Optional[int]``.
|
||||
|
||||
|
||||
Motivation
|
||||
==========
|
||||
Types have become a valuable and powerful part of the Python language. However, many type annotations are verbose and add
|
||||
considerable friction to using type annotations. By improving the typing syntax, adding types to Python code becomes simpler
|
||||
and improves the development experience for Python users.
|
||||
|
||||
In a similar vein, a PEP to introduce short hand syntax for `Union types <https://www.python.org/dev/peps/pep-0604/>`_ [1]_ has
|
||||
been approved and implemented.
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
||||
Types in Python can be quite verbose, this can be a hindrance when working towards type adoption. Making types more ergonomic,
|
||||
as was done with the Union type in PEP 604 (e.g., int | str), would reduce the effort needed to add types to new and existing Python code.
|
||||
The Optional annotation is used frequently in both partially and fully typed Python code bases. In a small sampling of `5 well-typed open
|
||||
source projects, on average 7% of annotations
|
||||
<https://gist.github.com/MaggieMoss/fd8dfe002b2702fae243dbf81a62624e>`_ [2] included at least one optional type. This indicates
|
||||
that updating the syntax has the potential to make types more concise, reduce code length and improve readability.
|
||||
|
||||
Simplifying the syntax for optionals has been `discussed previously <https://github.com/python/typing/issues/429>`_ [3] within the typing community.
|
||||
The consensus during these conversations has been that ``?`` is the preferred operator. There is no native support for unary ``?`` in Python and this will
|
||||
need to be added to the runtime.
|
||||
|
||||
Adding the ? sigil to the Python grammar has been proposed previously in `PEP 505 <https://www.python.org/dev/peps/pep-0505/>`_ [4], which is currently in a deferred state.
|
||||
PEP 505 proposes a:
|
||||
|
||||
- "None coalescing" binary operator ``??``
|
||||
|
||||
- "None-aware attribute access" operator ``?.`` ("maybe dot")
|
||||
|
||||
- "None-aware indexing" operator ``?[]`` ("maybe subscript")
|
||||
|
||||
|
||||
Should PEP 505 be approved in the future, it would not interfere with the typing specific ``?`` proposed in this PEP. As well,
|
||||
since all uses of the ``?`` would be conceptually related, it would not be confusing in terms of learning Python or a hindrance to quick visual comprehension.
|
||||
|
||||
The proposed syntax, with the postfix operator, mimics the optional syntax found in other typed languages, like C#, TypeScript and Swift.
|
||||
The widespread adoption and popularity of these languages means that Python developers are likely already familiar with this syntax.::
|
||||
|
||||
// Optional in Swift
|
||||
var example: String?
|
||||
|
||||
// Optional in C#
|
||||
string? example;
|
||||
|
||||
Adding this syntax would also follow the often used pattern of using builtin types as annotations. For example, `list`, `dict` and `None`. This would allow more annotations to be
|
||||
added to Python code without importing from `typing`.
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
The new optional syntax should be accepted for function, variable, attribute and parameter annotations.
|
||||
|
||||
::
|
||||
|
||||
# instead of
|
||||
# def foo(x: Optional[int], y: Optional[str], z: Optional[list[int]): ...
|
||||
def foo(x: int?, y: str?, x: list[int]?): ...
|
||||
|
||||
# def bar(x: list[typing.Optional[int]]): ...
|
||||
def bar(x: list[int?]): ...
|
||||
|
||||
The new optional syntax should be equivalent to the existing typing.Optional syntax
|
||||
|
||||
::
|
||||
|
||||
typing.Optional[int] == int?
|
||||
|
||||
The new optional syntax should have the same identity as the existing typing.Optional syntax.
|
||||
|
||||
::
|
||||
|
||||
typing.Optional[int] is int?
|
||||
|
||||
|
||||
It should also be equivalent to a Union with None.
|
||||
|
||||
::
|
||||
|
||||
# old syntax
|
||||
int? == typing.Union[int, None]
|
||||
|
||||
# new syntax
|
||||
int? == int | None
|
||||
|
||||
Since the new Union syntax specified in PEP 604 is supported in ``isinstance`` and ``issubclass``, the new optional syntax should be supported in both ``isinstance`` and ``issubclass``,
|
||||
|
||||
::
|
||||
|
||||
isinstance(1, int?) # true
|
||||
issubclass(Child, Super?) # true
|
||||
|
||||
A new dunder method will need to be implemented to allow the `?` operator to be overloaded for other functionality.
|
||||
|
||||
|
||||
Backwards Compatibility
|
||||
=======================
|
||||
|
||||
``?`` is currently unused in Python syntax, therefore this PEP is fully backwards compatible.
|
||||
|
||||
Reference Implementation
|
||||
========================
|
||||
|
||||
A reference implementation can be found `here <https://github.com/python/cpython/compare/master...MaggieMoss:new-optional-syntax-postfix>`_ [5].
|
||||
|
||||
Rejected Ideas
|
||||
==============
|
||||
|
||||
Discussed alternatives were
|
||||
|
||||
* The ``~`` operator was considered in place of ``?``.
|
||||
* A prefix operator (``?int``).
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] PEP 604
|
||||
(https://www.python.org/dev/peps/pep-0604/)
|
||||
.. [2] Use of Optional Annotations in Open Source Python projects
|
||||
(https://gist.github.com/MaggieMoss/fd8dfe002b2702fae243dbf81a62624e)
|
||||
.. [3] Github Issue Discussion of Optional syntax
|
||||
(https://github.com/python/typing/issues/429)
|
||||
.. [4] PEP 505
|
||||
(https://www.python.org/dev/peps/pep-0505/)
|
||||
.. [5] Reference Implementation
|
||||
(https://github.com/python/cpython/compare/master...MaggieMoss:new-optional-syntax-postfix)
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
Loading…
Reference in New Issue