Skip to content

Commit

Permalink
Parse and apply "python" / "pythonPath" in the adapter rather than in…
Browse files Browse the repository at this point in the history
… the launcher.

Fix errors with missing "args".

Add test for "pythonPath".
  • Loading branch information
int19h committed May 9, 2020
1 parent 65b8b38 commit 73665b9
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 23 deletions.
25 changes: 21 additions & 4 deletions src/debugpy/adapter/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import debugpy
from debugpy import adapter, launcher
from debugpy.common import fmt, json, log, messaging, sockets
from debugpy.common import compat, fmt, json, log, messaging, sockets
from debugpy.common.compat import unicode
from debugpy.adapter import components, servers, sessions

Expand Down Expand Up @@ -272,6 +272,21 @@ def property_or_debug_option(prop_name, flag_name):

return value

# "pythonPath" is a deprecated legacy spelling. If "python" is missing, then try
# the alternative. But if both are missing, the error message should say "python".
python_key = "python"
if python_key in request:
if "pythonPath" in request:
raise request.isnt_valid(
'"pythonPath" is not valid if "python" is specified'
)
elif "pythonPath" in request:
python_key = "pythonPath"
python = request(python_key, json.array(unicode, vectorize=True, size=(0,)))
if not len(python):
python = [compat.filename(sys.executable)]
request.arguments["pythonArgs"] = python[1:]

program = module = code = ()
if "program" in request:
program = request("program", unicode)
Expand Down Expand Up @@ -300,7 +315,7 @@ def property_or_debug_option(prop_name, flag_name):
args_expansion = request("argsExpansion", json.enum("shell", "none", optional=True))
if args_expansion == "shell":
args += request("args", json.array(unicode))
del request.arguments["args"]
request.arguments.pop("args", None)

cwd = request("cwd", unicode, optional=True)
if cwd == ():
Expand Down Expand Up @@ -330,6 +345,7 @@ def property_or_debug_option(prop_name, flag_name):
launchers.spawn_debuggee(
self.session,
request,
python,
launcher_path,
adapter_host,
args,
Expand Down Expand Up @@ -537,8 +553,9 @@ def notify_of_subprocess(self, conn):
body["name"] = fmt("Subprocess {0}", conn.pid)
body["request"] = "attach"
body["subProcessId"] = conn.pid
body.pop("processName", None)
body.pop("args", None)

for key in "args", "processName", "pythonArgs":
body.pop(key, None)

host = body.pop("host", None)
port = body.pop("port", None)
Expand Down
4 changes: 3 additions & 1 deletion src/debugpy/adapter/launchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def terminate_debuggee(self):
def spawn_debuggee(
session,
start_request,
python,
launcher_path,
adapter_host,
args,
Expand All @@ -79,7 +80,8 @@ def spawn_debuggee(
# -E tells sudo to propagate environment variables to the target process - this
# is necessary for launcher to get DEBUGPY_LAUNCHER_PORT and DEBUGPY_LOG_DIR.
cmdline = ["sudo", "-E"] if sudo else []
cmdline += [sys.executable, launcher_path]
cmdline += python
cmdline += [launcher_path]
env = {}

arguments = dict(start_request.arguments)
Expand Down
15 changes: 2 additions & 13 deletions src/debugpy/launcher/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,8 @@ def property_or_debug_option(prop_name, flag_name):

return value

# "pythonPath" is a deprecated legacy spelling. If "python" is missing, then try
# the alternative. But if both are missing, the error message should say "python".
python_key = "python"
if python_key in request:
if "pythonPath" in request:
raise request.isnt_valid(
'"pythonPath" is not valid if "python" is specified'
)
elif "pythonPath" in request:
python_key = "pythonPath"
cmdline = request(python_key, json.array(unicode, vectorize=True, size=(0,)))
if not len(cmdline):
cmdline = [compat.filename(sys.executable)]
python_args = request("pythonArgs", json.array(unicode, vectorize=True, size=(0,)))
cmdline = [compat.filename(sys.executable)] + python_args

if not request("noDebug", json.default(False)):
port = request("port", int)
Expand Down
7 changes: 2 additions & 5 deletions tests/debug/runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,12 +331,9 @@ def spawn_debuggee(occ):
attach_listen.host = "127.0.0.1"
attach_listen.port = net.get_test_server_port(5478, 5600)

all_launch_terminal = [launch["integratedTerminal"], launch["externalTerminal"]]

all_launch = [
launch["internalConsole"],
launch["integratedTerminal"],
launch["externalTerminal"],
]
all_launch = [launch["internalConsole"]] + all_launch_terminal

all_attach_listen = [attach_listen["api"], attach_listen["cli"]]

Expand Down
27 changes: 27 additions & 0 deletions tests/debugpy/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,30 @@ def code_to_debug():
# The launcher, however, should use our dummy sudo to spawn the debuggee,
# and the debuggee should report the environment variable accordingly.
assert backchannel.receive() == "1"


@pytest.mark.parametrize("run", runners.all_launch_terminal)
def test_custom_python(pyfile, run, target):
@pyfile
def code_to_debug():
import sys
import debuggee
from debuggee import backchannel

debuggee.setup()
backchannel.send(sys.executable)

class Session(debug.Session):
def run_in_terminal(self, args, cwd, env):
assert args[:2] == ["CUSTOMPY", "-O"]
args[0] = sys.executable
return super(Session, self).run_in_terminal(args, cwd, env)

with Session() as session:
session.config["pythonPath"] = ["CUSTOMPY", "-O"]

backchannel = session.open_backchannel()
with run(session, target(code_to_debug)):
pass

assert backchannel.receive() == sys.executable

0 comments on commit 73665b9

Please sign in to comment.