mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[debugger] PY-83906: enable shape/dtype evaluation for any type with shape/dtype attribute
removes allowlist with data container types also fixes PY-83971 Merge-request: IJ-MR-176078 Merged-by: Maxim Popov <maxim.popov@jetbrains.com> GitOrigin-RevId: 101694635e693029e6da01f49080a3def98e48d4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8e577154d3
commit
25f3f43a21
@@ -16,7 +16,7 @@ from _pydevd_bundle.pydevd_constants import dict_iter_items, dict_keys, IS_PY3K,
|
||||
from _pydevd_bundle.pydevd_extension_api import TypeResolveProvider, StrPresentationProvider
|
||||
from _pydevd_bundle.pydevd_user_type_renderers_utils import try_get_type_renderer_for_var
|
||||
from _pydevd_bundle.pydevd_utils import is_string, should_evaluate_full_value, \
|
||||
should_evaluate_shape, is_container_with_shape_dtype
|
||||
should_evaluate_shape, has_attribute_safe
|
||||
from _pydevd_bundle.pydevd_vars import get_label, array_default_format, is_able_to_format_number, MAXIMUM_ARRAY_SIZE, \
|
||||
get_column_formatter_by_type, get_formatted_row_elements, IAtPolarsAccessor, DEFAULT_DF_FORMAT, DATAFRAME_HEADER_LOAD_MAX_SIZE
|
||||
from pydev_console.pydev_protocol import DebugValue, GetArrayResponse, ArrayData, ArrayHeaders, ColHeader, RowHeader, \
|
||||
@@ -334,10 +334,10 @@ def var_to_struct(val, name, format='%s', do_trim=True, evaluate_full_value=True
|
||||
|
||||
# shape to struct
|
||||
try:
|
||||
if should_evaluate_shape() and is_container_with_shape_dtype(type_qualifier, typeName, v):
|
||||
if hasattr(v, 'shape') and not callable(v.shape):
|
||||
if should_evaluate_shape():
|
||||
if has_attribute_safe(v, 'shape') and not callable(v.shape):
|
||||
debug_value.shape = str(tuple(v.shape))
|
||||
elif hasattr(v, '__len__') and not is_string(v):
|
||||
elif has_attribute_safe(v, '__len__') and not is_string(v):
|
||||
debug_value.shape = str(len(v))
|
||||
except:
|
||||
pass
|
||||
@@ -345,7 +345,7 @@ def var_to_struct(val, name, format='%s', do_trim=True, evaluate_full_value=True
|
||||
# data type info to xml (for arrays and tensors)
|
||||
debug_value.arrayElementType = ''
|
||||
try:
|
||||
if is_container_with_shape_dtype(type_qualifier, typeName, v) and hasattr(v, 'dtype'):
|
||||
if has_attribute_safe(v, 'shape') and has_attribute_safe(v, 'dtype'):
|
||||
debug_value.arrayElementType = str(v.dtype)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -4,17 +4,6 @@ import ctypes
|
||||
import os
|
||||
import signal
|
||||
import traceback
|
||||
|
||||
try:
|
||||
import torch
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
import tensorflow as tf
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
import pydevd_file_utils
|
||||
|
||||
try:
|
||||
@@ -616,24 +605,6 @@ def is_pandas_container(type_qualifier, var_type, var):
|
||||
def is_numpy_container(type_qualifier, var_type, var):
|
||||
return var_type == "ndarray" and type_qualifier == "numpy" and hasattr(var, "shape")
|
||||
|
||||
def is_pytorch_tensor(type_qualifier, var):
|
||||
try:
|
||||
import torch
|
||||
return type_qualifier == "torch" and torch.is_tensor(var)
|
||||
except ImportError:
|
||||
return False # Can't be torch if it is not installed
|
||||
|
||||
def is_tf_tensor(type_qualifier, var):
|
||||
try:
|
||||
import tensorflow as tf
|
||||
return type_qualifier.startswith("tensorflow") and tf.is_tensor(var)
|
||||
except ImportError:
|
||||
return False # Can't be tensorflow if it is not installed
|
||||
|
||||
def is_container_with_shape_dtype(type_qualifier, var_type, var):
|
||||
return (is_numpy_container(type_qualifier, var_type, var)
|
||||
or is_pytorch_tensor(type_qualifier, var)
|
||||
or is_tf_tensor(type_qualifier, var))
|
||||
|
||||
def is_builtin(x):
|
||||
return getattr(x, '__module__', None) == BUILTINS_MODULE_NAME
|
||||
@@ -659,6 +630,12 @@ def should_evaluate_shape():
|
||||
return LOAD_VALUES_POLICY != ValuesPolicy.ON_DEMAND
|
||||
|
||||
|
||||
def has_attribute_safe(obj, attr_name):
|
||||
"""Evaluates the existence of attribute without accessing it."""
|
||||
attr = inspect.getattr_static(obj, attr_name, None)
|
||||
return attr is not None
|
||||
|
||||
|
||||
def is_safe_to_access(obj, attr_name):
|
||||
"""Evaluates the safety of attribute accessibility via `obj.attr_name`.
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ from _pydevd_bundle.pydevd_repr_utils import get_value_repr
|
||||
from _pydevd_bundle.pydevd_user_type_renderers_utils import \
|
||||
try_get_type_renderer_for_var
|
||||
from _pydevd_bundle.pydevd_utils import is_string, should_evaluate_full_value, \
|
||||
should_evaluate_shape, is_safe_to_access, is_container_with_shape_dtype
|
||||
should_evaluate_shape, has_attribute_safe
|
||||
|
||||
try:
|
||||
import types
|
||||
@@ -344,10 +344,10 @@ def var_to_xml(val, name, do_trim=True, additional_in_xml='', evaluate_full_valu
|
||||
# shape to xml
|
||||
xml_shape = ''
|
||||
try:
|
||||
if should_evaluate_shape() and is_container_with_shape_dtype(type_qualifier, typeName, v):
|
||||
if hasattr(v, 'shape') and not callable(v.shape):
|
||||
if should_evaluate_shape():
|
||||
if has_attribute_safe(v, 'shape') and not callable(v.shape):
|
||||
xml_shape = ' shape="%s"' % make_valid_xml_value(str(tuple(v.shape)))
|
||||
elif hasattr(v, '__len__') and not is_string(v):
|
||||
elif has_attribute_safe(v, '__len__') and not is_string(v):
|
||||
xml_shape = ' shape="%s"' % make_valid_xml_value("%s" % str(len(v)))
|
||||
except:
|
||||
pass
|
||||
@@ -356,7 +356,7 @@ def var_to_xml(val, name, do_trim=True, additional_in_xml='', evaluate_full_valu
|
||||
# we use it for view as image
|
||||
xml_data_type = ''
|
||||
try:
|
||||
if is_container_with_shape_dtype(type_qualifier, typeName, v):
|
||||
if has_attribute_safe(v, "dtype"):
|
||||
xml_data_type = ' arrayElementType="%s"' % make_valid_xml_value(str(v.dtype))
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -761,26 +761,4 @@ public class PythonDebuggerTest extends PyEnvTestCase {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyAccess() {
|
||||
runPythonTest(new PyDebuggerTask("/debug", "test_property_output.py") {
|
||||
|
||||
@Override
|
||||
public void before() { toggleBreakpoint(getScriptName(), 11); }
|
||||
|
||||
@Override
|
||||
public void testing() throws Exception {
|
||||
waitForPause();
|
||||
assertFalse("Output shouldn't contain unexpected prints from @property", output().contains("called property"));
|
||||
resume();
|
||||
waitForTerminate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLanguageLevelSupported(@NotNull final LanguageLevel level) {
|
||||
return level.compareTo(LanguageLevel.PYTHON27) > 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user