Metadata-Version: 2.4
Name: requireit
Version: 0.10.1
Summary: Tiny runtime validators for explicit precondition checks
Author-email: Eric Hutton <mcflugen@gmail.com>
Maintainer-email: Eric Hutton <mcflugen@gmail.com>
License-Expression: MIT
Project-URL: homepage, https://github.com/mcflugen/requireit
Project-URL: documentation, https://github.com/mcflugen/requireit/blob/main/README.md
Project-URL: repository, https://github.com/mcflugen/requireit
Project-URL: changelog, https://github.com/mcflugen/requireit/blob/main/CHANGES.md
Keywords: preconditions,runtime-checks,utilities,validation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE.md
Requires-Dist: numpy>=2.3
Provides-Extra: dev
Requires-Dist: nox; extra == "dev"
Dynamic: license-file

# requireit

**Tiny, numpy-aware runtime validators for explicit precondition checks.**

`requireit` provides a small collection of lightweight helper functions such as
`require_positive`, `require_between`, and `require_array` for validating values
and arrays at runtime.

It is intentionally minimal and dependency-light (*numpy* only).

## Why `requireit`?

* **Explicit** – reads clearly
* **numpy-aware** – works correctly with scalars *and* arrays
* **Fail-fast** – raises immediately with clear error messages
* **Lightweight** – just a bunch of small functions
* **Reusable** – avoids copy-pasted validation code across projects

```python
from requireit import require_one_of
from requireit import require_positive

require_positive(dt)
require_one_of(method, allowed={"foo", "bar"})
```

## Design principles

* Prefer small, single-purpose functions
* Raise standard exceptions (`ValidationError`)
* Never coerce or "fix" invalid inputs
* Validate *all* elements for array-like inputs
* Keep the public API small

## Non-goals

`requireit` is **not**:

* a schema or data-modeling system
* a replacement for static typing
* a validation framework
* a substitute for unit tests
* a coercion or parsing library

If you need structured validation, transformations, or user-facing error
aggregation, you probably want something heavier.

## Installation

```bash
pip install requireit
```

## API Summary

All validators:

* validate the first argument
* return the original value/array on success
* raise `ValidationError` on failure

### Arrays

* `require_array`: Validate an array to satisfy requirements.
* `require_dtype`: Validate that an array has a required dtype or can be safely cast to it.
* `require_like`: Validate that an array has the same shape and/or dtype as another.
* `require_ndim`: Validate that an array has a specific number of dimensions.
* `require_shape`: Validate that an array has the specified shape.
* `require_sorted`: Validate that an array is sorted.

### General

* `require_contains`: Require `collection` contains required values.
+ `require_instance`: Require `value` is an instance of one or more types.
* `require_none`: Require `value` is `None`.
* `require_not_none`: Require `value` is not `None`.
* `require_not_one_of`: Require `value` is not contained in `forbidden`
* `require_one_of`: Require `value` is contained in `allowed`

### Length

* `require_length`: Require `len(value) == length`
* `require_length_at_least`: Require `len(value) >= length`
* `require_length_at_most`: Require `len(value) <= length`
* `require_length_between`: Require `len(value)` falls within a specified range.

### Numeric

* `require_between`: Validate that a value lies within a specified interval.
* `require_greater_than`: Require `value > lower`
* `require_greater_than_or_equal`: Require `value >= lower`
* `require_less_than`: Require `value < upper`
* `require_less_than_or_equal`: Require `value <= upper`
* `require_negative`: Require `value < 0`
* `require_nonnegative`: Require `value >= 0`
* `require_nonpositive`: Require `value <= 0`
* `require_positive`: Require `value > 0`

### Paths

* `require_path_string`: Validate that a value is a string intended to be used as a path.

### Command-line integration

* `argparse_type`: Adapt a requireit validator for use as an argparse `type=` callable.

```python
import argparse
from requireit import argparse_type, require_positive


def parse_positive_int(value: str) -> int:
    return require_positive(int(value))


parser = argparse.ArgumentParser()
parser.add_argument("--count", type=argparse_type(parse_positive_int))
```

Converts `ValidationError` into `argparse.ArgumentTypeError`, allowing requireit
validators to produce clean command-line error messages.


## Errors

All validation failures raise:

```python
requireit.ValidationError
```

This allows callers to catch validation failures distinctly from other errors.
To adapt validation errors to another exception type, use `raise_as`:

```python
from requireit import raise_as
from requireit import require_positive

with raise_as(ValueError):
    require_positive(-1)
```

This raises:

```python
ValueError: value must be positive
```
Useful when integrating *requireit* into APIs that already expose a specific
exception type.

`raise_as` also accepts an optional `note`, attached to the raised exception
via [`add_note`](https://docs.python.org/3/library/exceptions.html#BaseException.add_note):

```python
with raise_as(ValueError, note="while parsing config.toml"):
    require_positive(-1)
```

To attach a note without changing the exception type, use `add_note` directly:

```python
from requireit import add_note

with add_note("while parsing config.toml"):
    require_positive(-1)
```

This still raises `ValidationError`, with the note included in the traceback.


## Contributing

This project is intentionally small.

Contributions should preserve:

* minimal surface area
* explicit semantics
* no additional dependencies

If a proposed change needs much explanation, it probably doesn’t belong here.

# Credits

## Development Leads

- [Eric Hutton](https://github.com/mcflugen)

# Release Notes


## 0.10.1 (2026-08-13)

## Fixes

* `require_between`, and the validators built on it (`require_positive`,
  `require_negative`, `require_nonnegative`, `require_nonpositive`,
  `require_greater_than`, `require_greater_than_or_equal`, `require_less_than`,
  and `require_less_than_or_equal`), now reject `nan` rather than silently
  treating it as satisfying the bound.
  [#56](https://github.com/mcflugen/requireit/issues/56)


## 0.10.0 (2026-07-28)

### Features

* Added `require_like` to validate that an array matches another array's shape
  and/or dtype. [#46](https://github.com/mcflugen/requireit/issues/46)
* Added `require_ndim` to validate that an array has a required number of dimensions.
  [#47](https://github.com/mcflugen/requireit/issues/47)
* Added `require_none` and `require_not_none` to validate that a value is,
  or is not, `None`. [#50](https://github.com/mcflugen/requireit/issues/50)
* Added `add_note` context manager to attach a note to a `RequireItError`
  raised within its block, and a `note` keyword to `raise_as` to do the same
  when converting a `ValidationError` to another exception type.
  [#51](https://github.com/mcflugen/requireit/issues/51)

### Changes

* Dropped support for Python 3.11.
  [#52](https://github.com/mcflugen/requireit/issues/52)


## Fixes

* Fixed `require_dtype` error messages for NumPy dtype families such as `np.floating`.
  [#45](https://github.com/mcflugen/requireit/issues/45)

### Tests

* Cleaned up the parametrized `require` tests by collecting the failing and
  passing cases into named `CHECKS_THAT_FAIL`/`CHECKS_THAT_PASS` dicts.
  [#49](https://github.com/mcflugen/requireit/issues/49)


## 0.9.0 (2026-04-23)

### Features

* Added `require_instance` to check that a value is an instance of a type.
  [#42](https://github.com/mcflugen/requireit/issues/42)

## Fixes

* Fixed CI test jobs so macOS runners use the Python version selected by
  `actions/setup-python`. [#43](https://github.com/mcflugen/requireit/issues/43)

## 0.8.0 (2026-04-14)

### Features

* Added `raise_as` context manager to re-raise `ValidationError` as a
  user-specified exception type. [#40](https://github.com/mcflugen/requireit/issues/40)

## 0.7.0 (2026-04-12)

### Features

* Added `require_sorted` to check that values are sorted in ascending order.
  [#35](https://github.com/mcflugen/requireit/issues/35)
* Added `require_dtype` to check that values have a given dtype or, optionally,
  can be safely cast to that dtype.
  [#36](https://github.com/mcflugen/requireit/issues/36)

### Changes

* Dropped support for Python 3.10.
  [#37](https://github.com/mcflugen/requireit/issues/37)

## 0.6.0 (2026-04-01)

### Features

* Allow the `dtype` keyword of `require_array` to accept *numpy* dtype families such as
  `np.integer` and `np.floating` in addition to exact dtypes.
  [#32](https://github.com/mcflugen/requireit/issues/32)

## 0.5.0 (2026-03-28)

### Features

* Extended ``require_array`` to allow flexible shape validation with support
  for wildcard dimensions (None or named axes).
  [#29](https://github.com/mcflugen/requireit/issues/29)

## 0.4.0 (2026-03-27)

### Features

* Added `require_greater_than`, `require_greater_than_or_equal`, and
  `require_less_than_or_equal` validators.
  [#26](https://github.com/mcflugen/requireit/issues/26)

## 0.3.0 (2026-03-23)

### Features

* Added `require_not_one_of` validator to ensure a value is not in a forbidden set
  [#15](https://github.com/mcflugen/requireit/issues/15)
* Added length validators to check that an object’s length is exactly, at most, or at least
  a given value [#16](https://github.com/mcflugen/requireit/issues/16)
* Added `require_length_between` validator to check that an object’s length is within
  a specified range [#19](https://github.com/mcflugen/requireit/issues/19)
* Added `require_contains` validator to ensure a collection contains required values
  [#21](https://github.com/mcflugen/requireit/issues/21)
* Added `import_package` validator to check for and import a package
  [#22](https://github.com/mcflugen/requireit/issues/22)
* Added `argparse_type` to allow *requireit* validators to be used as
  `argparse` `type=` callables
  [#17](https://github.com/mcflugen/requireit/issues/17)

### Changes

* Renamed length validators for consistency:
  `require_length_is` → `require_length`,
  `require_length_is_at_least` → `require_length_at_least`,
  `require_length_is_at_most` → `require_length_at_most`
  [#20](https://github.com/mcflugen/requireit/issues/20)

### Tests

* Added unit tests to verify that validators return the input value (not a copy)
  on success [#18](https://github.com/mcflugen/requireit/issues/18)


## 0.2.0 (2026-01-16)

- Standardized validation error messages [#8](https://github.com/mcflugen/requireit/issues/8)
- Renamed ``validate_array`` to ``require_array`` [#9](https://github.com/mcflugen/requireit/issues/9)
- Added optional ``name`` keyword to require functions to make error messages
  easier to read [#10](https://github.com/mcflugen/requireit/issues/10)
- Added new validator, ``require_path_string``, that checks if a value could be used
  as a file path [#11](https://github.com/mcflugen/requireit/issues/11)
- Added new validator, ``require_less_than``, that checks if one value is less than
  another [#12](https://github.com/mcflugen/requireit/issues/12)

## 0.1.0 (2026-01-12)

- Added documentation to the README [#1](https://github.com/mcflugen/requireit/issues/1)
- Added project metadata files [#2](https://github.com/mcflugen/requireit/issues/2)
- Added the `requireit` module [#3](https://github.com/mcflugen/requireit/issues/3)
- Added `pyproject.toml` file [#4](https://github.com/mcflugen/requireit/issues/4)
- Added `noxfile.py` file and linters [#5](https://github.com/mcflugen/requireit/issues/5)
- Added unit tests for `requireit` [#6](https://github.com/mcflugen/requireit/issues/6)
- Added GitHub Actions for CI [#7](https://github.com/mcflugen/requireit/issues/7)
