-
Notifications
You must be signed in to change notification settings - Fork 87
Correct return types to match current bluesky protocols #1248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e305db7
162d6f0
13a5452
64d5122
6e3f85c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,3 @@ | ||
| # type: ignore | ||
|
|
||
| import logging | ||
| import os | ||
| import types | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,3 @@ | ||
| # type: ignore | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import collections | ||
|
|
@@ -31,6 +29,8 @@ | |
| Union, | ||
| ) | ||
|
|
||
| from ophyd.utils.types import Hints | ||
|
|
||
| from .ophydobj import Kind, OphydObject | ||
| from .signal import Signal | ||
| from .status import DeviceStatus, StatusBase | ||
|
|
@@ -86,10 +86,6 @@ | |
| DEFAULT_CONNECTION_TIMEOUT = object() | ||
|
|
||
|
|
||
| class OrderedDictType(Dict[A, B]): | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this was here for compatibility with Python < 3.8 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can just replace it with |
||
| ... | ||
|
|
||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
|
|
@@ -371,6 +367,11 @@ def sub_value(self, func): | |
| "Value subscription decorator" | ||
| return self.subscriptions("value")(func) | ||
|
|
||
| # Placeholder required for components to conform to the Bluesky Moveable protocol | ||
| # The actual implementation will be provided by the cls passed into the Component | ||
| def set(self, *args, **kwargs) -> Any: | ||
| return super().set(*args, **kwargs) | ||
|
|
||
|
|
||
| class FormattedComponent(Component[K]): | ||
| """A Component which takes a dynamic format string | ||
|
|
@@ -562,7 +563,7 @@ def trigger(self) -> StatusBase: | |
| """ | ||
| pass | ||
|
|
||
| def read(self) -> OrderedDictType[str, Dict[str, Any]]: | ||
| def read(self) -> OrderedDict[str, Any]: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can use the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be great if we could just make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can wait and see. I suppose the difference is that bluesky doesn't require ophyd-async 🤔 |
||
| """Read data from the device. | ||
|
|
||
| This method is expected to be as instantaneous as possible, | ||
|
|
@@ -589,7 +590,7 @@ def read(self) -> OrderedDictType[str, Dict[str, Any]]: | |
| """ | ||
| return OrderedDict() | ||
|
|
||
| def describe(self) -> OrderedDictType[str, Dict[str, Any]]: | ||
| def describe(self) -> OrderedDict[str, Any]: | ||
| """Provide schema and meta-data for :meth:`~BlueskyInterface.read`. | ||
|
|
||
| This keys in the `OrderedDict` this method returns must match the | ||
|
|
@@ -1456,7 +1457,7 @@ def read(self): | |
| res.update(component.read()) | ||
| return res | ||
|
|
||
| def read_configuration(self) -> OrderedDictType[str, Dict[str, Any]]: | ||
| def read_configuration(self) -> OrderedDict[str, Any]: | ||
| """Dictionary mapping names to value dicts with keys: value, timestamp | ||
|
|
||
| To control which fields are included, change the Component kinds on the | ||
|
|
@@ -1475,7 +1476,7 @@ def describe(self): | |
| res.update(component.describe()) | ||
| return res | ||
|
|
||
| def describe_configuration(self) -> OrderedDictType[str, Dict[str, Any]]: | ||
| def describe_configuration(self) -> OrderedDict[str, Any]: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| """Provide schema & meta-data for :meth:`~BlueskyInterface.read_configuration` | ||
|
|
||
| This keys in the `OrderedDict` this method returns must match the | ||
|
|
@@ -1496,7 +1497,7 @@ def describe_configuration(self) -> OrderedDictType[str, Dict[str, Any]]: | |
| return res | ||
|
|
||
| @property | ||
| def hints(self): | ||
| def hints(self) -> Hints: | ||
| fields = [] | ||
| for _, component in self._get_components_of_kind(Kind.normal): | ||
| c_hints = component.hints | ||
|
|
@@ -1667,6 +1668,11 @@ def _repr_info(self): | |
| yield ("read_attrs", self.read_attrs) | ||
| yield ("configuration_attrs", self.configuration_attrs) | ||
|
|
||
| # Placeholder required for devices to conform to the Bluesky Moveable protocol | ||
| # The actual implementation will be provided by sub classes | ||
| def set(self, *args, **kwargs) -> Any: | ||
| return super().set(*args, **kwargs) | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These placeholder There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed? If
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. It made the type checker happy, but now that I look again, I don't think the base classes even have an implementation of I'll have to have another look at this. Maybe adding |
||
|
|
||
| class OphydAttrList(MutableSequence): | ||
| """list proxy to migrate away from Device.read_attrs and Device.config_attrs""" | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,9 +4,12 @@ | |
| import time | ||
| import warnings | ||
| import weakref | ||
| from typing import Any, OrderedDict | ||
|
|
||
| import numpy as np | ||
|
|
||
| from ophyd.utils.types import Hints | ||
|
|
||
| from . import get_cl | ||
| from .ophydobj import Kind, OphydObject | ||
| from .status import Status | ||
|
|
@@ -516,7 +519,7 @@ def value(self, value): | |
| self.put(value) | ||
|
|
||
| @raise_if_disconnected | ||
| def read(self): | ||
| def read(self) -> OrderedDict[str, Any]: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As before, we should use the bluesky protocols and |
||
| """Put the status of the signal into a simple dictionary format | ||
| for data acquisition | ||
|
|
||
|
|
@@ -547,7 +550,7 @@ def _infer_value_kind(self, inference_func): | |
| else: | ||
| return inferred_kind | ||
|
|
||
| def describe(self): | ||
| def describe(self) -> OrderedDict[str, Any]: | ||
| """Provide schema and meta-data for :meth:`~BlueskyInterface.read` | ||
|
|
||
| This keys in the `OrderedDict` this method returns must match the | ||
|
|
@@ -625,7 +628,7 @@ def high_limit(self): | |
| return self.limits[1] | ||
|
|
||
| @property | ||
| def hints(self): | ||
| def hints(self) -> Hints: | ||
| "Field hints for plotting" | ||
| if (~Kind.normal & Kind.hinted) & self.kind: | ||
| return {"fields": [self.name]} | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -12,9 +12,12 @@ | |||||
| from functools import partial | ||||||
| from tempfile import mkdtemp | ||||||
| from types import SimpleNamespace | ||||||
| from typing import Any | ||||||
|
|
||||||
| import numpy as np | ||||||
|
|
||||||
| from ophyd.utils.types import Hints | ||||||
|
|
||||||
| from .areadetector.base import EpicsSignalWithRBV | ||||||
| from .areadetector.paths import EpicsPathSignal | ||||||
| from .device import Component as Cpt | ||||||
|
|
@@ -524,15 +527,15 @@ def position(self): | |||||
|
|
||||||
| class SynAxisEmptyHints(SynAxis): | ||||||
| @property | ||||||
| def hints(self): | ||||||
| def hints(self) -> Hints: | ||||||
| return {} | ||||||
|
|
||||||
|
|
||||||
| class SynAxisNoHints(SynAxis): | ||||||
| readback = Cpt(_ReadbackSignal, value=0.0, kind="omitted") | ||||||
|
|
||||||
| @property | ||||||
| def hints(self): | ||||||
| def hints(self) -> Hints: | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this raises an
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we could also use |
||||||
| raise AttributeError | ||||||
|
|
||||||
|
|
||||||
|
|
@@ -761,7 +764,7 @@ class TrivialFlyer: | |||||
| name = "trivial_flyer" | ||||||
| parent = None | ||||||
|
|
||||||
| def kickoff(self): | ||||||
| def kickoff(self) -> Any: | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought I had to change that to |
||||||
| return NullStatus() | ||||||
|
|
||||||
| def describe_collect(self): | ||||||
|
|
@@ -773,7 +776,7 @@ def read_configuration(self): | |||||
| def describe_configuration(self): | ||||||
| return OrderedDict() | ||||||
|
|
||||||
| def complete(self): | ||||||
| def complete(self) -> Any: | ||||||
| return NullStatus() | ||||||
|
|
||||||
| def collect(self): | ||||||
|
|
@@ -902,9 +905,13 @@ def _scan(self): | |||||
| with self._lock: | ||||||
| self._data.append(event) | ||||||
|
|
||||||
| def stop(self, *, success=False): | ||||||
| def stop(self, success=False): | ||||||
| pass | ||||||
|
|
||||||
| # Placeholder required for components to conform to the Bluesky Moveable protocol | ||||||
| def set(self, *args, **kwargs) -> Any: | ||||||
| return super().set(*args, **kwargs) | ||||||
|
|
||||||
|
Comment on lines
+911
to
+914
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps this should just pass as well? This is a sim so wouldn't have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correction, it should still return a |
||||||
|
|
||||||
| class SynSignalWithRegistry(SynSignal): | ||||||
| """ | ||||||
|
|
@@ -1677,5 +1684,5 @@ def hw(save_path=None): | |||||
|
|
||||||
|
|
||||||
| # Dump instances of the example hardware generated by hw() into the global | ||||||
| # namespcae for convenience and back-compat. | ||||||
| # namespace for convenience and back-compat. | ||||||
| globals().update(hw().__dict__) | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |||||
| from collections import deque | ||||||
| from functools import partial | ||||||
| from logging import LoggerAdapter | ||||||
| from typing import Any | ||||||
| from warnings import warn | ||||||
|
|
||||||
| import numpy as np | ||||||
|
|
@@ -416,7 +417,7 @@ def _finished(self, success=True, **kwargs): | |||||
| ) | ||||||
| self.set_exception(exc) | ||||||
|
|
||||||
| def exception(self, timeout=None): | ||||||
| def exception(self, timeout=None) -> Any: | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| """ | ||||||
| Return the exception raised by the action. | ||||||
|
|
||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this type ignore statement was here, as well as the one at the top of
device.py.It was preventing mypy from traversing the submodules properly so I removed it. It didn't seem to break anything in the build, or when I imported it in to our beamline library so maybe its OK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removal of this wouldn't break anything other than type checking, which CI here doesn't do.
The question is whether it breaks type checking anywhere downstream using these methods... which I don't think it would since the methods aren't type hinted 🤔