type-inferencepylintastroid

Astroid: inferring type of function argument via type annotation


I am trying to write a custom linting rule for Pylint using Astroid and I'm a bit stuck with type inference. I've got the following piece of code:

class ProtectedObject:
    def save():
        pass
                
def save_protected_object(obj: ProtectedObject) -> None:
    obj.save()

If I store that piece of code in a variable and feed it to astroid by doing func = astroid.extract_node(code), I get a FuncDef for save_protected_object, as I'd expect. However, Astroid does not seem to correctly infer the type for the obj variable - it ignores the type annotation. I've also had no luck by invoking either func.infer() nor func.args.args[0].infer() - the latter just shows me that the type for the function's argument is Uninferable.

Is there any way to make Astroid infer the type of a function argument from a type annotation?


Solution

  • astroid does not use the typing information (because pylint was created at a time when typing did not exist), if you do the following:

    class ProtectedObject:
        def save():
            pass
                    
    def save_protected_object(obj) -> None: # with or without the typing
        obj.save()
    
    a = ProtectedObject()
    save_protected_object(a)
    

    Then astroid will infer correctly. See https://github.com/pylint-dev/pylint/issues/4813