Metadata-Version: 2.4
Name: pyneedy
Version: 1.4.0
Summary: A minimal library for writing tests with optional dependencies.
Project-URL: Homepage, https://pytooling.gitlab.io/needy/
Project-URL: Repository, https://gitlab.com/pytooling/needy
Project-URL: Documentation, https://pytooling.gitlab.io/needy/
Project-URL: Bug Tracker, https://gitlab.com/pytooling/needy/-/issues
Project-URL: Changelog, https://gitlab.com/pytooling/needy/-/blob/main/CHANGELOG.md
Author-email: Zurab Mujirishvili <zurab.mu@gmail.com>
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown

<p align="center">
    <a href="https://pytooling.gitlab.io/needy/">
        <img src="./docs/assets/logo.svg" width="280" alt="Needy logo">
    </a>
</p>

[![CI](https://gitlab.com/pytooling/needy/badges/main/pipeline.svg)](https://gitlab.com/pytooling/needy/-/pipelines) [![Coverage](https://codecov.io/gl/pytooling/needy/graph/badge.svg)](https://codecov.io/gl/pytooling/needy) [![PyPI](https://img.shields.io/pypi/v/pyneedy)](https://pypi.org/project/pyneedy/) [![Python](https://img.shields.io/pypi/pyversions/pyneedy)](https://pypi.org/project/pyneedy/) [![License](https://img.shields.io/pypi/l/pyneedy)](https://gitlab.com/pytooling/needy/-/blob/main/LICENSE)

# Needy

A tiny library for writing tests that depend on optional packages, without having everything crash when a package you need is just not there…

## Installation

Python 3.11+ is required.

```bash
pip install pyneedy  # needy was already taken ( ╥_╥)
```

## Quick Start

Define a probe for the optional dependency you want to use, like JAX:

```python
def jax_module() -> None:
    import jax as jax
```

Then just mark the tests that need it with `@needs.to_run(...)`:

```python
from needy import needs


@needs.to_run(jax_module)
def test_that_uses_jax() -> None:
    import jax.numpy as jnp

    assert jnp.array([1.0, 2.0]).sum() == 3.0
```

If `jax` is installed, the test runs. If it isn't, the test is just skipped instead of crashing the whole suite. Yay!

For optional imports at the top of a file (which would normally fail at collection time), use `needs.modules(...)`. See the [docs](https://pytooling.gitlab.io/needy/) for more.

## Documentation

|                                                                                  |                                                             |
| -------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| [Getting started](https://pytooling.gitlab.io/needy/guides/getting-started/)     | The basics: probes and `@needs.to_run(...)`                 |
| [Optional imports](https://pytooling.gitlab.io/needy/guides/optional-imports/)   | Handle missing modules at import time with `needs.modules`  |
| [Subtests](https://pytooling.gitlab.io/needy/guides/subtests/)                   | Mix required and optional paths in one test                 |
| [API reference](https://pytooling.gitlab.io/needy/api/)                          | Every type and function in one place                        |

## Development

Prerequisites:

- Python >= 3.11
- [uv](https://docs.astral.sh/uv/) (recommended) or pip
- [just](https://github.com/casey/just) (optional, for convenience)

Get set up:

```bash
git clone https://gitlab.com/pytooling/needy.git
cd needy
uv sync
uv run pre-commit install
```

Run all checks (lint, format, type-check, tests):

```bash
just check
```

Or manually:

```bash
uv run ruff check --fix && uv run ruff format && uv run pyright && uv run pytest
```

## License

MIT, see [LICENSE](LICENSE).
