Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PYDEVD_REMOTE_ROOT support #243

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions _pydevd_bundle/pydevd_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ def as_int_in_env(env_key, default):
# If PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS is set to False, the patching to hide pydevd threads won't be applied.
PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS = os.getenv('PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS', 'true').lower() in ENV_TRUE_LOWER_VALUES

# If set, configures the server's remote root regardless of what is provided.
PYDEVD_REMOTE_ROOT = os.getenv('PYDEVD_REMOTE_ROOT', None)

EXCEPTION_TYPE_UNHANDLED = 'UNHANDLED'
EXCEPTION_TYPE_USER_UNHANDLED = 'USER_UNHANDLED'
EXCEPTION_TYPE_HANDLED = 'HANDLED'
Expand Down
5 changes: 4 additions & 1 deletion _pydevd_bundle/pydevd_process_net_command_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from _pydevd_bundle.pydevd_net_command import NetCommand
from _pydevd_bundle.pydevd_utils import convert_dap_log_message_to_expression, ScopeRequest
from _pydevd_bundle.pydevd_constants import (PY_IMPL_NAME, DebugInfoHolder, PY_VERSION_STR,
PY_IMPL_VERSION_STR, IS_64BIT_PROCESS)
PY_IMPL_VERSION_STR, IS_64BIT_PROCESS, PYDEVD_REMOTE_ROOT)
from _pydevd_bundle.pydevd_trace_dispatch import USING_CYTHON
from _pydevd_frame_eval.pydevd_frame_eval_main import USING_FRAME_EVAL
from _pydevd_bundle.pydevd_comm import internal_get_step_in_targets_json
Expand Down Expand Up @@ -319,6 +319,9 @@ def on_completions_request(self, py_db, request):
self.api.request_completions(py_db, seq, thread_id, frame_id, text, line=line, column=column)

def _resolve_remote_root(self, local_root, remote_root):
if PYDEVD_REMOTE_ROOT is not None:
return PYDEVD_REMOTE_ROOT

if remote_root == '.':
cwd = os.getcwd()
append_pathsep = local_root.endswith('\\') or local_root.endswith('/')
Expand Down
4 changes: 3 additions & 1 deletion pydevd.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
clear_cached_thread_id, INTERACTIVE_MODE_AVAILABLE, SHOW_DEBUG_INFO_ENV, NULL,
NO_FTRACE, IS_IRONPYTHON, JSON_PROTOCOL, IS_CPYTHON, HTTP_JSON_PROTOCOL, USE_CUSTOM_SYS_CURRENT_FRAMES_MAP, call_only_once,
ForkSafeLock, IGNORE_BASENAMES_STARTING_WITH, EXCEPTION_TYPE_UNHANDLED, SUPPORT_GEVENT,
PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING, PYDEVD_IPYTHON_CONTEXT)
PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING, PYDEVD_IPYTHON_CONTEXT, PYDEVD_REMOTE_ROOT)
from _pydevd_bundle.pydevd_defaults import PydevdCustomization # Note: import alias used on pydev_monkey.
from _pydevd_bundle.pydevd_custom_frames import CustomFramesContainer, custom_frames_container_init
from _pydevd_bundle.pydevd_dont_trace_files import DONT_TRACE, PYDEV_FILE, LIB_FILE, DONT_TRACE_DIRS
Expand Down Expand Up @@ -3263,6 +3263,8 @@ def _log_initial_info():
pydev_log.debug("Using cython: %s", USING_CYTHON)
pydev_log.debug("Using frame eval: %s", USING_FRAME_EVAL)
pydev_log.debug("Using gevent mode: %s / imported gevent module support: %s", SUPPORT_GEVENT, bool(pydevd_gevent_integration))
if PYDEVD_REMOTE_ROOT is not None:
pydev_log.debug("Using remote root: %s", PYDEVD_REMOTE_ROOT)


def config(protocol='', debug_mode='', preimport=''):
Expand Down
27 changes: 27 additions & 0 deletions tests_python/test_debugger_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -6633,6 +6633,33 @@ def additional_output_checks(writer, stdout, stderr):
writer.finished_ok = True


def test_remote_root_set_in_env_var(case_setup_dap, pyfile):

def get_environ(self):
env = os.environ.copy()
print(os.path.dirname(self.TEST_FILE))
env["PYDEVD_REMOTE_ROOT"] = os.path.dirname(self.TEST_FILE)
return env

@pyfile
def target():
print('TEST SUCEEDED') # break here

with case_setup_dap.test_file(target, get_environ=get_environ) as writer:
json_facade = JsonFacade(writer)

json_facade.write_launch(pathMappings=[{
'localRoot': os.path.dirname(writer.TEST_FILE),
'remoteRoot': "/tmp/somepath", # A path we likely aren't writing to
}])
break_line = writer.get_line_index_with_content('break here')
json_facade.write_set_breakpoints(break_line)
json_facade.write_make_initial_run()
json_facade.wait_for_thread_stopped(line=break_line)
json_facade.write_continue()
writer.finished_ok = True


if __name__ == '__main__':
pytest.main(['-k', 'test_replace_process', '-s'])