8

As a minimal case I have a class Example that works like in abstract capacity for a range of other classes.

class Example(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)            

class Test(Example):
    def __init__(self, foo='bar'):
        super(Test, self).__init__(foo=foo)

In the real case, Example does more things.

Is there a way to on Test inform PyCharm that Test will have one field Test.foo and even better, let it know that foo is expected to be a string?

To be clear, consider delegating the setting of fields from Example to Test not possible.

The closest I've gotten is the @ivar of Epydoc, but I can't get it to work

deinonychusaur
  • 7,094
  • 3
  • 30
  • 44
  • 1
    AFAIK, you can't. If you define the members of an object dynamically, you have to forget about hints. You could define class attributes on `Test` that will be "shadowed" by instance attributes, but it is not worth the price. Just live with it. – bgusach Apr 29 '15 at 12:27
  • *sigh*, oh well, but thank's for the answer. – deinonychusaur Apr 29 '15 at 12:30
  • Yeah pitty, but Pycharm would have to be extremely smart to understand the code and offer you hinting. In many cases I avoid "dynamic" code in favour of "manually typed" code just to have a little bit more security and enjoy the annotations as well. At the end it is a general problem of dynamically typed languages... IDEs can't do too much. – bgusach Apr 29 '15 at 12:41

2 Answers2

8

As others have mentioned, you can't. However, you can tell PyCharm to accept missing attributes with @DynamicAttrs:

class Example(object):
   """
   @DynamicAttrs
   """
   def __init__(self, **kwargs):
      for key, value in kwargs.items():
         setattr(self, key, value)

Update: If Python3.5 is an option, see this question about using type hints for dynamic attributes.

Community
  • 1
  • 1
TomBo
  • 81
  • 2
  • 3
3

I had exactly same problem you are facing. I didn't want code suggestion I just wanted PyCharm to stop warning me about undefined attributes ( foo is not attribute of class Test )

I couldn't fix the code hinting problem but I overcame the warning by implementing Example class like that

class Example(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)            

    def __getattr__(self, name):
        """
        Does absolutely nothing, only for pycharm to stop complaining about massing attributes
        This function is *only* called when python fail to find certain attribute, so it always raises exception
        """
        raise AttributeError("Attribute %s is not part of %s class" % (name, self.__class__.__name__))
Ramast
  • 7,157
  • 3
  • 32
  • 32