Metadata-Version: 2.4
Name: typesentinel
Version: 0.2.3
Summary: Runtime type checking decorators with sync and async support.
Project-URL: Homepage, https://github.com/grayjou/typesentinel
Project-URL: Repository, https://github.com/grayjou/typesentinel
Author: GrayJou
License: MIT License
        
        Copyright (c) 2025 GrayJou
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: decorators,runtime,type-checking,typing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown


# typesentinel
<p align="center">
  <img src="https://raw.githubusercontent.com/Grayjou/typesentinel/refs/heads/main/logo.png" alt="typesentinel" width="160" />
</p>

**typesentinel** is a lightweight, dependency-free library for **runtime type checking**
of Python function arguments. It supports both synchronous and asynchronous functions,
Union types, custom failure handlers, and signature-aware error messages.

```bash
pip install typesentinel
````

---

## 🧠 Why `typesentinel`?

Other libraries like Pydantic, Beartype, Enforce, or typeguard offer runtime validation,
but often come with heavy dependencies, global monkey-patching, performance costs, or
complicated configuration.

`typesentinel` focuses on **one thing** and does it well:

* ✔ **Minimal** — zero dependencies, tiny footprint
* ✔ **Explicit** — works only where you decorate; never global
* ✔ **Async-friendly** — supports async functions & async failure handlers
* ✔ **Precise errors** — error messages include the real parameter names
* ✔ **Flexible** — annotations, shorthand, or explicit `TypeCheck` objects
* ✔ **Safe** — never mutates your function’s signature or typing info

If you want simple, predictable runtime validation with no overhead,
**typesentinel is built for you.**

---

## 🚀 Quick Start

### Type checking from function annotations

```python
from typesentinel.decorator import type_check

@type_check
def greet(name: str, excited: bool = False):
    return f"Hello, {name}{'!' if excited else ''}"

greet("Alice")       # OK
greet(123)           # ❌ Invalid type for argument 'name': expected str, got int
```

### Shorthand keyword type checks

```python
@type_check(name=str, times=int)
async def repeat(name, times):
    return ", ".join(name for _ in range(times))
```

---

## 🔍 Union Type Support

```python
from typing import Union

@type_check(a=Union[int, str])
def fn(a):
    return a

@type_check(a=int | str)
def fn(a):
    return a
```

Error message:

```
Invalid type for argument 'a': expected int | str, got float
```

---

## 🛠 Custom Failure Handling

```python
from typesentinel.decorator import type_check
from typesentinel.type_check import TypeCheckResult

async def capture(*fails: TypeCheckResult):
    raise ValueError("validation failed")

@type_check(a=int, on_failure=capture)
async def double(a):
    return a * 2
```

---

## 🧩 Explicit TypeCheck Objects

```python
from typesentinel.decorator import type_check
from typesentinel.type_check import TypeCheck, ArgKind

checks = [
    TypeCheck(0, int, ArgKind.POSITIONAL),
    TypeCheck("label", str, ArgKind.KEYWORD, message="label must be a string"),
]

@type_check(checks)
def render(value, *, label):
    return f"{label}: {value}"
```

---

## 🧪 Testing

```bash
python -m pytest
```

---

## 📄 License

MIT License. See `LICENSE` for details.

```

---
