from rest_framework import mixins
class ListModelMixin: # Not used in the first test, skip it at first read.
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
return 42
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
class UserViewSet(ReadOnlyModelViewSet):
def list(self, request, *args, **kwargs):
print("foo")
return super().list(request, *args, **kwargs)
E1101: Super of 'UserViewSet' has no 'list' member (no-member)
In the parents of ReadOnlyModelViewSet there's mixins.ListModelMixin which contains a list method, so I don't expect to get this error.
Strangely, if we remove "mixins" so it use the fake one I implemented above, the error dissapear. A bit like if pylint/astroid can't find the mixins module, or find a wrong one, or I don't know.
pylint 2.3.1
astroid 2.2.5
Python 3.7.3rc1 (default, Mar 13 2019, 11:01:15)
[GCC 8.3.0]
I'll gladly help a bit more on resolving this one, but I don't really know what can I check, is there some tools to see maybe what's pylint seeing? Only thing I checked is the right file is opened by the process:
```openat(AT_FDCWD, "/home/mdk/.venvs/3.7.3/lib/python3.7/site-packages/rest_framework/mixins.py", O_RDONLY|O_CLOEXEC) = 3
which contains literally:
class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, args, *kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
```
I have the same issue.
Django 2.2.3
djangorestframework 3.9.4
pylint-django 2.0.10
pylint 2.3.1
class ExampleViewSet(ModelViewSet):
def perform_destroy(self, instance):
instance.file.delete(save=False)
super().perform_destroy(instance)
pylint Error no-member: Super of 'SampleViewSet' has no 'perform_destroy' member
The definition of ModelViewSet is in rest_framework/viewsets.py.
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
The method perform_destroy is in rest_framework/mixins.py:
class DestroyModelMixin(object):
"""
Destroy a model instance.
"""
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance):
instance.delete()
The pylint is wrong.
This is not a django-specific problem.
It will occur in a situation where:
class ClassAB(module.ClassA, module.ClassB) and not class ClassAB(ClassA, ClassB) )base.py
class ClassA(object):
pass
class ClassB(object):
def test(self):
return True
derived.py
import base
class ClassAB(base.ClassA, base.ClassB):
def method(self):
super().test() # E1101: Super of 'ClassAB' has no 'test' member (no-member)
Calling ClassAB().method() returns True, but pylint thinks the test() method is missing.
It occurs with super() and super(ClassAB, self). Also, no difference if the files are within a package or not.
Unclear if OS (tested on Fedora 29) or python version (tested on 3.7) affect the result.
$ pylint --version
pylint 2.3.1
astroid 2.2.5
Python 3.7.4 (default, Jul 9 2019, 16:48:28)
[GCC 8.3.1 20190223 (Red Hat 8.3.1-2)]
@teknodan you meant return super().test(), in method.
I'm able to reproduce it:
printf "class ClassA(object):\n pass\n\nclass ClassB(object):\n def test(self):\n return True\n" > base.py
printf "import base\n\n\nclass ClassAB(base.ClassA, base.ClassB):\n def method(self):\n return super().test() # E1101: Super of 'ClassAB' has no 'test' member (no-member)\n" > derived.py
cat base.py
```python
class ClassA(object):
pass
class ClassB(object):
def test(self):
return True
```bash
cat derived.py
```python
import base
class ClassAB(base.ClassA, base.ClassB):
def method(self):
return super().test() # E1101: Super of 'ClassAB' has no 'test' member (no-member)
```bash
pylint --version
pylint 2.3.1
astroid 2.2.5
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516]
```bash
python --version
Python 3.5.3
```bash
$ pylint derived.py
************* Module derived
[...]
derived.py:5:15: E1101: Super of 'ClassAB' has no 'test' member (no-member)
Same with
$ pylint --version
pylint 2.6.0
astroid 2.4.2
Python 3.8.4 (default, Jul 14 2020, 09:37:22)
[GCC 9.3.0]
Thanks folks, I can reproduce the same issue. Did not manage yet to investigate why it's happening though, but looks like an inference bug.
can repro
inheriting from viewsets.ModelViewSet
def perform_destroy(self, instance):
...
return super().perform_destroy(instance)
has no 'perform_destroy' memberpylint(no-member)
I think I have the same issue, it is not related to Django but to yappi library, and there is no multiple inheritance, only a very straightforward call of the superclass method.
import yappi
stats = yappi.get_func_stats()
stats.save()
$ pylint -E yappi_test.py
************* Module yappi_test
yappi_test.py:5:0: E1101: Instance of 'YStats' has no 'save' member (no-member)
md5-f356afe87508c0a68cab5dd7832513cf
pylint 2.4.4
astroid 2.3.3
Python 3.6.9 (default, Nov 7 2019, 10:44:02)
[GCC 8.3.0]
Same problem here: inheriting from rest_framework.viewsets.ModelViewSet and overriding destroy leads to no-member error.
Same problem here.
class DebuggingAPIView(viewsets.ModelViewSet):
queryset = Debugger.objects.all()
serializer_class = DebuggerSerializer
def create(self, request, *args, **kwargs):
print("create method of debugging endpoint is called")
return super(DebuggingAPIView, self).create(request, *args, **kwargs)
def list(self, request, *args, **kwargs):
print("list method of debugging endpoint is called")
return super(DebuggingAPIView, self).list(request, *args, **kwargs)
def retrieve(self, request, *args, **kwargs):
print("retrieve method of debugging endpoint is called")
return super(DebuggingAPIView, self).retrieve(request, *args, **kwargs)
def update(self, request, *args, **kwargs):
print("update method of debugging endpoint is called")
return super(DebuggingAPIView, self).update(request, *args, **kwargs)
def partial_update(self, request, *args, **kwargs):
print("partial update method of debugging endpoint is called")
return super(DebuggingAPIView, self).partial_update(request, *args, **kwargs)
def destroy(self, request, *args, **kwargs):
print("destroy method of debugging endpoint is called")
return super(DebuggingAPIView, self).destroy(request, *args, **kwargs)
where class viewsets.ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, ...):.
Pylint is failed to detect multiple inheritance and shows error for no-member.
Only the inheritance's method is fine (create in my case.)
@pistex thanks for the report. Do you think it is possible to have a simpler snippet that reproduces the bug without using django?
@hippo91 is https://github.com/PyCQA/pylint/issues/2854#issuecomment-520865608 the simpler snippet that reproduce it without external dependencies you need?
@JulienPalard that's it! Sorry for not having seen it. Thanks.
Having the same issue, was this not fixed?
@ahaq0 no, it's not fixed yet (issue is still open) and there's no PR to propose a fix. If you feel it try it :) the road is long, but the way is clear ;)
Duplicate of #3901
Do one of this issues should be closed?
@Randomneo thanks for noticing this.
In fact this issue should be fixed by PyCQA/astroid#844.
I'm closing it.
Most helpful comment
@teknodan you meant
return super().test(), in method.I'm able to reproduce it:
```python
class ClassA(object):
pass
class ClassB(object):
def test(self):
return True
```python
import base
class ClassAB(base.ClassA, base.ClassB):
def method(self):
return super().test() # E1101: Super of 'ClassAB' has no 'test' member (no-member)
```bash
python --version
Python 3.5.3
Same with