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

class inside a class #3855

Closed
ostcar opened this issue Aug 21, 2017 · 7 comments
Closed

class inside a class #3855

ostcar opened this issue Aug 21, 2017 · 7 comments
Labels

Comments

@ostcar
Copy link

ostcar commented Aug 21, 2017

I am trying to use mypy on an existing django project. In Django models can have a special sub-class Meta and the Models can inherit from each other. Therefore I have a situation like this one:

class Foo:
    class Meta:
        pass

class Bar:
    class Meta:
        pass

class FooBar(Foo, Bar):
    pass

mypy reports an error on the FooBar class definition:

Cannot determine type of 'Meta' in base class 'Foo'
Cannot determine type of 'Meta' in base class 'Bar'

I am not sure if a missed a feature that would solve this. I think there should be a way to define the type sub class. For example with:

class Foo:
    class Meta:  # type: object
        pass
@gvanrossum
Copy link
Member

Hm, interesting. There is an ongoing project writing stubs for django (https://github.com/machinalis/mypy-django) -- maybe that has a solution already, or maybe someone on that project can help you if you file an issue there?

@ostcar
Copy link
Author

ostcar commented Aug 21, 2017

Thank you for the tip. I opened an issue on there project.

But I think this problem is not django specific. I don't know if classes in classes is a good style, but another projects may also use them.

@gvanrossum
Copy link
Member

It's pretty uncommon outside Django's patterns.

@ilevkivskyi
Copy link
Member

This one is actually quite straightforward to fix. The symbol table nodes for nested classes are created in the first pass (when little is known) so that their types are set to None. They are however never updated in the second pass. I would propose to update the types to either Type[Nested] or CallableType[<signature of __init__>, Nested]. Both versions have their pluses and minuses, so I am not sure here.

@sacha-sentier
Copy link

FYI, similar issues #2871 #4956

@ilevkivskyi
Copy link
Member

This is closed by #5926 that emits a better error message, and accepts safe use cases (e.g. when one nested class is a subclass of another nested class).

Note that mypy still emits an error on the original example, because it is technically unsafe. Note however that @mkurnikov works on a mypy plugin for Django that will suppress this error for Django specific use cases.

@ilevkivskyi
Copy link
Member

Also for those who don't want to use the Django mypy plugin, or if you want to silence this error for other reason you can either just put # type: ignore on the subclass definition, or use this pattern:

Unsafe: Any = object

class A:
    class Sub(Unsafe):
        pass

class B:
    class Sub(Unsafe):
        pass

class C(A, B):  # no complains from mypy
    pass

Note however it will disable many checks for A.Sub and B.Sub.

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

No branches or pull requests

4 participants