Skip to content

Type annotation erasure at compile time #400

Closed
@ambv

Description

@ambv

Problem definition

Current usage of type hints shows the following patterns:

  • users often use "Dict", "List", "Set" without adding the required imports from typing; this is especially possible in case of type comments which don't fail at runtime;
  • users try to put generics on built-in collections, which again mostly happens in type comments which don't fail at runtime;
  • users get confused as to why there is List but there's no Str.

On top of this, I noticed the following tricky typing situation (generalization of actual code at FB):

if TYPE_CHECKING:
    from expensive_unrelated_module import SomeType  # noqa
    from dependency_cycle import CycleType  # noqa

def function(arg: 'SomeType') -> 'CycleType':
    from dependency_cycle import CycleType  # noqa
    return CycleType(arg)

You cannot simply write SomeType or CycleType because it would fail at runtime. So you wrap it in strings. But when you wrap, linters start reporting the imports as unused, or shadowing previous unused imports. So you need to additionally add silencing comments. The resulting code is pretty hideous.

Solution

I'm proposing revisiting the PEP 484 suggestion to make all annotations evaluate to strings at runtime with Python 3.7.

Rationale:

  • this lets us seamlessly integrate generics on builtin collections without the need to modify C code to support indexing;
  • this provides seamless forward reference support;
  • this gives the user seamless access to imports made in the if TYPE_CHECKING: block;
  • this accelerates import time and decreases memory usage at runtime.

Details:

  • access to an evaluated expression is still possible via typing.get_type_hints();
  • the expression is still expected to be syntactically valid and using known names;
  • for 3.7 a future import would be required, tentatively called static_annotations (2 characters longer than absolute_imports, 4 characters than with_statement and print_function)
  • no other behavioral changes are expected.

Summing up, I think this greatly improves the user experience.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions