Skip to content

Conversation

@FBumann
Copy link
Member

@FBumann FBumann commented Jan 23, 2026

Summary

Replaces list[Flow] with FlowContainer for inputs, outputs, and flows attributes. Provides dual access by index (inputs[0]) or label (inputs['Q_th']).

Breaking Change

Use .values() for flow iteration: for flow in component.inputs.values():

Summary by CodeRabbit

  • New Features

    • Introduced FlowContainer for flexible access to component and bus flows by index or label (e.g., inputs[0] or inputs['Q_th'])
    • Added new flows property to components and buses for unified access to both inputs and outputs
  • Refactor

    • Updated internal flow collection handling to use dict-based containers for improved access patterns

✏️ Tip: You can customize this high-level summary in your review settings.

…s done:

  Summary

  1. Created FlowContainer Class (structure.py)

  - Added FlowContainer class that extends ContainerMixin
  - Uses flow.label_full as the key (e.g., 'Boiler(Q_th)')
  - Supports index-based access: inputs[0]
  - Supports label-based access: inputs['Boiler(Q_th)']
  - Added __add__ method to ContainerMixin for concatenation

  2. Updated Component Class (elements.py)

  - Changed inputs and outputs from list[Flow] to FlowContainer
  - Modified __init__ to accept both list[Flow] and dict[str, Flow] (for deserialization)
  - Updated _check_unique_flow_labels() and _connect_flows() to accept lists as parameters
  - FlowContainers are created after connecting flows (so label_full is correct)

  3. Updated Bus Class (elements.py)

  - Changed inputs and outputs from list[Flow] to FlowContainer

  4. Updated Iteration Patterns

  All iteration patterns were updated from:
  - for flow in self.inputs: → for flow in self.inputs.values():
  - for flow in self.inputs + self.outputs: → for flow in (self.inputs + self.outputs).values():

  Files updated:
  - elements.py (Component, Bus, BusModel, ComponentModel)
  - components.py (TransmissionModel, LinearConverterModel)
  - flow_system.py (flow population and network connection)
  - io.py (format_flow_details)
  - statistics_accessor.py (various plotting methods)
  - tests/deprecated/test_integration.py

  Usage Examples

  boiler = Boiler(label='Boiler', inputs=[Flow('Q_th', bus=heat_bus)])

  # Both access methods work
  assert boiler.inputs[0] == boiler.inputs['Boiler(Q_th)']
  assert len(boiler.inputs) == 1

  # Iteration requires .values()
  for flow in boiler.inputs.values():
      print(flow.label_full)

  # Concatenation works
  all_flows = boiler.inputs + boiler.outputs
  for flow in all_flows.values():
      print(flow.label)

  All 1570 tests passed.
  Added all_flows property to Component and Bus classes using itertools.chain:

  @Property
  def all_flows(self) -> Iterator[Flow]:
      """Iterate over all flows (inputs and outputs) without creating intermediate containers."""
      return chain(self.inputs.values(), self.outputs.values())

  Performance Improvement
  ┌─────────┬──────────────────────────────┬───────────────────────┐
  │ Pattern │            Before            │         After         │
  ├─────────┼──────────────────────────────┼───────────────────────┤
  │ Memory  │ O(n) - creates new container │ O(1) - iterator only  │
  ├─────────┼──────────────────────────────┼───────────────────────┤
  │ Time    │ O(n) - copies all elements   │ O(1) - lazy iteration │
  └─────────┴──────────────────────────────┴───────────────────────┘
  Usage

  # Efficient iteration (no allocation)
  for flow in component.all_flows:
      ...

  # When you need a list (e.g., reusing multiple times)
  all_flows = list(component.all_flows)

  # Container concatenation still available when needed
  combined = component.inputs + component.outputs  # Creates new FlowContainer

  Files Updated

  - elements.py - Added property, updated 8 iteration patterns
  - components.py - Updated 1 pattern
  - flow_system.py - Updated 3 patterns
  - statistics_accessor.py - Updated 1 pattern

  All 1570 tests pass.
  1. FlowContainer now supports short-label access

  When all flows in a container belong to the same component, you can access by short label:

  # Both work for component.inputs, component.outputs, and component.flows:
  component.inputs['Boiler(Q_th)']  # Full label
  component.inputs['Q_th']          # Short label ✓

  # The `in` operator also supports short labels:
  if 'Q_th' in component.flows:    # Works!
      ...

  2. Component.flows is now a FlowContainer (cached property)

  # Before (dict keyed by short label):
  component.flows: dict[str, Flow]

  # After (FlowContainer with full/short label access):
  component.flows: FlowContainer  # cached_property

  API Summary
  ┌─────────────────────┬──────────────────────────────────────┐
  │   Access Pattern    │               Example                │
  ├─────────────────────┼──────────────────────────────────────┤
  │ Full label          │ component.flows['Boiler(Q_th)']      │
  ├─────────────────────┼──────────────────────────────────────┤
  │ Short label         │ component.flows['Q_th']              │
  ├─────────────────────┼──────────────────────────────────────┤
  │ Index               │ component.flows[0]                   │
  ├─────────────────────┼──────────────────────────────────────┤
  │ Membership          │ 'Q_th' in component.flows            │
  ├─────────────────────┼──────────────────────────────────────┤
  │ Iteration           │ for flow in component.flows.values() │
  ├─────────────────────┼──────────────────────────────────────┤
  │ Efficient iteration │ for flow in component.all_flows      │
  └─────────────────────┴──────────────────────────────────────┘
  Note: Short-label access only works when all flows in the container share the same component (which is always true for component.inputs,
  component.outputs, and component.flows).
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Unifies flow collections by introducing FlowContainer and replacing list-based inputs + outputs patterns with container-based access (e.g., .flows.values() / .inputs.values() / .outputs.values()), updating component/bus initialization, topology wiring, modeling, IO, statistics, and tests accordingly.

Changes

Cohort / File(s) Summary
Flow container core
flixopt/structure.py
Added FlowContainer supporting index/label access and improved membership; added ContainerMixin.__add__ to concatenate containers.
Component & Bus declarations
flixopt/elements.py
Component.__init__ accepts list or dict for inputs/outputs; new _connect_flows, flows (FlowContainer) and all_flows properties; Bus updated to expose flows/all_flows.
Flow system wiring
flixopt/flow_system.py
Replace iterations over inputs + outputs with comp.flows.values(); bus wiring switched from list appends to set .add() for bus.inputs/bus.outputs; updated topology/linking logic.
Models updated
flixopt/components.py
TransmissionModel and LinearConverterModel updated to iterate/link over flow containers (.flows.values() / .inputs.values() / .outputs.values()) when building constraints.
I/O and statistics
flixopt/io.py, flixopt/statistics_accessor.py
Iteration and labeling logic changed to use .values() on inputs/outputs and component/bus flow containers for plotting and effect-share calculations.
Tests
tests/deprecated/test_integration.py
Adjusted test setup to iterate merged flow containers via .values() when building flow mappings.
Changelog
CHANGELOG.md
Documented FlowContainer introduction and flow-access API changes.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

v3.0.0

Poem

🐇 I hop through flows both short and long,

containers sing a tidy song,
indices, labels, all in line,
components link and models shine—
a little refactor, neat and strong.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description is incomplete. It lacks the required template sections including Type of Change, Related Issues, Testing checklist, and the complete Checklist items. Use the repository's pull request template and complete all required sections including Type of Change checkboxes, Related Issues, Testing status, and full Checklist.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: introducing FlowContainer for inputs/outputs attributes to provide dual access patterns.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@FBumann FBumann changed the title Feature/containers Add FlowContainer for inputs/outputs with dual access (index + label) Jan 23, 2026
@FBumann
Copy link
Member Author

FBumann commented Jan 23, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@FBumann FBumann changed the title Add FlowContainer for inputs/outputs with dual access (index + label) Add FlowContainer for inputs/outputs Jan 23, 2026
@FBumann FBumann marked this pull request as ready for review January 23, 2026 14:45
@FBumann FBumann merged commit 8e8fe5c into main Jan 23, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants