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

Feature/custom properties #32

Merged
merged 9 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ Changelog
-----

* Improved code quality

* Add Entity.custom_properties
36 changes: 17 additions & 19 deletions src/oemof/network/network/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class Entity:
representation of this node will instead be generated based on this
nodes `class` and `id`.

custom_properties: `dict`
This dictionary that can be used to store information that can be used
to easily attach custom information to any Entity.

Attributes
----------
__slots__: str or iterable of str
Expand All @@ -50,27 +54,21 @@ class Entity:
information.
"""

__slots__ = ["_label", "_in_edges", "_inputs", "_outputs"]
__slots__ = [
"_label",
"_in_edges",
"_inputs",
"_outputs",
"custom_properties",
]

def __init__(self, *args, **kwargs):
args = list(args)
def __init__(self, label=None, *, custom_properties=None, **kwargs):
self._label = label
if custom_properties is None:
custom_properties = {}
self.custom_properties = custom_properties
self._inputs = Inputs(self)
self._outputs = Outputs(self)
for optional in ["label"]:
if optional in kwargs:
if args:
raise (
TypeError(
(
"{}.__init__()\n"
" got multiple values for argument '{}'"
).format(type(self), optional)
)
)
setattr(self, "_" + optional, kwargs[optional])
else:
if args:
setattr(self, "_" + optional, args.pop())

def __eq__(self, other):
return id(self) == id(other)
Expand Down Expand Up @@ -100,7 +98,7 @@ def label(self):
"""
return (
self._label
if hasattr(self, "_label")
if self._label is not None
else "<{} #0x{:x}>".format(type(self).__name__, id(self))
)

Expand Down
29 changes: 26 additions & 3 deletions tests/test_network_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,10 @@ def test_entity_input_output_type_assertions(self):

def test_node_label_without_private_attribute(self):
"""
A `Node` with no explicit `label` doesn't have a `_label` attribute.
A `Node` without `label` doesn't have the `_label` attribute set.
"""
n = Node()
with pytest.raises(AttributeError):
n._label
assert not n._label

def test_node_label_if_its_not_explicitly_specified(self):
"""If not explicitly given, a `Node`'s label is based on its `id`."""
Expand Down Expand Up @@ -351,3 +350,27 @@ def test_deprecated_classes():
Source()
with pytest.warns(FutureWarning):
Transformer()


def test_custom_properties():
node0 = Node()

assert not node0.custom_properties

node1 = Node(
custom_properties={
"foo": "bar",
1: 2,
}
)
assert node1.custom_properties["foo"] == "bar"
assert node1.custom_properties[1] == 2


def test_comparision():
node0 = Node(label=0)
node1 = Node(label=2)
node2 = Node(label=-5)

assert node0 < node1
assert node0 > node2