or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-frozenlist

A list-like structure which implements collections.abc.MutableSequence that can be frozen to become immutable and hashable

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/frozenlist@1.7.x

To install, run

npx @tessl/cli install tessl/pypi-frozenlist@1.7.0

index.mddocs/

FrozenList

A specialized list-like data structure that implements collections.abc.MutableSequence with a unique freezing mechanism. FrozenList allows normal list operations (append, insert, modify) while mutable, but becomes immutable and hashable after calling freeze(), making it ideal for scenarios requiring both mutable construction and immutable usage.

Package Information

  • Package Name: frozenlist
  • Language: Python
  • Installation: pip install frozenlist

Core Imports

from frozenlist import FrozenList

For explicit access to implementations:

from frozenlist import PyFrozenList  # Pure Python implementation
# CFrozenList is available as FrozenList when Cython extensions are loaded

Access to package constants:

from frozenlist import __version__, __all__, NO_EXTENSIONS

Basic Usage

from frozenlist import FrozenList

# Create a new FrozenList
fl = FrozenList([1, 2, 3])

# Add items while mutable
fl.append(4)
fl.extend([5, 6])
fl.insert(0, 0)
print(fl)  # <FrozenList(frozen=False, [0, 1, 2, 3, 4, 5, 6])>

# Check if frozen
print(fl.frozen)  # False

# Freeze the list to make it immutable
fl.freeze()
print(fl.frozen)  # True

# Now it's hashable and can be used as a dict key
data = {fl: "my frozen list"}
print(hash(fl))  # Works now

# Modifications now raise RuntimeError
try:
    fl.append(7)
except RuntimeError as e:
    print(e)  # Cannot modify frozen list.

Architecture

FrozenList provides dual implementations for optimal performance:

  • Python Implementation: Pure Python fallback (PyFrozenList) always available
  • Cython Implementation: High-performance version with atomic operations for thread-safe frozen state management
  • Automatic Selection: Uses Cython version by default unless FROZENLIST_NO_EXTENSIONS environment variable is set

The design supports two distinct phases:

  1. Mutable Phase: Full list functionality, supports all modification operations
  2. Frozen Phase: Immutable state, becomes hashable and can be used as dict keys or set elements

Capabilities

Package Constants

__version__: str
"""Package version string (currently "1.7.0")."""

__all__: tuple
"""Exported public API: ("FrozenList", "PyFrozenList")."""

NO_EXTENSIONS: bool
"""Boolean flag indicating if Cython extensions are disabled via FROZENLIST_NO_EXTENSIONS environment variable."""

Core Construction and Control

class FrozenList:
    def __init__(self, items=None):
        """
        Initialize FrozenList with optional items.
        
        Parameters:
        - items: Iterable, optional initial items (default: None)
        """

    @property
    def frozen(self) -> bool:
        """Check if the list is frozen (immutable)."""

    def freeze(self) -> None:
        """
        Freeze the list, making it immutable and hashable.
        After calling this method, any modification attempts will raise RuntimeError.
        """

Sequence Access Operations

# Overloaded methods support both int and slice operations
@overload
def __getitem__(self, index: int) -> _T:
    """Get item by index."""

@overload  
def __getitem__(self, index: slice) -> FrozenList[_T]:
    """Get items by slice."""

def __getitem__(self, index):
    """
    Get item(s) by index or slice.
    
    Parameters:
    - index: int or slice, position(s) to access
    
    Returns:
    - _T: Item at index (when index is int)
    - FrozenList[_T]: New FrozenList containing sliced items (when index is slice)
    """

@overload
def __setitem__(self, index: int, value: _T) -> None:
    """Set item by index."""

@overload
def __setitem__(self, index: slice, value: Iterable[_T]) -> None:
    """Set items by slice."""

def __setitem__(self, index, value):
    """
    Set item(s) by index or slice.
    
    Parameters:
    - index: int or slice, position(s) to modify
    - value: _T or Iterable[_T], new value(s)
    
    Raises:
    RuntimeError: If list is frozen
    """

@overload
def __delitem__(self, index: int) -> None:
    """Delete item by index."""

@overload
def __delitem__(self, index: slice) -> None:
    """Delete items by slice."""

def __delitem__(self, index):
    """
    Delete item(s) by index or slice.
    
    Parameters:
    - index: int or slice, position(s) to delete
    
    Raises:
    RuntimeError: If list is frozen
    """

def __len__(self) -> int:
    """Return the number of items in the list."""

def __iter__(self):
    """Return an iterator over the list items."""

def __reversed__(self):
    """Return a reverse iterator over the list items."""

def __contains__(self, item) -> bool:
    """
    Check if item is in the list.
    
    Parameters:
    - item: any, item to search for
    
    Returns:
    bool: True if item is found
    """

List Modification Operations

def insert(self, pos: int, item):
    """
    Insert item at specified position.
    
    Parameters:
    - pos: int, position to insert at
    - item: any, item to insert
    
    Raises:
    RuntimeError: If list is frozen
    """

def append(self, item):
    """
    Append item to the end of the list.
    
    Parameters:
    - item: any, item to append
    
    Raises:
    RuntimeError: If list is frozen
    """

def extend(self, items):
    """
    Extend list with items from an iterable.
    
    Parameters:
    - items: iterable, items to add
    
    Raises:
    RuntimeError: If list is frozen
    """

def remove(self, item):
    """
    Remove first occurrence of item.
    
    Parameters:
    - item: any, item to remove
    
    Raises:
    RuntimeError: If list is frozen
    ValueError: If item is not found
    """

def pop(self, index: int = -1):
    """
    Remove and return item at index.
    
    Parameters:
    - index: int, position to remove (default: -1 for last item)
    
    Returns:
    Removed item
    
    Raises:
    RuntimeError: If list is frozen
    IndexError: If index is out of range
    """

def clear(self):
    """
    Remove all items from the list.
    
    Raises:
    RuntimeError: If list is frozen
    """

def reverse(self):
    """
    Reverse the list in place.
    
    Raises:
    RuntimeError: If list is frozen
    """

def __iadd__(self, items):
    """
    In-place addition (+=) operator.
    
    Parameters:
    - items: iterable, items to add
    
    Returns:
    self
    
    Raises:
    RuntimeError: If list is frozen
    """

Search and Query Operations

def index(self, item):
    """
    Return index of first occurrence of item.
    
    Parameters:
    - item: any, item to find
    
    Returns:
    int: Index of item
    
    Raises:
    ValueError: If item is not found
    """

def count(self, item) -> int:
    """
    Count occurrences of item in the list.
    
    Parameters:
    - item: any, item to count
    
    Returns:
    int: Number of occurrences
    """

Comparison Operations

def __eq__(self, other) -> bool:
    """
    Test equality with another sequence.
    
    Parameters:
    - other: any, object to compare with
    
    Returns:
    bool: True if sequences are equal
    """

def __ne__(self, other) -> bool:
    """Not equal comparison."""

def __lt__(self, other) -> bool:
    """Less than comparison."""

def __le__(self, other) -> bool:
    """Less than or equal comparison."""

def __gt__(self, other) -> bool:
    """Greater than comparison."""

def __ge__(self, other) -> bool:
    """Greater than or equal comparison."""

Hashing and Representation

def __hash__(self) -> int:
    """
    Return hash of the frozen list.
    
    Returns:
    int: Hash value based on tuple of items
    
    Raises:
    RuntimeError: If list is not frozen
    """

def __repr__(self) -> str:
    """
    Return string representation showing frozen state and contents.
    
    Returns:
    str: Representation like '<FrozenList(frozen=True, [1, 2, 3])>'
    """

Utility Operations

def __deepcopy__(self, memo):
    """
    Create a deep copy of the FrozenList.
    
    Parameters:
    - memo: dict, memoization dictionary for circular reference handling
    
    Returns:
    FrozenList: Deep copy with same frozen state
    
    Note: Only available in Cython implementation (CFrozenList).
    The Python implementation (PyFrozenList) does not include this method.
    """

Types and Aliases

# Type definitions (from typing module)
from typing import TypeVar, Generic, Iterable, Iterator, overload

_T = TypeVar("_T")

# Generic class definition
class FrozenList(Generic[_T]):
    """Generic FrozenList parameterized by type _T."""

# Implementation aliases
PyFrozenList = FrozenList
"""Explicit reference to pure Python implementation."""

# CFrozenList is available as FrozenList when Cython extensions are loaded

Implementation Notes

MutableSequence Interface

FrozenList implements the complete collections.abc.MutableSequence interface. The Cython implementation explicitly registers with MutableSequence.register(FrozenList).

Implementation Differences

Cython Implementation (CFrozenList - default when available):

  • Uses atomic operations (atomic[bint]) for thread-safe frozen flag management
  • Includes __deepcopy__ method for deep copying with circular reference handling
  • Implements comparison operations via __richcmp__ method
  • Includes internal optimization methods (_check_frozen, _fast_len)

Python Implementation (PyFrozenList - fallback):

  • Uses simple boolean for frozen flag (not thread-safe)
  • No __deepcopy__ method - relies on standard copy.deepcopy behavior
  • Implements individual comparison methods (__eq__, __le__, etc.)
  • No internal optimization methods

Generic Type Support

Both implementations support generic type hints via __class_getitem__ = classmethod(types.GenericAlias).

Error Handling

FrozenList raises the following exceptions:

  • RuntimeError: Raised when attempting to modify a frozen list or hash an unfrozen list
  • Standard exceptions: IndexError, ValueError, etc. are raised for standard list operations as expected

Environment Variables

  • FROZENLIST_NO_EXTENSIONS: Set to any non-empty value to force use of pure Python implementation instead of Cython accelerated version