Search code examples
pythonooppylint

Python/pylint E1101 Need assistance about proper object definition


Need a little help understanding what I am doing wrong. Probably pretty basic, but I haven't wrapped my brain around it.

My code is this:

class baseElement(object):
    def __init__(self):
        self.Portal = ''
        self.locator = ''

    def present(self):
        return self.Portal.PTF.Presence_of_Element(self.locator)    

    def visible(self):
        return self.Portal.PTF.Is_Element_Visible(self.locator)    

class baseActiveElement(baseElement):
    def hover(self):
        self.Portal.PTF.Mouse_over_element(self.locator)

    def click(self):
        self.Portal.PTF.Click_on_Element(self.locator)

    def get(self):
        return self.locator

I define the Portal when I instantiate objects from these bases and it includes some functions to perform the specified actions. This works. No problems there.

But pylint complains thusly:

E1101:  8,15:baseElement.present: Instance of 'str' has no 'PTF' member
E1101: 11,15:baseElement.visible: Instance of 'str' has no 'PTF' member
E1101: 15,8:baseActiveElement.hover: Instance of 'str' has no 'PTF' member
E1101: 18,8:baseActiveElement.click: Instance of 'str' has no 'PTF' member

What should I be doing to not cause this error?

Edit: If I change my init to this:

class baseElement(object):
def __init__(self):
    self.Portal = object
    self.Portal.PTF = self.Portal.PTF
    self.locator = ''

The pylint objection goes away, and I can see the value of defining portal as a base object, since it will eventually be a real object, but defining Portal.PTF as itself looks like nonsense to me.


Solution

  • The recommended python way is to initialize self.Portal and self.locator to None in __init__ if your API does not require client code to supply values for these attributes to the __int__ method (in which case, your class API is probably lacking a method to set the value of these two attributes).

    Pylint tries to do type inference: if the only affectation to self.Portal it can see in your code is with a string, it will infer that the type of the attribute is str, and use this to check calls performed on self.Portal.

    If you write:

    class baseElement(object):
        def __init__(self, portal, locator):
            self.Portal = portal
            self.locator = locator
    

    It will try know that it knows nothing about the type of portal and locator.

    If you have in the same module code such as:

    from somewhere import PortalClass, LocatorClass
    # [...] 
    element = SomeClassDerivingFromBaseElement(PortalClass(), LocatorClass()) 
    

    then Pylint will be able to use this to gather some knowledge about the possible type of portal and locator, and it will be able to analyze the definitions of PortalClass and LocatorClass for attributes such as PTF, and probably check the prototype of Presence_of_Element.

    Sidenote: I suggest to try to achieve some consistency in the naming of your classes, attributes and methods. Pylint will help you and you can customize the regexps it uses to match the naming conventions you use.