Hello everybody,

I just publish the PEP-0604 for discussions (https://www.python.org/dev/peps/pep-0604/).

Scala 3 propose a new syntax for Union type. See here. I propose to add a similar syntax in Python.

# Operator for Union
assert( int | str == Union[int,str])
assert( int | str | float == Union[int,str,float])
# Operator for Optional
assert( ~int == Optional[int])

Now, it's possible to write:

def fn(bag:List[int | str], option: ~int = None) -> float | str: ...

in place of

def fn(bag:List[Option[int,str]], option: Optional[int] = None) -> Union[float,str]: ...

The discussion on python-new@python.org here have emerged the idea of extending also issubclass() and isinstance().

isinstance(int, int | str)

I think these syntaxes are more clear, and can help with the adoption of typing.

I test and implement these ideas in a two fork : One for CPython and one for MyPy. See the branches add_OR_to_types (for Union syntax), add_INVERT_to_types (for Union and Optional syntax) or updage_isinstance (for new isinstance() and issubclass()).

How I implement that ? I add the operators __or__ and __revert__ to PyType_Type. The C code is similar of :

from typing import *
def type_or(self,right):
  return Union[self,right]
type(type).__or__ = type_or

with some check before return Union.

Actually, the accepted BNF syntax for typing is :

annotation: name_type
name_type: NAME (args)?
args: '[' paramslist ']'
paramslist: annotation (',' annotation)* [',']

I propose to extend the BNF syntax to :

annotation: ( name_type | or_type | invert_type )
name_type: NAME (args)?
args: '[' paramslist ']'
paramslist: annotation (',' annotation)* [',']

or_type: name_type '|' annotation

invert_type: '~' annotation

Your remarks are welcome.

Philippe Prados