pydantic_sweep

Submodules

Attributes

__version__

Classes

BaseModel

Base model with validation enabled by default.

DefaultValue

Indicator class for a default value in the field method.

Functions

check_model(→ None)

Best-effort check that the model has the correct configuration.

check_unique(→ bool)

Check that models are unique.

config_chain(→ list[pydantic_sweep.types.Config])

Chain configuration dictionaries behind each other.

config_combine(→ list[pydantic_sweep.types.Config])

Flexible combination of configuration dictionaries.

config_product(→ list[pydantic_sweep.types.Config])

A product of existing configuration dictionaries.

config_roundrobin(→ list[pydantic_sweep.types.Config])

Interleave the configuration dictionaries.

config_zip(→ list[pydantic_sweep.types.Config])

Return the zip-combination of configuration dictionaries.

field(→ list[pydantic_sweep.types.Config])

Assign various values to a field in a pydantic Model.

initialize(…)

Instantiate the models with the given parameters.

model_replace(→ pydantic_sweep.types.BaseModelT)

Create a copy of the pydantic model with nested value replacement.

model_diff(→ dict[str, Any])

Return a nested dictionary of model diffs.

as_hashable(→ collections.abc.Hashable)

Convert input into a unique, hashable representation.

random_seeds(→ list[int])

Generate unique random values within a certain range.

Package Contents

class pydantic_sweep.BaseModel(/, **data: Any)[source]

Bases: pydantic.BaseModel

Base model with validation enabled by default.

class pydantic_sweep.DefaultValue[source]

Indicator class for a default value in the field method.

classmethod __init_subclass__(**kwargs: Any) None[source]
pydantic_sweep.check_model(model: pydantic.BaseModel | type[pydantic.BaseModel], /, *, unhashable: Literal['warn', 'ignore', 'raise'] = 'warn') None[source]

Best-effort check that the model has the correct configuration.

This recurses into the models, but there’s probably a way to achieve a false positive if one tries.

Parameters:
  • model – The model to check.

  • unhashable – The action to take when a non-hashable type hint is encountered in the mode.

pydantic_sweep.check_unique(*models_: pydantic_sweep.types.Config | pydantic.BaseModel | collections.abc.Iterable[pydantic_sweep.types.Config | pydantic.BaseModel], raise_exception: bool = True) bool[source]

Check that models are unique.

Parameters:
  • *models_ – Iterables of models to check for uniqueness. If multiple are passed, they are chained together and jointly checked.

  • raise_exception – If False, return a boolean instead of raising an exception on failure.

Raises:

ValueError – If models are not unique.

pydantic_sweep.config_chain(*configs: collections.abc.Iterable[pydantic_sweep.types.Config]) list[pydantic_sweep.types.Config][source]

Chain configuration dictionaries behind each other.

>>> config_chain(field("a", [1, 2]), field("b", [3, 4]))
[{'a': 1}, {'a': 2}, {'b': 3}, {'b': 4}]
pydantic_sweep.config_combine(*configs: collections.abc.Iterable[pydantic_sweep.types.Config], combiner: pydantic_sweep.types.Combiner | None = None, chainer: pydantic_sweep.types.Chainer | None = None) list[pydantic_sweep.types.Config][source]

Flexible combination of configuration dictionaries.

In contrast to the more specific functions below, this allows you to flexibly use existing functions from itertools in order to create new combiners. All existing combiners build on top of this function.

The output of this function is a valid input to both itself and other combiner functions.

Parameters:
  • configs – The configurations we want to combine.

  • combiner – A function that takes as input multiple iterables and yields tuples. For example: itertools.product.

  • chainer – A function that takes as input multiple iterables and yields a single new iterable. For example: itertools.chain.

Returns:

list[Config] – A list of new configuration objects after combining or chaining.

pydantic_sweep.config_product(*configs: collections.abc.Iterable[pydantic_sweep.types.Config]) list[pydantic_sweep.types.Config][source]

A product of existing configuration dictionaries.

This is the most common way of constructing searches. It constructs the product of the inputs.

>>> config_product(field("a", [1, 2]), field("b", [3, 4]))
[{'a': 1, 'b': 3}, {'a': 1, 'b': 4}, {'a': 2, 'b': 3}, {'a': 2, 'b': 4}]

The output of this function is a valid input to both itself and other combiner functions.

pydantic_sweep.config_roundrobin(*configs: collections.abc.Iterable[pydantic_sweep.types.Config]) list[pydantic_sweep.types.Config][source]

Interleave the configuration dictionaries.

This is the same behavior as config_chain, but instead of chaining them behind each other, takes from the different iterables in turn.

>>> config_roundrobin(field("a", [1, 2, 3]), field("b", [3, 4]))
[{'a': 1}, {'b': 3}, {'a': 2}, {'b': 4}, {'a': 3}]
pydantic_sweep.config_zip(*configs: collections.abc.Iterable[pydantic_sweep.types.Config]) list[pydantic_sweep.types.Config][source]

Return the zip-combination of configuration dictionaries.

>>> config_zip(field("a", [1, 2]), field("b", [3, 4]))
[{'a': 1, 'b': 3}, {'a': 2, 'b': 4}]
pydantic_sweep.field(path: pydantic_sweep.types.Path, /, values: collections.abc.Iterable[pydantic_sweep.types.FieldValue], *, check: bool = True) list[pydantic_sweep.types.Config][source]

Assign various values to a field in a pydantic Model.

Parameters:
  • path – The path to the key in the model. Can either be a dot-separated string of keys (e.g., my.key) or a tuple of keys (e.g., ('my', 'key').

  • values – The different values that should be assigned to the field. Note that the DefaultValue class has a special meaning, since it will be effectively ignored, allowing it to be kept to the default model.

  • check – If True, check that values are indeed hashable or pydantic Models.

Returns:

list[Config] – A list of partial configuration dictionaries that can be passed to the pydantic model.

Examples

>>> import pydantic_sweep as ps
>>> class Sub(ps.BaseModel):
...     x: int = 5
...     y: int = 6
>>> class Model(ps.BaseModel):
...     sub: Sub
...     seed: int = 5
>>> _ = Model.model_rebuild()
>>> configs = ps.field("sub.x", [10, 20])
>>> ps.initialize(Model, configs)
[Model(sub=Sub(x=10, y=6), seed=5), Model(sub=Sub(x=20, y=6), seed=5)]
pydantic_sweep.initialize(model: type[pydantic_sweep.types.BaseModelT], configs: collections.abc.Iterable[pydantic_sweep.types.Config], *, constant: pydantic_sweep.types.FlexibleConfig | None = None, default: pydantic_sweep.types.FlexibleConfig | None = None, to: pydantic_sweep.types.Path, at: pydantic_sweep.types.Path | None = None, check: bool = True) list[pydantic_sweep.types.Config][source]
pydantic_sweep.initialize(model: type[pydantic_sweep.types.BaseModelT], configs: collections.abc.Iterable[pydantic_sweep.types.Config], *, constant: pydantic_sweep.types.FlexibleConfig | None = None, default: pydantic_sweep.types.FlexibleConfig | None = None, to: pydantic_sweep.types.Path | None = None, at: pydantic_sweep.types.Path, check: bool = True) list[pydantic_sweep.types.Config]
pydantic_sweep.initialize(model: type[pydantic_sweep.types.BaseModelT], configs: collections.abc.Iterable[pydantic_sweep.types.Config], *, constant: pydantic_sweep.types.FlexibleConfig | None = None, default: pydantic_sweep.types.FlexibleConfig | None = None, to: None = None, at: None = None, check: bool = True) list[pydantic_sweep.types.BaseModelT]

Instantiate the models with the given parameters.

Parameters:
  • model – The pydantic model that we want to finalize. This can be either a model cass or an instance of a specific model. In both cases, the configuration is checked for safety and the models are instantiated.

  • configs – The partial config dictionaries that we want to initialize with pydantic.

  • constant – Constant values that should be initialized for all models. These are safely merged with the parameters. Can be either a nested, or a flattened dictionary.

  • default – Default parameter that are initialized for all models, but may be overwritten by other fields without any error checking. Can be either a nested or a flattened dictionary.

  • to – If provided, will first initialize the model and then return a configuration dictionary that sets the model as the values at the given path. Essentially a shortcut to first passing the models to field(to, models).

  • at – If provided, will initialize the model at the given path in the configuration.

  • check – Whether to apply error checks to model.

pydantic_sweep.model_replace(model: pydantic_sweep.types.BaseModelT, *, values: pydantic_sweep.types.FlexibleConfig) pydantic_sweep.types.BaseModelT[source]

Create a copy of the pydantic model with nested value replacement.

Parameters:
  • model – The pydantic model to replace the fields in.

  • values – A dictionary of fields to overwrite in the model. This can be either a nested dictionary or a flat dictionary. A DefaultValue in the dictionary means that the field will take the default value from the base model.

Returns:

A new instance of the model with the fields replaced.

pydantic_sweep.model_diff(m1: Any, m2: Any, /, *, compare: collections.abc.Callable[[Any, Any], bool] = operator.eq) dict[str, Any][source]

Return a nested dictionary of model diffs.

That is, given two models this function iterates over all nested sub-model fields and returns a nested dictionaries with leaf values that are tuples of the corresponding value of the left model, and the value of the right model.

Parameters:
  • m1 – The first model, or nested structure.

  • m2 – The second model, or nested structure

  • compare – Function to compare two elements, returns True if they are equal.

Examples

>>> class Sub(pydantic.BaseModel):
...     x: int = 0
>>> class Model(pydantic.BaseModel):
...     s: Sub = Sub()
...     y: int = 2
>>> model_diff(Model(s=Sub(x=1)), Model(s=Sub(x=2)))
{'s': {'x': (1, 2)}}
>>> model_diff(Model(), Model())
{}
pydantic_sweep.as_hashable(item: Any, /) collections.abc.Hashable[source]

Convert input into a unique, hashable representation.

In addition to the builtin hashable types, this also works for dictionaries and pydantic Models (recursively). Sets and lists are also supported, but not dealt with recursively.

Parameters:

item – The item that we want to convert to something hashable.

Returns:

Hashable – A hashable representation of the item.

pydantic_sweep.random_seeds(num: int, *, upper: int = 1000) list[int][source]

Generate unique random values within a certain range.

This is useful in scenarios where we don’t want to hard-code a random seed, but also need reproducibility by setting a seed. Sampling the random seed is a good compromise there.

Parameters:
  • num – The number of random seeds to generate.

  • upper – A non-inclusive upper bound on the maximum seed to generate.

Returns:

list[int] – A list of integer seeds.

pydantic_sweep.__version__[source]