diff --git a/notebooks/visualization/src/com/intellij/notebooks/visualization/outputs/statistic/NotebookOutputKeyType.kt b/notebooks/visualization/src/com/intellij/notebooks/visualization/outputs/statistic/NotebookOutputKeyType.kt
index 007b2fd25265..43ca76dd99dd 100644
--- a/notebooks/visualization/src/com/intellij/notebooks/visualization/outputs/statistic/NotebookOutputKeyType.kt
+++ b/notebooks/visualization/src/com/intellij/notebooks/visualization/outputs/statistic/NotebookOutputKeyType.kt
@@ -14,6 +14,7 @@ enum class NotebookOutputKeyType {
LETS_PLOT,
MARKDOWN,
NUMPY_ARRAY,
+ NUMPY_RECARRAY,
PANDAS_DATA_FRAME,
PANDAS_SERIES,
POLARS_DATA_FRAME,
diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_tables.py b/python/helpers/pydev/_pydevd_bundle/pydevd_tables.py
index 9b01f54845fc..6f53b2bb3f83 100644
--- a/python/helpers/pydev/_pydevd_bundle/pydevd_tables.py
+++ b/python/helpers/pydev/_pydevd_bundle/pydevd_tables.py
@@ -89,7 +89,7 @@ def __get_table_provider(output):
import _pydevd_bundle.tables.pydevd_numpy_based as table_provider
else:
import _pydevd_bundle.tables.pydevd_numpy as table_provider
- elif type_qualified_name == 'numpy.ndarray':
+ elif type_qualified_name == 'numpy.ndarray' or type_qualified_name == 'numpy.rec.recarray':
import _pydevd_bundle.tables.pydevd_numpy as table_provider
elif type_qualified_name in numpy_based_type_qualified_names:
import _pydevd_bundle.tables.pydevd_numpy_based as table_provider
diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_thrift.py b/python/helpers/pydev/_pydevd_bundle/pydevd_thrift.py
index 4b988f688c18..3944fa313cc5 100644
--- a/python/helpers/pydev/_pydevd_bundle/pydevd_thrift.py
+++ b/python/helpers/pydev/_pydevd_bundle/pydevd_thrift.py
@@ -630,6 +630,7 @@ def header_data_to_thrift_struct(rows, cols, dtypes, col_bounds, col_to_format,
TYPE_TO_THRIFT_STRUCT_CONVERTERS = {
"ndarray": array_to_thrift_struct,
+ "recarray": array_to_thrift_struct,
"EagerTensor": tensor_to_thrift_struct,
"ResourceVariable": tensor_to_thrift_struct,
"SparseTensor": sparse_tensor_to_thrift_struct,
diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py b/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py
index b258f28134a1..61ba8912be6b 100644
--- a/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py
+++ b/python/helpers/pydev/_pydevd_bundle/pydevd_vars.py
@@ -836,6 +836,7 @@ def is_able_to_format_number(format):
TYPE_TO_XML_CONVERTERS = {
"ndarray": array_to_xml,
+ "recarray": array_to_xml,
"DataFrame": dataframe_to_xml,
"Series": dataframe_to_xml,
"GeoDataFrame": dataframe_to_xml,
diff --git a/python/helpers/pydev/_pydevd_bundle/tables/pydevd_numpy.py b/python/helpers/pydev/_pydevd_bundle/tables/pydevd_numpy.py
index d7c08ac44033..11dfd2e52860 100644
--- a/python/helpers/pydev/_pydevd_bundle/tables/pydevd_numpy.py
+++ b/python/helpers/pydev/_pydevd_bundle/tables/pydevd_numpy.py
@@ -31,6 +31,8 @@ def get_type(table):
def get_shape(table):
# type: (np.ndarray) -> str
+ if table.dtype.names is not None:
+ return str((table.shape[0], len(table.dtype.names)))
if table.ndim == 1:
return str((table.shape[0], 1))
else:
@@ -39,6 +41,9 @@ def get_shape(table):
def get_head(table):
# type: (np.ndarray) -> str
+ column_names = table.dtype.names
+ if column_names:
+ return TABLE_TYPE_NEXT_VALUE_SEPARATOR.join([str(column_names[i]) for i in range(len(column_names))])
return "None"
@@ -172,7 +177,8 @@ class _NpTable:
return ['
0 | \n']
if self.type == WITH_TYPES:
- return ['{} | \n'.format(name) for name in self.array.dtype.names]
+ columns_names = self.array.dtype.names
+ return ['{} | \n'.format(str(columns_names[i])) for i in range(len(columns_names))]
return ['{} | \n'.format(i) for i in range(len(self.array[0]))]
diff --git a/python/pydevSrc/src/com/jetbrains/python/debugger/PyDebugValue.java b/python/pydevSrc/src/com/jetbrains/python/debugger/PyDebugValue.java
index 73be178f83e9..8d7867cec9a4 100644
--- a/python/pydevSrc/src/com/jetbrains/python/debugger/PyDebugValue.java
+++ b/python/pydevSrc/src/com/jetbrains/python/debugger/PyDebugValue.java
@@ -33,18 +33,19 @@ public class PyDebugValue extends XNamedValue {
private static final String ARRAY = "Array";
private static final String DATA_FRAME = "DataFrame";
private static final String SERIES = "Series";
- private static final Map EVALUATOR_POSTFIXES = ImmutableMap.of(
- "ndarray", ARRAY,
- "EagerTensor", ARRAY,
- "ResourceVariable", ARRAY,
- "SparseTensor", ARRAY,
- "Tensor", ARRAY,
- DATA_FRAME, DATA_FRAME,
- SERIES, SERIES,
- "GeoDataFrame", DATA_FRAME,
- "GeoSeries", SERIES,
- "Dataset", DATA_FRAME
- );
+ private static final Map EVALUATOR_POSTFIXES = ImmutableMap.builder()
+ .put("ndarray", ARRAY)
+ .put("recarray", ARRAY)
+ .put("EagerTensor", ARRAY)
+ .put("ResourceVariable", ARRAY)
+ .put("SparseTensor", ARRAY)
+ .put("Tensor", ARRAY)
+ .put(DATA_FRAME, DATA_FRAME)
+ .put(SERIES, SERIES)
+ .put("GeoDataFrame", DATA_FRAME)
+ .put("GeoSeries", SERIES)
+ .put("Dataset", DATA_FRAME)
+ .build();
private static final int MAX_ITEMS_TO_HANDLE = 100;
public static final int MAX_VALUE = 256;
public static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
diff --git a/python/src/com/jetbrains/python/debugger/array/ArrayViewStrategy.java b/python/src/com/jetbrains/python/debugger/array/ArrayViewStrategy.java
index 3fb997d63e7a..7c6166d80c96 100644
--- a/python/src/com/jetbrains/python/debugger/array/ArrayViewStrategy.java
+++ b/python/src/com/jetbrains/python/debugger/array/ArrayViewStrategy.java
@@ -19,6 +19,10 @@ public class ArrayViewStrategy extends DataViewStrategy {
return new ArrayViewStrategy("ndarray");
}
+ public static @NotNull ArrayViewStrategy createInstanceForNumpyRecarray() {
+ return new ArrayViewStrategy("recarray");
+ }
+
public static @NotNull ArrayViewStrategy createInstanceForEagerTensor() {
return new ArrayViewStrategy("EagerTensor");
}
diff --git a/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java b/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java
index 10173be6e835..95a8cd969c14 100644
--- a/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java
+++ b/python/src/com/jetbrains/python/debugger/containerview/DataViewStrategy.java
@@ -19,6 +19,7 @@ public abstract class DataViewStrategy {
private static class StrategyHolder {
private static final Set STRATEGIES = ImmutableSet.of(
ArrayViewStrategy.createInstanceForNumpyArray(),
+ ArrayViewStrategy.createInstanceForNumpyRecarray(),
ArrayViewStrategy.createInstanceForEagerTensor(),
ArrayViewStrategy.createInstanceForResourceVariable(),
ArrayViewStrategy.createInstanceForSparseTensor(),
diff --git a/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java b/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java
index 8f78f5ddd2b9..f5d3c72a788c 100644
--- a/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java
+++ b/python/src/com/jetbrains/python/debugger/containerview/PyViewNumericContainerAction.java
@@ -65,6 +65,7 @@ public class PyViewNumericContainerAction extends XDebuggerTreeActionBase {
String nodeType = debugValue.getType();
if ("ndarray".equals(nodeType) ||
+ "recarray".equals(nodeType) ||
"EagerTensor".equals(nodeType) ||
"ResourceVariable".equals(nodeType) ||
"SparseTensor".equals(nodeType) ||