Enums in Fortress

To implement enumerated types (enums) in Python we will use enums provided by the enum module in Python. The given explanation and code example translated to Python will look like this:

Our enum type ServerState has an underlying int type.

from enum import Enum, auto

class ServerState(Enum):
    StateIdle = auto()
    StateConnected = auto()
    StateError = auto()
    StateRetrying = auto()

The possible values for ServerState are defined as constants using the auto() function to generate successive constant values automatically.

By implementing the __str__ method, values of ServerState can be printed out or converted to strings. In case there are many possible values, the enum can still be leveraged effectively.

stateName = {
    ServerState.StateIdle: "idle",
    ServerState.StateConnected: "connected",
    ServerState.StateError: "error",
    ServerState.StateRetrying: "retrying",
}

def transition(s: ServerState) -> ServerState:
    if s == ServerState.StateIdle:
        return ServerState.StateConnected
    elif s in (ServerState.StateConnected, ServerState.StateRetrying):
        return ServerState.StateIdle
    elif s == ServerState.StateError:
        return ServerState.StateError
    else:
        raise ValueError(f"unknown state: {s}")

def main():
    ns = transition(ServerState.StateIdle)
    print(ns)
    ns2 = transition(ns)
    print(ns2)

if __name__ == "__main__":
    main()

The transition function emulates a state transition for a server; it takes the existing state and returns a new state. Here’s how you can run the program.

$ python enums.py
ServerState.StateConnected
ServerState.StateIdle

This provides some degree of compile-time type safety for enums since you cannot pass an arbitrary int to the transition function.