Metadata-Version: 2.5
Name: tenspec
Version: 0.1.0
Summary: Tensor specifications that a function, a model, or a direct call checks at its boundary.
Project-URL: Source, https://github.com/egordm/tenspec
Project-URL: Documentation, https://egordm.github.io/tenspec/
Project-URL: Issues, https://github.com/egordm/tenspec/issues
Author: Egor Dmitriev
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.13
Requires-Dist: pydantic<3,>=2.13.4
Requires-Dist: typing-extensions>=4.13
Provides-Extra: dev
Requires-Dist: numpy>=2.1; (python_version < '3.14') and extra == 'dev'
Requires-Dist: numpy>=2.3.2; (python_version >= '3.14') and extra == 'dev'
Requires-Dist: poethepoet>=0.30; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Requires-Dist: torch>=2.6; (python_version < '3.14') and extra == 'dev'
Requires-Dist: torch>=2.9; (python_version >= '3.14') and extra == 'dev'
Requires-Dist: ty>=0.0.78; extra == 'dev'
Provides-Extra: numpy
Requires-Dist: numpy>=2.1; (python_version < '3.14') and extra == 'numpy'
Requires-Dist: numpy>=2.3.2; (python_version >= '3.14') and extra == 'numpy'
Provides-Extra: torch
Requires-Dist: torch>=2.6; (python_version < '3.14') and extra == 'torch'
Requires-Dist: torch>=2.9; (python_version >= '3.14') and extra == 'torch'
Description-Content-Type: text/markdown

# tenspec

Declare what an array must be, beside the value it describes, and check it at one boundary.

Tenspec moves the shape and dtype checks from the top of a function into its signature, where a
reader and a type checker both see them. It accepts or refuses the array the caller passed. It
converts nothing, moves nothing, and copies nothing, unless the declaration names a transform
that copies.

This is an early release, at version 0.1.0. The interface can change before version 1.0.

## Install

Install it with pip, or with uv. Either one is enough, so run the line for the tool you use:

```bash
pip install "tenspec[numpy]"   # or: uv add "tenspec[numpy]"
```

Name the array library you need as an extra: `numpy` or `torch`. `import tenspec` loads neither
one. It needs Python 3.13 or newer.

## What it gives you

- **Ordinary types.** A declaration is an ordinary annotation carrying your backend's array
  type, so a type checker reads it and untouched code still runs. The checkers, the settings
  they need and their measured limits are on
  [Type checkers and Ruff](https://egordm.github.io/tenspec/type-checkers.html).
- **Pydantic boundaries, natively.** `TensorContracts` relates the fields of your own model
  inside one model validation.
- **Runtime checks are opt in.** An annotation alone performs no runtime work.
- **Transforms are explicit.** A value changes only when a declaration names a transform, and
  the runtime verifies the result kept its class, shape, native dtype and device.

## The three entry points

| Entry point | Use it for |
|---|---|
| `@checked` | a function or a method, with its arguments and its return |
| `TensorContracts` | a Pydantic model, whose related fields share one boundary |
| `validate(value, annotation)` | one value, or one tuple of related values |

```python
from typing import Literal as Shape

import numpy as np

from tenspec import checked
from tenspec.numpy import Float


@checked
def weigh_columns(
    values: Float[Shape["rows features"]], weights: Float[Shape["features"]]
) -> Float[Shape["rows features"]]:
    return values * weights


print(weigh_columns(np.ones((3, 4)), np.array([1.0, 2.0, 3.0, 4.0])).shape)
```

`weights` must cover as many features as `values` has columns. A disagreement is a run-time
refusal naming the axis, both extents, and the bindings the boundary held.

No type checker compares two shapes. A shape that disagrees is a run-time refusal, never a
static error.

## Documentation

[The documentation site](https://egordm.github.io/tenspec/) holds the guide, the API reference
and two executed tutorials. The
[repository](https://github.com/egordm/tenspec) holds the source.

## Attribution

The shape notation follows [jaxtyping](https://github.com/patrick-kidger/jaxtyping), which is
MIT licensed. jaxtyping is not a dependency of this package.

## License

MIT. See `LICENSE`.
