diff --git a/.mypy.ini b/.mypy.ini index c3abf98fcbb..df699b94800 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -35,18 +35,25 @@ ignore_missing_imports = True [mypy-ert._clib.*] ignore_missing_imports = True -[mypy-ert.gui.ertwidgets.*] +[mypy-ert.gui.model.node] ignore_missing_imports = True ignore_errors = True -[mypy-ert.gui.model.node] +[mypy-ert.gui.model.snapshot] ignore_missing_imports = True ignore_errors = True -[mypy-ert.gui.model.snapshot] +[mypy-ert.gui.ertwidgets.validationsupport] ignore_missing_imports = True ignore_errors = True +[mypy-ert.gui.ertwidgets.analysismodulevariablespanel] +ignore_missing_imports = True +ignore_errors = True + +[mypy-ert.gui.ertwidgets.listeditbox] +ignore_missing_imports = True +ignore_errors = True [mypy-ert.gui.simulation.*] ignore_missing_imports = True @@ -92,6 +99,9 @@ ignore_missing_imports = True [mypy-SALib.*] ignore_missing_imports = True +[mypy-seaborn.*] +ignore_missing_imports = True + [mypy-pluggy.*] ignore_missing_imports = True diff --git a/src/ert/gui/ertwidgets/__init__.py b/src/ert/gui/ertwidgets/__init__.py index 98b21c91f18..f6f4c7a00cc 100644 --- a/src/ert/gui/ertwidgets/__init__.py +++ b/src/ert/gui/ertwidgets/__init__.py @@ -2,13 +2,14 @@ from qtpy.QtCore import Qt from qtpy.QtGui import QCursor from qtpy.QtWidgets import QApplication +from typing import Callable, Any -def showWaitCursorWhileWaiting(func): +def showWaitCursorWhileWaiting(func: Callable[..., Any]) -> Callable[..., Any]: """A function decorator to show the wait cursor while the function is working.""" - def wrapper(*arg): - QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) + def wrapper(*arg: Any) -> Any: + QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor)) try: res = func(*arg) return res diff --git a/src/ert/gui/ertwidgets/analysismoduleedit.py b/src/ert/gui/ertwidgets/analysismoduleedit.py index f6892727567..92270bfb0a7 100644 --- a/src/ert/gui/ertwidgets/analysismoduleedit.py +++ b/src/ert/gui/ertwidgets/analysismoduleedit.py @@ -30,7 +30,7 @@ def __init__( variables_popup_button.clicked.connect(self.showVariablesPopup) variables_popup_button.setMaximumSize(20, 20) - layout.addWidget(variables_popup_button, 0, Qt.AlignLeft) + layout.addWidget(variables_popup_button, 0, Qt.AlignmentFlag.AlignLeft) layout.setContentsMargins(QMargins(0, 0, 0, 0)) layout.addStretch() @@ -40,5 +40,9 @@ def showVariablesPopup(self) -> None: variable_dialog = AnalysisModuleVariablesPanel( self.analysis_module, self.ensemble_size ) - dialog = ClosableDialog("Edit variables", variable_dialog, self.parent()) + dialog = ClosableDialog( + "Edit variables", + variable_dialog, + self.parent(), # type: ignore + ) dialog.exec_() diff --git a/src/ert/gui/ertwidgets/checklist.py b/src/ert/gui/ertwidgets/checklist.py index 416a80f20be..5c01005d24b 100644 --- a/src/ert/gui/ertwidgets/checklist.py +++ b/src/ert/gui/ertwidgets/checklist.py @@ -1,4 +1,8 @@ -from qtpy.QtCore import QSize, Qt +from __future__ import annotations + +from typing import TYPE_CHECKING, Optional + +from qtpy.QtCore import QPoint, QSize, Qt from qtpy.QtGui import QIcon from qtpy.QtWidgets import ( QAbstractItemView, @@ -14,14 +18,21 @@ from ert.gui.ertwidgets import SearchBox +if TYPE_CHECKING: + from .models.selectable_list_model import SelectableListModel + class CheckList(QWidget): - def __init__(self, model, label: str = "", custom_filter_button=None): + def __init__( + self, + model: SelectableListModel, + label: str = "", + custom_filter_button: Optional[QToolButton] = None, + ): """ :param custom_filter_button: if needed, add a button that opens a custom filter menu. Useful when search alone isn't enough to filter the list. - :type custom_filter_button: QToolButton """ QWidget.__init__(self) @@ -32,7 +43,7 @@ def __init__(self, model, label: str = "", custom_filter_button=None): self._createCheckButtons() self._list = QListWidget() - self._list.setContextMenuPolicy(Qt.CustomContextMenu) + self._list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self._list.setSelectionMode(QAbstractItemView.ExtendedSelection) self._search_box = SearchBox() @@ -76,20 +87,20 @@ def _createCheckButtons(self) -> None: self._checkAllButton = QToolButton() self._checkAllButton.setIcon(QIcon("img:check.svg")) self._checkAllButton.setIconSize(QSize(16, 16)) - self._checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) + self._checkAllButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) self._checkAllButton.setAutoRaise(True) self._checkAllButton.setToolTip("Select all") self._uncheckAllButton = QToolButton() self._uncheckAllButton.setIcon(QIcon("img:checkbox_outline.svg")) self._uncheckAllButton.setIconSize(QSize(16, 16)) - self._uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) + self._uncheckAllButton.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) self._uncheckAllButton.setAutoRaise(True) self._uncheckAllButton.setToolTip("Unselect all") - def itemChanged(self, item: QListWidgetItem): - if item.checkState() == Qt.Checked: + def itemChanged(self, item: QListWidgetItem) -> None: + if item.checkState() == Qt.CheckState.Checked: self._model.selectValue(str(item.text())) - elif item.checkState() == Qt.Unchecked: + elif item.checkState() == Qt.CheckState.Unchecked: self._model.unselectValue(str(item.text())) else: raise AssertionError("Unhandled checkstate!") @@ -101,12 +112,12 @@ def modelChanged(self) -> None: for item in items: list_item = QListWidgetItem(item) - list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable) + list_item.setFlags(list_item.flags() | Qt.ItemFlag.ItemIsUserCheckable) if self._model.isValueSelected(item): - list_item.setCheckState(Qt.Checked) + list_item.setCheckState(Qt.CheckState.Checked) else: - list_item.setCheckState(Qt.Unchecked) + list_item.setCheckState(Qt.CheckState.Unchecked) self._list.addItem(list_item) @@ -117,6 +128,7 @@ def filterList(self, _filter: str) -> None: for index in range(0, self._list.count()): item = self._list.item(index) + assert item is not None text = item.text().lower() if not _filter or _filter in text: @@ -130,6 +142,7 @@ def checkAll(self) -> None: """ for index in range(0, self._list.count()): item = self._list.item(index) + assert item is not None if not item.isHidden(): self._model.selectValue(str(item.text())) @@ -140,22 +153,14 @@ def uncheckAll(self) -> None: self._model.unselectAll() def checkSelected(self) -> None: - items = [] for item in self._list.selectedItems(): - items.append(str(item.text())) - - for item in items: - self._model.selectValue(item) + self._model.selectValue(str(item.text())) def uncheckSelected(self) -> None: - items = [] for item in self._list.selectedItems(): - items.append(str(item.text())) - - for item in items: - self._model.unselectValue(item) + self._model.unselectValue(str(item.text())) - def showContextMenu(self, point): + def showContextMenu(self, point: QPoint) -> None: p = self._list.mapToGlobal(point) menu = QMenu() check_selected = menu.addAction("Check selected") diff --git a/src/ert/gui/ertwidgets/closabledialog.py b/src/ert/gui/ertwidgets/closabledialog.py index 68d18cfdd4f..f02cdda8c9a 100644 --- a/src/ert/gui/ertwidgets/closabledialog.py +++ b/src/ert/gui/ertwidgets/closabledialog.py @@ -6,6 +6,7 @@ from qtpy.QtWidgets import QDialog, QHBoxLayout, QPushButton, QVBoxLayout, QWidget if TYPE_CHECKING: + from qtpy.QtGui import QKeyEvent from qtpy.QtWidgets import QT_SLOT @@ -16,9 +17,14 @@ def __init__( QDialog.__init__(self, parent) self.setWindowTitle(title) self.setModal(True) - self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint) - self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) - self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) + self.setWindowFlags(self.windowFlags() | Qt.WindowType.CustomizeWindowHint) + self.setWindowFlags( + self.windowFlags() + & ~Qt.WindowFlags(Qt.WindowType.WindowContextHelpButtonHint) + ) + self.setWindowFlags( + self.windowFlags() & ~Qt.WindowFlags(Qt.WindowType.WindowCloseButtonHint) + ) layout = QVBoxLayout() layout.addWidget(widget, stretch=1) @@ -41,9 +47,11 @@ def disableCloseButton(self) -> None: def enableCloseButton(self) -> None: self.close_button.setEnabled(True) - def keyPressEvent(self, q_key_event): - if self.close_button.isEnabled() or q_key_event.key() != Qt.Key_Escape: - QDialog.keyPressEvent(self, q_key_event) + def keyPressEvent(self, a0: Optional[QKeyEvent]) -> None: + if self.close_button.isEnabled() or ( + a0 is not None and a0.key() != Qt.Key.Key_Escape + ): + QDialog.keyPressEvent(self, a0) def addButton(self, caption: str, listener: QT_SLOT) -> None: button = QPushButton(caption) diff --git a/src/ert/gui/ertwidgets/create_experiment_dialog.py b/src/ert/gui/ertwidgets/create_experiment_dialog.py index 1cd6a75af92..9a5d8572e9a 100644 --- a/src/ert/gui/ertwidgets/create_experiment_dialog.py +++ b/src/ert/gui/ertwidgets/create_experiment_dialog.py @@ -44,8 +44,9 @@ def __init__( ) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) - self._ok_button = buttons.button(QDialogButtonBox.Ok) - assert self._ok_button + ok_button = buttons.button(QDialogButtonBox.Ok) + assert ok_button + self._ok_button = ok_button self._ok_button.clicked.connect( lambda: self.onDone.emit( diff --git a/src/ert/gui/ertwidgets/ensemblelist.py b/src/ert/gui/ertwidgets/ensemblelist.py index 4a9963d44e8..e944c4522b4 100644 --- a/src/ert/gui/ertwidgets/ensemblelist.py +++ b/src/ert/gui/ertwidgets/ensemblelist.py @@ -110,5 +110,5 @@ def updateList(self) -> None: item = QListWidgetItem( f"{ensemble.name} - {ensemble.started_at} ({ensemble.id})" ) - item.setData(Qt.UserRole, ensemble) + item.setData(Qt.ItemDataRole.UserRole, ensemble) self._list.addItem(item) diff --git a/src/ert/gui/ertwidgets/ensembleselector.py b/src/ert/gui/ertwidgets/ensembleselector.py index 38159cdd2f2..db0d977c449 100644 --- a/src/ert/gui/ertwidgets/ensembleselector.py +++ b/src/ert/gui/ertwidgets/ensembleselector.py @@ -81,7 +81,7 @@ def populate(self) -> None: def _ensemble_list(self) -> Iterable[Ensemble]: if self._show_only_undefined: - ensemble_list = ( + ensembles = ( ensemble for ensemble in self.notifier.storage.ensembles if all( @@ -90,8 +90,8 @@ def _ensemble_list(self) -> Iterable[Ensemble]: ) ) else: - ensemble_list = self.notifier.storage.ensembles - ensemble_list = list(ensemble_list) + ensembles = self.notifier.storage.ensembles + ensemble_list = list(ensembles) if self._show_only_no_children: parents = [ ens.parent for ens in self.notifier.storage.ensembles if ens.parent diff --git a/src/ert/gui/ertwidgets/legend.py b/src/ert/gui/ertwidgets/legend.py index bd0989b20f8..9733cf3c2e2 100644 --- a/src/ert/gui/ertwidgets/legend.py +++ b/src/ert/gui/ertwidgets/legend.py @@ -1,7 +1,7 @@ from typing import Optional from qtpy.QtCore import QSize -from qtpy.QtGui import QColor, QPainter +from qtpy.QtGui import QColor, QPainter, QPaintEvent from qtpy.QtWidgets import QHBoxLayout, QLabel, QWidget @@ -16,8 +16,7 @@ def __init__(self, color: QColor): self.color = color - def paintEvent(self, paintevent): - """Paints the box""" + def paintEvent(self, a0: Optional[QPaintEvent]) -> None: painter = QPainter(self) rect = self.contentsRect() diff --git a/src/ert/gui/ertwidgets/message_box.py b/src/ert/gui/ertwidgets/message_box.py index 6c4f9928b9a..b3aa6d495da 100644 --- a/src/ert/gui/ertwidgets/message_box.py +++ b/src/ert/gui/ertwidgets/message_box.py @@ -28,8 +28,8 @@ def __init__( super().__init__(parent) self.box = QDialogButtonBox( QDialogButtonBox.Ok, - centerButtons=True, ) + self.box.setCenterButtons(True) self.box.accepted.connect(self.accept) self.details_text = QTextEdit() @@ -39,7 +39,9 @@ def __init__( self.label_text = QLabel(text) self.label_icon = QLabel() - icon = self.style().standardIcon(QStyle.SP_MessageBoxCritical) + style = self.style() + assert style is not None + icon = style.standardIcon(QStyle.StandardPixmap.SP_MessageBoxCritical) self.label_icon.setPixmap(icon.pixmap(32)) lay = QGridLayout(self) diff --git a/src/ert/gui/ertwidgets/models/path_model.py b/src/ert/gui/ertwidgets/models/path_model.py index 8d8cedaa600..e03df7e7152 100644 --- a/src/ert/gui/ertwidgets/models/path_model.py +++ b/src/ert/gui/ertwidgets/models/path_model.py @@ -1,3 +1,5 @@ +from typing import Optional + from ert.gui.ertwidgets.models.valuemodel import ValueModel @@ -39,7 +41,7 @@ def pathMustExist(self) -> bool: def pathMustBeAbsolute(self) -> bool: return self._path_must_be_absolute - def getPath(self) -> str: + def getPath(self) -> Optional[str]: return self.getValue() def setPath(self, value: str) -> None: diff --git a/src/ert/gui/ertwidgets/models/storage_model.py b/src/ert/gui/ertwidgets/models/storage_model.py index 1061e898fbf..39720b40a53 100644 --- a/src/ert/gui/ertwidgets/models/storage_model.py +++ b/src/ert/gui/ertwidgets/models/storage_model.py @@ -51,7 +51,7 @@ def row(self) -> int: return self._parent._children.index(self) return 0 - def data(self, index: QModelIndex, role) -> Any: + def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> Any: if not index.isValid(): return None @@ -78,7 +78,7 @@ def row(self) -> int: return self._parent._children.index(self) return 0 - def data(self, index: QModelIndex, role) -> Any: + def data(self, index: QModelIndex, role: Qt.ItemDataRole) -> Any: if not index.isValid(): return None @@ -111,7 +111,9 @@ def row(self) -> int: return self._parent._children.index(self) return 0 - def data(self, index: QModelIndex, role=Qt.ItemDataRole.DisplayRole) -> Any: + def data( + self, index: QModelIndex, role: Qt.ItemDataRole = Qt.ItemDataRole.DisplayRole + ) -> Any: if not index.isValid(): return None diff --git a/src/ert/gui/ertwidgets/pathchooser.py b/src/ert/gui/ertwidgets/pathchooser.py index 43eed5e1961..4875601eb2b 100644 --- a/src/ert/gui/ertwidgets/pathchooser.py +++ b/src/ert/gui/ertwidgets/pathchooser.py @@ -128,11 +128,11 @@ def selectPath(self) -> None: current_directory = self.getPath() if self._model.pathMustBeAFile(): - current_directory: tuple[str, str] = QFileDialog.getOpenFileName( + current_directory = QFileDialog.getOpenFileName( self, "Select a file path", current_directory )[0] else: - current_directory: str = QFileDialog.getExistingDirectory( + current_directory = QFileDialog.getExistingDirectory( self, "Select a directory", current_directory ) diff --git a/src/ert/gui/ertwidgets/searchbox.py b/src/ert/gui/ertwidgets/searchbox.py index 2647129fcd2..c84499e74de 100644 --- a/src/ert/gui/ertwidgets/searchbox.py +++ b/src/ert/gui/ertwidgets/searchbox.py @@ -1,7 +1,7 @@ -from typing import Any +from typing import Any, Optional from qtpy.QtCore import Qt, Signal -from qtpy.QtGui import QColor +from qtpy.QtGui import QColor, QFocusEvent, QKeyEvent from qtpy.QtWidgets import QLineEdit @@ -54,17 +54,17 @@ def exitSearch(self) -> None: if not self.text(): self.presentSearch() - def focusInEvent(self, focus_event): - QLineEdit.focusInEvent(self, focus_event) + def focusInEvent(self, a0: Optional[QFocusEvent]) -> None: + QLineEdit.focusInEvent(self, a0) self.enterSearch() - def focusOutEvent(self, focus_event): - QLineEdit.focusOutEvent(self, focus_event) + def focusOutEvent(self, a0: Optional[QFocusEvent]) -> None: + QLineEdit.focusOutEvent(self, a0) self.exitSearch() - def keyPressEvent(self, key_event): - if key_event.key() == Qt.Key_Escape: + def keyPressEvent(self, a0: Optional[QKeyEvent]) -> None: + if a0 is not None and a0.key() != Qt.Key.Key_Escape: self.clear() self.clearFocus() else: - QLineEdit.keyPressEvent(self, key_event) + QLineEdit.keyPressEvent(self, a0) diff --git a/src/ert/gui/ertwidgets/statusdialog.py b/src/ert/gui/ertwidgets/statusdialog.py index 01ea3414cd2..42ecb195d8d 100644 --- a/src/ert/gui/ertwidgets/statusdialog.py +++ b/src/ert/gui/ertwidgets/statusdialog.py @@ -1,6 +1,7 @@ from typing import Any, List, Optional, cast from qtpy.QtCore import Qt, Signal, Slot +from qtpy.QtGui import QKeyEvent from qtpy.QtWidgets import ( QDialog, QHBoxLayout, @@ -14,7 +15,7 @@ class StatusDialog(QDialog): - close = Signal() + close = Signal() # type: ignore run = Signal() def __init__( @@ -24,9 +25,14 @@ def __init__( self.setWindowTitle(title) self.setModal(True) - self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint) - self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) - self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint) + self.setWindowFlags(self.windowFlags() | Qt.WindowType.CustomizeWindowHint) + self.setWindowFlags( + self.windowFlags() + & ~Qt.WindowFlags(Qt.WindowType.WindowContextHelpButtonHint) + ) + self.setWindowFlags( + self.windowFlags() & ~Qt.WindowFlags(Qt.WindowType.WindowCloseButtonHint) + ) layout = QVBoxLayout() layout.addWidget(widget) @@ -53,9 +59,11 @@ def __init__( self.setLayout(layout) - def keyPressEvent(self, q_key_event): - if self._close_button.isEnabled() or q_key_event.key() != Qt.Key_Escape: - QDialog.keyPressEvent(self, q_key_event) + def keyPressEvent(self, a0: Optional[QKeyEvent]) -> None: + if self._close_button.isEnabled() or ( + a0 is not None and a0.key() != Qt.Key.Key_Escape + ): + QDialog.keyPressEvent(self, a0) def enable_button(self, caption: Any, enabled: bool = True) -> None: button = self.findChild(QPushButton, str(caption).capitalize()) diff --git a/src/ert/gui/ertwidgets/storage_info_widget.py b/src/ert/gui/ertwidgets/storage_info_widget.py index 3ebc3795a8b..8ca06bfeb36 100644 --- a/src/ert/gui/ertwidgets/storage_info_widget.py +++ b/src/ert/gui/ertwidgets/storage_info_widget.py @@ -5,7 +5,7 @@ import numpy as np import seaborn as sns import yaml -from matplotlib.backends.backend_qt5agg import FigureCanvas +from matplotlib.backends.backend_qt5agg import FigureCanvas # type: ignore from matplotlib.figure import Figure from qtpy.QtCore import Qt, Slot from qtpy.QtWidgets import ( @@ -121,12 +121,12 @@ def __init__(self) -> None: self._name_label = QLabel() self._uuid_label = QLabel() - layout = QVBoxLayout() - layout.addWidget(self._name_label) - layout.addWidget(self._uuid_label) - layout.addStretch() + info_layout = QVBoxLayout() + info_layout.addWidget(self._name_label) + info_layout.addWidget(self._uuid_label) + info_layout.addStretch() - info_frame.setLayout(layout) + info_frame.setLayout(info_layout) self._state_text_edit = QTextEdit() self._state_text_edit.setReadOnly(True) @@ -148,10 +148,10 @@ def __init__(self) -> None: self._canvas.setFocusPolicy(Qt.FocusPolicy.StrongFocus) self._canvas.setFocus() - layout = QHBoxLayout() - layout.addWidget(self._observations_tree_widget) - layout.addWidget(self._canvas) - observations_frame.setLayout(layout) + observations_layout = QHBoxLayout() + observations_layout.addWidget(self._observations_tree_widget) + observations_layout.addWidget(self._canvas) + observations_frame.setLayout(observations_layout) self._tab_widget = QTabWidget() self._tab_widget.insertTab( @@ -187,11 +187,13 @@ def _currentItemChanged( ax.set_title(observation_name) ax.grid(True) - response_name, response_type = self._ensemble.experiment.response_info_for_obs( + ensemble = self._ensemble + assert ensemble is not None + response_name, response_type = ensemble.experiment.response_info_for_obs( observation_name ) - observation_ds = self._ensemble.experiment.get_single_obs_ds(observation_name) - response_ds = self._ensemble.load_responses( + observation_ds = ensemble.experiment.get_single_obs_ds(observation_name) + response_ds = ensemble.load_responses( response_name, ) @@ -211,7 +213,7 @@ def _currentItemChanged( ax.errorbar( x="Observation", - y=observation_ds.get("observations"), + y=observation_ds.get("observations"), # type: ignore yerr=observation_ds.get("std"), fmt=".", linewidth=1, @@ -231,7 +233,7 @@ def _currentItemChanged( ax.errorbar( x="Observation", - y=observation_ds.get("observations"), + y=observation_ds.get("observations"), # type: ignore yerr=observation_ds.get("std"), fmt=".", linewidth=1, @@ -245,7 +247,9 @@ def _currentTabChanged(self, index: int) -> None: if index == _EnsembleWidgetTabs.STATE_TAB: self._state_text_edit.clear() html = "
{state_index:d}. | {value.name} |