Avoid Pylint warning E1101: 'Instance of .. has no .. member' for class with dynamic attributes

Question:

Imagine a function which dynamically adds attributes to an object using setattr. The reason for doing so is that I want to map some external structure (e.g. a given parameter tree) to an object:

my_object = SomeClass()
apply_structure(my_object, some_descriptor)
my_object.device1.enabled = True

Technically this works but of course Pylint rightly complains about ‘device1’ being not a member of SomeClass.

I could disable the warning but that would be bad (because I still want to get the warning in all cases when the attribute does not exist because of misspelling, etc).

Is there a common and legal (Pylint-proof) way to dynamically add members to an object that not leads to warnings?

Alternatively: Can I disable Pylint for just one object rather than a line/block/file?

Explanation:

You might wonder why I should equip an object with member attributes dynamically when I plan to access these attributes in a hard-coded way later.

The reason is: I have a dynamic part of the program (where the decoration happens) and a static part which is specialized for a certain scenario. So I could also create a static class for this scenario but that would be overkill in a lot of situations.

The following specialized code might allow access to some parameter of a device which might be attached to some bus:

class MyDeviceHandler:
   on_get_some_subtree_element(self):
      return _some_internal_value
   on_set_some_subtree_element(self, value):
      _some_internal_value = value

dev = MyDeviceHandler()

decorate_object_with_device_structure(dev, 'some/attached/device')

dev.some.subtree.element = 5       <--- will call the set-callback
x = dev.some.subtree.element       <--- will call the get-callback

So the structure behind 'some/attached/device' might be arbitrary and very complex and I don’t want to reproduce it in a class structure.

One way to get rid of this warning would be to create/access a dict based tree:

dev['some']['subtree']['element'] = 5

But this is harder to write and not nice to read – I would only do this to quieten Pylint.

Asked By: frans

||

Answers:

Just to provide the answer that works for me now – as The Compiler suggested you can add a rule for the problematic class in your projects .pylintrc:

[TYPECHECK]
ignored-classes=Fysom,MyClass
Answered By: frans

This page describes the error and gives an easy way to address it directly in the code. tl;dr

Used when an object (variable, function, …) is accessed for a non-existent member.

False positives: This message may report object members that are created dynamically, but exist at the time they are accessed.

A commentor mentions that it can be disabled on a single line at the top of the file with # pylint: disable=no-member. I also found that you can use # pylint: disable=E1101 based on this reddit entry.

Answered By: user2577

Try this! My problem solved!

Pylint doesn’t understand the Django’s dynamic filed. Thus, we need to teach what the Django is to Pylint

*for vscode in Windows 10 *

$ pip install pylint-django
$ cd your_project_folder
$ code . // run vscode  

Install extension for Python, Django Snippets, Django Template in vscode

Open .vscode/settings.json in vscode and add:

{
   "python.linting.pylintEnabled": true,
   "python.linting.enabled": true,
   "python.pythonPath": "venv\Scripts\python.exe",
   "python.linting.pylintArgs": [
       "--load-plugins",
       "pylint_django"
   ],
}
Answered By: yongtaek jun

PyLint gives this type of errors on two cases Link:

  • Used when an object (variable, function, …) is accessed for a
    non-existent member.

  • False positives: This message may report object members that are
    created dynamically, but exist at the time they are accessed.

As this error is identified as E1101 error. You can solve the issue by adding the following line in your code.

# pylint: disable=E1101
Answered By: user10424859

For me just installing pylint-django solved the issue:

pip install pylint-django
Answered By: mona-mk

I was able to avoid this warning by adding the __getattr__ method to my class, which python calls when an attribute is not found on an object. Although definitely not the cleanest solution, it worked for my particular use-case as pylint considers the object valid.

import warnings
class AppConfiguration(object):     
    ... 
    def __getattr__(self, name):
        ''' will only get called for undefined attributes '''
        warnings.warn('No member "%s" contained in settings config.' % name)
        return ''

More information about the __getattr__ method can be found here.

Answered By: Joshua

Hesitate to add to this answer, since I’d prefer if there was an explicit way to do this with pylint. But there is a hack around solution that is working (at least as of pylint 2.7.4). In this example code I use a "getattr" null-op to prevent pylint from thinking it knows anything about the object. Obviously something this simple might not continue working going forward, but I like the fact that you can control which exact things you want pylint to ignore without having to touch anything other than source file, and without having to disable the check globally throughout the source file.

class MyClass():
    """an empty class"""

myc = MyClass()
print(myc.hello_world)  # pylint no-member
myc = globals()['myc']
print(myc.hello_world)  # no error flagged

class MyDeviceHolder1():
    """a device holder class"""
    def __init__(self):
        self.devices = MyClass()

mdh1 = MyDeviceHolder1()
print(mdh1.devices.hello_world)  # pylint no-member

class MyDeviceHolder2():
    """a device holder class"""
    def __init__(self):
        self.devices = MyClass()
        self.devices = getattr(self, 'devices')

mdh2 = MyDeviceHolder2()
print(mdh2.devices.hello_world)  # no error flagged
print(mdh2.devixes.hello_world)  # pylint no-member
Answered By: Fred S

Another possible reason for getting the no-member is, that the self argument of the __init_() method of this class is missing:

Wrong:

class foo:
    def __init__(bar):
        self.bar = bar

Right:

class foo:
    def __init__(self, bar):
        self.bar = bar

Application code to get the no-member warning:

x = foo('bar')
print(x.bar) # <-- this line will be the reported error line
Answered By: dothebart
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.