Skip to content

Commit 92a3948

Browse files
authored
v1.5.0
version 1.5.0
2 parents 88dbf55 + 1623b61 commit 92a3948

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+5628
-5286
lines changed

mypy.ini

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[mypy]
2+
# strict checking
3+
strict = True
4+
implicit_reexport = True
5+
6+
# Minimum version supported
7+
python_version = 3.11
8+
9+
packages=pyobs_gui
10+
exclude = docs/
11+
12+
# Allows Type[T] to refer to abstract classes, which is not otherwise supported.
13+
# See https://github.com/python/mypy/issues/4717
14+
disable_error_code = type-abstract
15+
16+
[mypy-pyobs_gui.qt.*]
17+
ignore_errors = true
18+
19+
[mypy-astropy.*]
20+
ignore_missing_imports = True
21+
22+
[mypy-astroplan.*]
23+
ignore_missing_imports = True
24+
25+
[mypy-qasync.*]
26+
ignore_missing_imports = True

pyobs_gui/base.py

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,8 @@
33
import asyncio
44
import logging
55
from collections.abc import Coroutine
6-
from typing import (
7-
List,
8-
Dict,
9-
Tuple,
10-
Any,
11-
Union,
12-
TypeVar,
13-
Optional,
14-
Callable,
15-
)
16-
17-
from PyQt5 import QtWidgets, QtGui, QtCore
6+
from typing import Any, TypeVar, Callable, Type
7+
from PySide6 import QtWidgets, QtGui, QtCore # type: ignore
188
from astroplan import Observer
199

2010
from pyobs.comm import Comm, Proxy
@@ -33,18 +23,24 @@
3323
class BaseWindow:
3424
def __init__(self) -> None:
3525
"""Base class for MainWindow and all widgets."""
36-
self.modules: List[Proxy] = []
37-
self.comm: Optional[Comm] = None
38-
self.observer: Optional[Observer] = None
39-
self.vfs: Optional[Union[VirtualFileSystem, Dict[str, Any]]] = None
40-
self._base_widgets: List[BaseWidget] = []
26+
self.modules: list[Proxy] = []
27+
self._comm: Comm | None = None
28+
self.observer: Observer | None = None
29+
self.vfs: VirtualFileSystem | dict[str, Any] | None = None
30+
self._base_widgets: list[BaseWidget] = []
4131

4232
@property
43-
def module(self) -> Optional[Proxy]:
33+
def comm(self) -> Comm:
34+
if self._comm is None:
35+
raise ValueError("No comm object.")
36+
return self._comm
37+
38+
@property
39+
def module(self) -> Proxy:
4440
"""Returns the first module in the list or None, if list is empty"""
45-
return self.modules[0] if len(self.modules) > 0 else None
41+
return self.modules[0]
4642

47-
def module_by_name(self, name: str) -> Optional[Proxy]:
43+
def module_by_name(self, name: str) -> Proxy | None:
4844
"""Return the module with the given name or None, if not exists.
4945
5046
Args:
@@ -62,7 +58,7 @@ def module_by_name(self, name: str) -> Optional[Proxy]:
6258
# nothing found
6359
return None
6460

65-
def modules_by_interface(self, interface: Any) -> List[Proxy]:
61+
def modules_by_interface(self, interface: Any) -> list[Proxy]:
6662
"""Returns all modules that implement the given interface.
6763
6864
Args:
@@ -73,7 +69,7 @@ def modules_by_interface(self, interface: Any) -> List[Proxy]:
7369
"""
7470
return list(filter(lambda m: isinstance(m, interface), self.modules))
7571

76-
def module_by_interface(self, interface: Any) -> Optional[Proxy]:
72+
def module_by_interface(self, interface: Any) -> Proxy | None:
7773
"""Returns first modules that implement the given interface, or None, if no exist.
7874
7975
Args:
@@ -85,7 +81,7 @@ def module_by_interface(self, interface: Any) -> Optional[Proxy]:
8581
modules = self.modules_by_interface(interface)
8682
return None if len(modules) == 0 else modules[0]
8783

88-
def create_widget(self, config: Union[Dict[str, Any], type], **kwargs: Any) -> "BaseWidget":
84+
def create_widget(self, config: dict[str, Any] | type, **kwargs: Any) -> "BaseWidget":
8985
"""Creates new widget.
9086
9187
Args:
@@ -112,37 +108,38 @@ def create_widget(self, config: Union[Dict[str, Any], type], **kwargs: Any) -> "
112108

113109
async def open(
114110
self,
115-
modules: Optional[List[Proxy]] = None,
116-
comm: Optional[Comm] = None,
117-
observer: Optional[Observer] = None,
118-
vfs: Optional[Union[VirtualFileSystem, Dict[str, Any]]] = None,
111+
modules: list[Proxy] | None = None,
112+
comm: Comm | None = None,
113+
observer: Observer | None = None,
114+
vfs: VirtualFileSystem | dict[str, Any] | None = None,
119115
) -> None:
120116
# store
121117
self.modules = [] if modules is None else modules
122118
self.vfs = vfs
123-
self.comm = comm
119+
self._comm = comm
124120
self.observer = observer
125121

126122
"""Open all widgets."""
127123
for widget in self._base_widgets:
128124
await self._open_child(widget)
129125

130-
async def _open_child(self, widget: BaseWidget):
126+
async def _open_child(self, widget: BaseWidget) -> None:
131127
await widget.open(modules=self.modules, vfs=self.vfs, comm=self.comm, observer=self.observer)
132128

133129

134-
class BaseWidget(BaseWindow):
135-
_show_error = QtCore.pyqtSignal(str)
136-
_enable_buttons = QtCore.pyqtSignal(list, bool)
130+
class BaseWidget(BaseWindow, QtWidgets.QWidget): # type: ignore
131+
_show_error = QtCore.Signal(str)
132+
_enable_buttons = QtCore.Signal(list, bool)
137133

138134
def __init__(
139135
self,
140-
update_func: Optional[Callable[[], Any]] = None,
136+
update_func: Callable[[], Any] | None = None,
141137
update_interval: float = 1,
142138
*args: Any,
143139
**kwargs: Any,
144140
):
145141
BaseWindow.__init__(self)
142+
QtWidgets.QWidget.__init__(self)
146143

147144
# signals
148145
self._show_error.connect(self.show_error)
@@ -151,15 +148,15 @@ def __init__(
151148
# update
152149
self._update_func = update_func
153150
self._update_interval = update_interval
154-
self._update_task: Optional[Any] = None
151+
self._update_task: Any | None = None
155152

156153
# sidebar
157-
self.sidebar_widgets: List[BaseWidget] = []
158-
self.sidebar_layout: Optional[QtWidgets.QVBoxLayout] = None
154+
self.sidebar_widgets: list[BaseWidget] = []
155+
self.sidebar_layout: QtWidgets.QVBoxLayout | None = None
159156

160157
# button to extract to window
161-
self.extract_window_button: Optional[QtWidgets.QToolButton] = None
162-
self._windows: List[QtWidgets.QDialog] = []
158+
self.extract_window_button: QtWidgets.QToolButton | None = None
159+
self._windows: list[QtWidgets.QDialog] = []
163160

164161
# has it been initialized?
165162
self._initialized = False
@@ -168,18 +165,18 @@ def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
168165
if self.extract_window_button:
169166
self.extract_window_button.move(self.width() - 20, 0)
170167

171-
def show_extract_button(self, klass, title):
168+
def show_extract_button(self, klass: Type[Any], title: str) -> None:
172169
# button to extract to window
173170
self.extract_window_button = QtWidgets.QToolButton(self)
174171
# self.extract_window_button.setText("X")
175172
self.extract_window_button.setIcon(QtGui.QIcon(":/resources/arrow-up-right-from-square-solid.svg"))
176-
self.colorize_button(self.extract_window_button, QtCore.Qt.darkCyan)
173+
self.colorize_button(self.extract_window_button, QtCore.Qt.GlobalColor.darkCyan)
177174
self.extract_window_button.move(self.width() - 20, 0)
178175
self.extract_window_button.resize(20, 20)
179176
self.extract_window_button.raise_()
180177

181178
# method for creating new window
182-
def create_window():
179+
def create_window() -> None:
183180
# create dialog and add widget
184181
dialog = QtWidgets.QDialog()
185182
dialog.setWindowTitle(title)
@@ -203,9 +200,12 @@ async def add_to_sidebar(self, widget: BaseWidget) -> None:
203200
if self.sidebar_layout is None:
204201
self.sidebar_layout = QtWidgets.QVBoxLayout()
205202
self.sidebar_layout.setContentsMargins(0, 0, 0, 0)
206-
spacer_item = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
203+
spacer_item = QtWidgets.QSpacerItem(
204+
20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding
205+
)
207206
self.sidebar_layout.addItem(spacer_item)
208-
self.widgetSidebar.setLayout(self.sidebar_layout)
207+
if hasattr(self, "widgetSidebar"):
208+
self.widgetSidebar.setLayout(self.sidebar_layout)
209209

210210
# open it
211211
await self._open_child(widget)
@@ -246,8 +246,9 @@ async def _update_loop(self) -> None:
246246
while True:
247247
try:
248248
# get module state
249-
if isinstance(self.module, IModule):
250-
state = await self.module.get_state()
249+
module = self.module
250+
if isinstance(module, IModule):
251+
state = await module.get_state()
251252
self.setEnabled(state == ModuleState.READY)
252253
if state != ModuleState.READY:
253254
return
@@ -259,7 +260,7 @@ async def _update_loop(self) -> None:
259260
# sleep a little
260261
await asyncio.sleep(1)
261262

262-
except exc.PyObsError:
263+
except (exc.PyObsError, IndexError):
263264
# ignore these and sleep a little
264265
await asyncio.sleep(1)
265266

@@ -292,11 +293,11 @@ async def show_error(self, exception: exc.PyObsError) -> None:
292293
title, message = err.split(":") if ":" in err else ("Error", err)
293294
await QAsyncMessageBox.warning(self, title, message)
294295

295-
def enable_buttons(self, widgets: List[QtWidgets.QWidget], enable: bool) -> None:
296+
def enable_buttons(self, widgets: list[QtWidgets.QWidget], enable: bool) -> None:
296297
for w in widgets:
297298
w.setEnabled(enable)
298299

299-
def get_fits_headers(self, namespaces: Optional[List[str]] = None, **kwargs: Any) -> Dict[str, Tuple[Any, str]]:
300+
def get_fits_headers(self, namespaces: list[str] | None = None, **kwargs: Any) -> dict[str, tuple[Any, str]]:
300301
"""Returns FITS header for the current status of this module.
301302
302303
Args:
@@ -311,19 +312,20 @@ def get_fits_headers(self, namespaces: Optional[List[str]] = None, **kwargs: Any
311312
hdr[k] = v
312313
return hdr
313314

314-
def colorize_button(self, button: Any, background: Any, black_on_white: bool = True) -> None:
315+
@staticmethod
316+
def colorize_button(button: Any, background: Any, black_on_white: bool = True) -> None:
315317
# get palette
316318
pal = button.palette()
317319

318320
# change active colors
319-
pal.setColor(QtGui.QPalette.Button, background)
321+
pal.setColor(QtGui.QPalette.ColorRole.Button, background)
320322
pal.setColor(
321-
QtGui.QPalette.ButtonText,
322-
QtCore.Qt.black if black_on_white else QtCore.Qt.white,
323+
QtGui.QPalette.ColorRole.ButtonText,
324+
QtCore.Qt.GlobalColor.black if black_on_white else QtCore.Qt.GlobalColor.white,
323325
)
324326

325327
# change disabled colors
326-
pal.setColor(QtGui.QPalette.Disabled, QtGui.QPalette.Button, QtCore.Qt.gray)
328+
pal.setColor(QtGui.QPalette.ColorGroup.Disabled, QtGui.QPalette.ColorRole.Button, QtCore.Qt.GlobalColor.gray)
327329

328330
# set palette again
329331
button.setPalette(pal)

0 commit comments

Comments
 (0)