Skip to content
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

Added Docstrings to base.py #35

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ multi_line_output = 3

[tool.ruff]
line-length = 90
select = ["E", "F"] #, "D"] #, "N", "C", "ANN"]
select = ["E", "F", "D"]#, "N", "C", "ANN"]
exclude = [
"tests",
]
extend-ignore = [
"D213", "D203"
]
96 changes: 91 additions & 5 deletions znflow/base.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""The base module of znflow."""
from __future__ import annotations

import contextlib
Expand Down Expand Up @@ -29,6 +30,12 @@ class Property:
"""

def __init__(self, fget=None, fset=None, fdel=None, doc=None):
"""Init method of the property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
self.fget = disable_graph()(fget)
self.fset = disable_graph()(fset)
self.fdel = disable_graph()(fdel)
Expand All @@ -38,36 +45,78 @@ def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self._name = ""

def __set_name__(self, owner, name):
"""Set Name Method of the Property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
self._name = name

def __get__(self, obj, objtype=None):
"""Get Method of the Property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
if obj is None:
return self
if self.fget is None:
raise AttributeError(f"property '{self._name}' has no getter")
return self.fget(obj)

def __set__(self, obj, value):
"""Set Method of the Property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
if self.fset is None:
raise AttributeError(f"property '{self._name}' has no setter")
self.fset(obj, value)

def __delete__(self, obj):
"""Delete Method of the Property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
if self.fdel is None:
raise AttributeError(f"property '{self._name}' has no deleter")
self.fdel(obj)

def getter(self, fget):
"""Getter Method of the Property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
prop = type(self)(fget, self.fset, self.fdel, self.__doc__)
prop._name = self._name
return prop

def setter(self, fset):
"""Setter Method of the Property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
prop = type(self)(self.fget, fset, self.fdel, self.__doc__)
prop._name = self._name
return prop

def deleter(self, fdel):
"""Deleter Method of the Property class.

References
----------
Adapted from https://docs.python.org/3/howto/descriptor.html#properties
"""
prop = type(self)(self.fget, self.fset, fdel, self.__doc__)
prop._name = self._name
return prop
Expand Down Expand Up @@ -98,23 +147,36 @@ class NodeBaseMixin:

@property
def uuid(self):
"""A method that generates a UUID to create a hashable object for each node."""
return self._uuid

@uuid.setter
def uuid(self, value):
"""A method that checks for an existing UUID.

If no UUID exists, it sets the previously defined UUID for the node.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a Raises section


Raises
------
ValueError
If a UUID is already set for the current node.
"""
if self._uuid is not None:
raise ValueError("uuid is already set")
self._uuid = value

def run(self):
"""Run Method of NodeBaseMixin."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The run method is a really important abstract method. It's the method that is executed upon the graph run call.

raise NotImplementedError


def get_graph():
"""Gets Graph from the NodeBaseMixin class."""
return NodeBaseMixin._graph_


def set_graph(value):
"""Sets a value for the NodeBaseMixin graph."""
NodeBaseMixin._graph_ = value


Expand All @@ -132,30 +194,40 @@ def get_attribute(obj, name, default=_get_attribute_none):
@dataclasses.dataclass(frozen=True)
class Connection:
"""A Connector for Nodes.
instance: either a Node or FunctionFuture
attribute:
Node.attribute

Instance
--------
Either a Node or FunctionFuture.

Attributes
----------
attribute : Node.attribute
or FunctionFuture.result
or None if the class is passed and not an attribute
or None if the class is passed and not an attribute.
"""

instance: any
attribute: any
item: any = None

def __getitem__(self, item):
"""TODO."""
return dataclasses.replace(self, instance=self, attribute=None, item=item)

def __post_init__(self):
"""Raises a Valueerror if a private attribute is called."""
if self.attribute is not None and self.attribute.startswith("_"):
raise ValueError("Private attributes are not allowed.")

@property
def uuid(self):
"""Gets value of the UUID."""
return self.instance.uuid

@property
def result(self):
"""Returns the instance and if available, also the attribute."""

if self.attribute:
result = getattr(self.instance, self.attribute)
elif isinstance(self.instance, (FunctionFuture, self.__class__)):
Expand All @@ -167,6 +239,15 @@ def result(self):

@dataclasses.dataclass
class FunctionFuture(NodeBaseMixin):
"""A class that creates a future object out of a function.

Attributes
----------
function : callable
args : tuple
kwargs : dict
"""

function: typing.Callable
args: typing.Tuple
kwargs: typing.Dict
Expand All @@ -177,7 +258,12 @@ class FunctionFuture(NodeBaseMixin):
_protected_ = NodeBaseMixin._protected_ + ["function", "args", "kwargs"]

def run(self):
self.result = self.function(*self.args, **self.kwargs)
"""Run Method of the FunctionFuture class.

Executes the function with the given arguments and saves the result.
"""
self._result = self.function(*self.args, **self.kwargs)
Ruttor marked this conversation as resolved.
Show resolved Hide resolved

def __getitem__(self, item):
"""Gets the object with all the information of the Connection class."""
return Connection(instance=self, attribute=None, item=item)
1 change: 1 addition & 0 deletions znflow/graph.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""The graph module of ZnFlow."""
import functools
import logging
import typing
Expand Down
1 change: 1 addition & 0 deletions znflow/node.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""The node module of ZnFlow."""
from __future__ import annotations

import functools
Expand Down
1 change: 0 additions & 1 deletion znflow/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def default(self, value, **kwargs):
@functools.singledispatchmethod
def handle(self, value, **kwargs):
"""Fallback handling if no siggledispatch was triggered."""

result = self.default(value, **kwargs)
if result is not value:
self.updated = True
Expand Down