asm
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See LICENSE in the project root
|
||||
# for license information.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import debugpy
|
||||
from debugpy import launcher
|
||||
from debugpy.common import json
|
||||
from debugpy.launcher import debuggee
|
||||
|
||||
|
||||
def launch_request(request):
|
||||
debug_options = set(request("debugOptions", json.array(str)))
|
||||
|
||||
# Handling of properties that can also be specified as legacy "debugOptions" flags.
|
||||
# If property is explicitly set to false, but the flag is in "debugOptions", treat
|
||||
# it as an error. Returns None if the property wasn't explicitly set either way.
|
||||
def property_or_debug_option(prop_name, flag_name):
|
||||
assert prop_name[0].islower() and flag_name[0].isupper()
|
||||
|
||||
value = request(prop_name, bool, optional=True)
|
||||
if value == ():
|
||||
value = None
|
||||
|
||||
if flag_name in debug_options:
|
||||
if value is False:
|
||||
raise request.isnt_valid(
|
||||
'{0}:false and "debugOptions":[{1}] are mutually exclusive',
|
||||
json.repr(prop_name),
|
||||
json.repr(flag_name),
|
||||
)
|
||||
value = True
|
||||
|
||||
return value
|
||||
|
||||
python = request("python", json.array(str, size=(1,)))
|
||||
cmdline = list(python)
|
||||
|
||||
if not request("noDebug", json.default(False)):
|
||||
# see https://github.com/microsoft/debugpy/issues/861
|
||||
if sys.version_info[:2] >= (3, 11):
|
||||
cmdline += ["-X", "frozen_modules=off"]
|
||||
|
||||
port = request("port", int)
|
||||
cmdline += [
|
||||
os.path.dirname(debugpy.__file__),
|
||||
"--connect",
|
||||
launcher.adapter_host + ":" + str(port),
|
||||
]
|
||||
|
||||
if not request("subProcess", True):
|
||||
cmdline += ["--configure-subProcess", "False"]
|
||||
|
||||
qt_mode = request(
|
||||
"qt",
|
||||
json.enum(
|
||||
"none", "auto", "pyside", "pyside2", "pyqt4", "pyqt5", optional=True
|
||||
),
|
||||
)
|
||||
cmdline += ["--configure-qt", qt_mode]
|
||||
|
||||
adapter_access_token = request("adapterAccessToken", str, optional=True)
|
||||
if adapter_access_token != ():
|
||||
cmdline += ["--adapter-access-token", adapter_access_token]
|
||||
|
||||
debugpy_args = request("debugpyArgs", json.array(str))
|
||||
cmdline += debugpy_args
|
||||
|
||||
# Use the copy of arguments that was propagated via the command line rather than
|
||||
# "args" in the request itself, to allow for shell expansion.
|
||||
cmdline += sys.argv[1:]
|
||||
|
||||
process_name = request("processName", sys.executable)
|
||||
|
||||
env = os.environ.copy()
|
||||
env_changes = request("env", json.object((str, type(None))))
|
||||
if sys.platform == "win32":
|
||||
# Environment variables are case-insensitive on Win32, so we need to normalize
|
||||
# both dicts to make sure that env vars specified in the debug configuration
|
||||
# overwrite the global env vars correctly. If debug config has entries that
|
||||
# differ in case only, that's an error.
|
||||
env = {k.upper(): v for k, v in os.environ.items()}
|
||||
new_env_changes = {}
|
||||
for k, v in env_changes.items():
|
||||
k_upper = k.upper()
|
||||
if k_upper in new_env_changes:
|
||||
if new_env_changes[k_upper] == v:
|
||||
continue
|
||||
else:
|
||||
raise request.isnt_valid(
|
||||
'Found duplicate in "env": {0}.'.format(k_upper)
|
||||
)
|
||||
new_env_changes[k_upper] = v
|
||||
env_changes = new_env_changes
|
||||
if "DEBUGPY_TEST" in env:
|
||||
# If we're running as part of a debugpy test, make sure that codecov is not
|
||||
# applied to the debuggee, since it will conflict with pydevd.
|
||||
env.pop("COV_CORE_SOURCE", None)
|
||||
env.update(env_changes)
|
||||
env = {k: v for k, v in env.items() if v is not None}
|
||||
|
||||
if request("gevent", False):
|
||||
env["GEVENT_SUPPORT"] = "True"
|
||||
|
||||
console = request(
|
||||
"console",
|
||||
json.enum(
|
||||
"internalConsole", "integratedTerminal", "externalTerminal", optional=True
|
||||
),
|
||||
)
|
||||
|
||||
redirect_output = property_or_debug_option("redirectOutput", "RedirectOutput")
|
||||
if redirect_output is None:
|
||||
# If neither the property nor the option were specified explicitly, choose
|
||||
# the default depending on console type - "internalConsole" needs it to
|
||||
# provide any output at all, but it's unnecessary for the terminals.
|
||||
redirect_output = console == "internalConsole"
|
||||
if redirect_output:
|
||||
# sys.stdout buffering must be disabled - otherwise we won't see the output
|
||||
# at all until the buffer fills up.
|
||||
env["PYTHONUNBUFFERED"] = "1"
|
||||
# Force UTF-8 output to minimize data loss due to re-encoding.
|
||||
env["PYTHONIOENCODING"] = "utf-8"
|
||||
|
||||
if property_or_debug_option("waitOnNormalExit", "WaitOnNormalExit"):
|
||||
if console == "internalConsole":
|
||||
raise request.isnt_valid(
|
||||
'"waitOnNormalExit" is not supported for "console":"internalConsole"'
|
||||
)
|
||||
debuggee.wait_on_exit_predicates.append(lambda code: code == 0)
|
||||
if property_or_debug_option("waitOnAbnormalExit", "WaitOnAbnormalExit"):
|
||||
if console == "internalConsole":
|
||||
raise request.isnt_valid(
|
||||
'"waitOnAbnormalExit" is not supported for "console":"internalConsole"'
|
||||
)
|
||||
debuggee.wait_on_exit_predicates.append(lambda code: code != 0)
|
||||
|
||||
debuggee.spawn(process_name, cmdline, env, redirect_output)
|
||||
return {}
|
||||
|
||||
|
||||
def terminate_request(request):
|
||||
del debuggee.wait_on_exit_predicates[:]
|
||||
request.respond({})
|
||||
debuggee.kill()
|
||||
|
||||
|
||||
def disconnect():
|
||||
del debuggee.wait_on_exit_predicates[:]
|
||||
debuggee.kill()
|
||||
Reference in New Issue
Block a user