Skip to content

Commit 9631bc8

Browse files
author
Pavel Minaev
authored
Merge pull request #40 from int19h/client
s/IDE/client/
2 parents 0529b8f + 8c114ed commit 9631bc8

15 files changed

Lines changed: 99 additions & 149 deletions

File tree

src/debugpy/adapter/__main__.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
def main(args):
2323
from debugpy import adapter
2424
from debugpy.common import compat, log, sockets
25-
from debugpy.adapter import ide, servers, sessions
25+
from debugpy.adapter import clients, servers, sessions
2626

2727
if args.for_server is not None:
2828
if os.name == "posix":
@@ -58,15 +58,13 @@ def main(args):
5858
else:
5959
endpoints = {"server": {"host": server_host, "port": server_port}}
6060
try:
61-
ide_host, ide_port = ide.serve(args.host, args.port)
61+
client_host, client_port = clients.serve(args.host, args.port)
6262
except Exception as exc:
6363
if args.for_server is None:
6464
raise
65-
endpoints = {
66-
"error": "Can't listen for IDE connections: " + str(exc)
67-
}
65+
endpoints = {"error": "Can't listen for client connections: " + str(exc)}
6866
else:
69-
endpoints["client"] = {"host": ide_host, "port": ide_port}
67+
endpoints["client"] = {"host": client_host, "port": client_port}
7068

7169
if args.for_server is not None:
7270
log.info(
@@ -96,9 +94,7 @@ def main(args):
9694

9795
listener_file = os.getenv("DEBUGPY_ADAPTER_ENDPOINTS")
9896
if listener_file is not None:
99-
log.info(
100-
"Writing endpoints info to {0!r}:\n{1!j}", listener_file, endpoints
101-
)
97+
log.info("Writing endpoints info to {0!r}:\n{1!j}", listener_file, endpoints)
10298

10399
def delete_listener_file():
104100
log.info("Listener ports closed; deleting {0!r}", listener_file)
@@ -115,13 +111,13 @@ def delete_listener_file():
115111
raise log.exception("Error writing endpoints info to file:")
116112

117113
if args.port is None:
118-
ide.IDE("stdio")
114+
clients.Client("stdio")
119115

120116
# These must be registered after the one above, to ensure that the listener sockets
121117
# are closed before the endpoint info file is deleted - this way, another process
122118
# can wait for the file to go away as a signal that the ports are no longer in use.
123119
atexit.register(servers.stop_serving)
124-
atexit.register(ide.stop_serving)
120+
atexit.register(clients.stop_serving)
125121

126122
servers.wait_until_disconnected()
127123
log.info("All debug servers disconnected; waiting for remaining sessions...")
Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from debugpy.adapter import components, servers, sessions
1414

1515

16-
class IDE(components.Component):
17-
"""Handles the IDE side of a debug session."""
16+
class Client(components.Component):
17+
"""Handles the client side of a debug session."""
1818

1919
message_handler = components.Component.message_handler
2020

@@ -36,7 +36,7 @@ class Expectations(components.Capabilities):
3636

3737
def __init__(self, sock):
3838
if sock == "stdio":
39-
log.info("Connecting to IDE over stdio...", self)
39+
log.info("Connecting to client over stdio...", self)
4040
stream = messaging.JsonIOStream.from_stdio()
4141
# Make sure that nothing else tries to interfere with the stdio streams
4242
# that are going to be used for DAP communication from now on.
@@ -46,22 +46,22 @@ def __init__(self, sock):
4646
stream = messaging.JsonIOStream.from_socket(sock)
4747

4848
with sessions.Session() as session:
49-
super(IDE, self).__init__(session, stream)
49+
super(Client, self).__init__(session, stream)
5050

5151
self.client_id = None
5252
"""ID of the connecting client. This can be 'test' while running tests."""
5353

5454
self.has_started = False
55-
"""Whether the "launch" or "attach" request was received from the IDE, and
55+
"""Whether the "launch" or "attach" request was received from the client, and
5656
fully handled.
5757
"""
5858

5959
self.start_request = None
60-
"""The "launch" or "attach" request as received from the IDE.
60+
"""The "launch" or "attach" request as received from the client.
6161
"""
6262

6363
self._initialize_request = None
64-
"""The "initialize" request as received from the IDE, to propagate to the
64+
"""The "initialize" request as received from the client, to propagate to the
6565
server later."""
6666

6767
self._deferred_events = []
@@ -70,11 +70,11 @@ def __init__(self, sock):
7070
"""
7171

7272
self._known_subprocesses = set()
73-
"""servers.Connection instances for subprocesses that this IDE has been
73+
"""servers.Connection instances for subprocesses that this client has been
7474
made aware of.
7575
"""
7676

77-
session.ide = self
77+
session.client = self
7878
session.register()
7979

8080
# For the transition period, send the telemetry events with both old and new
@@ -97,26 +97,26 @@ def __init__(self, sock):
9797
)
9898

9999
def propagate_after_start(self, event):
100-
# pydevd starts sending events as soon as we connect, but the IDE doesn't
100+
# pydevd starts sending events as soon as we connect, but the client doesn't
101101
# expect to see any until it receives the response to "launch" or "attach"
102-
# request. If IDE is not ready yet, save the event instead of propagating
102+
# request. If client is not ready yet, save the event instead of propagating
103103
# it immediately.
104104
if self._deferred_events is not None:
105105
self._deferred_events.append(event)
106106
log.debug("Propagation deferred.")
107107
else:
108-
self.ide.channel.propagate(event)
108+
self.client.channel.propagate(event)
109109

110110
def _propagate_deferred_events(self):
111-
log.debug("Propagating deferred events to {0}...", self.ide)
111+
log.debug("Propagating deferred events to {0}...", self.client)
112112
for event in self._deferred_events:
113113
log.debug("Propagating deferred {0}", event.describe())
114-
self.ide.channel.propagate(event)
115-
log.info("All deferred events propagated to {0}.", self.ide)
114+
self.client.channel.propagate(event)
115+
log.info("All deferred events propagated to {0}.", self.client)
116116
self._deferred_events = None
117117

118-
# Generic event handler. There are no specific handlers for IDE events, because
119-
# there are no events from the IDE in DAP - but we propagate them if we can, in
118+
# Generic event handler. There are no specific handlers for client events, because
119+
# there are no events from the client in DAP - but we propagate them if we can, in
120120
# case some events appear in future protocol versions.
121121
@message_handler
122122
def event(self, event):
@@ -166,7 +166,6 @@ def initialize_request(self, request):
166166
# See https://github.com/microsoft/vscode/issues/4902#issuecomment-368583522
167167
# for the sequence of request and events necessary to orchestrate the start.
168168
def _start_message_handler(f):
169-
170169
@components.Component.message_handler
171170
def handle(self, request):
172171
assert request.is_request("launch", "attach")
@@ -195,7 +194,9 @@ def handle(self, request):
195194
# The launcher is doing output redirection, so we don't need the
196195
# server to do it, as well.
197196
arguments = dict(arguments)
198-
arguments["debugOptions"] = list(debug_options - {"RedirectOutput"})
197+
arguments["debugOptions"] = list(
198+
debug_options - {"RedirectOutput"}
199+
)
199200

200201
if arguments.get("redirectOutput"):
201202
arguments = dict(arguments)
@@ -232,7 +233,7 @@ def handle(self, request):
232233
},
233234
)
234235

235-
# Let the IDE know that it can begin configuring the adapter.
236+
# Let the client know that it can begin configuring the adapter.
236237
self.channel.send_event("initialized")
237238

238239
self.start_request = request
@@ -310,12 +311,12 @@ def attach_request(self, request):
310311
#
311312
# If neither is specified, and "waitForAttach" is false, this is attach-by-socket
312313
# in which the server has spawned the adapter via debugpy.listen(). There
313-
# is no PID known to the IDE in advance, but the server connection should be
314+
# is no PID known to the client in advance, but the server connection should be
314315
# either be there already, or the server should be connecting shortly, so there
315316
# must be a timeout.
316317
#
317318
# In the last two cases, if there's more than one server connection already,
318-
# this is a multiprocess re-attach. The IDE doesn't know the PID, so we just
319+
# this is a multiprocess re-attach. The client doesn't know the PID, so we just
319320
# connect it to the oldest server connection that we have - in most cases, it
320321
# will be the one for the root debuggee process, but if it has exited already,
321322
# it will be some subprocess.
@@ -379,7 +380,7 @@ def configurationDone_request(self, request):
379380
self.start_request.respond({})
380381
self._propagate_deferred_events()
381382

382-
# Notify the IDE of any child processes of the debuggee that aren't already
383+
# Notify the client of any child processes of the debuggee that aren't already
383384
# being debugged.
384385
for conn in servers.connections():
385386
if conn.server is None and conn.ppid == self.session.pid:
@@ -418,15 +419,15 @@ def debugpySystemInfo_request(self, request):
418419

419420
@message_handler
420421
def terminate_request(self, request):
421-
self.session.finalize('IDE requested "terminate"', terminate_debuggee=True)
422+
self.session.finalize('client requested "terminate"', terminate_debuggee=True)
422423
return {}
423424

424425
@message_handler
425426
def disconnect_request(self, request):
426427
terminate_debuggee = request("terminateDebuggee", bool, optional=True)
427428
if terminate_debuggee == ():
428429
terminate_debuggee = None
429-
self.session.finalize('IDE requested "disconnect"', terminate_debuggee)
430+
self.session.finalize('client requested "disconnect"', terminate_debuggee)
430431
return {}
431432

432433
def notify_of_subprocess(self, conn):
@@ -460,7 +461,7 @@ def notify_of_subprocess(self, conn):
460461

461462
def serve(host, port):
462463
global listener
463-
listener = sockets.serve("IDE", IDE, host, port)
464+
listener = sockets.serve("Client", Client, host, port)
464465
return listener.getsockname()
465466

466467

src/debugpy/adapter/components.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __init__(self, type):
2020

2121

2222
class Component(util.Observable):
23-
"""A component managed by a debug adapter: IDE, launcher, or debug server.
23+
"""A component managed by a debug adapter: client, launcher, or debug server.
2424
2525
Every component belongs to a Session, which is used for synchronization and
2626
shared data.
@@ -65,8 +65,8 @@ def __str__(self):
6565
return fmt("{0}[{1}]", type(self).__name__, self.session.id)
6666

6767
@property
68-
def ide(self):
69-
return self.session.ide
68+
def client(self):
69+
return self.session.client
7070

7171
@property
7272
def launcher(self):

src/debugpy/adapter/launchers.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,24 @@ def __init__(self, session, stream):
3434
@message_handler
3535
def process_event(self, event):
3636
self.pid = event("systemProcessId", int)
37-
self.ide.propagate_after_start(event)
37+
self.client.propagate_after_start(event)
3838

3939
@message_handler
4040
def output_event(self, event):
41-
self.ide.propagate_after_start(event)
41+
self.client.propagate_after_start(event)
4242

4343
@message_handler
4444
def exited_event(self, event):
4545
self.exit_code = event("exitCode", int)
46-
# We don't want to tell the IDE about this just yet, because it will then
46+
# We don't want to tell the client about this just yet, because it will then
4747
# want to disconnect, and the launcher might still be waiting for keypress
4848
# (if wait-on-exit was enabled). Instead, we'll report the event when we
4949
# receive "terminated" from the launcher, right before it exits.
5050

5151
@message_handler
5252
def terminated_event(self, event):
5353
try:
54-
self.ide.channel.send_event("exited", {"exitCode": self.exit_code})
54+
self.client.channel.send_event("exited", {"exitCode": self.exit_code})
5555
except Exception:
5656
pass
5757
self.channel.close()
@@ -94,7 +94,7 @@ def on_launcher_connected(sock):
9494
if console == "internalConsole":
9595
log.info("{0} spawning launcher: {1!r}", session, cmdline)
9696

97-
# If we are talking to the IDE over stdio, sys.stdin and sys.stdout are
97+
# If we are talking to the client over stdio, sys.stdin and sys.stdout are
9898
# redirected to avoid mangling the DAP message stream. Make sure the
9999
# launcher also respects that.
100100
subprocess.Popen(
@@ -107,12 +107,9 @@ def on_launcher_connected(sock):
107107

108108
else:
109109
log.info('{0} spawning launcher via "runInTerminal" request.', session)
110-
session.ide.capabilities.require("supportsRunInTerminalRequest")
111-
kinds = {
112-
"integratedTerminal": "integrated",
113-
"externalTerminal": "external",
114-
}
115-
session.ide.channel.request(
110+
session.client.capabilities.require("supportsRunInTerminalRequest")
111+
kinds = {"integratedTerminal": "integrated", "externalTerminal": "external"}
112+
session.client.channel.request(
116113
"runInTerminal",
117114
{
118115
"kind": kinds[console],
@@ -124,9 +121,7 @@ def on_launcher_connected(sock):
124121

125122
if not session.wait_for(lambda: session.launcher, timeout=10):
126123
raise start_request.cant_handle(
127-
'{0} timed out waiting for {1} to connect',
128-
session,
129-
session.launcher,
124+
"{0} timed out waiting for {1} to connect", session, session.launcher
130125
)
131126

132127
try:

src/debugpy/adapter/servers.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ def __init__(self, sock):
136136
log.info("No active debug session for parent process of {0}.", self)
137137
else:
138138
try:
139-
parent_session.ide.notify_of_subprocess(self)
139+
parent_session.client.notify_of_subprocess(self)
140140
except Exception:
141-
# This might fail if the IDE concurrently disconnects from the parent
141+
# This might fail if the client concurrently disconnects from the parent
142142
# session. We still want to keep the connection around, in case the
143-
# IDE reconnects later. If the parent session was "launch", it'll take
143+
# client reconnects later. If the parent session was "launch", it'll take
144144
# care of closing the remaining server connections.
145145
log.exception("Failed to notify parent session about {0}:", self)
146146

@@ -159,7 +159,7 @@ def authenticate(self):
159159

160160
def request(self, request):
161161
raise request.isnt_valid(
162-
"Requests from the debug server to the IDE are not allowed."
162+
"Requests from the debug server to the client are not allowed."
163163
)
164164

165165
def event(self, event):
@@ -273,16 +273,16 @@ def request(self, request):
273273
# Do not delegate requests from the server by default. There is a security
274274
# boundary between the server and the adapter, and we cannot trust arbitrary
275275
# requests sent over that boundary, since they may contain arbitrary code
276-
# that the IDE will execute - e.g. "runInTerminal". The adapter must only
276+
# that the client will execute - e.g. "runInTerminal". The adapter must only
277277
# propagate requests that it knows are safe.
278278
raise request.isnt_valid(
279-
"Requests from the debug server to the IDE are not allowed."
279+
"Requests from the debug server to the client are not allowed."
280280
)
281281

282282
# Generic event handler, used if there's no specific handler below.
283283
@message_handler
284284
def event(self, event):
285-
self.ide.propagate_after_start(event)
285+
self.client.propagate_after_start(event)
286286

287287
@message_handler
288288
def initialized_event(self, event):
@@ -293,7 +293,7 @@ def initialized_event(self, event):
293293
def process_event(self, event):
294294
# If there is a launcher, it's handling the process event.
295295
if not self.launcher:
296-
self.ide.propagate_after_start(event)
296+
self.client.propagate_after_start(event)
297297

298298
@message_handler
299299
def continued_event(self, event):
@@ -306,7 +306,7 @@ def continued_event(self, event):
306306
# in "launch" or "attach" request, which defaults to true. If explicitly set
307307
# to false, pydevd will only resume the thread that was stepping.
308308
#
309-
# To ensure that the IDE is aware that other threads are getting resumed in
309+
# To ensure that the client is aware that other threads are getting resumed in
310310
# that mode, pydevd sends a "continued" event with "allThreadsResumed": true.
311311
# when responding to a step request. This ensures correct behavior in VSCode
312312
# and other DAP-conformant clients.
@@ -316,14 +316,14 @@ def continued_event(self, event):
316316
# does not expect to see "continued" events explicitly reflecting that fact.
317317
# If such events are sent regardless, VS behaves erratically. Thus, we have
318318
# to suppress them specifically for VS.
319-
if self.ide.client_id not in ("visualstudio", "vsformac"):
320-
self.ide.propagate_after_start(event)
319+
if self.client.client_id not in ("visualstudio", "vsformac"):
320+
self.client.propagate_after_start(event)
321321

322322
@message_handler
323323
def exited_event(self, event):
324324
# If there is a launcher, it's handling the exit code.
325325
if not self.launcher:
326-
self.ide.propagate_after_start(event)
326+
self.client.propagate_after_start(event)
327327

328328
@message_handler
329329
def terminated_event(self, event):

0 commit comments

Comments
 (0)