-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expressions, Parameters and Renderers #55
Expressions, Parameters and Renderers #55
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add change notes
src/dewret/__main__.py
Outdated
except Exception as exc: | ||
import traceback | ||
|
||
print(exc, exc.__cause__, exc.__context__) | ||
traceback.print_exc() | ||
else: | ||
if pretty: | ||
yaml.dump(cwl, sys.stdout, indent=2) | ||
if len(rendered) == 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change: Write logic for outputting different formats
|
||
@classmethod | ||
def assimilate(cls, left: Workflow, right: Workflow) -> "Workflow": | ||
def assimilate(cls, *workflow_args: Workflow) -> "Workflow": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change: improve performance by merging n workflows together simultaneously, instead of pairwise (for example, if we had a function with 5 step results as input arguments, this would get called 4 times, but now gets called once)
@@ -657,14 +765,206 @@ def __workflow__(self) -> Workflow: | |||
... | |||
|
|||
|
|||
class Reference: | |||
"""Superclass for all symbolic references to values.""" | |||
class FieldableProtocol(Protocol): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change: a mixin for structures that use fields
but ParameterReferences are specific, this carries the actual workflow reference. | ||
|
||
Returns: | ||
Workflow that the referee is related to. | ||
""" | ||
|
||
parameter: Parameter[RawType] | ||
__workflow__: Workflow | ||
class ParameterReferenceMetadata(Generic[T]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change: moving metadata (more) into an attribute called _
for step and parameter references.
|
||
U = TypeVar("U") | ||
class IterableParameterReference(IterableMixin[U], ParameterReference[U]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change: add iterable references to handle things we can loop through or index into
@@ -1179,3 +1633,104 @@ def is_task(task: Lazy) -> bool: | |||
True if `task` is indeed a task. | |||
""" | |||
return isinstance(task, LazyEvaluation) | |||
|
|||
def expr_to_references(expression: Any, remap: Callable[[Any], Any] | None = None) -> tuple[ExprType, list[Reference[Any] | Parameter[Any]]]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change: add support for sympy expressions involving references.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left some comments with change suggestions.
I still have a few files to review and test out.
src/dewret/render.py
Outdated
render_module = cast(BaseRenderModule, module) | ||
else: | ||
render_module = renderer | ||
if not isinstance(render_module, StructuredRenderModule): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a bit hard to follow.
This is understandable
# This is understandable
render_module: BaseRenderModule
if isinstance(renderer, Path):
if (render_dir := str(renderer.parent)) not in sys.path:
sys.path.append(render_dir)
# Attempt to load renderer as package, falling back to a single module otherwise.
# This enables relative imports in renderers and therefore the ability to modularize.
module = load_module_or_package("__renderer__", renderer)
sys.modules["__renderer_mod__"] = module
render_module = cast(BaseRenderModule, module)
else:
render_module = renderer
But can we handle conditionals here in a similar way to this?
Since the renderer has to be Path | RawRenderModule | StructuredRenderModule and StructuredRenderModule is a BaseRenderModule
and when we render_module = cast(BaseRenderModule, module)
I can see what every modules implementation is without having to think about it.
My first thought was what happened to the BaseRenderModule
if isinstance(render_module, RawRenderModule):
return render_module.render_raw
elif isinstance(render_module, (StructuredRenderModule)):
def _render(workflow: Workflow, render_module: StructuredRenderModule, pretty: bool=False, **kwargs: RenderConfiguration) -> dict[str, str]:
rendered = render_module.render(workflow, **kwargs)
return {
key: structured_to_raw(value, pretty=pretty)
for key, value in rendered.items()
}
return cast(RenderCall, partial(_render, render_module=render_module, pretty=pretty))
raise NotImplementedError("This render module neither seems to be a structured nor a raw render module.")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KamenDimitrov97 To solve
metadata += list(parent_metadata) | ||
return parent_type, tuple(metadata) | ||
|
||
RenderConfiguration = dict[str, RawType] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly irrelevant ignore if it is but maybe a comment like this
# Configuration settings for the renderer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KamenDimitrov97 keep
Generic type for configuration settings for the renderer
src/dewret/annotations.py
Outdated
If `fn` is a class, it takes the constructor, and if it is a method, it takes | ||
the `__func__` attribute. | ||
""" | ||
self.fn = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how I feel about these.
if inspect.isclass(fn):
self.fn = fn.__init__
elif inspect.ismethod(fn):
self.fn = fn.__func__
else:
self.fn = fn
It might be a lack of years of experience with python but it just seems harder to read
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KamenDimitrov97 change this
docs/renderer_tutorial.md
Outdated
from dewret.workflow import Lazy | ||
from dewret.workflow import Reference, Raw, Workflow, Step, Task | ||
from dewret.utils import BasicType | ||
from dewret.workflow import Reference, Workflow, Step, Task | ||
|
||
RawType = typing.Union[BasicType, list[str], list["RawType"], dict[str, "RawType"]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow up comment: We should also update the documentations and tutorials to use |
instead of 'union'
src/dewret/__main__.py
Outdated
if len(rendered) == 1: | ||
with opener("", "w") as output_f: | ||
output_f.write(rendered["__root__"]) | ||
elif "%" in output: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep this in outside the utility function
… added explanitory comments
…s as a package nor isolated module
assert entry.relline == 2 | ||
assert "attempted relative import with no known parent package" in str(exc.value) | ||
|
||
nonfrender_py = Path(__file__).parent / "_lib/nonfrender.py" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing module runtime check against protocol.
…s as a package nor isolated module
…s as a package nor isolated module
f9b3e8c
to
b6677c0
Compare
ee37865
to
2fa4145
Compare
2fa4145
to
3b9ccfe
Compare
…ded for a custom renderer to be considered a dewret renderer
✨ Feature
Description
Please describe and motivate the new feature you've implemented.
Changes Made
Workflows
workflow
(removessubworkflow
andnested_step
)Renderers
Additional Information
Still TODO (help appreciated):
Checklist
Who can review?
@KamenDimitrov97 @elleryames