0

file.py:

import attr

from base import BaseClass

@attr.s 
class MyClass(BaseClass):
  def set_ids(self, args):
    if id not in self.daily.obj_dict:
      # do some stuff
      print("testing")

base.py:

from abc import ABCMeta, abstractmethod
from six import with_metaclass
from daily import Daily

class BaseClass(with_metaclass(ABCMeta, object)):
  @abstractmethod
  def set_ids(self, args):
    pass

  def process(self, vals, ids):
    obj_dict = {
      id: vals[id]
      for id in ids
    }

    self.daily = Daily(obj_dict)

daily.py:

import attr
from builtins import object

@attr.s(frozen=True)
class Daily(object):
    obj_dict = attr.ib(default=None)

python2.7 -m pylint file.py produces the error

E:  8,17: Value 'self.daily.obj_dict' doesn't support membership test (unsupported-membership-test)

It seems the python2.7 linter cannot figure out that this attribute is a dict.

python3 -m pylint file.py produces no such error. So it seems there's something specific to python2.7 that's causing the linter to fail.

I did some further playing around and saw that if I remove the (frozen=True) (which I believe makes Daily instances immutable after instantiation), the linter error seems to disappear. Not sure why that would change anything

If I remove the base class, and just do

file.py:

from daily import Daily

class MyClass:
  def set_ids(self, args):
    if id not in self.daily.obj_dict:
      print("testing")

  def process(self, vals, ids):
    obj_dict = {
      id: vals[id]
      for id in ids
    }

    self.daily = Daily(obj_dict)

there does not appear to be this lint error

jinkins
  • 25
  • 1
  • 6
  • 1
    Does it know it's a dict? – user253751 Feb 22 '23 at 23:34
  • 1
    Either you're mistaken, and `self.obj_dict` isn't really a dict, or else it's declared in such a way that pylint doesn't know it's a dict. Show us the class definition, in particular the code where `self.obj_dict` is assigned. – John Gordon Feb 22 '23 at 23:40
  • You *must* provide a [mcve]. – juanpa.arrivillaga Feb 23 '23 at 00:47
  • So, for example, the code you provided *doesn't even compile*. It is filled with undefined names, etc. If I make a reasonable version of that and run pylint on it, I do not get the error you get, I get a bunch of errors about docstrings, and an error about `Attribute 'obj_dict' defined outside __init__`, but not the one you are reporting. – juanpa.arrivillaga Feb 23 '23 at 01:04
  • Please post a small version of the code that is _complete_, and that _also demonstrates this problem_. – John Gordon Feb 23 '23 at 01:15
  • So, it seems to have something to do with `attr.ib(default=None)`, pylint in Python 2.7 doesn't handle it correctly. Seeing as Python 2 is three years passed it's end of life. I also found: https://stackoverflow.com/questions/47972143/using-attr-with-pylint – juanpa.arrivillaga Feb 23 '23 at 03:15
  • @juanpa.arrivillaga hmm, but then why does it not have the lint error if I remove the base class? (see updated OP with the snippet). `attr.ib(default=None)` remains unchanged – jinkins Feb 23 '23 at 04:43

1 Answers1

-1

If you need to pass the linter for checking in code then add initialization to your class:

class MyClass(BaseClass):
  def __init__(self):
    self.obj_dict = dict()
  def set_ids(args):
    if id not in self.obj_dict:
      # do some stuff

Or if it's actually initialized in the base class someplace:

class MyClass(BaseClass):
  def __init__(self):
    super().__init__(self)
  def set_ids(args):
    if id not in self.obj_dict:
      # do some stuff

As long is it's set to a dict before use it won't throw a runtime error.

John Hall
  • 556
  • 1
  • 4
  • 10