-1

PyCharm Python Lint does not give warning for incorrect class members. It continues running my code, I have productName member below, not productNameTest.

PyCharm Settings > Misspelling Warnings is enabled on desktop, however if member "is spelled correctly" but doesn't exist in class, no warning is issued.

How can we setup PyCharm to send a warning for no member?

Product Model:

@dataclass(init=False)
class ProductModel:
    
    productId: int
    productName: str

class ProductService:

    def __init__(self, productModel: ProductModel):
        self.productModel= productModel

    def getProductModel(self, curveData):
        self.productModel.productNameTest = "ABCD"  # productNameTest is not a member and should give warning
bad_coder
  • 11,289
  • 20
  • 44
  • 72
mattsmith5
  • 540
  • 4
  • 29
  • 67
  • 2
    `Product Service:` is a syntax error. – Barmar Mar 23 '21 at 02:13
  • Note that you aren't assigning the nonexistent name to an instance of your DataClass, you're assigning it *to the DataClass itself* - there's no practical way for that to be detected as an error, since there's no mechanism for declaring what attributes the class should have. Instead, the class acts as declaration for what attributes its instances have. – jasonharper Mar 23 '21 at 02:43
  • hi @jasonharper so what is the solution? should I rewrite the code, feel free to place in answer, and I can send points – mattsmith5 Mar 23 '21 at 04:01
  • I am using an instance method? – mattsmith5 Mar 23 '21 at 04:10
  • @mattsmith5 beyond this it starts getting more complicated, you can [use these techniques](https://stackoverflow.com/q/3603502) the most appropriate depends on the exact circumstances of what you want to do. – bad_coder Mar 23 '21 at 12:57
  • @jasonharper I'm pretty sure the attribute is assigned on the instance and not on the class in this case (just tested it). Granted, giving a quick comment is error prone (I have to look this stuff up in the documentation every time). I'm just saying so the OP doesn't get confused. I'll delete this comment after you've read it. – bad_coder Mar 23 '21 at 13:02

1 Answers1

1

if member "is spelled correctly" but doesn't exist in class, no warning is issued.

This is not how Python class instances work. What you are doing is an attribute assignment that effectively adds the attribute productNameTest to the instance of ProductModel in an instance of ProductService. Python allows such attributions -as explained below- because it's dynamic and the dataclass definition doesn't forbid dynamically setting attributes on the instance.

3. Data model

Class instances

Attribute assignments and deletions update the instance’s dictionary, never a class’s dictionary. (...)

Special attributes: __dict__ is the attribute dictionary; __class__ is the instance’s class.

If you check __dict__ before and after the assignment, you can see the attribute was added and it's valid Python.

>>> the_instance = ProductService(ProductModel(1, "two"))
>>> the_instance.productModel.__dict__

{'productId': 1, 'productName': 'two'}

>>> the_instance.get_product_model("curve_data_str")
>>> the_instance.productModel.__dict__

 {'productId': 1, 'productName': 'two', 'productNameTest': 'ABCD'}

How can we setup PyCharm to send a warning for no member?

There's nothing here for the PyCharm linter to warn you about, if you try a 3rd party linter there will also be no warning, it's the programmer's job to know about this. If you continue reading the documentation excerpt above the solution becomes apparent: what you can do is implement a run-time exception (which is not a linter warning):

If the class has a __setattr__() or __delattr__() method, this is called instead of updating the instance dictionary directly.

NB. I changed @dataclass(init=False) to @dataclass(init=True) just for the convenience of having the __init__ available in a single line, it doesn't change anything in regard to the attribute assignment this question is about.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
  • interesting, by the way, I set @dataclass(init=False), so I can create a instance, without having to set all the instance members At Once, I gradually calculate them throughout my program due to complexity and gathering data, do you recommend against this? or have alternative – mattsmith5 Mar 23 '21 at 15:14
  • also, I know lot of the items you mentioned about Python, so how do I safely update value, while triggering a mispelling error? is there any possible way? setattr was not triggering warning either – mattsmith5 Mar 23 '21 at 16:17
  • You can't get an IDE linter warning for this case (the answer demonstrates why not). Implementing `__setattr__` is shown in the thread I linked under the question. – bad_coder Mar 23 '21 at 17:11