pythonpython-typingforward-declaration

Python avoid mypy fails when redefining a class from another class in mutual reference


Consider a pair of classes which represent the same thing in Python and each implements a method that converts one to the other. As an example consider transforming from cartesian to polar coordinates and viceversa.

@dataclass
class CartesianCoordinates:
  x: float
  y: float
  
  def toPolarCoordinates(self) -> PolarCoordinates:
      radius = ...
      theta = ...
      result = PolarCoordinates(radius, theta)
      return result
  

@dataclass
class PolarCoordinates:
  radius: float
  theta: float

  def toCartesianCoordinates(self) -> CartesianCoordinates:
    x = ...
    y = ...
    result = CartesianCoordinates(x,y)
    return result

Since I am using PolarCoordinates before it is defined, I've tried forwarding (actually redefining) its declaration by inserting the following lines before the CartesianCoordinates definition:

class PolarCoordinates:
    # forwarding declaration
    pass

This works, in the sense that the code runs correctly but checks like mypy will fail due to the class redefinition with an error like Name PolarCoordinates already defined.

I know a real forward-declaration in Python is not possible, but is there anything equivalent that allows to reference a class before it is completely defined and that allow s the python checks like mypy to pass?


Solution

  • Python supports forward type declarations. You can either use strings:

        def toPolarCoordinates(self) -> 'PolarCoordinates':
    

    or import FROM THE FUTURE (no DeLorean required):

    from __future__ import annotations
    
    …
    
        def toPolarCoordinates(self) -> PolarCoordinates: