Skip to content

Commit

Permalink
Backport PR #23460 on branch 6.x (PR: Avoid error when getting an obj…
Browse files Browse the repository at this point in the history
…ect's value to copy it (Variable Explorer)) (#23461)
  • Loading branch information
meeseeksmachine authored Jan 14, 2025
1 parent 8d0dcbd commit 479880d
Showing 1 changed file with 69 additions and 11 deletions.
80 changes: 69 additions & 11 deletions spyder/widgets/collectionseditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1384,13 +1384,32 @@ def save_array(self):

@Slot()
def copy(self):
"""Copy text to clipboard"""
"""
Copy text representation of objects to clipboard.
Notes
-----
For Numpy arrays and dataframes we try to get a better representation
by using their `savetxt` and `to_csv` methods, respectively.
"""
clipboard = QApplication.clipboard()
clipl = []
retrieve_failed = False
array_failed = False
dataframe_failed = False

for idx in self.selectedIndexes():
if not idx.isValid():
continue
obj = self.delegate.get_value(idx)

# Prevent error when it's not possible to get the object's value
# Fixes spyder-ide/spyder#12913
try:
obj = self.delegate.get_value(idx)
except Exception:
retrieve_failed = True
continue

# Check if we are trying to copy a numpy array, and if so make sure
# to copy the whole thing in a tab separated format
if (isinstance(obj, (np.ndarray, np.ma.MaskedArray)) and
Expand All @@ -1399,10 +1418,8 @@ def copy(self):
try:
np.savetxt(output, obj, delimiter='\t')
except Exception:
QMessageBox.warning(self, _("Warning"),
_("It was not possible to copy "
"this array"))
return
array_failed = True
continue
obj = output.getvalue().decode('utf-8')
output.close()
elif (isinstance(obj, (pd.DataFrame, pd.Series)) and
Expand All @@ -1411,19 +1428,60 @@ def copy(self):
try:
obj.to_csv(output, sep='\t', index=True, header=True)
except Exception:
QMessageBox.warning(self, _("Warning"),
_("It was not possible to copy "
"this dataframe"))
return
dataframe_failed = True
continue
obj = output.getvalue()
output.close()
elif is_binary_string(obj):
obj = to_text_string(obj, 'utf8')
else:
obj = to_text_string(obj)
obj = str(obj)

clipl.append(obj)

# Copy to clipboard the final result
clipboard.setText('\n'.join(clipl))

# Show appropriate error messages after we tried to copy all objects
# selected by users.
if retrieve_failed:
QMessageBox.warning(
self.parent(),
_("Warning"),
_(
"It was not possible to retrieve the value of one or more "
"of the variables you selected in order to copy them."
),
)

if array_failed and dataframe_failed:
QMessageBox.warning(
self,
_("Warning"),
_(
"It was not possible to copy one or more of the "
"dataframes and Numpy arrays you selected"
),
)
elif array_failed:
QMessageBox.warning(
self,
_("Warning"),
_(
"It was not possible to copy one or more of the "
"Numpy arrays you selected"
),
)
elif dataframe_failed:
QMessageBox.warning(
self,
_("Warning"),
_(
"It was not possible to copy one or more of the "
"dataframes you selected"
),
)

def import_from_string(self, text, title=None):
"""Import data from string"""
data = self.source_model.get_data()
Expand Down

0 comments on commit 479880d

Please sign in to comment.