Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: spyder-ide/spyder
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b471e0efd05ce514dcadb76424c346523fd35a27
Choose a base ref
..
head repository: spyder-ide/spyder
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1ce2ee6813610c6101cacc0f4e49d1b93dd46c58
Choose a head ref
4 changes: 3 additions & 1 deletion spyder/plugins/tests/test_editor_introspection.py
Original file line number Diff line number Diff line change
@@ -15,12 +15,13 @@
from unittest.mock import Mock
except ImportError:
from mock import Mock # Python 2

from qtpy.QtWidgets import QWidget, QApplication
from qtpy.QtCore import Qt

# Local imports
from spyder.utils.introspection.jedi_plugin import JEDI_010
from spyder.utils.qthelpers import qapplication
from spyder.py3compat import PY2

# Location of this file
LOCATION = osp.realpath(osp.join(os.getcwd(), osp.dirname(__file__)))
@@ -59,6 +60,7 @@ def get_spyder_pythonpath(*args):


@pytest.mark.slow
@pytest.mark.skipif(PY2, reason="Strange segfaults with other tests on Py2.")
@pytest.mark.skipif(not JEDI_010,
reason="This feature is only supported in jedy >= 0.10")
def test_introspection(setup_editor):
10 changes: 5 additions & 5 deletions spyder/widgets/variableexplorer/dataframeeditor.py
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@
REAL_NUMBER_TYPES = (float, int, np.int64, np.int32)
COMPLEX_NUMBER_TYPES = (complex, np.complex64, np.complex128)
# Used to convert bool intrance to false since bool('False') will return True
_bool_false = ['false', '0']
_bool_false = ['false', 'f', '0', '0.', '0.0', ' ']

# Default format for data frames with floats
DEFAULT_FORMAT = '%.6g'
@@ -359,9 +359,9 @@ def setData(self, index, value, role=Qt.EditRole, change_type=None):
else:
val = from_qvariant(value, str)
current_value = self.get_value(row, column-1)
if isinstance(current_value, bool):
if isinstance(current_value, (bool, np.bool_)):
val = bool_false_check(val)
supported_types = (bool,) + REAL_NUMBER_TYPES + COMPLEX_NUMBER_TYPES
supported_types = (bool, np.bool_) + REAL_NUMBER_TYPES
if (isinstance(current_value, supported_types) or
is_text_string(current_value)):
try:
@@ -372,8 +372,8 @@ def setData(self, index, value, role=Qt.EditRole, change_type=None):
return False
else:
QMessageBox.critical(self.dialog, "Error",
"The type of the cell is not a supported "
"type")
"Editing dtype {0!s} not yet supported."
.format(type(current_value).__name__))
return False
self.max_min_col_update()
return True
126 changes: 123 additions & 3 deletions spyder/widgets/variableexplorer/tests/test_dataframeeditor.py
Original file line number Diff line number Diff line change
@@ -292,9 +292,8 @@ def test_dataframemodel_set_data_overflow(monkeypatch):


@flaky(max_runs=3)
@pytest.mark.skipif(os.environ.get('CI', None) is not None or
platform.startswith('linux'),
reason="Fails on Travis CI for unknown reasons.")
@pytest.mark.skipif(platform.startswith('linux'),
reason="Fails on some Linux platforms locally and Travis.")
def test_dataframeeditor_edit_overflow(qtbot, monkeypatch):
"""Test #6114: entry of an overflow int is caught and handled properly"""
MockQMessageBox = Mock()
@@ -323,6 +322,7 @@ def test_dataframeeditor_edit_overflow(qtbot, monkeypatch):
qtbot.keyClicks(view, '5')
qtbot.keyPress(view, Qt.Key_Down)
qtbot.keyPress(view, Qt.Key_Space)
qtbot.keyPress(view.focusWidget(), Qt.Key_Backspace)
qtbot.keyClicks(view.focusWidget(), str(int(2 ** bit_exponet)))
qtbot.keyPress(view.focusWidget(), Qt.Key_Down)
MockQMessageBox.critical.assert_called_with(ANY, "Error", ANY)
@@ -336,5 +336,125 @@ def test_dataframeeditor_edit_overflow(qtbot, monkeypatch):
dialog.get_value().as_matrix()) == len(expected_df)


def test_dataframemodel_set_data_complex(monkeypatch):
"""Unit test #6115: editing complex dtypes raises error in df editor"""
MockQMessageBox = Mock()
attr_to_patch = ('spyder.widgets.variableexplorer' +
'.dataframeeditor.QMessageBox')
monkeypatch.setattr(attr_to_patch, MockQMessageBox)

test_params = [(1, numpy.complex128), (2, numpy.complex64), (3, complex)]

for count, complex_type in test_params:
test_df = DataFrame(numpy.arange(10, 15), dtype=complex_type)
model = DataFrameModel(test_df.copy())
index = model.createIndex(2, 1)
assert not model.setData(index, '42')
MockQMessageBox.critical.assert_called_with(ANY, "Error", ANY)
assert MockQMessageBox.critical.call_count == count
assert numpy.sum(test_df[0].as_matrix() ==
model.df.as_matrix()) == len(test_df)


@flaky(max_runs=3)
@pytest.mark.skipif(os.environ.get('CI', None) is not None and
platform.startswith('linux'),
reason="Fails on Travis for no good reason.")
def test_dataframeeditor_edit_complex(qtbot, monkeypatch):
"""Test for #6115: editing complex dtypes raises error in df editor"""
MockQMessageBox = Mock()
attr_to_patch = ('spyder.widgets.variableexplorer' +
'.dataframeeditor.QMessageBox')
monkeypatch.setattr(attr_to_patch, MockQMessageBox)

test_params = [(1, numpy.complex128), (2, numpy.complex64), (3, complex)]

for count, complex_type in test_params:
test_df = DataFrame(numpy.arange(10, 15), dtype=complex_type)
dialog = DataFrameEditor()
assert dialog.setup_and_check(test_df, 'Test Dataframe')
dialog.show()
qtbot.waitForWindowShown(dialog)
view = dialog.dataTable

qtbot.keyPress(view, Qt.Key_Right)
qtbot.keyPress(view, Qt.Key_Down)
qtbot.keyPress(view, Qt.Key_Space)
qtbot.keyPress(view.focusWidget(), Qt.Key_Backspace)
qtbot.keyClicks(view.focusWidget(), "42")
qtbot.keyPress(view.focusWidget(), Qt.Key_Down)
MockQMessageBox.critical.assert_called_with(ANY, "Error", ANY)
assert MockQMessageBox.critical.call_count == count * 2 - 1
qtbot.keyPress(view, Qt.Key_Down)
qtbot.keyClick(view, '1')
qtbot.keyPress(view.focusWidget(), Qt.Key_Down)
MockQMessageBox.critical.assert_called_with(
ANY, "Error", ("Editing dtype {0!s} not yet supported."
.format(type(test_df.iloc[1, 0]).__name__)))
assert MockQMessageBox.critical.call_count == count * 2
qtbot.keyPress(view, Qt.Key_Return)
qtbot.wait(1000)
assert numpy.sum(test_df[0].as_matrix() ==
dialog.get_value().as_matrix()) == len(test_df)


def test_dataframemodel_set_data_bool(monkeypatch):
"""Unit test that bools are editible in df and false-y strs are detected"""
MockQMessageBox = Mock()
attr_to_patch = ('spyder.widgets.variableexplorer' +
'.dataframeeditor.QMessageBox')
monkeypatch.setattr(attr_to_patch, MockQMessageBox)

test_params = [numpy.bool_, numpy.bool, bool]
test_strs = ['foo', 'false', 'f', '0', '0.', '0.0', '', ' ']
expected_df = DataFrame([1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=bool)

for bool_type in test_params:
test_df = DataFrame([0, 1, 1, 1, 1, 1, 1, 1, 0], dtype=bool_type)
model = DataFrameModel(test_df.copy())
for idx, test_str in enumerate(test_strs):
assert model.setData(model.createIndex(idx, 1), test_str)
assert not MockQMessageBox.critical.called
assert numpy.sum(expected_df[0].as_matrix() ==
model.df.as_matrix()[:, 0]) == len(expected_df)


@flaky(max_runs=3)
@pytest.mark.skipif(os.environ.get('CI', None) is not None and
platform.startswith('linux'),
reason="Fails on Travis for no good reason.")
def test_dataframeeditor_edit_bool(qtbot, monkeypatch):
"""Unit test that bools are editible in df and false-y strs are detected"""
MockQMessageBox = Mock()
attr_to_patch = ('spyder.widgets.variableexplorer' +
'.dataframeeditor.QMessageBox')
monkeypatch.setattr(attr_to_patch, MockQMessageBox)

test_params = [numpy.bool_, numpy.bool, bool]
test_strs = ['foo', 'false', 'f', '0', '0.', '0.0', '', ' ']
expected_df = DataFrame([1, 0, 0, 0, 0, 0, 0, 0, 0], dtype=bool)

for bool_type in test_params:
test_df = DataFrame([0, 1, 1, 1, 1, 1, 1, 1, 0], dtype=bool_type)
dialog = DataFrameEditor()
assert dialog.setup_and_check(test_df, 'Test Dataframe')
dialog.show()
qtbot.waitForWindowShown(dialog)
view = dialog.dataTable

qtbot.keyPress(view, Qt.Key_Right)
for test_str in test_strs:
qtbot.keyPress(view, Qt.Key_Space)
qtbot.keyPress(view.focusWidget(), Qt.Key_Backspace)
qtbot.keyClicks(view.focusWidget(), test_str)
qtbot.keyPress(view.focusWidget(), Qt.Key_Down)
assert not MockQMessageBox.critical.called
qtbot.keyPress(view, Qt.Key_Return)
qtbot.wait(1000)
assert (numpy.sum(expected_df[0].as_matrix() ==
dialog.get_value().as_matrix()[:, 0]) ==
len(expected_df))


if __name__ == "__main__":
pytest.main()