Search code examples
pythoncompiler-constructioninterpretertype-hinting

Python - Is there a way to make typing that declared later


I was making parser stuff, and I want to make some "typing" in my code for type hinting. But, the classes of a file has been referenced and inherited each other. So, my code is now spaghetti :(

I've tried tons of numbers of cases that I can make. I tried everything in one class, and I changed the order. But, nothing has changed. Still, got errors kinda 'Unresolved reference'

from abc import ABC, abstractmethod

class Expression(ABC):
    class Visitor(ABC):
        @abstractmethod
        def visit_assign(self, expr: Assign):
            pass

    @abstractmethod
    def accept(self, visitor: Visitor):
        pass

class Assign(Expression):
    def accept(self, visitor: Visitor):
        # ...

Assign has been declared later than Visitor class. So, it occurs "Unresolved Reference" error.


Solution

  • There are two ways to do this.

    The first is to run from __future__ import annotations, which defers annotation parsing to runtime, allowing your code to run unmodified.

    The second is to change your type annotations to strings, which has practically the same effect:

    from abc import ABC, abstractmethod
    
    class Expression(ABC):
        class Visitor(ABC):
            @abstractmethod
            def visit_assign(self, expr: 'Assign'):
                pass
    
        @abstractmethod
        def accept(self, visitor: 'Visitor'):  # not needed; for consistency only
            pass
    
    class Assign(Expression):
        def accept(self, visitor: 'Visitor'):
            pass