Review feedback and fixup more types

This commit is contained in:
rchiodo 2024-07-24 22:40:47 +00:00
parent 7a1350a740
commit 8ce6670e15
8 changed files with 36 additions and 31 deletions

View file

@ -219,9 +219,9 @@ class Client(components.Component):
if self.session.no_debug:
servers.dont_wait_for_first_connection()
request("debugOptions", json.array(str))
request_options = request("debugOptions", json.array(str))
self.session.debug_options = debug_options = set(
request_options
)
f(self, request)
@ -656,7 +656,7 @@ class Client(components.Component):
result = {"debugpy": {"version": debugpy.__version__}}
if self.server:
try:
pydevd_info: messaging.AssociatableMessageDict = self.server.channel.request("pydevdSystemInfo")
pydevd_info: messaging.MessageDict = self.server.channel.request("pydevdSystemInfo")
except Exception:
# If the server has already disconnected, or couldn't handle it,
# report what we've got.
@ -777,7 +777,7 @@ class Client(components.Component):
def serve(host, port):
global listener
listener = sockets.serve("Client", Client, host, port) # type: ignore
listener = sockets.serve("Client", Client, host, port)
sessions.report_sockets()
return listener.getsockname()

View file

@ -399,7 +399,7 @@ class Server(components.Component):
def serve(host="127.0.0.1", port=0):
global listener
listener = sockets.serve("Server", Connection, host, port) # type: ignore
listener = sockets.serve("Server", Connection, host, port)
sessions.report_sockets()
return listener.getsockname()

View file

@ -408,7 +408,7 @@ class MessageDict(collections.OrderedDict):
raise message.isnt_valid("{0}{1}", json.repr(key), err)
return value
def _invalid_if_no_key(func: Callable[..., Any]): # type: ignore
def _invalid_if_no_key(func: Callable[..., Any]): # pyright: ignore[reportSelfClsParameterName]
def wrap(self, key, *args, **kwargs):
try:
return func(self, key, *args, **kwargs)
@ -425,11 +425,11 @@ class MessageDict(collections.OrderedDict):
del _invalid_if_no_key
class AssociatableMessageDict(MessageDict):
class AssociableMessageDict(MessageDict):
def associate_with(self, message: Message):
self.message = message
def is_associatable(obj) -> TypeIs[AssociatableMessageDict]:
def is_associable(obj) -> TypeIs[AssociableMessageDict]:
return isinstance(obj, MessageDict) and hasattr(obj, "associate_with")
def _payload(value):
@ -446,7 +446,7 @@ def _payload(value):
# Missing payload. Construct a dummy MessageDict, and make it look like it was
# deserialized. See JsonMessageChannel._parse_incoming_message for why it needs
# to have associate_with().
value = AssociatableMessageDict(None)
value = AssociableMessageDict(None)
return value
@ -471,7 +471,7 @@ class Message(object):
"""
def __str__(self):
return json.repr(self.json).__str__() if self.json is not None else repr(self)
return str(json.repr(self.json)) if self.json is not None else repr(self)
def describe(self):
"""A brief description of the message that is enough to identify it.
@ -483,14 +483,17 @@ class Message(object):
raise NotImplementedError
@property
def payload(self) -> MessageDict:
def payload(self) -> MessageDict | Exception:
"""Payload of the message - self.body or self.arguments, depending on the
message type.
"""
raise NotImplementedError
def __call__(self, *args, **kwargs):
def __call__(self, *args, **kwargs) -> MessageDict | Any | int | float:
"""Same as self.payload(...)."""
assert not isinstance(self.payload, Exception)
if args.count == 0 and kwargs == {}:
return self.payload
return self.payload(*args, **kwargs)
def __contains__(self, key):
@ -573,12 +576,12 @@ class Event(Message):
the appropriate exception type that applies_to() the Event object.
"""
def __init__(self, channel, seq, event, body, json=None):
def __init__(self, channel, seq, event, body: MessageDict, json=None):
super().__init__(channel, seq, json)
self.event = event
if is_associatable(body):
if is_associable(body):
body.associate_with(self)
self.body = body
@ -667,12 +670,12 @@ class Request(Message):
the appropriate exception type that applies_to() the Request object.
"""
def __init__(self, channel, seq, command, arguments, json=None):
def __init__(self, channel, seq, command, arguments: MessageDict, json=None):
super().__init__(channel, seq, json)
self.command = command
if is_associatable(arguments):
if is_associable(arguments):
arguments.associate_with(self)
self.arguments = arguments
@ -787,7 +790,7 @@ class OutgoingRequest(Request):
def describe(self):
return f"{self.seq} request {json.repr(self.command)} to {self.channel}"
def wait_for_response(self, raise_if_failed=True)-> AssociatableMessageDict | Exception:
def wait_for_response(self, raise_if_failed=True)-> MessageDict:
"""Waits until a response is received for this request, records the Response
object for it in self.response, and returns response.body.
@ -804,6 +807,8 @@ class OutgoingRequest(Request):
if raise_if_failed and not self.response.success and isinstance( self.response.body, BaseException):
raise self.response.body
assert not isinstance(self.response.body, Exception)
return self.response.body
def on_response(self, response_handler):
@ -889,13 +894,13 @@ class Response(Message):
the appropriate exception type that applies_to() the Response object.
"""
def __init__(self, channel, seq, request, body, json=None):
def __init__(self, channel, seq, request, body: MessageDict | Exception, json=None):
super().__init__(channel, seq, json)
self.request = request
"""The request to which this is the response."""
if is_associatable(body):
if is_associable(body):
body.associate_with(self)
self.body = body
"""Body of the response if the request was successful, or an instance
@ -1366,7 +1371,7 @@ class JsonMessageChannel(object):
# for all JSON objects, and track them so that they can be later wired up to
# the Message they belong to, once it is instantiated.
def object_hook(d):
d = AssociatableMessageDict(None, d)
d = AssociableMessageDict(None, d)
if "seq" in d:
self._prettify(d)
setattr(d, "associate_with", associate_with)

View file

@ -141,9 +141,9 @@ class ThreadSafeSingleton(Singleton):
# with @threadsafe_method. Such methods should perform the necessary locking to
# ensure thread safety for the callers.
@staticmethod
def assert_locked(self): # type: ignore
def assert_locked(self):
lock = type(self)._lock
assert lock is not None
assert lock.acquire(blocking=False), (
"ThreadSafeSingleton accessed without locking. Either use with-statement, "
"or if it is a method or property, mark it as @threadsafe_method or with "

View file

@ -5,7 +5,7 @@
import socket
import sys
import threading
from typing import Callable, Union
from typing import Any, Callable, Union
from debugpy.common import log
from debugpy.common.util import hide_thread_from_debugger
@ -89,7 +89,7 @@ def close_socket(sock):
sock.close()
def serve(name: str, handler: Callable[[socket.socket], None], host: str, port: int=0, backlog=socket.SOMAXCONN, timeout: Union[int, None]=None):
def serve(name: str, handler: Callable[[socket.socket], Any], host: str, port: int=0, backlog=socket.SOMAXCONN, timeout: Union[int, None]=None):
"""Accepts TCP connections on the specified host and port, and invokes the
provided handler function for every new connection.

View file

@ -91,7 +91,7 @@ def spawn(process_name, cmdline, env, redirect_output):
try:
global process
process = subprocess.Popen(cmdline, env=env, bufsize=0, **kwargs) # type: ignore
process = subprocess.Popen(cmdline, env=env, bufsize=0, **kwargs)
except Exception as exc:
raise messaging.MessageHandlingError(
"Couldn't spawn debuggee: {0}\n\nCommand line:{1!r}".format(
@ -244,7 +244,7 @@ def _wait_for_user_input():
log.debug("msvcrt available - waiting for user input via getch()")
sys.stdout.write("Press any key to continue . . . ")
sys.stdout.flush()
msvcrt.getch() # type: ignore
msvcrt.getch() # pyright: ignore[reportPossiblyUnboundVariable, reportAttributeAccessIssue]
else:
log.debug("msvcrt not available - waiting for user input via read()")
sys.stdout.write("Press Enter to continue . . . ")

View file

@ -64,14 +64,14 @@ def _errcheck(is_error_result=(lambda result: not result)):
def impl(result, func, args):
if is_error_result(result):
log.debug("{0} returned {1}", func.__name__, result)
raise ctypes.WinError() # type: ignore
raise ctypes.WinError() # pyright: ignore[reportAttributeAccessIssue]
else:
return result
return impl
kernel32 = ctypes.windll.kernel32 # type: ignore
kernel32 = ctypes.windll.kernel32 # pyright: ignore[reportAttributeAccessIssue]
kernel32.AssignProcessToJobObject.errcheck = _errcheck()
kernel32.AssignProcessToJobObject.restype = BOOL

View file

@ -54,16 +54,16 @@ class _settrace():
def ensure_logging():
"""Starts logging to log.log_dir, if it hasn't already been done."""
if ensure_logging.ensured: # type: ignore
if ensure_logging.ensured: # pyright: ignore[reportFunctionMemberAccess]
return
ensure_logging.ensured = True # type: ignore
ensure_logging.ensured = True # pyright: ignore[reportFunctionMemberAccess]
log.to_file(prefix="debugpy.server")
log.describe_environment("Initial environment:")
if log.log_dir is not None:
pydevd.log_to(log.log_dir + "/debugpy.pydevd.log")
ensure_logging.ensured = False # type: ignore
ensure_logging.ensured = False # pyright: ignore[reportFunctionMemberAccess]
def log_to(path):