How to Use Multi-Value Parameter Types (`multi_int`, `multi_float`) in Hypster
The HP class in Hypster provides multi_int and multi_float helper methods that return validated lists of integers or floats while enforcing optional bounds checking and strict type constraints.
The gilad-rubin/hypster library offers robust configuration management through type-safe parameter validation. When you need to capture lists of numeric values rather than single scalars, multi-value parameter types apply rigorous IntValidator or FloatValidator checks to every element. This guide demonstrates how to define integer and float list parameters with constraints, default values, and strict type enforcement.
Defining Integer Lists with multi_int
The multi_int method creates a parameter that accepts a list of integers. According to the implementation in [src/hypster/hp.py lines 525-543](https://github.com/gilad-rubin/hypster/blob/master/src/hypster/hp.py#L525-L543), this helper validates each element using IntValidator and applies optional min and max constraints to every item in the list.
Basic Syntax and Bounds Checking
Call hp.multi_int(default_list, *, name, min=None, max=None) to define an integer list parameter. The method requires a default list and a parameter name, with optional bounds that apply to each element individually.
from hypster import HP, instantiate
from typing import List
def cfg(hp: HP) -> List[int]:
# Default list [1, 2, 3]; each element must be in [0, 10]
return hp.multi_int([1, 2, 3], name="values", min=0, max=10)
# Normal usage – returns the default list
assert instantiate(cfg) == [1, 2, 3]
# Override via values dict
assert instantiate(cfg, values={"values": [5, 6, 7]}) == [5, 6, 7]
This example demonstrates the bounds enforcement verified in [tests/test_multi_parameters.py lines 10-22](https://github.com/gilad-rubin/hypster/blob/master/tests/test_multi_parameters.py#L10-L22). If you pass values outside the specified range, the validation raises an appropriate error before instantiation completes.
Working with Float Lists via multi_float
The multi_float method, defined in [src/hypster/hp.py lines 545-563](https://github.com/gilad-rubin/hypster/blob/master/src/hypster/hp.py#L545-L563), operates similarly but uses FloatValidator for element validation. This helper includes a strict parameter that controls whether integers are automatically converted to floats or rejected as type errors.
Strict Mode vs. Flexible Type Coercion
By default, multi_float operates with strict=False, allowing integer inputs to be silently converted to floating-point values. When strict=True, the validator raises a ValueError if any element is not a native float.
def cfg_strict(hp: HP) -> List[float]:
# strict=True forbids integer elements
return hp.multi_float([1.0, 2.0], name="vals", strict=True)
# Valid call with native floats
assert instantiate(cfg_strict, values={"vals": [1.5, 2.5]}) == [1.5, 2.5]
# Invalid – integers raise ValueError
import pytest
with pytest.raises(ValueError, match="expected float but got int"):
instantiate(cfg_strict, values={"vals": [1, 2]})
As shown in [tests/test_multi_parameters.py lines 39-46](https://github.com/gilad-rubin/hypster/blob/master/tests/test_multi_parameters.py#L39-L46), strict mode ensures type safety when your configuration requires genuine floating-point inputs.
Automatic Integer Conversion
When strict mode is disabled (the default), the system converts valid integers to floats automatically:
def cfg_flexible(hp: HP) -> List[float]:
# strict=False (default) – ints are auto-converted
return hp.multi_float([1.0, 2.0], name="vals")
assert instantiate(cfg_flexible, values={"vals": [1, 2]}) == [1.0, 2.0]
This behavior is validated in [tests/test_multi_parameters.py lines 48-52](https://github.com/gilad-rubin/hypster/blob/master/tests/test_multi_parameters.py#L48-L52).
How Multi-Value Validation Works Internally
Understanding the internal implementation helps debug complex configurations. Both multi_int and multi_float delegate to _execute_multi, which forwards to _handle_multi_value in [src/hypster/hp.py lines 153-188](https://github.com/gilad-rubin/hypster/blob/master/src/hypster/hp.py#L153-L188).
The validation pipeline follows three steps:
-
Spec Creation: Each call builds a
MultiValueSpecdataclass (defined in [hp.pylines 71-78](https://github.com/gilad-rubin/hypster/blob/master/src/hypster/hp.py#L71-L78)) that stores the name, default list, element validator, and constraint flags. -
Multi-Validation: The
MultiValidatorclass (fromhp_calls.py) validates each list element individually. Formulti_float, it applies thestrictflag duringFloatValidatorchecks; formulti_int, it ensures every item is an integer. -
Bounds Enforcement: After type validation, the system checks
minandmaxconstraints against each element usingvalidate_boundsbefore storing the final list under the parameter path.
This architecture ensures consistent validation across all multi-value parameter types while maintaining clear error messages that identify which specific element failed validation.
Summary
multi_intcreates validated integer lists with optionalmin/maxbounds applied to every element, implemented viaIntValidatorinsrc/hypster/hp.py.multi_floatcreates float lists with an optionalstrictmode; when enabled, rejects integers rather than converting them, usingFloatValidatorlogic.- Both methods store configurations as
MultiValueSpecobjects processed throughHP._handle_multi_valueto ensure type safety and bounds compliance. - Override multi-value defaults by passing dictionaries to
instantiate()with the parameter name as the key and a list as the value.
Frequently Asked Questions
What happens if I pass a single value instead of a list to multi_int or multi_float?
The MultiValidator expects an iterable collection. Passing a single scalar value will cause the validation to treat the scalar as the input, typically resulting in an iteration error or validation failure depending on the specific value type. Always wrap single overrides in a list, for example: values={"param": [5]} rather than values={"param": 5}.
Can I use multi_int and multi_float with negative bounds?
Yes. The min and max parameters accept any valid integer or float, including negative values. The bounds validation in _handle_multi_value performs standard numeric comparisons, so you can constrain ranges like min=-10, max=-1 or mix positive and negative boundaries as needed for your domain.
How does strict mode affect performance?
Strict mode adds minimal overhead because it only changes the type-checking logic within FloatValidator. According to the implementation in src/hypster/hp_calls.py, the check is a simple isinstance validation prior to conversion. The performance difference is negligible for typical configuration lists, though strict mode prevents silent data type changes that might cause precision issues in downstream mathematics.
Can I combine multi_int with other parameter types in the same configuration function?
Absolutely. You can mix multi_int, multi_float, single-value parameters like int or float, and selection parameters within the same HP configuration. Each parameter maintains its own namespace, and the instantiate function resolves all values simultaneously. Ensure each parameter has a unique name to avoid collisions during the configuration phase.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →