pythonpython-typingpyright

coc-pyright fail to report reportAttributeAccessIssue if __setattr__ is provided


from pydantic import BaseModel
class User2(BaseModel):
    name:str
    age: int
    '''
    def __setattr__(self, key, value):
        super().__setattr__(key, value)
    '''
user2 = User2(name="Alice", age=1)
>>> user2.foo = 1 # Should report: Cannot assign to attribute "foo" for class "User2" \ Attribute "foo" is unknown

if I uncomment the __setattr__ function, user2.foo = 1, coc-pyright doesn't report an error. I want to use a __setattr__ method but also have it report an error. How can I do this?


Solution

  • The presence of __setattr__ does not report reportAttributeAccess issue for pyright as well as mypy. The trick is to not reveal that such a method exists. This can be done by defining it in an if not TYPE_CHECKING: block. Linters and checkers might mark the code there as unreachable which can be undesired, therefore you can redirect the call to a normal private method that is executed instead:

    from pydantic import BaseModel
    from typing import TYPE_CHECKING
    
    
    class User2(BaseModel):
        name: str
        age: int
    
        if not TYPE_CHECKING:
            # hide from type-checker to report AttributeAccessIssue
            def __setattr__(self, key, value):
                self._setattr(key, value)
    
        # Use a different method to not create "unreachable code"
        def _setattr(self, key, value):
            super().__setattr__(key, value)
    
    
    user2 = User2(name="Alice", age=1)
    user2.foo = 1  # reportAttributeAccess