Skip to main content

Generate Python .pyi stub files from pyo3-annotated Rust source code statically without compilation

Project description

Rylai

CI

Generate Python .pyi stub files from pyo3-annotated Rust source code — statically, without compilation.

Features

  • Parses #[pymodule], #[pyfunction], and #[pyclass] annotations directly from Rust source
  • Maps Rust types to Python types automatically (i32int, Vec<T>list[T] or t.List[T] depending on python_version, Option<T>T | None or t.Optional[T], etc.)
  • Extracts doc comments and emits them as Python docstrings
  • Generates one .pyi file per top-level #[pymodule]; when classes use #[pyclass(module = "...")], emits additional sibling .pyi files under -o (first module segment is implicit) so type checkers and runtime __module__ agree
  • Python-version-aware output (T | None for ≥ 3.10, t.Optional[T] for older; PEP 585 built-in generics list[T] / dict[...] / … for ≥ 3.9, t.List / t.Dict / … for 3.8; t.Self for ≥ 3.11; stubs always include import typing as t for consistent [[add_content]] placement)
  • Generates __all__ in every stub listing public top-level exports; names starting with _ are excluded by default; configurable globally and per file via [[all]]
  • Parses create_exception! / pyo3::create_exception!(module, Name, Base) (PyO3 custom exceptions): emits matching class Name(Base): ... stubs in the pymodule file; the first macro argument must be the pymodule’s Python-visible name (#[pymodule(name = "...")], #[pyo3(name = "...")], or the Rust identifier). Builtin pyo3::exceptions::Py* bases map to stdlib exception names; chaining another create_exception! type uses that class name as the base
  • Optional [[add_content]]: inject extra Python (e.g. version branches, shared type aliases) into specific generated .pyi files by path under -o; use location = "file" to create standalone .pyi files that don't correspond to any Rust module
  • Optional [[macro_expand]]: expand configured macro_rules! invocations before AST parsing so wrapped add_class / add_function calls can be collected
  • Zero-config by default; optionally configured via rylai.toml

Why Rylai?

Compared with other tools that generate .pyi stubs for PyO3 projects, Rylai offers:

  • No compilation — Rylai parses Rust source code directly (via syn). You don’t need to build the crate or depend on compiled artifacts, so stub generation is fast and works even when the project doesn’t compile (e.g. missing native deps or wrong toolchain).
  • No code changes — No need to add build scripts, #[cfg] blocks, or extra annotations to your Rust code. Point Rylai at your crate root and it reads existing #[pymodule] / #[pyfunction] / #[pyclass] and create_exception! macros as-is.
  • No Python version lock-in — Stubs are plain text. You generate them once and use them with any Python version; there’s no dependency on a specific Python interpreter or ABI, so you avoid “built for Python 3.x” issues and cross-version workflows stay simple.

Together, this makes Rylai easy to integrate into CI, docs, or local dev without touching your PyO3 code or your Python environment.

Installation

Choose one of the following:

Method Command Notes
Cargo cargo install rylai Build from source and install to ~/.cargo/bin
uv uv tool install rylai Install to uv tools dir; requires publish to PyPI first
uvx uvx rylai Run without installing (same as uv; requires PyPI release)
crgx crgx rylai Run pre-built binary without compiling; requires crgx and a GitHub Release

For local development:

cargo install --path .

Usage

The path you pass is the project root — the folder that contains Cargo.toml (and usually a src/ directory). Rylai scans all .rs files under that project’s src/ and uses the root for rylai.toml, pyproject.toml, etc.

# Run in the current directory (must be the project root with Cargo.toml)
rylai

# Specify the project root explicitly (folder containing Cargo.toml)
rylai path/to/my_crate

# Write stubs to a custom output directory
rylai path/to/my_crate --output path/to/out/

# Use a custom config file
rylai --config path/to/rylai.toml

For developers (this repo)

You don’t need to install the binary. Use cargo run and pass arguments after --:

# Run on a single example
cargo run -- examples/basic_function_sample --output examples/basic_function_sample/python/basic_function_sample

# Show help
cargo run -- --help

Anything after -- is forwarded to the rylai binary.

Examples

The examples/ directory contains several self-contained sample projects, each demonstrating different Rylai features:

Example What it demonstrates
add_content_sample [[add_content]] with tail location and location = "file" to create standalone .pyi files
basic_function_sample #[pyfunction], #[pyo3(name = "...")] rename, #[pyclass], create_exception!
cross_module_sample #[pyclass(module = "...")] with cross-module imports, [[add_content]]
override_sample [[override]] via stub and via param_types / return_type, [[add_content]]
macro_expand_sample [[macro_expand]] auto-discover and explicit modes

Regenerating all example stubs

Install just, then run:

just gen-pyi-examples

This regenerates .pyi files for every example. CI checks that the committed stubs match the generated output; if they differ, CI fails.

Multi-module stubs (#[pyclass(module = "...")])

If you annotate a class with PyO3’s module attribute, e.g. #[pyclass(module = "abcd.efg")], Rylai will emit multiple .pyi files instead of a single flat stub. -o is treated as the first segment of the Python module path (the top-level #[pymodule] name). So for -o stubs/ and pymodule abcd, submodule abcd.efg is written to stubs/efg.pyi, not stubs/abcd/efg.pyi. The root stub is stubs/abcd.pyi. Only deeper paths add folders after that first segment (e.g. abcd.abcd.ffabcd/ff.pyi under -o; abcd.abcd.abcd.ggabcd/abcd/gg.pyi). If #[pyclass(module = "pkg.pkg")] resolves to the same file as the root stub (pkg.pyi), those classes are merged into pkg.pyi. If no class has module set, behavior is unchanged: one {name}.pyi per top-level #[pymodule]. If everything is routed to submodules so the root stub would be empty, Rylai still writes abcd.pyi (possibly empty, but still carrying the pymodule docstring when present).

When #[pyclass(module = "...")] does not start with {pymodule}. (for example pymodule _pkg and module = "pkg.abc"), the extension name and the public Python package can differ: Rylai still collects items from that #[pymodule], but emits those classes by dropping the first dotted segment of module (the public top-level package) and mirroring the rest under -o — e.g. stubs/abc.pyi, or stubs/cba/foo.pyi for pkg.cba.foo. #[pyfunction] and classes without module stay in {pymodule}.pyi (e.g. stubs/_pkg.pyi).

When using --output / -o, you can point either at a parent directory (e.g. stubs/stubs/abcd.pyi and stubs/efg.pyi) or directly at the package directory whose name matches the top-level #[pymodule] (e.g. -o python/abcdpython/abcd/abcd.pyi and python/abcd/efg.pyi). If two different layout paths still resolve to the same output file, Rylai reports a duplicate-path error; point -o at a parent directory so distinct stubs land on different paths.

Runtime __module__ for pyfunction / m.add may follow Maturin’s module-name (e.g. abcd.abcd), but Rylai still emits those symbols into the top-level #[pymodule] stub (abcd.pyi) together with any #[pyclass] that has no module = "..." attribute. Only classes with an explicit #[pyclass(module = "...")] are written to the matching submodule stub.

When a stub references a #[pyclass] type that is emitted in another submodule (e.g. a return type uses a class defined under abcd.ff while generating ee.pyi), Rylai prepends absolute imports such as from abcd.ff import SomeClass (after typing / pathlib imports) so Pyright and mypy can resolve the name.

Configuration

You can configure rylai in either (or both) of these places:

  • rylai.toml in the crate root
  • [tool.rylai] in pyproject.toml

When both exist, duplicate keys are resolved in favor of rylai.toml; all other options from both files apply. Array tables (e.g. [[override]], [[add_content]], [[all]], [[macro_expand]], and their [[tool.rylai.*]] forms) are replaced as a whole by the same key in rylai.toml, not merged item-by-item. All sections are optional.

Example rylai.toml:

# Root-level keys (e.g. format) should appear before any [section] or [[array]] to avoid being parsed as part of a table.
# After generating .pyi files, run these commands with the generated .pyi paths appended.
# Only use when you trust this config file — commands are executed as configured.
# Each command must be executable (on PATH or use a full path); rylai will error if it cannot be run.
# Empty or whitespace-only entries are ignored.
# You may need "uvx ruff" or "uv/pdm run ruff" instead of "ruff"
format = ["ruff format", "ruff check --select I --fix"]

[output]
# Target Python version — affects t.Optional[T] vs T | None (3.10+), PEP 585 list[T] vs t.List (3.9+),
# t.Self vs class name (3.11+), and related stub output (default: "3.10")
python_version = "3.10"

# Prepend auto-generated header comment (default: true)
add_header = true

# Include names that start with `_` (private / dunder) in __all__ (default: false).
# Can be overridden per file with [[all]].
all_include_private = false

[fallback]
# What to emit when a type cannot be resolved statically:
#   "any"   — emit t.Any and print a warning (default)
#   "error" — abort with an error
#   "skip"  — silently omit the item
strategy = "any"

[features]
# cfg features to treat as active during parsing
enabled = ["some_feature"]

[type_map]
# Custom Rust type → Python type overrides
"numpy::PyReadonlyArray1" = "numpy.ndarray"
"numpy::PyReadonlyArray2" = "numpy.ndarray"
# Limitations (read this if a mapping seems ignored):
# - Keys must be Rust *path* types: a single identifier (e.g. PyBbox, PyColor) or a qualified path
#   (e.g. crate::types::MyHandle). Rylai derives the lookup key from path segments only.
# - Anonymous tuple types written in source, e.g. (u8, u8, u8, u8), are *not* path types and
#   cannot appear as keys. They are always stubbed as tuple[...] (or t.Tuple[...] when python_version
#   is below 3.9) from their elements. To emit a
#   single Python name (e.g. PyColor), define `type PyColor = (u8, u8, u8, u8);`, use `PyColor` in
#   signatures and fields, then add "PyColor" = "Color" under [type_map].
# - If a Rust `type` alias is listed here, Rylai keeps that alias name when generating stubs
#   (instead of expanding it), so nested uses like Vec<ThatAlias> still resolve to your Python type.
# - If two keys share the same last path segment but map to different Python types, Rylai warns on
#   stderr, omits the ambiguous short-name lookup, and does not preserve that alias name during
#   expansion (use a single consistent target or disambiguate with a bare key only when unique).

# Optional: expand custom macro_rules invocations before syn parsing.
# Use this when pyo3 registration calls are wrapped in declarative macros.
#
# Mode A: explicit matcher/transcriber (macro-rules-rt Rule::new)
[[macro_expand]]
name = "add_pymodule"
from = '$py:expr, $parent:expr, $name:expr, [$($cls:ty),* $(,)?]'
to = '{ let sub = pyo3::types::PyModule::new($py, $name)?; $(sub.add_class::<$cls>()?;)* $parent.add_submodule(&sub)?; Ok::<_, pyo3::PyErr>(()) }'
#
# Mode B: auto-discover macro_rules! definition from Rust source by name
[[macro_expand]]
name = "register_classes"
# Mode B is best-effort; duplicate macro names across files use the first match (warning). Unparsable
# .rs files are skipped when searching for the definition (warning).

[[override]]
# Single-line def/class header for a top-level item (Rust `///` doc is copied into the .pyi when present).
# You do not need a trailing `...`; Rylai adds `    ...` as the body when there is no Rust doc.
# For `#[pyfunction]`, the last segment of `item` may be the Python-exposed name *or* the Rust `fn` ident
# (they differ when `#[pyo3(name = "...")]` is set), e.g. `tablers::get_intersections_from_edges` or
# `tablers::py_get_intersections_from_edges` for the same export.
item = "my_module::complex_function"
stub = "def complex_function(x: t.Any, **kwargs: t.Any) -> dict[str, t.Any]:"

# #[pyclass] / #[pymethods] methods: same `[[override]]` mechanism as top-level items.
# `item` is `{logical_module}::{class}::{method}` — instance methods, @staticmethod, @classmethod,
# @property / setter, and #[new] when you want a custom __init__ line in the .pyi.
#
# `logical_module` (first segment) is the **Python module for the .pyi file where that class is
# emitted**, not “always the #[pymodule] name”. It matches how Rylai splits output:
#   - Classes without #[pyclass(module = "...")] (and all module-level functions/constants) use the
#     top-level #[pymodule] name, e.g. `pkg` for `pkg.pyi`.
#   - A class with #[pyclass(module = "pkg.abc")] is emitted into that submodule’s stub; use the
#     **exact** `module = "..."` string as the first segment, e.g. `pkg.abc::MyClass::method`,
#     not `pkg::...` (unless layout merges that stub into the root file — then the root module name
#     applies).
# `class` may be the Rust struct name or the Python #[pyclass(name = "...")] name. `method` is the
# Rust fn ident or #[pyo3(name = "...")]. For #[new], Rylai already emits `def __init__(...)`;
# override when you need a different signature (e.g. **kwargs: Unpack[...]). You may match with
# `...::__init__` as the method segment for #[new] only.
# Suffix form: `item` may end with `::Class::method` (no bare method name — ambiguous).
[[override]]
item = "my_module::Widget::reload"
stub = "def reload(self, force: bool = False) -> None:"

# Instead of `stub`, you may set `param_types` and/or `return_type` (mutually exclusive with `stub`).
# `param_types`: table mapping parameter names → full annotation after `:`. `return_type`: one string
# for the whole return annotation. Rylai still builds `def ...` from Rust and `#[pyo3(signature)]`;
# parameter types come from Rust except where listed in `param_types`; return type from Rust unless
# `return_type` is set. Keys use the bare name (`kwargs` / `**kwargs` normalized the same). Only for
# module-level functions and class methods. Unused `param_types` keys → warning. `#[new]` / setters
# still emit `-> None` in stubs; `return_type` applies to other methods and to module functions.
# [[override]]
# item = "my_module::f"
# param_types = { "**kwargs" = "Unpack[KwargsItems]" }
# return_type = "dict[str, t.Any]"

# Optional: per-file __all__ rules (path is relative to -o, use /, same convention as add_content).
# Multiple [[all]] entries for the same file are merged (include/exclude sets are unioned;
# the last matching include_private wins).
[[all]]
file = "my_package.pyi"
# Override the global all_include_private for this file only (optional).
include_private = true
# Force these already-emitted top-level names into __all__ even if they start with `_` (optional).
include = ["_special_export"]
# Always remove these names from __all__ — highest priority, beats include (optional).
exclude = ["InternalHelper"]

# Optional: splice raw Python into a generated file (path is relative to -o, use /).
# For head / after-import-typing / tail: file must match a stub generated in this run.
[[add_content]]
file = "my_package/sub.pyi"
location = "after-import-typing" # head | tail | after-import-typing | file
content = """
from my_package._internal import KwargsItems
"""

# Create a standalone .pyi that doesn't correspond to any Rust module.
# location = "file" writes content as-is (no banner or typing import added).
# The file is created if it doesn't exist, or replaces the generated stub if it does (with a warning).
# Only one [[add_content]] entry per file is allowed when location = "file".
# Content is written verbatim — write version-compatible Python for your target.
[[add_content]]
file = "extra_types.pyi"
location = "file"
content = """
Point = tuple[float, float]
"""

For class-method overrides, the first segment of item is the logical Python module of the stub file that contains that class: usually the #[pymodule] name for the root .pyi, or the full #[pyclass(module = "...")] string (e.g. pkg.abc) when Rylai emits a separate submodule stub — not the pymodule name in that case.

location:

  • head — inserted right after the # Auto-generated by rylai... banner (and its following blank line), suitable for file-level notes or comments. If output.add_header is false so that banner is absent, the snippet is inserted at the very beginning of the file.
  • after-import-typing — inserted immediately after the first line import typing as t (every stub includes this line; use ruff check --select F401 --fix if you need to drop an unused import — ruff format does not remove imports).
  • tail — appended at end of file.
  • file — write content as the complete file. If the file does not match any generated stub, a new file is created under -o. If it does match a generated stub, the stub is completely replaced (a warning is printed). Only one [[add_content]] entry per file is allowed when location = "file", and it cannot be mixed with other locations for the same file. Use this for standalone .pyi files (e.g. shared type aliases) or to fully override generated output. Content is written verbatim — unlike the other locations, no banner, import typing as t, or other boilerplate is added, so write version-compatible Python for your target.

For head, after-import-typing, and tail locations, file must match a .pyi path produced in that run; otherwise Rylai exits with an error. Omit the .pyi suffix only when the last path segment has no extension; otherwise use the same relative names as under -o (e.g. pkg/aaa.pyi).

For each [[add_content]] entry, if content does not already end with a newline, Rylai appends one so you do not need to write a trailing \n in TOML (you may still include it if you prefer).

__all__ generation

Every generated stub includes an __all__ list of all top-level public exports. The list is emitted after any import lines and before the first def / class / constant declaration.

Default behaviour: names whose Python identifier starts with _ (including dunder names such as __version__) are excluded from __all__. All other top-level symbols — functions, classes, constants, and inline sub-modules — are included in declaration order.

Priority rules (highest first):

  1. Per-file exclude — name is always absent from __all__.
  2. Per-file include — for a top-level name that Rylai already emitted in this stub, keep it in __all__ even when it would be dropped by the _ filter (does not invent entries for symbols that were not generated).
  3. Per-file include_private — overrides the global all_include_private for that file only.
  4. Global output.all_include_private.
  5. Default (false): _-prefixed names are excluded.

[[all]] entries follow the same file path convention as [[add_content]] (relative to -o, forward slashes, optional .pyi suffix). Multiple entries for the same file are merged: include/exclude sets are unioned; the last matching include_private wins.

Names added via [[add_content]] are not automatically added to __all__ — manage those yourself (e.g. by appending to __all__ in a tail snippet).

The same options can be set in pyproject.toml under [tool.rylai]:

[tool.rylai.output]
# Same semantics as [output] python_version in rylai.toml (Optional, PEP 585 vs typing, Self, …).
python_version = "3.10"

[tool.rylai.fallback]
strategy = "any"

[tool.rylai.type_map]
# Same rules as root [type_map] above (Rust paths only; literal tuples need a `type` alias + map).
"numpy::PyReadonlyArray1" = "numpy.ndarray"

[[tool.rylai.override]]
item = "my_module::complex_function"
stub = "def complex_function(x: t.Any, **kwargs: t.Any) -> dict[str, t.Any]:"

[[tool.rylai.macro_expand]]
name = "register_classes"

[[tool.rylai.add_content]]
file = "mymod.pyi"
location = "tail"
content = "X: t.TypeAlias = int"

[[tool.rylai.all]]
file = "mymod.pyi"
exclude = ["InternalHelper"]

[tool.rylai]
format = ["isort", "black"]

Supported Type Mappings

For [output] python_version: generic containers follow PEP 585 only on Python ≥ 3.9 (list[T], dict[K, V], tuple[...], set[T]). On 3.8, Rylai emits the equivalent typing forms with the usual stub alias: t.List[T], t.Dict[K, V], t.Tuple[...], t.Set[T] (stubs use import typing as t). Bare list / dict / set without type parameters stay as built-in names.

Rust type Python type
Scalars
i8i128, u8u128, isize, usize int
f32, f64 float
bool bool
str, String, char str
() None
Bytes
&[u8], [u8] bytes
Vec<u8> bytes
Path-like
Path, PathBuf (incl. std::path::*) Path | str / t.Union[Path, str]
Containers
Option<T> T | None / t.Optional[T]
Vec<T> list[T] (3.9+) / t.List[T] (3.8)
(T1, T2, ...) (non-empty tuple) tuple[...] (3.9+) / t.Tuple[...] (3.8)
HashMap<K,V>, BTreeMap<K,V>, IndexMap<K,V> dict[K, V] (3.9+) / t.Dict[K, V] (3.8)
HashSet<T>, BTreeSet<T> set[T] (3.9+) / t.Set[T] (3.8)
PyO3 types
PyResult<T>, Result<T, E> T (errors become Python exceptions)
Py<T>, Bound<T>, Borrowed<T> recurse into T
PyRef<T>, PyRefMut<T> recurse into T
PyBytes bytes
PyByteArray bytearray
PyString str
PyDict, PyList, PyTuple, PySet dict, list, tuple, set
PyAny, PyObject t.Any
Other
Self (in #[pymethods]) t.Self (py ≥ 3.11) or class name
#[pyclass] structs/enums Python class name (from crate)
Unknown types t.Any (configurable via [fallback])

Limitation

Rylai is purely static: it parses Rust source for #[pymodule], #[pyfunction], #[pyclass], etc., and does not run the compiler. It is therefore not a good fit for cases where concrete information is only known after compilation (e.g. procedural macros that generate Python bindings at compile time, or types/signatures that only exist in compiled artifacts).

Current limitations

  • Same-name items. Rylai keys most internal lookups (functions, classes, type aliases, impl blocks, struct fields) by bare identifier. If two items in different modules share the same Rust name (e.g. two struct Foo), the last one parsed silently wins — fields, methods, and attributes from earlier definitions are lost. Use unique names or #[pyclass(name = "...")] to disambiguate.
  • use … as … renamed imports. Rylai does not resolve import aliases. Code like use pyo3::prelude::PyResult as MyResult; followed by -> MyResult<T> will cause MyResult to be treated as an unknown type (falling back to t.Any). Use the original name or add a type alias + [type_map] entry instead.
  • create_exception! parsing. Parsing expects exactly three comma-separated macro arguments; if the exception base path contains generics (<...>), comma splitting may fail.
  • [[macro_expand]] repetition blocks. Due to a macro_rules_rt limitation, $(...)* blocks can only contain repeating variables (e.g. $cls). Non-repeating metavariables inside a repetition are not expanded. The standard workaround is to bind non-repeating variables outside the repetition with a let (see the macro_expand_sample example).

When to use a build-based tool instead

For more complex projects, or when you rely on type/signature information that only exists after a build, a build-based approach is a better choice — for example pyo3-stub-gen, which compiles the extension first and then generates stubs from runtime/compilation artifacts.

For relatively simple projects where PyO3 bindings are mostly hand-annotated with straightforward types, Rylai’s speed, no-compile workflow, and zero intrusion are strong advantages. This is especially true when you have Python version requirements (e.g. supporting versions below 3.10 which pyo3-stub-gen does not support). For declarative macros that wrap binding registration calls, you can now use [[macro_expand]] / [[tool.rylai.macro_expand]] to expand specific macros before parsing. Coverage is still opt-in and pattern-driven: unsupported macro patterns or unconfigured macros may still be missed.

Related support is planned, but Rylai cannot generate stubs for all possible PyO3 code.

Contributing

Before committing, run the pre-commit checks with prek. See CONTRIBUTING.md for details.

License

LICENSE

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rylai-0.4.0-py3-none-win_arm64.whl (1.7 MB view details)

Uploaded Python 3Windows ARM64

rylai-0.4.0-py3-none-win_amd64.whl (1.8 MB view details)

Uploaded Python 3Windows x86-64

rylai-0.4.0-py3-none-musllinux_1_2_x86_64.whl (1.8 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

rylai-0.4.0-py3-none-musllinux_1_2_aarch64.whl (1.6 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

rylai-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

rylai-0.4.0-py3-none-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

rylai-0.4.0-py3-none-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file rylai-0.4.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: rylai-0.4.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rylai-0.4.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 077e674cff871a4bda98828c96ce00153f610825704a004099fb7625a37bfd57
MD5 2190ea6516028582c9a486e880776283
BLAKE2b-256 3e07ff3626950ce76d0afd1dc63b6e98116a888fcb245a14b1d23f8061998f94

See more details on using hashes here.

Provenance

The following attestation bundles were made for rylai-0.4.0-py3-none-win_arm64.whl:

Publisher: release.yml on monchin/Rylai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rylai-0.4.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: rylai-0.4.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.8 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rylai-0.4.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 25542da264b5d5f36e8d59eb57c4a9efe27d570ee714603c80cf12ea719259a0
MD5 844188dcff6753c4534f97419d8a84bc
BLAKE2b-256 07e914a480ed886e82ccbec55e72351a05a9fa14c708902e303c24cb71feb09d

See more details on using hashes here.

Provenance

The following attestation bundles were made for rylai-0.4.0-py3-none-win_amd64.whl:

Publisher: release.yml on monchin/Rylai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rylai-0.4.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

  • Download URL: rylai-0.4.0-py3-none-musllinux_1_2_x86_64.whl
  • Upload date:
  • Size: 1.8 MB
  • Tags: Python 3, musllinux: musl 1.2+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rylai-0.4.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 cf45dc600a7d021ff9d23544fa437257a252fabec2b7ad0b4443524b0b441e7b
MD5 45c08e084625db17f2bfda72515cb383
BLAKE2b-256 3213c6726d07bcc44e1eabec2f78a3c832ec2766f88eef93051c9210c1640648

See more details on using hashes here.

Provenance

The following attestation bundles were made for rylai-0.4.0-py3-none-musllinux_1_2_x86_64.whl:

Publisher: release.yml on monchin/Rylai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rylai-0.4.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for rylai-0.4.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 b41c839a1978414dfd086bc91ae4d01896b57cb5b3119a85e6dfd79d6a3e6308
MD5 453d38ae90941a3b9ae522174f6192e7
BLAKE2b-256 638b956aefcab6061ae2c14818dd788e6dd1e8124d139916dde356184a9964e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for rylai-0.4.0-py3-none-musllinux_1_2_aarch64.whl:

Publisher: release.yml on monchin/Rylai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rylai-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rylai-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6e6c5ee0783a3ce81117d1e7b9905edbe566a67c7db9e268f1efa4506bd5379f
MD5 69d0d8cb3a14d2402382cd39c4eb6c3a
BLAKE2b-256 7cc728b71bba8194e5f77837725c9966d08e50b5e996ecc7310d1c46cde807a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for rylai-0.4.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on monchin/Rylai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rylai-0.4.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: rylai-0.4.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.6 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rylai-0.4.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a5b9b0dba346192549d67de93667f537f86be96fa0f991a5e1f7c3d02b4113fa
MD5 b1ae855b8b1c170ffaafe45def9de5a4
BLAKE2b-256 c59f885ff7204eb2233f4d72f6d9a131d04416a9639aa85060e81eb2ef902236

See more details on using hashes here.

Provenance

The following attestation bundles were made for rylai-0.4.0-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on monchin/Rylai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rylai-0.4.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rylai-0.4.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5ddbf2c5d330d884316de6e0017ba7faf4fa8caee1e6df76d55b19ed76bacfb2
MD5 299e7644f766e226a5921ce4f96f76db
BLAKE2b-256 b810721ac486c50468ad750abaf55d0226d256627ffef9b296a247767ef4f635

See more details on using hashes here.

Provenance

The following attestation bundles were made for rylai-0.4.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on monchin/Rylai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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