I'm currently building an algebraic data type to represent the state of a task, as per this question, but want to extend it to make it a little cleaner to use.
Here are the definitions of my states:
@dataclass
class StatusWaiting:
# Nothing
pass
@dataclass
class StatusRunning:
progress: float
@dataclass
class StatusComplete:
result: int
@dataclass
class StatusFailure:
reason: str
However, the way that I intend to use these variants has two seemingly incompatible behaviours:
Type annotation should behave as follows:
Status = StatusWaiting | StatusRunning | StatusComplete | StatusFailure
def get_status() -> Status:
...
Instantiation should behave as follows:
class Status:
Waiting = StatusWaiting
Running = StatusRunning
Failed = StatusFailed
Complete = StatusComplete
my_status = Status.Running(0.42)
How can I define the Status
type so that I can have it behave as a union when used as a type annotation, and also behave as a collection of the variants for simple initialization?
Status = ???
def get_status() -> Status:
return Status.Failed("Something has gone horribly wrong")
I've tried using an Enum
, but this doesn't appear to allow for instantiation.
class Status(Enum):
Waiting = StatusWaiting
Running = StatusRunning
Complete = StatusComplete
Failure = StatusFailure
def get_status() -> Status:
# Mypy: "Status" not callable
return Status.Complete(42)