Skip to content

new collection based on easy_list#226

Draft
rozyczko wants to merge 2 commits intodevelopfrom
collection_base_easylist
Draft

new collection based on easy_list#226
rozyczko wants to merge 2 commits intodevelopfrom
collection_base_easylist

Conversation

@rozyczko
Copy link
Member

@rozyczko rozyczko commented Mar 9, 2026

CollectionBase Design — Derived from EasyList

Overview

This document proposes the design for a new CollectionBase class that:

  • Derives from EasyList rather than re-implementing MutableSequence from scratch.
  • Removes all functionality now owned by EasyList (sequence operations, type protection, deduplication, serialization).
  • Assumes legacy collection-specific concerns such as graph edges, interface propagation,
    and NotarizedDict have already been removed before this class is introduced.

Context

Goal

Define a single CollectionBase that:

  1. Treats EasyList as the complete MutableSequence implementation.
  2. Retains a small, explicit compatibility layer needed for in-place replacement.
  3. Provides a data property and supports the legacy _convert_to_dict encoder path.

Preconditions

This design assumes the following changes land first:

  1. DescriptorBase, DescriptorNumber, and Parameter are migrated onto the NewBase hierarchy.
  2. Any remaining code that depends on global_object.map edge management at the collection layer has been migrated away.

Under those assumptions, inheriting from EasyList is structurally valid. The remaining design work is about
compatibility and migration, not object-model mismatch.


Inheritance Hierarchy

NewBase
  └── EasyList[T]                   ← full MutableSequence, serialization, type protection
        └── CollectionBase[T]       ← adds aggregation methods only

CollectionBase does not inherit from ModelBase.
The parameter-aggregation logic (get_all_variables etc.) is implemented directly on
CollectionBase, iterating self._data rather than inspecting class attributes with dir().


What EasyList Provides Directly

EasyList already covers almost all of the sequence machinery. The items below should stay inherited unless
backward-compatibility requires a thin adapter.

Category Method / Feature
Core sequence protocol __getitem__, __setitem__, __delitem__, __len__, insert
Derived protocol (MutableSequence mixin) append, extend, remove, pop, index, count, clear, __iter__
Multi-mode indexing __getitem__(int), __getitem__(slice), __getitem__(str) by unique_name
Membership testing __contains__(item), __contains__(str)
Reverse iteration __reversed__
Ordering sort(key, reverse)
Deduplication Warns and ignores items already present in the list
Type protection protected_types constructor argument
Identity unique_name, display_name (from NewBase)
Representation __repr__
New serialization path to_dict(), from_dict()

What CollectionBase Must Add

1. Parameter / Variable Aggregation

def get_all_variables(self) -> List[DescriptorBase]:
    """
    Recursively collect every DescriptorBase (and Parameter) from the
    contained items.

    - If an item is itself a DescriptorBase, include it directly.
    - Else if it has get_all_variables(), delegate to that method.
    - Otherwise skip it.
    """

def get_all_parameters(self) -> List[Parameter]:
    """Filter get_all_variables() to Parameter instances only."""

def get_parameters(self) -> List[Parameter]:
    """Compatibility alias for get_all_parameters()."""

def get_fittable_parameters(self) -> List[Parameter]:
    """Parameters where independent=True."""

def get_free_parameters(self) -> List[Parameter]:
    """Parameters where fixed=False (subset of fittable)."""

def get_fit_parameters(self) -> List[Parameter]:
    """Alias for get_free_parameters(); retained for backward compatibility."""

These mirror the methods on ModelBase, but aggregate across the list of items rather than
across the attribute names of a single object.

The DescriptorBase leaf fallback should be treated as required, not optional. A collection of raw
parameters or descriptors is a first-class use case.

2. data Property

@property
def data(self) -> tuple:
    """Immutable tuple view of the contained items.
    Backward-compatible with the old CollectionBase.data property."""
    return tuple(self._data)

3. Legacy Serialization (_convert_to_dict)

def _convert_to_dict(
    self,
    in_dict: dict,
    encoder: Any,
    skip: Optional[List[str]] = None,
    **kwargs: Any,
) -> dict:
    """
    Support for the legacy encoder-based serialization path.
    Serializes all items in _data under the 'data' key, consistent
    with the old CollectionBase._convert_to_dict signature.
    Include `name` as well if old CollectionBase payloads are still consumed.
    """

The compatibility layer should be deliberate and temporary.


Migration Notes

Sequencing

Recommended order of work:

  1. Land the NewBase migration for variable classes.
  2. Introduce CollectionBase on top of EasyList with the minimum compatibility surface.
  3. Migrate call sites off the compatibility layer.
  4. Remove deprecated items and converge on the thinner final API.

@rozyczko rozyczko marked this pull request as draft March 9, 2026 14:04
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

This pull request does not contain a valid label. Please add one of the following labels: ['[scope] bug', '[scope] enhancement', '[scope] documentation', '[scope] significant', '[scope] maintenance']

@rozyczko rozyczko mentioned this pull request Mar 9, 2026
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