Metadata-Version: 2.4
Name: acaster
Version: 1.0.1
Summary: Automatic type conversion library for Python
Author-email: Marc Benedi <marc@marcb.pro>
License: MIT License
        
        Copyright (c) 2026 Marc Benedí
        
        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.
        
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: loguru
Provides-Extra: all
Requires-Dist: torch; extra == "all"
Requires-Dist: numpy; extra == "all"
Requires-Dist: open3d; extra == "all"
Requires-Dist: omegaconf; extra == "all"
Provides-Extra: torch
Requires-Dist: torch; extra == "torch"
Requires-Dist: numpy; extra == "torch"
Provides-Extra: open3d
Requires-Dist: open3d; extra == "open3d"
Requires-Dist: numpy; extra == "open3d"
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

# autocast

[![GitHub](https://img.shields.io/badge/github-%23121011.svg?logo=github&logoColor=white)](https://github.com/marcbenedi/autocast)
[![PyPI version](https://badge.fury.io/py/acaster.svg)](https://badge.fury.io/py/acaster)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python Versions](https://img.shields.io/pypi/pyversions/acaster.svg)](https://pypi.org/project/acaster/)

**Automatic type conversion for Python.**

`autocast` is a lightweight library that automatically converts objects from one type to another using a graph of registered transformation functions. If a direct conversion isn't available, `autocast` finds the shortest path through intermediate types to get you the result you need.

It comes with built-in support for **NumPy**, **PyTorch**, **Open3D**, and **OmegaConf**, but it is designed to be easily extensible for your own classes.

## 📦 Installation

```bash
pip install acaster
```

To install with support for all optional backends (PyTorch, Open3D, etc.):

```bash
pip install "acaster[all]"
```

## 🚀 Quick Start

### Basic Usage

The core function is `acast(object, target_type)`.

```python
import torch
import numpy as np
from autocast import acast

# Create a Torch tensor
tensor = torch.ones((3, 3))

# Automatically convert to NumPy array
array = acast(tensor, np.ndarray)

print(type(array)) 
# <class 'numpy.ndarray'>
```

### Advanced Usage (Open3D)

Build an Open3D Point Cloud directly from PyTorch `tensors` or Numpy `arrays` without manually converting them to Open3D `Vector3dVector`:

```python
import open3d as o3d
import torch
from autocast import acast

H, W = 448, 448
rgb_image = torch.rand(H, W, 3) # H x W x 3
predicted_pts = torch.rand(H * W, 3) # H * W x 3 

# Cast a tuple of (points, colors) directly to a PointCloud
pcd = acast((predicted_pts, rgb_image), o3d.geometry.PointCloud)

print(type(pcd))
# <class 'open3d.cpu.pybind.geometry.PointCloud'> 

# o3d.io.write_point_cloud("output.ply", pcd)
```

### Recursive Collection Handling

`autocast` automatically handles nested lists and dictionaries.

```python
data = {
    "points": torch.rand(100, 3),
    "colors": torch.rand(100, 3),
    "meta": [torch.tensor(1.0), torch.tensor(2.0)]
}

# Convert everything inside the dict to NumPy arrays
numpy_data = acast(data, np.ndarray)

print(type(numpy_data['points'])) 
# <class 'numpy.ndarray'>
```

## 🛠 Features
- **Graph-Based Casting**: Uses Breadth-First Search (BFS) to find conversion paths. If you have `A -> B` and `B -> C`, autocast can do `A -> C` automatically.
- **Zero-Overhead Imports**: Backend modules (like `torch` or `open3d`) are only imported if they are installed in your environment.
- **Extensible**: Register your own types and conversion functions easily.

| From | To | Notes |
| :--- | :--- | :--- |
| `torch.Tensor` | `numpy.ndarray` | Zero-copy where possible |
| `numpy.ndarray` | `torch.Tensor` | |
| `list`/`tuple` | `np.ndarray` | |
| `open3d.geometry` | `numpy.ndarray` | Vector3dVector support |
| `omegaconf.ListConfig` | `list`/`dict` | Converts to native containers |

## 🧩 Extending autocast

You can register your own casts using the `add_acast` function or the `@acaster` decorator.

### Option 1: The Decorator

```python
from autocast import acaster, acast

class Cat:
    def speak(self): return "Meow"

class Dog:
    def speak(self): return "Woof"

# Register a function that converts Cat -> Dog
@acaster(Cat, Dog)
def cat_to_dog(cat_instance):
    return Dog()

my_cat = Cat()
my_dog = acast(my_cat, Dog)
```

### Option 2: Manual Registration

```python
from autocast import add_acast

def str_to_int(s):
    return int(s)

add_acast(str, int, str_to_int)

print(acast("123", int)) # 123
```

## 🤝 Contributing
We welcome contributions! If you want to add support for a new library (e.g., Pandas, Polars, JAX), please submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/new-cast`)
3. Commit your changes
4. Push to the branch
5. Open a Pull Request

To run the tests, install `pytests` and run `python -m pytest`.

### Publishing (Maintainers Only)

To release a new version of `acaster`:

1. Bump Version: Update `version = "x.y.z"` in `pyproject.toml`.
2. Tag Release:
```bash
git tag v0.x.y
git push origin --tags
```
3. Build & Upload:
```bash
rm -rf dist/
python -m build
twine upload dist/*
```

## 📄 License
Distributed under the MIT License. See [LICENSE](https://github.com/marcbenedi/autocast/blob/main/LICENSE) for more information.

## Acknowledgements

The idea for this library was inspired by [erezsh/autocast](https://github.com/erezsh/autocast).
