Skip to main content

Standard Rust core types implementations for Python.

Project description

sain

a dependency-free library which implements a set of minimal abstraction that brings Rust's ecosystem to Python. It offers a few of the core Rust features like Vec<T> and Result<T, E> and more. See the equivalent type section below.

This library provides a type-safe mechanism for writing Python code, such as the Result<T, E> and Option<T> types, which provides zero exception handling, where you simply return errors as values.

multiple core/std types are implemented in Python. Check the project documentation

Install

You'll need Python 3.10 or higher.

PyPI

pip install sain

Overview

Advanced examples in examples

no try/except

Exceptions suck, Result and Option is a much better way to avoid runtime exceptions.

from __future__ import annotations

from sain import Ok, Err
from sain import Some
from sain import Vec

import typing
from dataclasses import dataclass, field

if typing.TYPE_CHECKING:
    # These are just type aliases that have no cost at runtime.
    # __annotations__ needs to be imported.
    from sain import Result, Option


@dataclass
class Chunk:
    tag: str
    data: Option[bytes] = Some(None)


@dataclass
class BlobStore:
    buffer: Vec[Chunk] = field(default_factory=Vec)
    size: int = 1024

    def put(self, tag: str) -> Result[Chunk, str]:
        if self.buffer.len() >= self.size:
            # The return type of the error doesn't have to be a str.
            # its much better to have it an opaque type such as enums
            # or any data type with more context.
            return Err("Reached maximum capacity sry :3")

        chunk = Chunk(tag, Some(f"chunk.{tag}".encode("utf-8")))
        self.buffer.push(chunk)
        return Ok(chunk)

    def next_chunk(self, filtered: str = "") -> Option[Chunk]:
        # this code makes you feel right at home.
        return self
            .buffer
            .iter()
            .take_while(lambda chunk: filtered in chunk.tag)
            .next()


storage = BlobStore()
match storage.put("first"):
    case Ok(chunk):
        print(storage.next_chunk())
    case Err(why):
        print(why)

built-in types

name in Rust name in Python note restrictions
Option<T>, Some(T), None Option[T], Some(T), Some(None) Some(None) has the same layout as None in Rust
Result<T, E>, Ok(T), Err(E) Result[T, E], Ok(T), Err(E)
Vec<T> Vec[T]
Cell<T> Cell[T] this isn't an interior mutability type
RefCell<T> RefCell[T] this isn't an interior mutability type
LazyLock<T> Lazy[T]
OnceLock<T> Once[T]
Box<T> Box[T] this isn't a heap box, See
MaybeUninit<T> MaybeUninit[T] they serve the same purpose, but slightly different
Default Default[T]
&dyn Error Error
Iterator<T> Iterator[T]
Iter<'a, T> Iter[T] collections called by .iter are built from this type
iter::once::<T>() iter.once[T]
iter::empty::<T>() iter.empty[T]
iter::repeat::<T>() iter.repeat[T]
cfg!() cfg() runtime cfg, not all predictions are supported
#[cfg_attr] @cfg_attr() runtime cfg, not all predictions are supported
#[doc] @doc() the docs get generated at runtime
todo!() todo()
#[deprecated] @deprecated() will get removed when it get stabilized in warnings in Python 3.13
unimplemented!() @unimplemented()

Notes

Since Rust is a compiled language, Whatever predict in cfg and cfg_attr returns False will not compile.

But there's no such thing as this in Python, So RuntimeError will be raised and whatever was predicated will not run.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sain-1.1.0.tar.gz (42.9 kB view hashes)

Uploaded Source

Built Distribution

sain-1.1.0-py2.py3-none-any.whl (65.9 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page