Skip to content

Instantly share code, notes, and snippets.

@tlambert03
Created May 11, 2021 15:38
Show Gist options
  • Select an option

  • Save tlambert03/cdbed6bfa19e85efc869815cb760f319 to your computer and use it in GitHub Desktop.

Select an option

Save tlambert03/cdbed6bfa19e85efc869815cb760f319 to your computer and use it in GitHub Desktop.
iter_events in napari
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