Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
91d1094
add check raw_to_derived argument type
Nov 17, 2025
b3750f7
fix test name
Nov 17, 2025
060ba24
Merge branch 'main' into improve-error-when-raw2derived-has-no-type
Villtord Nov 17, 2025
f65ffe5
use inspect module
Dec 5, 2025
ffaf6aa
fix small typing issues pylance
Dec 5, 2025
674b378
Merge branch 'main' into improve-error-when-raw2derived-has-no-type
Villtord Dec 5, 2025
ce5704a
remove commented lines
Dec 5, 2025
b3b7798
Merge branch 'main' into improve-error-when-raw2derived-has-no-type
Villtord Dec 9, 2025
a892cf8
fix raw_to_derived signature and move empty hints check to factory
Dec 11, 2025
0570649
fix multi derived test
Dec 12, 2025
199ed8f
convert string annotations to class
Dec 12, 2025
8bc79cc
add lost test back
Dec 12, 2025
3c25ef2
add type hint test for many-to-many
Dec 15, 2025
1919565
remove unnecessary derived_to_raw functino
Dec 15, 2025
ec3c454
move helper dict_wrapper method out from class
Dec 15, 2025
2e2616c
add type hints
Dec 15, 2025
ca20b1f
Merge branch 'main' into improve-error-when-raw2derived-has-no-type
Villtord Dec 15, 2025
9bcadcf
Merge branch 'main' into improve-error-when-raw2derived-has-no-type
Villtord Dec 17, 2025
e463319
test_subclasses_in_hints
Dec 17, 2025
f7ea387
fix test
Dec 17, 2025
7939630
simplify logic
Dec 17, 2025
ee5359d
add typeVar checking
Dec 17, 2025
72886a3
make type checking happy
Dec 17, 2025
b87d586
remove noqa
Dec 17, 2025
f527c6d
add "cls" to excluded names
Dec 17, 2025
7cff97a
remove unnecessary get_type_hints
Dec 18, 2025
4955163
reply comments
Dec 19, 2025
d9adee5
Merge branch 'main' into improve-error-when-raw2derived-has-no-type
Villtord Dec 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/ophyd_async/core/_derived_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def _make_factory(
raw_devices_and_constants: dict[str, Device | Primitive] | None = None,
) -> DerivedSignalFactory:
if raw_to_derived:
_get_first_arg_datatype(raw_to_derived) # validate first arg type

class DerivedTransform(Transform):
def raw_to_derived(self, **kwargs) -> dict[str, SignalDatatypeT]:
Expand Down Expand Up @@ -278,11 +279,11 @@ def derived_signal_rw(
The names of these arguments must match the arguments of raw_to_derived.
"""
raw_to_derived_datatype = _get_return_datatype(raw_to_derived)
set_derived_datatype = _get_first_arg_datatype(set_derived)
if raw_to_derived_datatype != set_derived_datatype:
set_derived_arg_datatype = _get_first_arg_datatype(set_derived)
if raw_to_derived_datatype != set_derived_arg_datatype:
msg = (
f"{raw_to_derived} has datatype {raw_to_derived_datatype} "
f"!= {set_derived_datatype} datatype {set_derived_datatype}"
f"!= {set_derived_arg_datatype} datatype {set_derived_arg_datatype}"
)
raise TypeError(msg)

Expand Down
31 changes: 23 additions & 8 deletions tests/unit_tests/core/test_single_derived_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,29 @@ async def _put(value: float) -> None:
pass


# function without type hint on first argument
def _get_no_type(ts) -> float:
return ts


async def test_derived_signal_rw_get_method_no_param_type():
signal_rw = soft_signal_rw(int, initial_value=4)
with pytest.raises(
TypeError,
match=" does not have a type hinted argument",
):
derived_signal_rw(_get_no_type, _put, ts=signal_rw)


async def test_derived_signal_r_get_method_no_param_type():
signal_rw = soft_signal_rw(int, initial_value=4)
with pytest.raises(
TypeError,
match=" does not have a type hinted argument",
):
derived_signal_r(_get_no_type, ts=signal_rw)


@pytest.fixture
def derived_signal_backend() -> SignalBackend[SignalDatatype]:
signal_rw = soft_signal_rw(int, initial_value=4)
Expand Down Expand Up @@ -264,14 +287,6 @@ async def test_set_derived_callback_already_set(derived_signal_backend: SignalBa
derived_signal_backend.set_callback(mock_callback)


@patch("ophyd_async.core._derived_signal.get_type_hints", return_value={})
def test_get_return_datatype_no_type(movable_beamstop: MovableBeamstop):
with pytest.raises(
TypeError, match=re.escape("does not have a type hint for it's return value")
):
derived_signal_r(movable_beamstop._get_position)


@patch("ophyd_async.core._derived_signal.get_type_hints", return_value={})
def test_get_first_arg_datatype_no_type(movable_beamstop: MovableBeamstop):
with pytest.raises(
Expand Down