| 3089 | |
| 3090 | |
| 3091 | class _PdbClient: |
| 3092 | def __init__(self, pid, server_socket, interrupt_sock): |
| 3093 | self.pid = pid |
| 3094 | self.read_buf = b"" |
| 3095 | self.signal_read = None |
| 3096 | self.signal_write = None |
| 3097 | self.sigint_received = False |
| 3098 | self.raise_on_sigint = False |
| 3099 | self.server_socket = server_socket |
| 3100 | self.interrupt_sock = interrupt_sock |
| 3101 | self.pdb_instance = Pdb() |
| 3102 | self.pdb_commands = set() |
| 3103 | self.completion_matches = [] |
| 3104 | self.state = "dumb" |
| 3105 | self.write_failed = False |
| 3106 | self.multiline_block = False |
| 3107 | |
| 3108 | def _ensure_valid_message(self, msg): |
| 3109 | # Ensure the message conforms to our protocol. |
| 3110 | # If anything needs to be changed here for a patch release of Python, |
| 3111 | # the 'revision' in protocol_version() should be updated. |
| 3112 | match msg: |
| 3113 | case {"reply": str()}: |
| 3114 | # Send input typed by a user at a prompt to the remote PDB. |
| 3115 | pass |
| 3116 | case {"signal": "EOF"}: |
| 3117 | # Tell the remote PDB that the user pressed ^D at a prompt. |
| 3118 | pass |
| 3119 | case {"signal": "INT"}: |
| 3120 | # Tell the remote PDB that the user pressed ^C at a prompt. |
| 3121 | pass |
| 3122 | case { |
| 3123 | "complete": { |
| 3124 | "text": str(), |
| 3125 | "line": str(), |
| 3126 | "begidx": int(), |
| 3127 | "endidx": int(), |
| 3128 | } |
| 3129 | }: |
| 3130 | # Ask the remote PDB what completions are valid for the given |
| 3131 | # parameters, using readline's completion protocol. |
| 3132 | pass |
| 3133 | case _: |
| 3134 | raise AssertionError( |
| 3135 | f"PDB message doesn't follow the schema! {msg}" |
| 3136 | ) |
| 3137 | |
| 3138 | def _send(self, **kwargs): |
| 3139 | self._ensure_valid_message(kwargs) |
| 3140 | json_payload = json.dumps(kwargs) |
| 3141 | try: |
| 3142 | self.server_socket.sendall(json_payload.encode() + b"\n") |
| 3143 | except OSError: |
| 3144 | # This means that the client has abruptly disconnected, but we'll |
| 3145 | # handle that the next time we try to read from the client instead |
| 3146 | # of trying to handle it from everywhere _send() may be called. |
| 3147 | # Track this with a flag rather than assuming readline() will ever |
| 3148 | # return an empty string because the socket may be half-closed. |