define type of queue items in python

Question:

I have a function with a queue.Queue as an argument. This queue contains elements of my self defined class PlantCommand and should be processed by another thread.
Therefor, I defined the thread target function in the following way:

def run(command_queue: queue.Queue, status: PlantStatus) -> None:

When I now remove one item from the queue using its get()-function, the type of the element is not known anymore. Is there a way to define the type of the queue items? Something like

def run(command_queue: queue.Queue<PlantCommand>, status: PlantStatus) -> None:

Or can I define the item type afterwards?
I often use the auto completition and also check my code using the syntax highlighting. And in the case of missing type information, it doesn’t work anymore. I.e. when I type in _cmd. I get no suggestions related to the PlantCommand-class of the items, that I put into the queue.

syntax highlighting

class PlantCommand():
    NO_CMD = 0
    ENABLE_REMOTE_CONTROL = 1
    RUN_NC_SCRIPT = 2
    ABORT = 3
    TERMINATE = 4

    _valid_commands = (NO_CMD,
                       ENABLE_REMOTE_CONTROL,
                       RUN_NC_SCRIPT,
                       ABORT,
                       TERMINATE)

    def __init__(self, command: int = NO_CMD, file: str = '') -> None:
        if command not in PlantCommand._valid_commands:
            raise ValueError('No valid command.')
        self.command = command
        self.file = file

def run(command_queue: queue.Queue, status: PlantStatus) -> None:
    logging.debug('Plant thread started.')
    # statemachine
    while True:
        try:
            _cmd = command_queue.get_nowait()
            if _cmd.command == PlantCommand.TERMINATE:
                pass
        except queue.Empty:
            # no item in queue -> continue
            pass
Asked By: paul_schaefer

||

Answers:

Just use proper Python syntax for typing container items:

def run(command_queue: queue.Queue[int], status: PlantStatus) -> None:
    ...

Since you are new to the language, keep in mind that typing is optional and only requested by the tooling that surrounds your development stage: if you ever get to a situation where proper typing would be too complicated, you can always just ignore it altogether.

(in time: this syntax is implemented for queue.Queue from Python 3.9 onwards)

This is documented here: https://docs.python.org/3.9/library/stdtypes.html#types-genericalias – although the documentation only uses examples of the built-in types, other collections defined in Python’s stdlib also work that way. The full reasoning and implementation is described on PEP 585 – https://peps.python.org/pep-0585/ . Support for this even comes for free if one implements their collection classes inheriting from the appropriate abstract base classes in collections.abc .

Nonetheless, regardless of being able to find the proper documentation for typing something, keep in mind that Typing expressions following the : must be valid ("classic") Python expressions themselves. So the < and > symbos are only used as operators in the language, and never as brackets – and since the language could actually make use of the [ and ] for classes even before any language changes were made to support it (as operator overloading for classes would already work since Python 2.2, and it was just a matter of defining how [ ] indexing would work for classes), those were adopted.

Answered By: jsbueno
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.