From cef21d7ab8d26373d85a8773c330f104896c05cf Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sat, 8 Dec 2018 18:56:34 -0800 Subject: [PATCH] Allow per-channel triggers to inherit from global (if untyped dicts) (#83) trigger: edge_strength: -1 --- ovgenpy/channel.py | 25 +++++++++++++++++++------ ovgenpy/config.py | 6 ++---- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ovgenpy/channel.py b/ovgenpy/channel.py index bdb728d..3490ac1 100644 --- a/ovgenpy/channel.py +++ b/ovgenpy/channel.py @@ -1,13 +1,15 @@ from os.path import abspath -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Union -from ovgenpy.config import register_config, Alias +import attr +from ruamel.yaml.comments import CommentedMap + +from ovgenpy.config import register_config, Alias, OvgenError +from ovgenpy.triggers import ITriggerConfig from ovgenpy.util import coalesce from ovgenpy.wave import _WaveConfig, Wave - if TYPE_CHECKING: - from ovgenpy.triggers import ITriggerConfig from ovgenpy.ovgenpy import Config @@ -15,7 +17,8 @@ if TYPE_CHECKING: class ChannelConfig: wav_path: str - trigger: Optional['ITriggerConfig'] = None # TODO test channel-specific triggers + # Supplying a dict inherits attributes from global trigger. + trigger: Union[ITriggerConfig, dict, None] = None # TODO test channel-specific triggers # Multiplies how wide the window is, in milliseconds. trigger_width: Optional[int] = None render_width: Optional[int] = None @@ -67,7 +70,17 @@ class Channel: self.render_stride = rsub * rw # Create a Trigger object. - tcfg = cfg.trigger or ovgen_cfg.trigger + if isinstance(cfg.trigger, ITriggerConfig): + tcfg = cfg.trigger + elif isinstance(cfg.trigger, (CommentedMap, dict)): # CommentedMap may/not be subclass of dict. + tcfg = attr.evolve(ovgen_cfg.trigger, **cfg.trigger) + elif cfg.trigger is None: + tcfg = ovgen_cfg.trigger + else: + raise OvgenError( + f'invalid per-channel trigger {cfg.trigger}, type={type(cfg.trigger)}, ' + f'must be (*)TriggerConfig, dict, or None') + self.trigger = tcfg( wave=self.wave, tsamp=trigger_samp, diff --git a/ovgenpy/config.py b/ovgenpy/config.py index 0ce811f..8354813 100644 --- a/ovgenpy/config.py +++ b/ovgenpy/config.py @@ -26,10 +26,8 @@ class MyYAML(YAML): return stream.getvalue() -# https://yaml.readthedocs.io/en/latest/dumpcls.html -# >Only yaml = YAML(typ='unsafe') loads and dumps Python objects out-of-the-box. And -# >since it loads any Python object, this can be unsafe. -# I assume roundtrip is safe. +# Default typ='roundtrip' creates 'ruamel.yaml.comments.CommentedMap' instead of dict. +# Is isinstance(CommentedMap, dict)? IDK yaml = MyYAML() _yaml_loadable = yaml_object(yaml)