Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic inner classes sees type variable from outer class #3144

Open
pkch opened this issue Apr 8, 2017 · 9 comments
Open

Generic inner classes sees type variable from outer class #3144

pkch opened this issue Apr 8, 2017 · 9 comments

Comments

@pkch
Copy link
Contributor

pkch commented Apr 8, 2017

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

@ilevkivskyi
Copy link
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.

@pkch
Copy link
Contributor Author

pkch commented Apr 9, 2017

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.

@ilevkivskyi
Copy link
Member

So is my understanding below correct?

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

@pkch
Copy link
Contributor Author

pkch commented Apr 9, 2017

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).

@sixolet
Copy link
Collaborator

sixolet commented Apr 14, 2017

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.

@sixolet
Copy link
Collaborator

sixolet commented Apr 14, 2017

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.

@pkch
Copy link
Contributor Author

pkch commented Apr 14, 2017

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

@sixolet
Copy link
Collaborator

sixolet commented Apr 14, 2017 via email

@sixolet
Copy link
Collaborator

sixolet commented Apr 17, 2017

#3113 now fixes this.

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

No branches or pull requests

3 participants