From b348e8dfe799b36eb72d068d37ea22223f9e9712 Mon Sep 17 00:00:00 2001 From: Fabio Zadrozny Date: Wed, 6 Nov 2019 17:35:53 -0300 Subject: [PATCH] Add cython:True|False and frame_eval:True|False to pydevdSystemInfo. Fixes #1880 (#1883) --- .../_debug_adapter/debugProtocolCustom.json | 20 +++++- .../_debug_adapter/pydevd_schema.py | 67 ++++++++++++++++++- .../pydevd_process_net_command_json.py | 9 ++- .../_pydevd_bundle/pydevd_trace_dispatch.py | 4 ++ .../pydevd_frame_eval_main.py | 6 +- .../pydevd/tests_python/test_debugger_json.py | 11 ++- 6 files changed, 110 insertions(+), 7 deletions(-) diff --git a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/debugProtocolCustom.json b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/debugProtocolCustom.json index 288dd654..a0a9b873 100644 --- a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/debugProtocolCustom.json +++ b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/debugProtocolCustom.json @@ -184,9 +184,13 @@ "process": { "$ref": "#/definitions/PydevdProcessInfo", "description": "Information about the current process." + }, + "pydevd": { + "$ref": "#/definitions/PydevdInfo", + "description": "Information about pydevd." } }, - "required": [ "python", "platform", "process" ] + "required": [ "python", "platform", "process", "pydevd" ] } }, "required": [ "body" ] @@ -257,6 +261,20 @@ } } }, + "PydevdInfo": { + "type": "object", + "description": "This object contains details on pydevd.", + "properties": { + "usingCython": { + "type": "boolean", + "description": "Specifies whether the cython native module is being used." + }, + "usingFrameEval": { + "type": "boolean", + "description": "Specifies whether the frame eval native module is being used." + } + } + }, "PydevdAuthorizeRequest": { "allOf": [ { "$ref": "#/definitions/Request" }, { "type": "object", diff --git a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_schema.py b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_schema.py index 6e5b5433..36a78da3 100644 --- a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_schema.py +++ b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_schema.py @@ -13712,12 +13712,17 @@ class PydevdSystemInfoResponse(BaseSchema): "process": { "$ref": "#/definitions/PydevdProcessInfo", "description": "Information about the current process." + }, + "pydevd": { + "$ref": "#/definitions/PydevdInfo", + "description": "Information about pydevd." } }, "required": [ "python", "platform", - "process" + "process", + "pydevd" ] } } @@ -13971,6 +13976,51 @@ class PydevdProcessInfo(BaseSchema): return dct +@register +class PydevdInfo(BaseSchema): + """ + This object contains details on pydevd. + + Note: automatically generated code. Do not edit manually. + """ + + __props__ = { + "usingCython": { + "type": "boolean", + "description": "Specifies whether the cython native module is being used." + }, + "usingFrameEval": { + "type": "boolean", + "description": "Specifies whether the frame eval native module is being used." + } + } + __refs__ = set() + + __slots__ = list(__props__.keys()) + ['kwargs'] + + def __init__(self, usingCython=None, usingFrameEval=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + """ + :param boolean usingCython: Specifies whether the cython native module is being used. + :param boolean usingFrameEval: Specifies whether the frame eval native module is being used. + """ + self.usingCython = usingCython + self.usingFrameEval = usingFrameEval + self.kwargs = kwargs + + + def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) + usingCython = self.usingCython + usingFrameEval = self.usingFrameEval + dct = { + } + if usingCython is not None: + dct['usingCython'] = usingCython + if usingFrameEval is not None: + dct['usingFrameEval'] = usingFrameEval + dct.update(self.kwargs) + return dct + + @register_request('pydevdAuthorize') @register class PydevdAuthorizeRequest(BaseSchema): @@ -16191,17 +16241,22 @@ class PydevdSystemInfoResponseBody(BaseSchema): "process": { "description": "Information about the current process.", "type": "PydevdProcessInfo" + }, + "pydevd": { + "description": "Information about pydevd.", + "type": "PydevdInfo" } } - __refs__ = set(['python', 'platform', 'process']) + __refs__ = set(['python', 'platform', 'process', 'pydevd']) __slots__ = list(__props__.keys()) + ['kwargs'] - def __init__(self, python, platform, process, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__(self, python, platform, process, pydevd, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ :param PydevdPythonInfo python: Information about the python version running in the current process. :param PydevdPlatformInfo platform: Information about the plarforn on which the current process is running. :param PydevdProcessInfo process: Information about the current process. + :param PydevdInfo pydevd: Information about pydevd. """ if python is None: self.python = PydevdPythonInfo() @@ -16215,6 +16270,10 @@ class PydevdSystemInfoResponseBody(BaseSchema): self.process = PydevdProcessInfo() else: self.process = PydevdProcessInfo(update_ids_from_dap=update_ids_from_dap, **process) if process.__class__ != PydevdProcessInfo else process + if pydevd is None: + self.pydevd = PydevdInfo() + else: + self.pydevd = PydevdInfo(update_ids_from_dap=update_ids_from_dap, **pydevd) if pydevd.__class__ != PydevdInfo else pydevd self.kwargs = kwargs @@ -16222,10 +16281,12 @@ class PydevdSystemInfoResponseBody(BaseSchema): python = self.python platform = self.platform process = self.process + pydevd = self.pydevd dct = { 'python': python.to_dict(update_ids_to_dap=update_ids_to_dap), 'platform': platform.to_dict(update_ids_to_dap=update_ids_to_dap), 'process': process.to_dict(update_ids_to_dap=update_ids_to_dap), + 'pydevd': pydevd.to_dict(update_ids_to_dap=update_ids_to_dap), } dct.update(self.kwargs) return dct diff --git a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py index 124df44f..42efd452 100644 --- a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py +++ b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py @@ -14,7 +14,7 @@ from _pydevd_bundle._debug_adapter.pydevd_schema import ( GotoTargetsResponseBody, ModulesResponseBody, ProcessEventBody, ProcessEvent, Scope, ScopesResponseBody, SetExpressionResponseBody, SetVariableResponseBody, SourceBreakpoint, SourceResponseBody, - VariablesResponseBody, SetBreakpointsResponseBody, Response, InitializeRequest, InitializeResponse, + VariablesResponseBody, SetBreakpointsResponseBody, Response, Capabilities, PydevdAuthorizeRequest) from _pydevd_bundle.pydevd_api import PyDevdAPI from _pydevd_bundle.pydevd_breakpoints import get_exception_class @@ -28,6 +28,8 @@ from _pydevd_bundle.pydevd_net_command import NetCommand from _pydevd_bundle.pydevd_utils import convert_dap_log_message_to_expression from _pydevd_bundle.pydevd_constants import (PY_IMPL_NAME, DebugInfoHolder, PY_VERSION_STR, PY_IMPL_VERSION_STR, IS_64BIT_PROCESS) +from _pydevd_bundle.pydevd_trace_dispatch import USING_CYTHON +from _pydevd_frame_eval.pydevd_frame_eval_main import USING_FRAME_EVAL def _convert_rules_to_exclude_filters(rules, filename_to_server, on_error): @@ -991,10 +993,15 @@ class PyDevJsonCommandProcessor(object): executable=sys.executable, bitness=64 if IS_64BIT_PROCESS else 32, ) + pydevd_info = pydevd_schema.PydevdInfo( + usingCython=USING_CYTHON, + usingFrameEval=USING_FRAME_EVAL, + ) body = { 'python': py_info, 'platform': platform_info, 'process': process_info, + 'pydevd': pydevd_info, } response = pydevd_base_schema.build_response(request, kwargs={'body': body}) return NetCommand(CMD_RETURN, 0, response, is_json=True) diff --git a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch.py b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch.py index dc383155..c08742a4 100644 --- a/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch.py +++ b/src/ptvsd/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch.py @@ -7,6 +7,7 @@ from _pydev_bundle import pydev_log use_cython = os.getenv('PYDEVD_USE_CYTHON', None) dirname = os.path.dirname(os.path.dirname(__file__)) +USING_CYTHON = False # Do not show incorrect warning for .egg files for Remote debugger if not CYTHON_SUPPORTED or dirname.endswith('.egg'): # Do not try to import cython extensions if cython isn't supported @@ -37,6 +38,7 @@ def delete_old_compiled_extensions(): if use_cython == 'YES': # We must import the cython version if forcing cython from _pydevd_bundle.pydevd_cython_wrapper import trace_dispatch, global_cache_skips, global_cache_frame_skips, fix_top_level_trace_and_get_trace_func + USING_CYTHON = True elif use_cython == 'NO': # Use the regular version if not forcing cython @@ -55,6 +57,8 @@ elif use_cython is None: # delete_old_compiled_extensions() -- would be ok in dev mode but we don't want to erase # files from other python versions on release, so, just raise import error here. raise ImportError('Cython version of speedups does not match.') + else: + USING_CYTHON = True except ImportError: from _pydevd_bundle.pydevd_trace_dispatch_regular import trace_dispatch, global_cache_skips, global_cache_frame_skips, fix_top_level_trace_and_get_trace_func # @UnusedImport diff --git a/src/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_eval_main.py b/src/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_eval_main.py index c9fa1c01..d7b321de 100644 --- a/src/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_eval_main.py +++ b/src/ptvsd/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_eval_main.py @@ -2,6 +2,7 @@ import os import sys from _pydev_bundle import pydev_log +from _pydevd_bundle.pydevd_trace_dispatch import USING_CYTHON IS_PY36_OR_GREATER = sys.version_info >= (3, 6) @@ -11,22 +12,25 @@ dummy_trace_dispatch = None clear_thread_local_info = None use_cython = os.getenv('PYDEVD_USE_CYTHON', None) +USING_FRAME_EVAL = False # "NO" means we should not use frame evaluation, 'YES' we should use it (and fail if not there) and unspecified uses if possible. use_frame_eval = os.environ.get('PYDEVD_USE_FRAME_EVAL', None) -if use_frame_eval == 'NO' or use_cython == 'NO': +if use_frame_eval == 'NO' or use_cython == 'NO' or not USING_CYTHON: pass elif use_frame_eval == 'YES': # Fail if unable to use from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import frame_eval_func, stop_frame_eval, dummy_trace_dispatch, clear_thread_local_info + USING_FRAME_EVAL = True elif use_frame_eval is None: # Try to use if possible if IS_PY36_OR_GREATER: try: from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import frame_eval_func, stop_frame_eval, dummy_trace_dispatch, clear_thread_local_info + USING_FRAME_EVAL = True except ImportError: pydev_log.show_compile_cython_command_line() diff --git a/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py b/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py index 3c5c1c4f..8bb770c5 100644 --- a/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py +++ b/src/ptvsd/_vendored/pydevd/tests_python/test_debugger_json.py @@ -16,7 +16,7 @@ from _pydevd_bundle._debug_adapter.pydevd_schema import (ThreadEvent, ModuleEven InitializeRequestArguments, TerminateArguments, TerminateRequest, TerminatedEvent) from _pydevd_bundle.pydevd_comm_constants import file_system_encoding from _pydevd_bundle.pydevd_constants import (int_types, IS_64BIT_PROCESS, - PY_VERSION_STR, PY_IMPL_VERSION_STR, PY_IMPL_NAME) + PY_VERSION_STR, PY_IMPL_VERSION_STR, PY_IMPL_NAME, IS_PY36_OR_GREATER) from tests_python import debugger_unittest from tests_python.debug_constants import TEST_CHERRYPY, IS_PY2, TEST_DJANGO, TEST_FLASK, IS_PY26, \ IS_PY27, IS_CPYTHON @@ -3185,6 +3185,15 @@ def test_pydevd_systeminfo(case_setup): assert body['process']['executable'] == sys.executable assert body['process']['bitness'] == 64 if IS_64BIT_PROCESS else 32 + assert 'usingCython' in body['pydevd'] + assert 'usingFrameEval' in body['pydevd'] + + use_cython = os.getenv('PYDEVD_USE_CYTHON') + if use_cython is not None: + using_cython = use_cython == 'YES' + assert body['pydevd']['usingCython'] == using_cython + assert body['pydevd']['usingFrameEval'] == (using_cython and IS_PY36_OR_GREATER) + json_facade.write_continue() writer.finished_ok = True