mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
[pycharm] PY-79461 PY-79531 Debugger: load data in chunks
(cherry picked from commit 0e557f905cfafca704266d3a4cbacfe60820cd57) GitOrigin-RevId: 6cb9d292e0b2d246c364c9442899509f3d35fbb1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
edf3517b98
commit
7c2c005a18
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class ArrayData implements org.apache.thrift.TBase<ArrayData, ArrayData._Fields>, java.io.Serializable, Cloneable, Comparable<ArrayData> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ArrayData");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class ArrayHeaders implements org.apache.thrift.TBase<ArrayHeaders, ArrayHeaders._Fields>, java.io.Serializable, Cloneable, Comparable<ArrayHeaders> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ArrayHeaders");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class ColHeader implements org.apache.thrift.TBase<ColHeader, ColHeader._Fields>, java.io.Serializable, Cloneable, Comparable<ColHeader> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ColHeader");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class CompletionOption implements org.apache.thrift.TBase<CompletionOption, CompletionOption._Fields>, java.io.Serializable, Cloneable, Comparable<CompletionOption> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("CompletionOption");
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ package com.jetbrains.python.console.protocol;
|
||||
/**
|
||||
* Corresponds to completion types declared in "_pydev_bundle/_pydev_imports_tipper.py".
|
||||
*/
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public enum CompletionOptionType implements org.apache.thrift.TEnum {
|
||||
IMPORT(0),
|
||||
CLASS(1),
|
||||
|
||||
@@ -10,7 +10,7 @@ package com.jetbrains.python.console.protocol;
|
||||
* Corresponds to `PyDebugValue`.
|
||||
*/
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class DebugValue implements org.apache.thrift.TBase<DebugValue, DebugValue._Fields>, java.io.Serializable, Cloneable, Comparable<DebugValue> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DebugValue");
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ package com.jetbrains.python.console.protocol;
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class ExceedingArrayDimensionsException extends org.apache.thrift.TException implements org.apache.thrift.TBase<ExceedingArrayDimensionsException, ExceedingArrayDimensionsException._Fields>, java.io.Serializable, Cloneable, Comparable<ExceedingArrayDimensionsException> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ExceedingArrayDimensionsException");
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ package com.jetbrains.python.console.protocol;
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class GetArrayResponse implements org.apache.thrift.TBase<GetArrayResponse, GetArrayResponse._Fields>, java.io.Serializable, Cloneable, Comparable<GetArrayResponse> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("GetArrayResponse");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class KeyboardInterruptException extends org.apache.thrift.TException implements org.apache.thrift.TBase<KeyboardInterruptException, KeyboardInterruptException._Fields>, java.io.Serializable, Cloneable, Comparable<KeyboardInterruptException> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("KeyboardInterruptException");
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
public class PythonConsoleFrontendService {
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class PythonTableException extends org.apache.thrift.TException implements org.apache.thrift.TBase<PythonTableException, PythonTableException._Fields>, java.io.Serializable, Cloneable, Comparable<PythonTableException> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("PythonTableException");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class PythonUnhandledException extends org.apache.thrift.TException implements org.apache.thrift.TBase<PythonUnhandledException, PythonUnhandledException._Fields>, java.io.Serializable, Cloneable, Comparable<PythonUnhandledException> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("PythonUnhandledException");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class RowHeader implements org.apache.thrift.TBase<RowHeader, RowHeader._Fields>, java.io.Serializable, Cloneable, Comparable<RowHeader> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RowHeader");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package com.jetbrains.python.console.protocol;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2024-07-26")
|
||||
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.20.0)", date = "2025-04-23")
|
||||
public class UnsupportedArrayTypeException extends org.apache.thrift.TException implements org.apache.thrift.TBase<UnsupportedArrayTypeException, UnsupportedArrayTypeException._Fields>, java.io.Serializable, Cloneable, Comparable<UnsupportedArrayTypeException> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("UnsupportedArrayTypeException");
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from _pydevd_bundle.pydevd_constants import dict_keys, NEXT_VALUE_SEPARATOR
|
||||
from _pydevd_bundle.pydevd_tables import exec_table_command
|
||||
from _pydevd_bundle.pydevd_tables import exec_image_table_command
|
||||
from _pydevd_bundle.pydevd_user_type_renderers import parse_set_type_renderers_message
|
||||
from _pydevd_bundle.pydevd_vars import resolve_compound_var_object_fields, \
|
||||
table_like_struct_to_xml, eval_in_context, resolve_var_object
|
||||
@@ -95,6 +96,20 @@ def table_command(command_text):
|
||||
status, res = exec_table_command(command, command_type, start_index, end_index, format, namespace, namespace)
|
||||
print(res)
|
||||
|
||||
|
||||
def image_table_command(command_text):
|
||||
ipython_shell = get_ipython()
|
||||
namespace = ipython_shell.user_ns
|
||||
command, command_type, offset, image_id = command_text.split(NEXT_VALUE_SEPARATOR)
|
||||
|
||||
try:
|
||||
offset = int(offset)
|
||||
except ValueError:
|
||||
offset = None
|
||||
|
||||
status, res = exec_image_table_command(command, command_type, offset, image_id, namespace, namespace)
|
||||
print(res)
|
||||
|
||||
def serializeImage(img):
|
||||
if len(img.shape) != 2:
|
||||
return None
|
||||
|
||||
@@ -12,6 +12,7 @@ from _pydevd_bundle import pydevd_vars
|
||||
from _pydevd_bundle.pydevd_comm import InternalDataViewerAction
|
||||
from _pydevd_bundle.pydevd_constants import IS_JYTHON, dict_iter_items
|
||||
from _pydevd_bundle.pydevd_tables import exec_table_command
|
||||
from _pydevd_bundle.pydevd_tables import exec_image_table_command
|
||||
from _pydevd_bundle.pydevd_user_type_renderers import parse_set_type_renderers_message
|
||||
from pydev_console.pydev_protocol import CompletionOption, CompletionOptionType, \
|
||||
PythonUnhandledException, PythonTableException
|
||||
@@ -431,6 +432,23 @@ class BaseInterpreterInterface(BaseCodeExecutor):
|
||||
if not success:
|
||||
raise PythonTableException(str(res))
|
||||
|
||||
|
||||
#
|
||||
def execTableImageCommand(self, command, command_type, offset, image_id):
|
||||
# type: (str, str, int, str) -> Any
|
||||
try:
|
||||
try:
|
||||
offset = int(offset)
|
||||
except ValueError:
|
||||
offset = None
|
||||
success, res = exec_image_table_command(command, command_type, offset, image_id, self.get_namespace(), self.get_namespace())
|
||||
if success:
|
||||
return res
|
||||
except:
|
||||
raise PythonUnhandledException(traceback.format_exc())
|
||||
if not success:
|
||||
raise PythonTableException(str(res))
|
||||
|
||||
def handshake(self):
|
||||
if self.connect_status_queue is not None:
|
||||
self.connect_status_queue.put(True)
|
||||
|
||||
@@ -106,6 +106,7 @@ from _pydev_bundle.pydev_is_thread_alive import is_thread_alive
|
||||
from _pydev_bundle import pydev_log
|
||||
from _pydev_bundle import _pydev_completer
|
||||
from _pydevd_bundle.pydevd_tables import exec_table_command
|
||||
from _pydevd_bundle.pydevd_tables import exec_image_table_command
|
||||
|
||||
from pydevd_tracing import get_exception_traceback_str
|
||||
from _pydevd_bundle import pydevd_console
|
||||
@@ -144,7 +145,7 @@ from _pydevd_bundle.pydevd_comm_constants import (
|
||||
CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, CMD_THREAD_RESUME_SINGLE_NOTIFICATION,
|
||||
CMD_REDIRECT_OUTPUT, CMD_GET_NEXT_STATEMENT_TARGETS, CMD_SET_PROJECT_ROOTS, CMD_VERSION,
|
||||
CMD_RETURN, CMD_SET_PROTOCOL, CMD_ERROR, CMD_GET_SMART_STEP_INTO_VARIANTS, CMD_DATAVIEWER_ACTION,
|
||||
CMD_TABLE_EXEC, CMD_INTERRUPT_DEBUG_CONSOLE, CMD_SET_USER_TYPE_RENDERERS)
|
||||
CMD_TABLE_EXEC, CMD_INTERRUPT_DEBUG_CONSOLE, CMD_IMAGE_COMMAND_START_LOAD, CMD_IMAGE_COMMAND_CHUNK_LOAD, CMD_SET_USER_TYPE_RENDERERS)
|
||||
MAX_IO_MSG_SIZE = 1000 #if the io is too big, we'll not send all (could make the debugger too non-responsive)
|
||||
#this number can be changed if there's need to do so
|
||||
|
||||
@@ -1418,6 +1419,68 @@ class InternalTableCommand(InternalThreadCommand):
|
||||
frame.f_globals, frame.f_locals)
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# DebugImageViewerAction
|
||||
#=======================================================================================================================
|
||||
class InternalTableImageCommandBase(InternalThreadCommand):
|
||||
def __init__(self, sequence, thread_id, frame_id, init_command, command_type):
|
||||
super().__init__(thread_id)
|
||||
self.sequence = sequence
|
||||
self.frame_id = frame_id
|
||||
self.init_command = init_command
|
||||
self.command_type = command_type
|
||||
|
||||
def do_it(self, dbg):
|
||||
try:
|
||||
frame = pydevd_vars.find_frame(self.thread_id, self.frame_id)
|
||||
success, res = self.exec_command(frame)
|
||||
|
||||
if success:
|
||||
cmd = NetCommand(self.get_command_id(), self.sequence, res)
|
||||
dbg.writer.add_command(cmd)
|
||||
else:
|
||||
cmd = dbg.cmd_factory.make_error_message(self.sequence, str(res))
|
||||
dbg.writer.add_command(cmd)
|
||||
except Exception as e:
|
||||
cmd = dbg.cmd_factory.make_error_message(self.sequence, get_exception_traceback_str())
|
||||
dbg.writer.add_command(cmd)
|
||||
|
||||
def get_command_id(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def exec_command(self, frame):
|
||||
return exec_image_table_command(self.init_command, self.command_type,
|
||||
self.get_offset(), self.get_image_id(),
|
||||
frame.f_globals, frame.f_locals)
|
||||
|
||||
def get_offset(self):
|
||||
return None
|
||||
|
||||
def get_image_id(self):
|
||||
return None
|
||||
|
||||
|
||||
class InternalTableImageStartCommand(InternalTableImageCommandBase):
|
||||
def get_command_id(self):
|
||||
return CMD_IMAGE_COMMAND_START_LOAD
|
||||
|
||||
|
||||
class InternalTableImageChunkCommand(InternalTableImageCommandBase):
|
||||
def __init__(self, sequence, thread_id, frame_id, init_command, command_type, offset, image_id):
|
||||
super().__init__(sequence, thread_id, frame_id, init_command, command_type)
|
||||
self._offset = offset
|
||||
self._image_id = image_id
|
||||
|
||||
def get_command_id(self):
|
||||
return CMD_IMAGE_COMMAND_CHUNK_LOAD
|
||||
|
||||
def get_offset(self):
|
||||
return self._offset
|
||||
|
||||
def get_image_id(self):
|
||||
return self._image_id
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# InternalChangeVariable
|
||||
#=======================================================================================================================
|
||||
|
||||
@@ -95,6 +95,9 @@ CMD_TABLE_EXEC = 211
|
||||
|
||||
CMD_INTERRUPT_DEBUG_CONSOLE = 212
|
||||
|
||||
CMD_IMAGE_COMMAND_START_LOAD = 213
|
||||
CMD_IMAGE_COMMAND_CHUNK_LOAD = 214
|
||||
|
||||
CMD_VERSION = 501
|
||||
CMD_RETURN = 502
|
||||
CMD_SET_PROTOCOL = 503
|
||||
|
||||
@@ -64,6 +64,8 @@ from _pydevd_bundle.pydevd_comm import (CMD_RUN, CMD_VERSION, CMD_LIST_THREADS,
|
||||
CMD_DATAVIEWER_ACTION, InternalDataViewerAction,
|
||||
CMD_TABLE_EXEC, InternalTableCommand,
|
||||
CMD_INTERRUPT_DEBUG_CONSOLE,
|
||||
CMD_IMAGE_COMMAND_START_LOAD, InternalTableImageStartCommand,
|
||||
CMD_IMAGE_COMMAND_CHUNK_LOAD, InternalTableImageChunkCommand,
|
||||
CMD_SET_USER_TYPE_RENDERERS)
|
||||
from _pydevd_bundle.pydevd_constants import (get_thread_id, IS_PY3K, DebugInfoHolder,
|
||||
dict_keys, STATE_RUN,
|
||||
@@ -954,6 +956,22 @@ def process_net_command(py_db, cmd_id, seq, text):
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
elif cmd_id == CMD_IMAGE_COMMAND_START_LOAD:
|
||||
try:
|
||||
thread_id, frame_id, init_command, command_type = text.split('\t')
|
||||
int_cmd = InternalTableImageStartCommand(seq, thread_id, frame_id, init_command, command_type)
|
||||
py_db.post_internal_command(int_cmd, thread_id)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
elif cmd_id == CMD_IMAGE_COMMAND_CHUNK_LOAD:
|
||||
try:
|
||||
thread_id, frame_id, init_command, command_type, offset, image_id = text.split('\t')
|
||||
int_cmd = InternalTableImageChunkCommand(seq, thread_id, frame_id, init_command, command_type, int(offset), image_id)
|
||||
py_db.post_internal_command(int_cmd, thread_id)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
elif cmd_id == CMD_SET_USER_TYPE_RENDERERS:
|
||||
try:
|
||||
type_renderers = parse_set_type_renderers_message(text)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
from _pydevd_bundle import pydevd_vars
|
||||
from _pydevd_bundle.pydevd_constants import NEXT_VALUE_SEPARATOR
|
||||
from _pydevd_bundle.pydevd_xml import ExceptionOnEvaluate
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import load_image_chunk
|
||||
|
||||
|
||||
class TableCommandType:
|
||||
@@ -12,7 +13,8 @@ class TableCommandType:
|
||||
SLICE_CSV = "SLICE_CSV"
|
||||
DESCRIBE = "DF_DESCRIBE"
|
||||
VISUALIZATION_DATA = "VISUALIZATION_DATA"
|
||||
IMAGE = "IMAGE"
|
||||
IMAGE_START_CHUNK_LOAD = "IMAGE_START_CHUNK_LOAD"
|
||||
IMAGE_CHUNK_LOAD = "IMAGE_CHUNK_LOAD"
|
||||
|
||||
|
||||
def is_error_on_eval(val):
|
||||
@@ -24,6 +26,22 @@ def is_error_on_eval(val):
|
||||
is_exception_on_eval = False
|
||||
return is_exception_on_eval
|
||||
|
||||
def exec_image_table_command(init_command, command_type, offset, image_id, f_globals, f_locals):
|
||||
# type: (str, str, [int, None], [str, None], dict, dict) -> (bool, str)
|
||||
table = pydevd_vars.eval_in_context(init_command, f_globals, f_locals)
|
||||
is_exception_on_eval = is_error_on_eval(table)
|
||||
if is_exception_on_eval:
|
||||
return False, table.result
|
||||
|
||||
image_provider = __get_image_provider(table)
|
||||
if not image_provider:
|
||||
raise RuntimeError('No image provider for: {}'.format(type(table)))
|
||||
|
||||
if command_type == TableCommandType.IMAGE_START_CHUNK_LOAD:
|
||||
return True, image_provider.create_image(table)
|
||||
|
||||
return True, load_image_chunk(offset, image_id)
|
||||
|
||||
|
||||
def exec_table_command(init_command, command_type, start_index, end_index, format, f_globals,
|
||||
f_locals):
|
||||
@@ -34,7 +52,7 @@ def exec_table_command(init_command, command_type, start_index, end_index, forma
|
||||
return False, table.result
|
||||
|
||||
table_provider = __get_table_provider(table)
|
||||
if not table_provider and command_type != TableCommandType.IMAGE:
|
||||
if not table_provider:
|
||||
raise RuntimeError('No table data provider for: {}'.format(type(table)))
|
||||
|
||||
res = []
|
||||
@@ -59,10 +77,6 @@ def exec_table_command(init_command, command_type, start_index, end_index, forma
|
||||
elif command_type == TableCommandType.SLICE_CSV:
|
||||
res.append(table_provider.get_data(table, True, start_index, end_index, format))
|
||||
|
||||
elif command_type == TableCommandType.IMAGE:
|
||||
image_provider = __get_image_provider(table)
|
||||
res.append(image_provider.get_bytes(table))
|
||||
|
||||
return True, ''.join(res)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
import base64
|
||||
|
||||
IMAGE_DATA_STORAGE = {}
|
||||
DEFAULT_IMAGE_FORMAT = 'PNG'
|
||||
DEFAULT_ENCODING = 'utf-8'
|
||||
GRAYSCALE_MODE = 'L'
|
||||
RGB_MODE = 'RGB'
|
||||
RGBA_MODE = 'RGBA'
|
||||
CHUNK_SIZE = 8192
|
||||
|
||||
def load_image_chunk(offset, image_id):
|
||||
# type: (int, str) -> str
|
||||
try:
|
||||
bytes_data = IMAGE_DATA_STORAGE.get(image_id)
|
||||
if bytes_data is None:
|
||||
return "Error: No image data found."
|
||||
chunk = bytes_data[offset:offset + CHUNK_SIZE]
|
||||
next_offset = offset + CHUNK_SIZE
|
||||
if next_offset >= len(bytes_data):
|
||||
next_offset = -1
|
||||
IMAGE_DATA_STORAGE.pop(image_id, None)
|
||||
chunk_bytes = base64.b64encode(chunk)
|
||||
if not isinstance(chunk_bytes, str):
|
||||
chunk_bytes = chunk_bytes.decode(DEFAULT_ENCODING)
|
||||
return "{};{}".format(chunk_bytes, next_offset)
|
||||
except ValueError:
|
||||
return "Error: Invalid offset format."
|
||||
except Exception as e:
|
||||
return "Error: {}".format(e)
|
||||
@@ -1,18 +1,22 @@
|
||||
# Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
import base64
|
||||
import io
|
||||
import matplotlib
|
||||
import uuid
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import IMAGE_DATA_STORAGE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import DEFAULT_IMAGE_FORMAT
|
||||
|
||||
DEFAULT_IMAGE_FORMAT = 'PNG'
|
||||
DEFAULT_ENCODING = 'utf-8'
|
||||
|
||||
|
||||
def get_bytes(matplotlib_figure):
|
||||
def create_image(matplotlib_figure):
|
||||
# type: (matplotlib.figure.Figure) -> str
|
||||
try:
|
||||
bytes_buffer = io.BytesIO()
|
||||
matplotlib_figure.savefig(bytes_buffer, format=DEFAULT_IMAGE_FORMAT)
|
||||
bytes_buffer.seek(0)
|
||||
return base64.b64encode(bytes_buffer.getvalue()).decode(DEFAULT_ENCODING)
|
||||
try:
|
||||
matplotlib_figure.savefig(bytes_buffer, format=DEFAULT_IMAGE_FORMAT)
|
||||
bytes_buffer.seek(0)
|
||||
bytes_data = bytes_buffer.getvalue()
|
||||
image_id = str(uuid.uuid4())
|
||||
IMAGE_DATA_STORAGE[image_id] = bytes_data
|
||||
return "{}".format(image_id)
|
||||
finally:
|
||||
bytes_buffer.close()
|
||||
except Exception as e:
|
||||
return "Error: {}".format(e)
|
||||
return "Error: {}".format(e)
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
import numpy as np
|
||||
import io
|
||||
import base64
|
||||
|
||||
import uuid
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import IMAGE_DATA_STORAGE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import DEFAULT_IMAGE_FORMAT
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import RGB_MODE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import RGBA_MODE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import GRAYSCALE_MODE
|
||||
|
||||
try:
|
||||
import tensorflow as tf
|
||||
@@ -13,15 +17,7 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
DEFAULT_IMAGE_FORMAT = 'PNG'
|
||||
DEFAULT_ENCODING = 'utf-8'
|
||||
GRAYSCALE_MODE = 'L'
|
||||
RGB_MODE = 'RGB'
|
||||
RGBA_MODE = 'RGBA'
|
||||
|
||||
|
||||
def get_bytes(arr):
|
||||
def create_image(arr):
|
||||
# type: (np.ndarray) -> str
|
||||
try:
|
||||
from PIL import Image
|
||||
@@ -51,7 +47,8 @@ def get_bytes(arr):
|
||||
if arr_min == arr_max: # handle constant values
|
||||
arr_to_convert = np.full_like(arr_to_convert, 127, dtype=np.uint8)
|
||||
else:
|
||||
arr_to_convert = ((arr_to_convert - arr_min) / (arr_max - arr_min) * 255).astype(np.uint8)
|
||||
arr_to_convert = ((arr_to_convert - arr_min) / (
|
||||
arr_max - arr_min) * 255).astype(np.uint8)
|
||||
|
||||
arr_to_convert_ndim = arr_to_convert.ndim
|
||||
if arr_to_convert_ndim == 2:
|
||||
@@ -60,14 +57,20 @@ def get_bytes(arr):
|
||||
mode = RGBA_MODE
|
||||
else:
|
||||
mode = RGB_MODE
|
||||
|
||||
bytes_buffer = io.BytesIO()
|
||||
image = Image.fromarray(arr_to_convert, mode=mode)
|
||||
image.save(bytes_buffer, format=DEFAULT_IMAGE_FORMAT)
|
||||
return base64.b64encode(bytes_buffer.getvalue()).decode(DEFAULT_ENCODING)
|
||||
try:
|
||||
image = Image.fromarray(arr_to_convert, mode=mode)
|
||||
image.save(bytes_buffer, format=DEFAULT_IMAGE_FORMAT)
|
||||
bytes_data = bytes_buffer.getvalue()
|
||||
image_id = str(uuid.uuid4())
|
||||
IMAGE_DATA_STORAGE[image_id] = bytes_data
|
||||
return image_id
|
||||
finally:
|
||||
bytes_buffer.close()
|
||||
|
||||
except ImportError:
|
||||
return "Error: Pillow library is not installed."
|
||||
except (TypeError, ValueError):
|
||||
return "Error: Only non-complex numeric array types are supported."
|
||||
except Exception as e:
|
||||
return "Error: {}".format(e)
|
||||
return "Error: {}".format(e)
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
# Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
import numpy as np
|
||||
import io
|
||||
import base64
|
||||
import uuid
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import IMAGE_DATA_STORAGE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import DEFAULT_IMAGE_FORMAT
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import RGB_MODE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import RGBA_MODE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import GRAYSCALE_MODE
|
||||
|
||||
|
||||
DEFAULT_IMAGE_FORMAT = 'PNG'
|
||||
DEFAULT_ENCODING = 'utf-8'
|
||||
GRAYSCALE_MODE = 'L'
|
||||
RGB_MODE = 'RGB'
|
||||
RGBA_MODE = 'RGBA'
|
||||
|
||||
|
||||
def get_bytes(arr):
|
||||
def create_image(arr):
|
||||
# type: (np.ndarray) -> str
|
||||
try:
|
||||
from PIL import Image
|
||||
@@ -41,13 +38,21 @@ def get_bytes(arr):
|
||||
mode = RGBA_MODE
|
||||
else:
|
||||
mode = RGB_MODE
|
||||
|
||||
bytes_buffer = io.BytesIO()
|
||||
image = Image.fromarray(arr_to_convert, mode=mode)
|
||||
image.save(bytes_buffer, format=DEFAULT_IMAGE_FORMAT)
|
||||
return base64.b64encode(bytes_buffer.getvalue()).decode(DEFAULT_ENCODING)
|
||||
try:
|
||||
image = Image.fromarray(arr_to_convert, mode=mode)
|
||||
image.save(bytes_buffer, format=DEFAULT_IMAGE_FORMAT)
|
||||
bytes_data = bytes_buffer.getvalue()
|
||||
image_id = str(uuid.uuid4())
|
||||
IMAGE_DATA_STORAGE[image_id] = bytes_data
|
||||
return image_id
|
||||
finally:
|
||||
bytes_buffer.close()
|
||||
|
||||
except ImportError:
|
||||
return "Error: Pillow library is not installed."
|
||||
except (TypeError, ValueError):
|
||||
return "Error: Only non-complex numeric array types are supported."
|
||||
except Exception as e:
|
||||
return "Error: {}".format(e)
|
||||
return "Error: {}".format(e)
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
# Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
import base64
|
||||
import io
|
||||
import PIL
|
||||
import uuid
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import IMAGE_DATA_STORAGE
|
||||
from _pydevd_bundle.tables.images.pydevd_image_loader import DEFAULT_IMAGE_FORMAT
|
||||
|
||||
DEFAULT_IMAGE_FORMAT = 'PNG'
|
||||
DEFAULT_ENCODING = 'utf-8'
|
||||
GRAYSCALE_MODE = 'L'
|
||||
RGB_MODE = 'RGB'
|
||||
|
||||
|
||||
def get_bytes(pillow_image):
|
||||
def create_image(pillow_image):
|
||||
# type: (PIL.Image.Image) -> str
|
||||
try:
|
||||
bytes_buffer = io.BytesIO()
|
||||
image_format = pillow_image.format if pillow_image.format else DEFAULT_IMAGE_FORMAT
|
||||
pillow_image.save(bytes_buffer, format=image_format)
|
||||
return base64.b64encode(bytes_buffer.getvalue()).decode(DEFAULT_ENCODING)
|
||||
try:
|
||||
image_format = pillow_image.format if pillow_image.format else DEFAULT_IMAGE_FORMAT
|
||||
pillow_image.save(bytes_buffer, format=image_format)
|
||||
bytes_data = bytes_buffer.getvalue()
|
||||
image_id = str(uuid.uuid4())
|
||||
IMAGE_DATA_STORAGE[image_id] = bytes_data
|
||||
return "{}".format(image_id)
|
||||
finally:
|
||||
bytes_buffer.close()
|
||||
except Exception as e:
|
||||
return "Error: {}".format(e)
|
||||
return "Error: {}".format(e)
|
||||
|
||||
@@ -202,6 +202,9 @@ service PythonConsoleBackendService {
|
||||
void loadFullValue(1: LoadFullValueRequestSeq seq, 2: list<string> variables) throws (1: PythonUnhandledException unhandledException),
|
||||
|
||||
string execTableCommand(1: string tableVariable, 2: string commandType, 3: string startIndex, 4: string endIndex, 5: string format) throws (1: PythonUnhandledException unhandledException, 2: PythonTableException tableException)
|
||||
|
||||
string execTableImageCommand(1: string tableVariable, 2: string commandType, 3: string offset, 4: string imageId) throws (1: PythonUnhandledException unhandledException, 2: PythonTableException tableException)
|
||||
|
||||
}
|
||||
|
||||
exception KeyboardInterruptException {
|
||||
|
||||
@@ -499,7 +499,7 @@ public class PyDebugValue extends XNamedValue {
|
||||
|
||||
private static void addViewAsImageLink(XValueNodeImpl valueNode) {
|
||||
PyDebugValue debugValue = (PyDebugValue)valueNode.getXValue();
|
||||
if (!checkAndShowViewAsImageOnScreen(debugValue) || hasJupyterFrameAccessor(debugValue.getFrameAccessor()))
|
||||
if (!checkAndShowViewAsImageOnScreen(debugValue))
|
||||
return;
|
||||
String viewAsImageText = PydevBundle.message("pydev.view.as.image");
|
||||
valueNode.addAdditionalHyperlink(new XDebuggerTreeNodeHyperlink(viewAsImageText) {
|
||||
@@ -523,12 +523,6 @@ public class PyDebugValue extends XNamedValue {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: remove this check after dealing with IOPub
|
||||
private static boolean hasJupyterFrameAccessor(PyFrameAccessor frameAccessor) {
|
||||
if (frameAccessor == null) return true;
|
||||
return frameAccessor.getClass().getName().contains("JupyterVarsFrameAccessor");
|
||||
}
|
||||
|
||||
private static boolean checkAndShowViewAsImageOnScreen(PyDebugValue debugValue) {
|
||||
boolean showViewAsImage = Registry.get("actions.show.as.image.visibility").asBoolean();
|
||||
if (!showViewAsImage) {
|
||||
|
||||
@@ -97,6 +97,9 @@ public interface PyFrameAccessor {
|
||||
@Nullable
|
||||
String execTableCommand(String command, TableCommandType commandType, @Nullable TableCommandParameters tableCommandParameters) throws PyDebuggerException;
|
||||
|
||||
@Nullable
|
||||
String execTableImageCommand(String command, TableCommandType commandType, @Nullable TableCommandParameters tableCommandParameters) throws PyDebuggerException;
|
||||
|
||||
/**
|
||||
* @return result as a preview image packed into json array. Image can be compressed if necessary.
|
||||
*/
|
||||
|
||||
@@ -75,6 +75,9 @@ public abstract class AbstractCommand<T> {
|
||||
|
||||
public static final int INTERRUPT_DEBUG_CONSOLE = 212;
|
||||
|
||||
public static final int IMAGE_COMMAND_START_LOAD = 213;
|
||||
public static final int IMAGE_COMMAND_CHUNK_LOAD = 214;
|
||||
|
||||
/**
|
||||
* The code of the message that means that IDE received
|
||||
* {@link #PROCESS_CREATED} message from the Python debugger script.
|
||||
|
||||
@@ -212,6 +212,15 @@ public class ClientModeMultiProcessDebugger implements ProcessDebugger {
|
||||
return debugger(threadId).execTableCommand(threadId, frameId, command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String execTableImageCommand(String threadId,
|
||||
String frameId,
|
||||
String command,
|
||||
TableCommandType commandType, TableCommandParameters tableCommandParameters)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).execTableCommand(threadId, frameId, command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, Boolean>> getSmartStepIntoVariants(String threadId, String frameId, int startContextLine, int endContextLine)
|
||||
throws PyDebuggerException {
|
||||
|
||||
@@ -225,6 +225,15 @@ public class MultiProcessDebugger implements ProcessDebugger {
|
||||
return debugger(threadId).execTableCommand(threadId, frameId, command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String execTableImageCommand(String threadId,
|
||||
String frameId,
|
||||
String command,
|
||||
TableCommandType commandType, TableCommandParameters tableCommandParameters)
|
||||
throws PyDebuggerException {
|
||||
return debugger(threadId).execTableImageCommand(threadId, frameId, command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, Boolean>> getSmartStepIntoVariants(String threadId, String frameId, int startContextLine, int endContextLine)
|
||||
throws PyDebuggerException {
|
||||
|
||||
@@ -42,6 +42,10 @@ public interface ProcessDebugger {
|
||||
String execTableCommand(String threadId, String frameId, String command, TableCommandType commandType,
|
||||
TableCommandParameters tableCommandParameters) throws PyDebuggerException;
|
||||
|
||||
@Nullable
|
||||
String execTableImageCommand(String threadId, String frameId, String command, TableCommandType commandType,
|
||||
TableCommandParameters tableCommandParameters) throws PyDebuggerException;
|
||||
|
||||
enum GROUP_TYPE {
|
||||
DEFAULT,
|
||||
SPECIAL,
|
||||
|
||||
@@ -186,6 +186,14 @@ public class RemoteDebugger implements ProcessDebugger {
|
||||
return tableCommand.getCommandResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String execTableImageCommand(String threadId, String frameId, String command, TableCommandType commandType,
|
||||
TableCommandParameters tableCommandParameters) throws PyDebuggerException {
|
||||
final TableImageCommand tableImageCommand = new TableImageCommand(this, threadId, frameId, command, commandType, tableCommandParameters);
|
||||
tableImageCommand.execute();
|
||||
return tableImageCommand.getCommandResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XValueChildrenList loadFrame(final String threadId, final String frameId, GROUP_TYPE groupType) throws PyDebuggerException {
|
||||
return executeCommand(new GetFrameCommand(this, threadId, frameId, groupType)).getVariables();
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.debugger.pydev
|
||||
|
||||
import com.intellij.util.asSafely
|
||||
import com.jetbrains.python.debugger.pydev.tables.PyDevImageCommandParameters
|
||||
import com.jetbrains.python.tables.TableCommandParameters
|
||||
import com.jetbrains.python.tables.TableCommandType
|
||||
|
||||
class TableImageCommand(
|
||||
debugger: RemoteDebugger?, threadId: String?, frameId: String?,
|
||||
private val initExpr: String,
|
||||
private val commandType: TableCommandType,
|
||||
private val tableCommandParameters: TableCommandParameters?
|
||||
) : AbstractFrameCommand<String?>(debugger, getCommandCode(tableCommandParameters), threadId, frameId) {
|
||||
var commandResult: String? = null
|
||||
|
||||
override fun buildPayload(payload: Payload) {
|
||||
super.buildPayload(payload)
|
||||
payload.add(initExpr).add(commandType.name)
|
||||
if (commandType == TableCommandType.IMAGE_CHUNK_LOAD) {
|
||||
addChunkParameters(payload)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addChunkParameters(payload: Payload) {
|
||||
tableCommandParameters?.asSafely<PyDevImageCommandParameters>()?.let {
|
||||
payload.add(it.offset ?: -1).add(it.imageId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isResponseExpected(): Boolean = true
|
||||
|
||||
override fun processResponse(response: ProtocolFrame) {
|
||||
super.processResponse(response)
|
||||
commandResult = response.payload
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun getCommandCode(parameters: TableCommandParameters?): Int =
|
||||
if (parameters?.asSafely<PyDevImageCommandParameters>() == null) {
|
||||
IMAGE_COMMAND_START_LOAD
|
||||
}
|
||||
else {
|
||||
IMAGE_COMMAND_CHUNK_LOAD
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
@file:OptIn(IntellijInternalApi::class)
|
||||
|
||||
package com.jetbrains.python.debugger.pydev.tables
|
||||
|
||||
import com.intellij.openapi.util.IntellijInternalApi
|
||||
import com.jetbrains.python.tables.TableCommandParameters
|
||||
|
||||
class PyDevImageCommandParameters(val offset: Int?, val imageId: String?) : TableCommandParameters
|
||||
@@ -9,5 +9,6 @@ enum class TableCommandType {
|
||||
SLICE_CSV,
|
||||
DF_DESCRIBE,
|
||||
VISUALIZATION_DATA,
|
||||
IMAGE
|
||||
IMAGE_START_CHUNK_LOAD,
|
||||
IMAGE_CHUNK_LOAD
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.jetbrains.python.debugger.pydev.SetUserTypeRenderersCommand;
|
||||
import com.jetbrains.python.debugger.pydev.dataviewer.DataViewerCommandBuilder;
|
||||
import com.jetbrains.python.debugger.pydev.dataviewer.DataViewerCommandResult;
|
||||
import com.jetbrains.python.debugger.pydev.tables.PyDevCommandParameters;
|
||||
import com.jetbrains.python.debugger.pydev.tables.PyDevImageCommandParameters;
|
||||
import com.jetbrains.python.debugger.settings.PyDebuggerSettings;
|
||||
import com.jetbrains.python.debugger.variablesview.usertyperenderers.ConfigureTypeRenderersHyperLink;
|
||||
import com.jetbrains.python.debugger.variablesview.usertyperenderers.PyUserNodeRenderer;
|
||||
@@ -395,6 +396,34 @@ public abstract class PydevConsoleCommunication extends AbstractConsoleCommunica
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String execTableImageCommand(String command, TableCommandType commandType, TableCommandParameters tableCommandParameters) throws PyDebuggerException {
|
||||
if (!isCommunicationClosed()) {
|
||||
return executeBackgroundTask(
|
||||
() -> {
|
||||
String offset = "";
|
||||
String imageId = "";
|
||||
try {
|
||||
if (tableCommandParameters instanceof PyDevImageCommandParameters) {
|
||||
offset = String.valueOf(((PyDevImageCommandParameters)tableCommandParameters).getOffset());
|
||||
imageId = String.valueOf(((PyDevImageCommandParameters)tableCommandParameters).getImageId());
|
||||
}
|
||||
return getPythonConsoleBackendClient().execTableImageCommand(command, commandType.name(), offset, imageId);
|
||||
}
|
||||
catch (PythonTableException e) {
|
||||
throw new PyDebuggerException(e.message);
|
||||
}
|
||||
},
|
||||
true,
|
||||
createRuntimeMessage(PyBundle.message("console.getting.table.data")),
|
||||
PyBundle.message("console.table.failed.to.load")
|
||||
);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public List<PydevCompletionVariant> gerCompletionVariants(String text, String actTok) throws Exception {
|
||||
return doGetCompletions(text, actTok);
|
||||
|
||||
@@ -832,6 +832,13 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
return myDebugger.execTableCommand(frame.getThreadId(), frame.getFrameId(), command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String execTableImageCommand(String command, TableCommandType commandType, TableCommandParameters tableCommandParameters)
|
||||
throws PyDebuggerException {
|
||||
final PyStackFrame frame = currentFrame();
|
||||
return myDebugger.execTableImageCommand(frame.getThreadId(), frame.getFrameId(), command, commandType, tableCommandParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFrameCached(@NotNull XStackFrame contextFrame) {
|
||||
synchronized (myFrameCacheObject) {
|
||||
|
||||
Reference in New Issue
Block a user