Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get PyCharm to know what classes are mixin for

Our application has set of complex form wizards. To avoid code duplication I created several mixins.

The problem is that PyCharm highlights mixin methods with Unresolved attribute refference error.
This is correct as object does not have such methods. But I know that this mixin will be used only with special classes. Is there any way to tell this info to PyCharm?

For now I use such approach:

class MyMixin(object):
    def get_context_data(self, **kwargs):
        assert isinstance(self, (ClassToBeExtended, MyMixin))
        # super.get_context_data is still highlighter, 
        # as super is considered as object
        context = super(MyMixin, self).get_context_data(**kwargs)
        context.update(self.get_preview_context())
        return context

    def get_preview_context(self):
        # without this line PyCharm highlights the self.initial_data
        assert isinstance(self, (ClassToBeExtended, MyMixin))
        return {'needs': (self.initial_data['needs']
                          if 'type' not in self.initial_data
                          else '%(needs)s %(type)s' % self.initial_data)}

While this works for some cases like autocomplete for self., it fails for other cases like super. Is there a better approach to achieve the desired behavior?

P.S.: I know that I can disable reference check for specific name or whole class, but I don't want to do this as it will not help in typo checks and autocomplete.

like image 790
Igor Avatar asked Nov 27 '15 11:11

Igor


People also ask

What are Python mixin classes?

A mixin is a class that provides methods to other classes, but it's not considered a base class itself. 00:18 This special class is going to expose some methods that the derived class can utilize—methods that will essentially be mixed in to the derived class.

Is mixin a class?

In object-oriented programming languages, a mixin (or mix-in) is a class that contains methods for use by other classes without having to be the parent class of those other classes.

Is mixins multiple inheritance?

Mixin – is a generic object-oriented programming term: a class that contains methods for other classes. Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.

Does Python have mixin?

In Python, so-called mixins are classes that live in the normal inheritance tree, but they are kept small to avoid creating hierarchies that are too complicated for the programmer to grasp. In particular, mixins shouldn't have common ancestors other than object with the other parent classes.


2 Answers

You can type-hint to PyCharm what kind of classes to expect.

class DictMixin(object):
    def megamethod(
        self,  # type: dict
        key
    ):
        return self.get(key)

It's still not quite comparable to other type handling. PyCharm is lazy in evaluating it, and only does so when first working on self. Things are a bit tricky when accessing attributes of the mixin as well - self, # type: dict | DictMixin works for one of my classes, but not in my test code. In python 3.5, you should be able to use # type: typing.Union[dict, DictMixin].

like image 193
MisterMiyagi Avatar answered Sep 28 '22 13:09

MisterMiyagi


If you are creating Mixin, for, let's say ClassSub, which is subclass of ClassSuper, you can implement Mixins this way:

class Mixin1(ClassSuper):
    pass


class Mixin2(ClassSuper):
    pass

and then use them like:

class ClassSub(Mixin1, Mixin2):
    pass

That way I use some mixins for models in Django. Also, django-extensions uses similar pattern (gives models that are actually mixins). Basically, this way you don't have to inherit ClassSuper, because it's "included" in every of your mixins.

Most important - PyCharm works like a charm this way.

like image 40
ceruleus Avatar answered Sep 28 '22 12:09

ceruleus