77import re
88import sys
99from importlib .util import find_spec
10+ from typing import Any
1011
1112# debugpy.__main__ should have preloaded pydevd properly before importing this module.
1213# Otherwise, some stdlib modules above might have had imported threading before pydevd
1819from _pydevd_bundle import pydevd_runpy as runpy
1920
2021import debugpy
22+ import debugpy .server
2123from debugpy .common import log
2224from debugpy .server import api
2325
4143
4244class Options (object ):
4345 mode = None
44- address = None
46+ address : "tuple[str, int] | None" = None
4547 log_to = None
4648 log_to_stderr = False
47- target = None
48- target_kind = None
49+ target : str | None = None
50+ target_kind : str | None = None
4951 wait_for_client = False
5052 adapter_access_token = None
53+ config : "dict[str, Any]" = {}
5154
5255
5356options = Options ()
@@ -139,7 +142,7 @@ def set_config(arg, it):
139142 options .config [name ] = value
140143
141144
142- def set_target (kind , parser = (lambda x : x ), positional = False ):
145+ def set_target (kind : str , parser = (lambda x : x ), positional = False ):
143146 def do (arg , it ):
144147 options .target_kind = kind
145148 target = parser (arg if positional else next (it ))
@@ -252,9 +255,9 @@ def start_debugging(argv_0):
252255
253256 debugpy .configure (options .config )
254257
255- if options .mode == "listen" :
258+ if options .mode == "listen" and options . address is not None :
256259 debugpy .listen (options .address )
257- elif options .mode == "connect" :
260+ elif options .mode == "connect" and options . address is not None :
258261 debugpy .connect (options .address , access_token = options .adapter_access_token )
259262 else :
260263 raise AssertionError (repr (options .mode ))
@@ -272,7 +275,7 @@ def run_file():
272275 # parent directory to sys.path. Thus, importing other modules from the
273276 # same directory is broken unless sys.path is patched here.
274277
275- if os .path .isfile (target ):
278+ if target is not None and os .path .isfile (target ):
276279 dir = os .path .dirname (target )
277280 sys .path .insert (0 , dir )
278281 else :
@@ -293,7 +296,7 @@ def run_module():
293296 # actually invoking it.
294297 argv_0 = sys .argv [0 ]
295298 try :
296- spec = find_spec (options .target )
299+ spec = None if options . target is None else find_spec (options .target )
297300 if spec is not None :
298301 argv_0 = spec .origin
299302 except Exception :
@@ -318,16 +321,19 @@ def run_module():
318321
319322
320323def run_code ():
321- # Add current directory to path, like Python itself does for -c.
322- sys .path .insert (0 , str ("" ))
323- code = compile (options .target , str ("<string>" ), str ("exec" ))
324+ if options .target is not None :
325+ # Add current directory to path, like Python itself does for -c.
326+ sys .path .insert (0 , str ("" ))
327+ code = compile (options .target , str ("<string>" ), str ("exec" ))
324328
325- start_debugging (str ("-c" ))
329+ start_debugging (str ("-c" ))
326330
327- log .describe_environment ("Pre-launch environment:" )
328- log .info ("Running code:\n \n {0}" , options .target )
331+ log .describe_environment ("Pre-launch environment:" )
332+ log .info ("Running code:\n \n {0}" , options .target )
329333
330- eval (code , {})
334+ eval (code , {})
335+ else :
336+ log .error ("No target to run." )
331337
332338
333339def attach_to_pid ():
@@ -421,13 +427,14 @@ def main():
421427 )
422428
423429 try :
424- run = {
425- "file" : run_file ,
426- "module" : run_module ,
427- "code" : run_code ,
428- "pid" : attach_to_pid ,
429- }[options .target_kind ]
430- run ()
430+ if options .target_kind is not None :
431+ run = {
432+ "file" : run_file ,
433+ "module" : run_module ,
434+ "code" : run_code ,
435+ "pid" : attach_to_pid ,
436+ }[options .target_kind ]
437+ run ()
431438 except SystemExit as exc :
432439 log .reraise_exception (
433440 "Debuggee exited via SystemExit: {0!r}" , exc .code , level = "debug"
0 commit comments