from turtle import Turtle from typing import Optional, Collection, Any from controls.device import SynchronyDevice from controls.device import TraitDescriptor from controls.device import ActionDescriptor import inspect class TurtleDevice(SynchronyDevice): def open(self): super().open() def close(self): self.turtle.clear() super().close() def trait_descriptors(self) -> Collection[TraitDescriptor]: pass def action_descriptors(self) -> Collection[ActionDescriptor]: pass def __getitem__(self, trait_name: str) -> Optional[Any]: """Return logical state of trait `trait_name`.""" pass def read(self, trait_name: str) -> Any: pass def write(self, trait_name: str, value: Any) -> bool: self.turtle.write() def execute(self, action_name: str, *args, **kwargs): """Execute action `action_name`, using `args` and `kwargs` as action argument.""" pass def invalidate(self, trait_name: str): pass def get_descriptors(self): descriptors = dict(actions=dict(), traits=dict()) for m_name, member in inspect.getmembers(Turtle): if m_name.startswith("_"): continue if m_name.lower() != m_name: continue doc = inspect.getdoc(member) if doc is None: continue first_line_doc = inspect.getdoc(member).lower().split("\n")[0] print(first_line_doc) if not inspect.isfunction(member): descriptors["traits"][m_name] = TraitDescriptor(m_name, doc, readable=True, writable=False) print(m_name) continue if inspect.ismethod(member): print(m_name) return_in_doc = ("return" in first_line_doc) set_in_doc = ("set" in first_line_doc) if return_in_doc or set_in_doc: descriptors["traits"][m_name] = TraitDescriptor(m_name, doc, readable=return_in_doc, writable=set_in_doc) print("TRAIT") else: sig = inspect.signature(member) params_dict = dict(sig.parameters) descriptors["actions"][m_name] = ActionDescriptor(m_name, arguments=params_dict, info=doc) print("ACTION") print("------------------------------------------") return descriptors