Using classname in Python class function for callbacks causes warning

Question:

I’ve got a question regarding the use of a Python classname within itself. I’m making a Python TCP socket wrapper that handles messages between TCP clients, and fires a callback to other classes that can subscribe to it using an onMessage() function. Other classes can subscribe to incoming TCP messages by passing a callback function that receives the message, and a reference to the TCP client wrapper (to be able to respond if required). The callback has the format Callback[[str, TCPClient]], where TCPClient is the wrapper around the socket.

Somehow Visual Studio Code does not recognize the TCPClient class in the Callback type hint. It mentions: "TCPClient" is not defined Pylance (reportUndefinedVariable). It recognizes other classes just fine, even the Thread class that the TCPClient class is based on. The only way to bypass it is by adding TCPClient within the TCPClient file itself (which I imagine could only be bad).

Some code snippet from TCPClient that shows the problem better. VS Code does not recognize TCPClient in the callback on onMessage:

class TCPClient(Thread):
    """TCP Client wrapper that handles and adds functionality to raw TCP client sockets."""
    
    # ... Constructor and message handling code left out..

    def onMessage(self, callback:Callable[[str, TCPClient]]):
        self._callbacks.append(callback)

The error only disappears if I import TCPClient within itself. Why is this the case?

Asked By: Stathis91

||

Answers:

You can use quotations for this sort of typing. It’s usually needed if you have a circular dependency between several types.

Also, don’t forget to define the return type of callable as the correct syntax is Callable[[arg, ...], result]

from threading import Thread
from typing import Callable


class TCPClient(Thread):
    """TCP Client wrapper that handles and adds functionality to raw TCP client sockets."""

    # ... Constructor and message handling code left out..

    def onMessage(self, callback: Callable[[str, 'TCPClient'], object]):
        self._callbacks.append(callback)
Answered By: Majid
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.