Skip to content

Semantics of __type_variables__ #10

Closed
@JelleZijlstra

Description

@JelleZijlstra

I am looking at implementing this part of the PEP: https://peps.python.org/pep-0695/#accessing-type-parameters-at-runtime

The specification says that the __type_variables__ field contains all active type variables, including those from enclosing scopes. So we would want this behavior:

def outer[T]():
    def inner(): pass
    assert inner.__type_variables__ == (T,)

In practice, I think this would most commonly affect behavior for methods of generic classes.

I have a few problems with this behavior:

  • It makes it impossible to distinguish at runtime between functions that are themselves generic, and functions that are merely within another generic function. For example, in the above, outer.__type_variables__ and inner.__type_variables__ would be the same.
  • It's complicated to implement. It would require injecting cell variables for every nested function and class into the symbol table.
  • The motivation in the PEP relies on stringified annotations, but it mostly does not apply under PEP 649, which is very likely where we're headed. Under PEP 649, functions that use a type variable defined in an outer scope would simply capture them in a closure. The feature is most useful under from __future__ import annotations, but that mode is about to be deprecated.

So I would like to change the behavior so that __type_variables__ (or __type_params__, #8) only holds the type variables defined in the current class/function/type alias, not those inherited from enclosing scopes.

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