Skip to content

Generic inner classes sees type variable from outer class #3144

Open

Description

@pkch
T = TypeVar('T')
class Outer(Generic[T]):
    class Inner:
        x: T  # E: Invalid type "test.T" (correct)
        def f(self, x: T) -> T: ... # ok (incorrect)
        def g(self) -> None:
            y: T  # E: Invalid type "test.T" (correct)

Source

Activity

  1. ilevkivskyi commented on Apr 9, 2017

    @ilevkivskyi
    Member

    I looks like the method f is understood as a generic method with an independent variable, for example reveal_type(Outer[int].Inner.f) shows def [T] (self: tst22.Outer.Inner, x: T`-1) -> T`-1. i.e. T is not bound to int here.

    Anyway, I think this is confusing and worth prohibiting. One can just use another type variable to create a generic method.

  2. pkch commented on Apr 9, 2017

    @pkch
    ContributorAuthor

    So is my understanding below correct?

    According to PEP 484:

    A generic class nested in another generic class cannot use same type variables.

    I understand that rule as saying T can't be used anywhere in the class definition of Inner. I think that's a good rule, and I want it to be applied to Inner.f.

  3. ilevkivskyi commented on Apr 9, 2017

    @ilevkivskyi
    Member

    So is my understanding below correct?

    No, PEP has an explicit example showing what is prohibited.

  4. pkch commented on Apr 9, 2017

    @pkch
    ContributorAuthor

    Ahh I see, even though the variables are out of scope, they can be used to define a new generic function. That makes sense, and I no longer think it's a problem (although I agree it's slightly confusing).

  5. sixolet commented on Apr 14, 2017

    @sixolet
    Collaborator

    The PEP is ambiguous about this exact example. When you're defining an inner class, it specifically blacklists the outer class's parameters as valid parameters for the inner one, but semantically the outer class's parameters are out of scope -- the inner class doesn't have an instance context for the outer class. In a method in the inner class, there's no guidance. It's still semantically outside the scope of the outer class, but the reasons for blacklisting it have not gone away. In #3113 I may be changing this behavior to be more like the one you describe as less confusing, @pkch, I'll import your test there and see.

  6. sixolet commented on Apr 14, 2017

    @sixolet
    Collaborator

    Ok, no #3113 does not change this behavior. But if we want to, I have the code loaded into my head for exactly how, now.

  7. pkch commented on Apr 14, 2017

    @pkch
    ContributorAuthor

    @sixolet I would prohibit it both in the PEP and in mypy. I can propose the edit to the PEP.

  8. sixolet commented on Apr 14, 2017

    @sixolet
    Collaborator
  9. sixolet commented on Apr 17, 2017

    @sixolet
    Collaborator

    #3113 now fixes this.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions