Skip to content

Feature/compact repr#457

Merged
FBumann merged 4 commits intomainfrom
feature/compact-repr
Nov 5, 2025
Merged

Feature/compact repr#457
FBumann merged 4 commits intomainfrom
feature/compact-repr

Conversation

@FBumann
Copy link
Member

@FBumann FBumann commented Nov 4, 2025

Description

Add truncation to the repr of containers

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Code refactoring

Related Issues

Closes #(issue number)

Testing

  • I have tested my changes
  • Existing tests still pass

Checklist

  • My code follows the project style
  • I have updated documentation if needed
  • I have added tests for new functionality (if applicable)

Summary by CodeRabbit

  • Chores
    • Improved container display: lists of components, buses, effects and flows now truncate long outputs (default preview length shortened) for cleaner, more readable summaries.
  • Bug Fixes / Behavior
    • Clarified deprecation-style warning for missing flow data and now initializes empty flows when absent to avoid noisy messages.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 4, 2025

Walkthrough

Adds per-container truncation control via a new truncate_repr parameter in ContainerMixin and propagates it to EffectCollection, public containers in the flow system, and result containers; representation methods now support truncation and grouped outputs use each container’s truncated repr.

Changes

Cohort / File(s) Summary
Core representation logic
flixopt/structure.py
Added `truncate_repr: int
Effect collection support
flixopt/effects.py
Extended EffectCollection.__init__ signature to accept `truncate_repr: int
Flow system initialization
flixopt/flow_system.py
Public containers now initialize with truncation: self.components = ElementContainer(..., truncate_repr=10), self.buses = ElementContainer(..., truncate_repr=10), self.effects = EffectCollection(truncate_repr=10). _flows_cache creation in flows property now uses ElementContainer(..., truncate_repr=10).
Results container initialization
flixopt/results.py
CalculationResults.__init__ wraps public result containers with truncate_repr=10 for components, buses, effects, and flows. Missing-flow branch message updated to indicate deprecation context and sets _has_flow_data to False; flows still use truncate_repr=10 when present.

Sequence Diagram(s)

(omitted — representation/truncation changes do not alter control flow)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Focus areas:
    • flixopt/structure.py: verify _get_repr truncation logic, edge cases when max_items is None vs numeric, and grouping output correctness.
    • flixopt/effects.py: check self.submodel initialization and add_effects invocation during construction for side effects.
    • Consistency: ensure all intended containers use truncate_repr=10 and no callers rely on previous untruncated reprs.

Suggested labels

v3.0.0

Poem

🐰
I nibbled code until it shone,
Trimmed long lists so views feel grown,
Ten items peek, the rest take rest,
Clean reprs now look their best!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely incomplete with placeholder text, unchecked testing items, and missing key details about implementation changes. Complete the PR description by: filling in the related issue number, checking appropriate change type boxes, marking testing items as complete or not, and providing more detail about the truncation feature implementation.
Title check ❓ Inconclusive The title 'Feature/compact repr' is vague and uses non-descriptive terms that don't clearly convey what is being implemented. Use a more descriptive title like 'Add truncation support to container representations' to better summarize the main feature being added.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/compact-repr

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01f2c98 and 728a08b.

📒 Files selected for processing (4)
  • flixopt/effects.py (1 hunks)
  • flixopt/flow_system.py (2 hunks)
  • flixopt/results.py (2 hunks)
  • flixopt/structure.py (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • flixopt/results.py
  • flixopt/flow_system.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.10)
🔇 Additional comments (4)
flixopt/effects.py (1)

461-474: LGTM! Clean integration of truncation support.

The addition of the truncate_repr parameter is well-implemented:

  • Properly typed and documented
  • Correctly forwarded to the base class
  • Maintains backward compatibility with None default
flixopt/structure.py (3)

920-942: LGTM! Proper parameter addition with backward compatibility.

The truncate_repr parameter is correctly integrated:

  • Type hints and documentation are clear
  • Default None preserves existing behavior (shows all items)
  • Follows established patterns in the codebase

1005-1043: LGTM! Well-designed truncation implementation.

The _get_repr method provides flexible truncation control:

  • Proper fallback from max_items parameter to instance default
  • Correct truncation condition checking
  • Clean separation between truncated and full representations
  • Maintains natural sorting behavior

The logic correctly handles all cases including empty containers and various limit values.


1246-1247: LGTM! Accurate comment describing the new behavior.

The comment correctly notes that each container's __repr__ respects its own truncate_repr setting, which aligns with the implementation changes.


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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
flixopt/results.py (1)

249-251: Truncated repr for results containers — good default; consider making max items configurable.

Enabling truncation on components/buses/effects/flows improves readability for large results. As a small enhancement, consider a per-container or global knob (e.g., via ContainerMixin or CONFIG) to adjust the truncate threshold without code changes. Also, a tiny unit test asserting the presence of the “... (+N more)” suffix would be useful.

Also applies to: 254-255, 257-257, 272-272

flixopt/effects.py (1)

461-463: Forwarding truncate_repr in EffectCollection — LGTM; add a brief docstring.

The constructor change is sound. Add a short docstring to document truncate_repr for discoverability.

Apply this minimal docstring:

 def __init__(self, *effects: Effect, truncate_repr: bool = False):
-    super().__init__(element_type_name='effects', truncate_repr=truncate_repr)
+    """
+    Initialize the collection.
+    Args:
+        *effects: Effects to register.
+        truncate_repr: If True, limit repr listing length in grouped views.
+    """
+    super().__init__(element_type_name='effects', truncate_repr=truncate_repr)
flixopt/flow_system.py (1)

178-183: Consistent truncated repr for public containers — 👍; optional configurability.

Setting truncate_repr=True for components/buses/effects/flows aligns system-wide. Consider making the truncate threshold configurable (e.g., via a ContainerMixin arg or CONFIG) so users can widen/narrow listings without code edits.

Also applies to: 804-804

flixopt/structure.py (3)

924-935: New truncate_repr flag in ContainerMixin — solid plumbing; add optional per-container limit.

Flag storage is straightforward. Consider an optional repr_max_items to control truncation per container without touching call sites later.

Apply this small, backward-compatible extension:

 class ContainerMixin(dict[str, T]):
@@
-    def __init__(
+    def __init__(
         self,
         elements: list[T] | dict[str, T] | None = None,
         element_type_name: str = 'elements',
-        truncate_repr: bool = False,
+        truncate_repr: bool = False,
+        repr_max_items: int = 10,
     ):
@@
         self._element_type_name = element_type_name
-        self._truncate_repr = truncate_repr
+        self._truncate_repr = truncate_repr
+        self._repr_max_items = repr_max_items

1005-1034: _get_repr implementation — clear and efficient; reuse a per-instance default.

Logic and natural sort look good. If you add _repr_max_items, let callers omit max_items yet still pick up the per-instance default.

Minimal tweak:

-    def _get_repr(self, truncate: bool = False, max_items: int = 10) -> str:
+    def _get_repr(self, truncate: bool = False, max_items: int | None = None) -> str:
@@
-            if truncate and len(sorted_names) > max_items:
+            limit = max_items if max_items is not None else getattr(self, "_repr_max_items", 10)
+            if truncate and len(sorted_names) > limit:
                 # Show truncated list
-                for name in sorted_names[:max_items]:
+                for name in sorted_names[:limit]:
                     r += f' * {name}\n'
-                r += f' ... (+{len(sorted_names) - max_items} more)\n'
+                r += f' ... (+{len(sorted_names) - limit} more)\n'

1243-1247: Grouped container formatting honors truncation flag — nice.

Works as intended. Minor nit: isinstance(container, ContainerMixin) would read clearer than hasattr, but current duck-typing is fine.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between efb8532 and 01f2c98.

📒 Files selected for processing (4)
  • flixopt/effects.py (1 hunks)
  • flixopt/flow_system.py (2 hunks)
  • flixopt/results.py (2 hunks)
  • flixopt/structure.py (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
flixopt/flow_system.py (2)
flixopt/structure.py (1)
  • ElementContainer (1043-1052)
flixopt/effects.py (1)
  • EffectCollection (454-631)
flixopt/results.py (2)
flixopt/structure.py (2)
  • ResultsContainer (1055-1064)
  • solution (159-182)
flixopt/flow_system.py (1)
  • flows (799-805)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.10)
🔇 Additional comments (1)
flixopt/structure.py (1)

1038-1041: Never-truncated direct repr — good choice.

Keeps repr(element_container) complete while grouped views can truncate. No action needed.

  1. ContainerMixin in structure.py

  - Changed truncate_repr from bool to int | None
  - None = show all items (no truncation)
  - Integer value = maximum number of items to show in repr
  - Default is None (no truncation)

  2. Updated _get_repr() method

  - Simplified parameters from (truncate: bool, max_items: int) to just (max_items: int | None)
  - Uses instance's _truncate_repr as default if max_items is not provided
  - Cleaner logic: truncates only when limit is not None and limit > 0

  3. Updated __repr__() method

  - Now simply calls self._get_repr() without arguments
  - Respects the instance's truncate_repr setting

  4. Simplified _format_grouped_containers()

  - Removed the conditional logic checking for _truncate_repr
  - Now just calls repr(container) which automatically respects each container's setting

  5. Updated all call sites

  - flow_system.py: Changed truncate_repr=True → truncate_repr=10 (4 locations)
  - results.py: Changed truncate_repr=True → truncate_repr=10 (4 locations)
  - effects.py: Changed truncate_repr: bool = False → truncate_repr: int | None = None and added docstring
@FBumann FBumann merged commit fe3fe23 into main Nov 5, 2025
1 check passed
@FBumann FBumann deleted the feature/compact-repr branch November 19, 2025 13:41
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.

1 participant