From 820f9d3fb5c95bc7f87fd300d3b0cc13ec8bc490 Mon Sep 17 00:00:00 2001 From: Igor Dunaev Date: Mon, 6 Nov 2023 21:18:57 +0300 Subject: [PATCH] Repair broken methods --- equipment/turtle_device.py | 21 +++++++++++++-------- tests/equipment/test_turtle_device.py | 8 +++++++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/equipment/turtle_device.py b/equipment/turtle_device.py index 1f94d32..0e4689d 100644 --- a/equipment/turtle_device.py +++ b/equipment/turtle_device.py @@ -1,6 +1,6 @@ from turtle import Turtle from typing import Any, Collection, Optional -from types import FunctionType +from types import FunctionType, MethodType from inspect import getfullargspec from controls.device import SynchronyDevice @@ -33,16 +33,21 @@ class TurtleDevice(SynchronyDevice): super().close() def action_descriptors(self) -> Collection[ActionDescriptor]: - def get_args(f: FunctionType) -> dict[str, type]: - spec = getfullargspec(f) + if self.state != DeviceLifecycleState.OPEN: + raise DeviceError("Device is not opened") + + def get_args(name: str) -> dict[str, type]: + spec = getfullargspec(getattr(self._device, name)) return {arg: spec.annotations.get(arg, object) for arg in spec.args} - actions = (dict(filter(lambda i: not i[0].startswith('_'), - filter(lambda i: isinstance(i[1], FunctionType), - self._device.__dict__.items())))) # lisp :3 - return [ActionDescriptor(name=action[0],arguments=get_args(action[1])) for action in actions.items()] + actions = (filter(lambda name: not name.startswith("_"), + filter(lambda name: isinstance(getattr(self._device, name), MethodType), + dir(self._device)))) # lisp :3 + return [ActionDescriptor(name=action,arguments=get_args(action)) for action in actions] def trait_descriptors(self) -> Collection[TraitDescriptor]: + if self.state != DeviceLifecycleState.OPEN: + raise DeviceError("Device is not opened") traits = dict(filter(lambda i: not i[0].startswith('_'), filter(lambda i: not isinstance(i[1], FunctionType), self._device.__dict__.items()))) @@ -66,7 +71,7 @@ class TurtleDevice(SynchronyDevice): raise DeviceError("Device is not opened") if action_name not in self._actions: raise KeyError(f"\"{action_name}\" is not an action of {self.__class__}") - return self._device.__dict__[action_name](args, kwargs) + return getattr(self._device, action_name)(*args, **kwargs) def invalidate(self, trait_name: str): if trait_name in self._logical_traits: diff --git a/tests/equipment/test_turtle_device.py b/tests/equipment/test_turtle_device.py index a12912b..878c2e7 100644 --- a/tests/equipment/test_turtle_device.py +++ b/tests/equipment/test_turtle_device.py @@ -10,4 +10,10 @@ class TurtleDeviceTest(TestCase): def test_open(self): self.device.open() - self.device.close() \ No newline at end of file + self.device.close() + + def test_execute(self): + self.device.open() + dist = self.device.execute("distance", 1.0, 1.0) + self.assertAlmostEqual(dist, 1.41421, delta=1e-5) + self.device.close()