Skip to content

Instantly share code, notes, and snippets.

@MaggieMoss
Created September 3, 2020 18:53
Show Gist options
  • Save MaggieMoss/c848cb3a581979f445d075c15629c950 to your computer and use it in GitHub Desktop.
Save MaggieMoss/c848cb3a581979f445d075c15629c950 to your computer and use it in GitHub Desktop.

PEP: 12 Title: Allow writing optional types as x? Author: Maggie Moss <maggiebmoss@gmail.com> 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 [1] has been approved and the CPython implementation is in progress.

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 [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 [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 [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;

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

Backwards Compatibility

? is currently unused in Python syntax, therefore this PEP is fully backwards compatible.

Reference Implementation

A reference implementation can be found here [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 (python/typing#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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment