diff --git a/src/oemof/network/energy_system.py b/src/oemof/network/energy_system.py index 995a6de..ce45c83 100644 --- a/src/oemof/network/energy_system.py +++ b/src/oemof/network/energy_system.py @@ -17,6 +17,7 @@ import logging import os +import warnings from collections import deque import blinker @@ -134,24 +135,41 @@ class EnergySystem: .. _blinker: https://blinker.readthedocs.io/en/stable/ """ - def __init__(self, **kwargs): + def __init__( + self, + *, + groupings=None, + results=None, + timeindex=None, + timeincrement=None, + temporal=None, + nodes=None, + entities=None, + ): + if groupings is None: + groupings = [] + if entities is not None: + warnings.warn( + "Parameter 'entities' is deprecated, use 'nodes'" + + " instead. Will overwrite nodes.", + FutureWarning, + ) + nodes = entities + if nodes is None: + nodes = [] + self._first_ungrouped_node_index_ = 0 self._groups = {} self._groupings = [BY_UID] + [ - g if isinstance(g, Grouping) else Entities(g) - for g in kwargs.get("groupings", []) + g if isinstance(g, Grouping) else Entities(g) for g in groupings ] self._nodes = {} - self.results = kwargs.get("results") - - self.timeindex = kwargs.get("timeindex") - - self.timeincrement = kwargs.get("timeincrement", None) - - self.temporal = kwargs.get("temporal") - - self.add(*kwargs.get("entities", ())) + self.results = results + self.timeindex = timeindex + self.timeincrement = timeincrement + self.temporal = temporal + self.add(*nodes) def add(self, *nodes): """Add :class:`nodes ` to this energy system.""" diff --git a/src/oemof/network/graph.py b/src/oemof/network/graph.py index e6708fc..d8b7024 100644 --- a/src/oemof/network/graph.py +++ b/src/oemof/network/graph.py @@ -52,14 +52,13 @@ def create_nx_graph( >>> import oemof.network.graph as grph >>> datetimeindex = pd.date_range('1/1/2017', periods=3, freq='H') >>> es = EnergySystem(timeindex=datetimeindex) - >>> b_gas = Bus(label='b_gas', balanced=False) + >>> b_gas = Bus(label='b_gas') >>> bel1 = Bus(label='bel1') >>> bel2 = Bus(label='bel2') >>> demand_el = Sink(label='demand_el', inputs = [bel1]) >>> pp_gas = Transformer(label=('pp', 'gas'), ... inputs=[b_gas], - ... outputs=[bel1], - ... conversion_factors={bel1: 0.5}) + ... outputs=[bel1]) >>> line_to2 = Transformer(label='line_to2', inputs=[bel1], outputs=[bel2]) >>> line_from2 = Transformer(label='line_from2', ... inputs=[bel2], outputs=[bel1]) diff --git a/src/oemof/network/groupings.py b/src/oemof/network/groupings.py index 976e3e5..014d465 100644 --- a/src/oemof/network/groupings.py +++ b/src/oemof/network/groupings.py @@ -122,7 +122,7 @@ def __init__(self, key=None, constant_key=None, filter=None, **kwargs): + "one of `key` or `constant_key`." ) self.filter = filter - for kw in ["value", "merge", "filter"]: + for kw in ["value", "merge"]: if kw in kwargs: setattr(self, kw, kwargs[kw]) diff --git a/src/oemof/network/network/edge.py b/src/oemof/network/network/edge.py index 15c977c..9274d16 100644 --- a/src/oemof/network/network/edge.py +++ b/src/oemof/network/network/edge.py @@ -17,8 +17,6 @@ from .entity import Entity -EdgeLabel = namedtuple("EdgeLabel", ["input", "output"]) - class Edge(Entity): """ @@ -41,7 +39,7 @@ class Edge(Entity): name. """ - Label = EdgeLabel + Label = namedtuple("EdgeLabel", ["input", "output"]) def __init__( self, @@ -49,7 +47,8 @@ def __init__( output_node=None, flow=None, values=None, - **kwargs, + *, + custom_properties=None, ): if flow is not None and values is not None: raise ValueError( @@ -60,7 +59,10 @@ def __init__( f" `values`: {values}\n" "Choose one." ) - super().__init__(label=Edge.Label(input_node, output_node)) + super().__init__( + label=Edge.Label(input_node, output_node), + custom_properties=custom_properties, + ) self.values = values if values is not None else flow if input_node is not None and output_node is not None: input_node.outputs[output_node] = self diff --git a/src/oemof/network/network/entity.py b/src/oemof/network/network/entity.py index b63f476..63f83da 100644 --- a/src/oemof/network/network/entity.py +++ b/src/oemof/network/network/entity.py @@ -44,7 +44,7 @@ class Entity: to easily attach custom information to any Entity. """ - def __init__(self, label=None, *, custom_properties=None, **kwargs): + def __init__(self, label=None, *, custom_properties=None): self._label = label if custom_properties is None: custom_properties = {} @@ -76,11 +76,14 @@ def label(self): attribute holds the actual object passed as a parameter. Otherwise `node.label` is a synonym for `str(node)`. """ - return ( - self._label - if self._label is not None - else "<{} #0x{:x}>".format(type(self).__name__, id(self)) - ) + try: + return self._label if self._label is not None else self._id_label + except AttributeError: + return hash(self._id_label) + + @property + def _id_label(self): + return "<{} #0x{:x}>".format(type(self).__name__, id(self)) @label.setter def label(self, label): diff --git a/src/oemof/network/network/nodes.py b/src/oemof/network/network/nodes.py index 947e250..964c4f5 100644 --- a/src/oemof/network/network/nodes.py +++ b/src/oemof/network/network/nodes.py @@ -42,31 +42,43 @@ class Node(Entity): A dictionary mapping output nodes to corresponding outflows. """ - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + def __init__( + self, + label=None, + *, + inputs=None, + outputs=None, + custom_properties=None, + ): + super().__init__(label=label, custom_properties=custom_properties) self._inputs = Inputs(self) self._outputs = Outputs(self) self._in_edges = set() + if inputs is None: + inputs = {} + if outputs is None: + outputs = {} + msg = "{} {!r} of {!r} not an instance of Node but of {}." - for i in kwargs.get("inputs", {}): + for i in inputs: if not isinstance(i, Node): raise ValueError(msg.format("Input", i, self, type(i))) self._in_edges.add(i) try: - flow = kwargs["inputs"].get(i) + flow = inputs.get(i) except AttributeError: flow = None edge = Edge.from_object(flow) edge.input = i edge.output = self - for o in kwargs.get("outputs", {}): + for o in outputs: if not isinstance(o, Node): raise ValueError(msg.format("Output", o, self, type(o))) try: - flow = kwargs["outputs"].get(o) + flow = outputs.get(o) except AttributeError: flow = None edge = Edge.from_object(flow) diff --git a/tests/test_energy_system.py b/tests/test_energy_system.py index 6e602f5..6a5f533 100644 --- a/tests/test_energy_system.py +++ b/tests/test_energy_system.py @@ -13,11 +13,23 @@ SPDX-License-Identifier: MIT """ +import pytest + from oemof.network import energy_system as es from oemof.network.network import Edge from oemof.network.network.nodes import Node +def test_ensys_init(): + node = Node("label") + ensys = es.EnergySystem(nodes=[node]) + assert node in ensys.nodes + + with pytest.warns(FutureWarning): + ensys = es.EnergySystem(entities=[node]) + assert node in ensys.nodes + + class TestsEnergySystem: def setup_method(self): self.es = es.EnergySystem() diff --git a/tests/test_groupings/test_groupings_basic.py b/tests/test_groupings/test_groupings_basic.py index c509530..064ff6d 100644 --- a/tests/test_groupings/test_groupings_basic.py +++ b/tests/test_groupings/test_groupings_basic.py @@ -24,7 +24,7 @@ def test_entity_grouping_on_construction(): bus = Bus(label="test bus") - ensys = es.EnergySystem(entities=[bus]) + ensys = es.EnergySystem(nodes=[bus]) assert ensys.groups[bus.label] is bus @@ -37,8 +37,8 @@ def by_uid(n): ensys = es.EnergySystem(groupings=[by_uid]) - ungrouped = [Node(uid="Not in 'Group': {}".format(i)) for i in range(10)] - grouped = [Node(uid="In 'Group': {}".format(i)) for i in range(10)] + ungrouped = [Node(label="Not in 'Group': {}".format(i)) for i in range(10)] + grouped = [Node(label="In 'Group': {}".format(i)) for i in range(10)] assert None not in ensys.groups for g in ensys.groups.values(): for e in ungrouped: