Created
May 11, 2021 15:38
-
-
Save tlambert03/cdbed6bfa19e85efc869815cb760f319 to your computer and use it in GitHub Desktop.
iter_events in napari
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from dataclasses import dataclass | |
| from typing import Optional, Type | |
| import napari | |
| import inspect | |
| from napari.utils.events import EventedModel | |
| from napari.utils.settings._defaults import BaseNapariSettings | |
| from napari.components.viewer_model import ViewerModel | |
| def walk_modules(module, pkg='napari', _walked=None): | |
| if not _walked: | |
| _walked = set() | |
| yield module | |
| _walked.add(module) | |
| for name in dir(module): | |
| attr = getattr(module, name) | |
| if ( | |
| inspect.ismodule(attr) | |
| and attr.__package__.startswith(pkg) | |
| and attr not in _walked | |
| ): | |
| yield from walk_modules(attr, pkg, _walked=_walked) | |
| def iter_classes(module): | |
| for name in dir(module): | |
| attr = getattr(module, name) | |
| if inspect.isclass(attr) and attr.__module__ == module.__name__: | |
| yield attr | |
| @dataclass | |
| class Ev: | |
| name: str | |
| model: Type | |
| description: str = '' | |
| type_: Optional[Type] = None | |
| def on_viewer(self): | |
| if issubclass(self.model, ViewerModel): | |
| return f'viewer.events.{self.name}' | |
| for name, field_ in napari.Viewer.__fields__.items(): | |
| if field_.type_ is self.model: | |
| return f'viewer.{name}.events.{self.name}' | |
| return '' | |
| def type_name(self): | |
| if cls_name := getattr(self.type_, '__name__', None): | |
| return cls_name | |
| name = str(self.type_) if self.type_ else '' | |
| return name.replace("typing.", "") | |
| HEADER = ( | |
| 'Class', | |
| 'Event Name', | |
| 'From viewer', | |
| 'Description', | |
| 'Event Attributes', | |
| ) | |
| ROW = '| {:13.13} | {:16.16} | {:40.40} | {:20.20} | {:37.37} |' | |
| def iter_events(module=napari): | |
| for mod in walk_modules(module): | |
| for kls in iter_classes(mod): | |
| if not issubclass(kls, EventedModel) or issubclass( | |
| kls, BaseNapariSettings | |
| ): | |
| continue | |
| for name, field_ in kls.__fields__.items(): | |
| finfo = field_.field_info | |
| if finfo.allow_mutation: | |
| yield Ev(name, kls, finfo.description, field_.type_) | |
| if __name__ == '__main__': | |
| print(ROW.format(*HEADER)) | |
| print(ROW.format(*('-' * 60,) * 5)) | |
| for ev in iter_events(): | |
| if ev.on_viewer(): | |
| row = ROW.format( | |
| f'`{ev.model.__name__}`', | |
| ev.name, | |
| f'`{ev.on_viewer()}`', | |
| ev.description or '', | |
| f'value: `{ev.type_name()}`', | |
| ) | |
| print(row) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment