unxt-hypothesis API#
Complete API documentation for all unxt-hypothesis strategies.
Hypothesis strategies for unxt.
- unxt_hypothesis.derived_units(base: str | Unit | UnitBase | CompositeUnit | SearchStrategy[Unit | UnitBase | CompositeUnit], /, *, integer_powers: bool = True, max_complexity: int = 3)#
Generate hypothesis strategy for units from a given base unit.
This strategy generates units that are dimensionally equivalent to the input base unit by combining the base unit’s base units and discovered composed forms.
- Parameters:
draw (st.DrawFn) – Hypothesis draw function (automatically provided by @st.composite).
base (str | u.AbstractUnit | st.SearchStrategy[u.AbstractUnit]) – Base unit (e.g., “m”, “s”, “kg”) or a hypothesis strategy that generates such units.
integer_powers (bool, optional) – If True, only generate units with integer powers of base units. Default is True.
max_complexity (int, optional) – Maximum number of additional base unit factors to combine. Higher values create more complex compound units. Default is 3.
- Returns:
A unit with the same physical dimension as the input.
- Return type:
unxt.AbstractUnit
Examples
>>> import hypothesis.strategies as st >>> from hypothesis import given >>> import unxt_hypothesis as ust >>> import unxt as u
Generate units derived from a base unit:
>>> @given(unit=ust.derived_units("m")) ... def test_length_units(unit): ... assert u.dimension_of(unit) == u.dimension("length")
Generate units from a strategy:
>>> @given(unit=ust.derived_units(st.sampled_from(["km", "m/s^2"]))) ... def test_velocity_derived(unit): ... assert u.dimension_of(unit) in ( ... u.dimension("velocity"), ... u.dimension("acceleration"), ... )
Control complexity of generated units:
>>> @given(unit=ust.derived_units("kg", max_complexity=1)) ... def test_simple_mass_units(unit): ... assert u.dimension_of(unit) == u.dimension("mass")
Allow non-integer powers:
>>> @given(unit=ust.derived_units("m", integer_powers=False)) ... def test_fractional_powers(unit): ... dim = u.dimension_of(unit) ... assert dim == u.dimension("length")
- unxt_hypothesis.units(dimension: str | PhysicalType | SearchStrategy[PhysicalType] = named_dimensions(), /, **kwargs: Any)#
Generate hypothesis strategy for units with a given physical dimension.
This strategy generates units that are dimensionally equivalent to the input dimension by combining the dimension’s base units and discovered composed forms.
- Parameters:
draw (st.DrawFn) – Hypothesis draw function (automatically provided by @st.composite).
dimension (str | apyu.PhysicalType) – Physical dimension (e.g., “velocity”, “length”) or a hypothesis strategy that generates such dimensions. Default is a strategy sampling from SI base dimensions.
**kwargs (Any) –
Additional keyword arguments passed to derived_units(). For example:
- integer_powersbool
If True, only generate units with integer powers of base units. Default is True.
- max_complexityint
Maximum number of additional base unit factors to combine. Higher values create more complex compound units. Default is 3.
- Returns:
A unit with the same physical dimension as the input.
- Return type:
unxt.AbstractUnit
Examples
>>> import hypothesis.strategies as st >>> from hypothesis import given >>> import unxt_hypothesis as ust >>> import unxt as u
>>> @given(unit=ust.units("velocity")) ... def test_velocity_units(unit): ... assert u.dimension_of(unit) == u.dimension("velocity")
>>> @given(unit=ust.units("length", integer_powers=False)) ... def test_length_units(unit): ... dim = u.dimension_of(unit) ... assert dim == u.dimension("length")
The dimension argument can also be a strategy:
>>> from hypothesis import strategies as st >>> @given(unit=ust.units(st.sampled_from(["length", "time", "mass"]))) ... def test_multiple_dimensions(unit): ... dim = u.dimension_of(unit) ... assert dim in [ ... u.dimension("length"), ... u.dimension("time"), ... u.dimension("mass"), ... ]
Notes
The strategy works by:
Getting the canonical unit for the dimension
Decomposing it into base SI units
Finding composed forms using .compose()
Generating random combinations by multiplying/dividing other units with cancelling dimensions
- unxt_hypothesis.unitsystems(*units: str | Unit | UnitBase | CompositeUnit | SearchStrategy[Unit | UnitBase | CompositeUnit])#
Generate hypothesis strategy for unxt UnitSystem objects.
This strategy supports all the same unit input options as u.unitsystem(). The additional capability provided here is that any unit input can also be a hypothesis strategy, enabling property-based testing with varying units.
- Parameters:
draw (st.DrawFn) – Hypothesis draw function (automatically provided by @st.composite).
*units (str | unxt.AbstractUnit | st.SearchStrategy[u.AbstractUnit]) – Variable number of unit specifications. Each can be: - str: Fixed unit string (e.g., “kpc”, “Myr”, “Msun”) - unxt.AbstractUnit: Fixed unit object - SearchStrategy: Strategy that generates units
- Returns:
A UnitSystem object created from the specified units.
- Return type:
u.AbstractUnitSystem
Examples
>>> from hypothesis import given >>> import unxt as u >>> import unxt_hypothesis as ust
Create a unit system with fixed units:
>>> @given(usys=ust.unitsystems("m", "s", "kg", "rad")) ... def test_mks_system(usys): ... assert isinstance(usys, u.AbstractUnitSystem) ... assert len(usys) == 4
Create a unit system with varying length units:
>>> @given(usys=ust.unitsystems(ust.units("length"), "s", "kg", "rad")) ... def test_varying_length_system(usys): ... assert isinstance(usys, u.AbstractUnitSystem) ... assert len(usys) == 4 ... # Length unit will vary, but time is always seconds ... assert usys["time"] == u.unit("s")
Use predefined unit systems by name:
>>> @given(usys="galactic") # Predefined ... def test_galactic_system(usys): ... assert isinstance(usys, u.AbstractUnitSystem) ... assert len(usys) == 4
- unxt_hypothesis.quantities(unit: str | ~astropy.units.core.Unit | ~astropy.units.core.UnitBase | ~astropy.units.core.CompositeUnit | ~hypothesis.strategies.SearchStrategy[~astropy.units.core.Unit | ~astropy.units.core.UnitBase | ~astropy.units.core.CompositeUnit | ~astropy.units.physical.PhysicalType] | ~astropy.units.physical.PhysicalType = units(named_dimensions()), *, quantity_cls: type[~unxt._src.quantity.base.AbstractQuantity] = <class 'unxt._src.quantity.quantity.Quantity'>, dtype: ~typing.Any | ~hypothesis.strategies.SearchStrategy[~numpy.dtype] = <class 'jax.numpy.float32'>, shape: int | tuple[int, ...] | ~hypothesis.strategies.SearchStrategy[int | tuple[int, ...]] = (), elements: ~hypothesis.strategies.SearchStrategy[float] | None = None, unique: bool = False, static_value: bool | ~hypothesis.strategies.SearchStrategy[bool] = False, **kwargs: ~typing.Any)#
Generate hypothesis strategy for unxt Quantity objects.
This strategy combines JAX array generation with unit specifications to create valid Quantity objects for property-based testing.
- Parameters:
draw (st.DrawFn) – Hypothesis draw function (automatically provided by @st.composite).
unit (str | st.SearchStrategy[unxt.AbstractUnit]) –
Unit specification for the Quantity. Can be:
str: Fixed unit (e.g., “kpc”, “km/s”)
unxt.AbstractUnit: Fixed unit object
unxt.AbstractDimension: Dimension to derive unit from (uses unxt_hypothesis.units strategy)
SearchStrategy: Strategy that generates units (e.g., from units()) or dimensions. The default strategy samples from SI base units.
quantity_cls (type[unxt.AbstractQuantity], optional) – The target quantity class to convert to. Default is unxt.Quantity. Can be any unxt.AbstractQuantity subclass like unxt.Quantity or unxt.Angle.
dtype (Any, optional) – NumPy/JAX dtype for the underlying array. Default is jnp.float32. Can also be a SearchStrategy that generates dtypes.
shape (int | tuple[int, ...] | st.SearchStrategy[tuple[int, ...]]) –
Shape of the array. Can be:
int: 1D array of that length
tuple: fixed shape
SearchStrategy: strategy that generates shapes
elements (st.SearchStrategy[float] | None, optional) – Strategy for generating array elements. If None, uses finite floats.
unique (bool, optional) – Whether array elements should be unique. Default is False.
static_value (bool, optional) – Whether to wrap the generated array in unxt.quantity.StaticValue. Default is False.
**kwargs (Any) – Additional keyword arguments (currently unused, reserved for future use).
- Returns:
A Quantity object with the specified unit and array properties.
- Return type:
unxt.Quantity
Examples
Basic usage with fixed unit and shape:
>>> from hypothesis import given, strategies as st >>> import jax.numpy as jnp >>> import unxt as u >>> import unxt_hypothesis as ust
>>> @given(q=ust.quantities("kpc", shape=3)) ... def test_position(q): ... assert q.unit == u.unit("kpc") ... assert q.shape == (3,)
>>> @given(q=ust.quantities("km/s", shape=())) ... def test_scalar_velocity(q): ... assert q.unit == u.unit("km/s") ... assert q.shape == ()
Using a unit strategy to vary units across test runs:
>>> @given(q=ust.quantities(ust.units("length"), shape=3)) ... def test_length_with_varying_units(q): ... # Unit will vary across test runs ... assert u.dimension_of(q) == u.dimension("length") ... assert q.shape == (3,)
As a convenience, instead of nesting strategies with
ust.units, you can directly pass the dimension object (not a string) toust.quantities:>>> @given(q=ust.quantities(u.dimension("velocity"), shape=3)) ... def test_velocity_from_dimension(q): ... # Will generate different velocity units (m/s, km/s, etc.) ... assert u.dimension_of(q) == u.dimension("velocity") ... assert q.shape == (3,)
This (and
ust.units) support a strategy for dimensions:>>> dim_strat = st.sampled_from([u.dimension("length"), u.dimension("mass")]) >>> @given(q=ust.quantities(dim_strat, shape=())) ... def test_mixed_dimensions(q): ... # Will generate either length or mass quantities ... dim = u.dimension_of(q) ... assert dim in (u.dimension("length"), u.dimension("mass"))
Using dtype as a strategy:
>>> dtype_strat = st.sampled_from([jnp.float32, jnp.float64]) >>> @given(q=ust.quantities("m", dtype=dtype_strat)) ... def test_varying_dtype(q): ... # dtype will vary between float32 and float64 ... assert q.dtype in (jnp.float32, jnp.float64)
Using elements to constrain value ranges for distances (positive values):
>>> @given( ... q=ust.quantities( ... "kpc", shape=3, elements=st.floats(min_value=0, max_value=100, width=32) ... ) ... ) ... def test_positive_distance(q): ... # All elements will be positive (suitable for distances) ... assert jnp.all(q.value >= 0) ... assert jnp.all(q.value <= 100)
Using elements for longitude angles (0 to 360 degrees):
>>> @given( ... q=ust.quantities( ... "deg", ... shape=(), ... elements=st.floats(min_value=0, max_value=360, width=32), ... ) ... ) ... def test_longitude_range(q): ... # Longitude in [0, 360] degrees ... assert 0 <= q.value <= 360
Using quantity_cls to generate Angle objects:
>>> @given(angle=ust.quantities("rad", quantity_cls=u.Angle, shape=3)) ... def test_angle_generation(angle): ... # Creates Angle instances instead of Quantity ... assert isinstance(angle, u.Angle) ... assert angle.unit == u.unit("rad") ... assert angle.shape == (3,)
- unxt_hypothesis.wrap_to(quantity: AbstractQuantity | SearchStrategy[AbstractQuantity], /, min: AbstractQuantity | SearchStrategy[AbstractQuantity], max: AbstractQuantity | SearchStrategy[AbstractQuantity])#
Generate hypothesis strategy for wrapped quantities.
This strategy takes a quantity strategy and wraps the generated values to the specified [min, max) range using the wrap_to function.
- Parameters:
draw – Hypothesis draw function (automatically provided by @st.composite).
quantity (
Union[AbstractQuantity,SearchStrategy[AbstractQuantity]]) – Quantity or strategy that generates the base quantity to wrap.min (
Union[AbstractQuantity,SearchStrategy[AbstractQuantity]]) – Minimum value of the wrapping range (inclusive).max (
Union[AbstractQuantity,SearchStrategy[AbstractQuantity]]) – Maximum value of the wrapping range (exclusive).
- Returns:
The wrapped quantity in the range [min, max).
- Return type:
unxt.AbstractQuantity
Examples
Wrap angles to 0-360 degree range:
>>> from hypothesis import given >>> import hypothesis.strategies as st >>> import unxt as u >>> import unxt_hypothesis as ust
>>> @given( ... angle=ust.wrap_to( ... ust.quantities("deg", quantity_cls=u.Angle), ... min=u.Q(0, "deg"), ... max=u.Q(360, "deg"), ... ) ... ) ... def test_wrapped_angle(angle): ... assert 0 <= angle.value <= 360
Wrap angles with dynamic min/max:
>>> @given( ... angle=ust.wrap_to( ... ust.quantities("rad", quantity_cls=u.Angle), ... min=st.just(u.Q(0, "rad")), ... max=st.just(u.Q(6.28318530718, "rad")), ... ) ... ) ... def test_wrapped_angle_rad(angle): ... assert 0 <= angle.value <= 6.28318530718
- unxt_hypothesis.angles(*, wrap_to: tuple[Quantity | SearchStrategy[Quantity], Quantity | SearchStrategy[Quantity]] | None | SearchStrategy[tuple[Quantity | SearchStrategy[Quantity], Quantity | SearchStrategy[Quantity]] | None] = None, **kwargs: Any)#
Strategy for generating Angle instances.
- Parameters:
draw – Hypothesis draw function. Automatically provided by hypothesis.
wrap_to (
Union[tuple[Union[Quantity,SearchStrategy[Quantity]],Union[Quantity,SearchStrategy[Quantity]]],None,SearchStrategy[tuple[Union[Quantity,SearchStrategy[Quantity]],Union[Quantity,SearchStrategy[Quantity]]] |None]]) – Strategy for generating (min, max) bounds for angle wrapping. If None, the angle will have no wrapping specified.**kwargs (
Any) – Additional keyword arguments passed to unxt_hypothesis.quantities. Common options include ‘dtype’, ‘shape’, ‘elements’, ‘unique’. The arguments ‘unit’ and ‘quantity_cls’ are set automatically and should not be provided.
- Returns:
A strategy that generates Angle instances.
- Return type:
unxt.Angle
Examples
>>> from hypothesis import given >>> from unxt_hypothesis import angles >>> import unxt as u
>>> @given(angle=angles()) ... def test_angle(angle): ... assert isinstance(angle, u.Angle)
With wrapping:
>>> from hypothesis import strategies as st >>> wrap_bounds = st.just((u.Q(0, "deg"), u.Q(360, "deg"))) >>> @given(angle=angles(wrap_to=wrap_bounds)) ... def test_wrapped_angle(angle): ... assert angle.wrap_to is not None
- unxt_hypothesis.named_dimensions()#
Generate a named dimension from Astropy’s physical type catalogue.
This strategy samples from a finalized, pre-computed set of 134 named physical dimensions derived from Astropy’s physical type system. These dimensions are guaranteed to be resolvable by unxt.dimension().
The set of dimension names is curated from Astropy’s physical types and excludes names that cannot be directly interpreted by unxt (e.g., names with parenthetical qualifiers like “electrical charge (EMU)”).
- Parameters:
draw (st.DrawFn) – Hypothesis draw function (automatically provided by @st.composite).
- Returns:
A randomly selected dimension from the set of named dimensions.
- Return type:
unxt.AbstractDimension
Examples
Basic usage - generate a dimension:
>>> from hypothesis import given >>> import unxt as u >>> import unxt_hypothesis as ust
>>> @given(dim=ust.named_dimensions()) ... def test_physics_dimension(dim): ... assert isinstance(dim, u.AbstractDimension)
Using with unit generation to create quantities of any dimension:
>>> @given( ... dim=ust.named_dimensions(), ... q=ust.quantities(u.dimension("length"), shape=3), ... ) ... def test_dimension_and_quantity(dim, q): ... # dim varies across test runs from 134 physical types ... assert isinstance(dim, u.AbstractDimension) ... assert q.shape == (3,)
Combine with units strategy:
>>> @given(unit=ust.units(ust.named_dimensions())) ... def test_any_unit(unit): ... # Generate units from any named physical dimension ... assert isinstance(unit, u.AbstractUnit) ... assert u.dimension_of(unit) in [ ... u.dimension(name) for name in ust.DIMENSION_NAMES ... ]
Property-based testing across all 134 physical types:
>>> @given(dim=ust.named_dimensions()) ... def test_all_dimensions_are_valid(dim): ... # This test will run with 100 different random dimensions ... # (by default, Hypothesis runs 100 examples) ... assert isinstance(dim, u.AbstractDimension) ... assert dim in {u.dimension(name) for name in ust.DIMENSION_NAMES}
See also
DIMENSION_NAMESThe tuple of all available dimension names.
unxt.dimensionCreate a dimension from a name string.
unitsGenerate units with a specific dimension.
quantitiesGenerate quantities with a specific dimension.