Source code for spine.constants.factory

"""Helpers for parsing SPINE enum-like configuration values.

This module is intentionally separate from :mod:`spine.constants.enums`.
The enum module should define canonical enumerated types; this module contains
parsing helpers that translate user/config strings into those enum values.
"""

from typing import overload

from .columns import ClusterLabelCol
from .enums import NuInteractionScheme, ParticlePID, ParticleShape

__all__ = ["enum_factory"]


@overload
def enum_factory(enum: str, value: str) -> int:
    """Parse one enum-member name into its integer value."""


@overload
def enum_factory(enum: str, value: list[str] | tuple[str, ...]) -> list[int]:
    """Parse a sequence of enum-member names into integer values."""


[docs] def enum_factory( enum: str, value: str | list[str] | tuple[str, ...] ) -> int | list[int]: """Parse canonical SPINE enum values from config strings. This is a small compatibility/helper layer used by config-driven code that still refers to groups like ``"shape"`` or ``"pid"`` rather than importing enum classes directly. Parameters ---------- enum : str Name of the supported enum group to parse. Supported groups are ``"cluster"``, ``"shape"``, ``"pid"``, and ``"interaction_scheme"``. value : Union[str, Sequence[str]] One enum-member name or a sequence of enum-member names. Member names are matched case-insensitively through their uppercase representation. Returns ------- Union[int, List[int]] Integer value of the parsed enum member, or a list of integer values if a sequence of names is provided. Raises ------ ValueError If the requested enum group is not supported. ValueError If one of the provided member names does not exist on the target enum. """ enum_dict = { "cluster": ClusterLabelCol, "shape": ParticleShape, "pid": ParticlePID, "interaction_scheme": NuInteractionScheme, } if enum not in enum_dict: raise ValueError( f"Enumerated type not recognized: {enum}. " f"Must be one of {list(enum_dict.keys())}." ) enum_type = enum_dict[enum] def parse_one(name: str) -> int: member_name = name.upper() if not hasattr(enum_type, member_name): raise ValueError( f"Enumerated object not recognized: {name}. " f"Must be one of {[e.name for e in enum_type]}." ) return getattr(enum_type, member_name).value if isinstance(value, str): return parse_one(value) return [parse_one(v) for v in value]