A separate namespace for type annotations

The idea is to embed the typing and collections.abc module in the type annotation, but not to make them available outside the annotations, so as not to mess up the built-in namespace.

This way you will want to use typing more and more often, since typing is at your fingertips:

import typing
def f(x: typing.Callable[[typing.Any, typing.Any], typing.Any]) -> typing.Iterator[typing.Sequence[typing.Any]]:... 

this looks long compared to:

def f(x: Callable[[Any, Any], Any]) -> Iterator[Sequence[Any]]:...

Yes, you can tell me to use

from typing import Callable, Iterable, Sequence, Any

but this is inconvenient, and my suggestion would add a lot of convenience and more readability.
We also need this namespace to take priority over custom types with the same name. And if the names of user types match, then we should use the binding principle as in pattern matching.

def f(x: modue.Text):...

This way there will be fewer conflicts and less bad practices of overriding built-in types.

And in the priority of a separate space still lies the following meaning, in the future we can add the following typing types, but maybe it can be done now (name overriding)::

def f(x: hasattr['__add__', 'fromhex']):.
def f(x: issubclass[A, B, str]):...

Or any instead of Any, but this case is too late to apply, though if such a thing were done at the stage of designing a typecode annotation, we would not have typing.Any but python.

def f(x: any):...

As an additional feature, we would like typing.ReadOnly to be abbreviated as typing.ron, but this is unlikely.

+1 to this exposing typing primitives to annotation statements.

I keep spelling from typing import xxx in almost all of my code. It’s also not a great experience to maintain the import list in each files to keep up with the changes of my code.

Implementation-wise, name-lookup can be 1) locals 2) globals and 3) typing when parsing type annotations.

1 Like

This was already discussed quite a bit in Fall back to the typing.* namespace in lazy hint contexts

This is actually already part of the Why can’t we blog and will almost surely not happen. Your other suggestions for special cases here would probably fall into a similar category.

1 Like

IMO the best solution for this is to adopt typing as t style.
It’s used in the pallets projects, and I’ve had skeptical teammates come around after using it for a while.

The result is that you would write your example as:

def f(x: t.Callable[[t.Any, t.Any], t.Any]) -> t.Iterator[t.Sequence[t.Any]]:...

I even wrote a flake8 plugin for us to enforce it in our repos, which we have wired up with pre-commit: