Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stubs #38

Merged
merged 5 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 16 additions & 77 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,81 +1,20 @@
/target
# IDEs
/.idea/
/.vscode/

# Byte-compiled / optimized / DLL files
# Caches
.DS_Store
__pycache__/
.pytest_cache/
*.py[cod]
/.*cache/
/.hypothesis/

# C extensions
# Build
*.so

.hypothesis/

# docs generated rst
docs/generated

# Distribution / packaging
.Python
.venv/
env/
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
include/
man/
venv/
*.egg-info/
.installed.cfg
*.egg

# Installer logs
pip-log.txt
pip-delete-this-directory.txt
pip-selfcheck.json

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Translations
*.mo

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Rope
.ropeproject

# Django stuff:
*.log
*.pot

.DS_Store

# Sphinx documentation
docs/_build/

# PyCharm
.idea/

# VSCode
.vscode/

# Pyenv
.python-version

# testing
data/
fixture/
*.pyi
/target/
/dist/
/docs/_build/

# Coverage
/.coverage
/coverage.xml
93 changes: 93 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "zarrs"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why that worked. In #37, you made it so there are two Rust libraries called zarrs, which should be impossible.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point.

crate-type = ["cdylib"]
name = "zarrs_python"
crate-type = ["cdylib", "rlib"]

[dependencies]
pyo3 = "0.22.6"
Expand All @@ -18,6 +18,7 @@ openssl = { version = "0.10", features = ["vendored"] }
numpy = "0.22.1"
unsafe_cell_slice = "0.2.0"
serde_json = "1.0.128"
pyo3-stub-gen = { version = "0.6.1", git = "https://github.com/flying-sheep/pyo3-stub-gen.git", branch = "py-untyped-array" }

[profile.release]
lto = true
32 changes: 32 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::env;
use std::path::PathBuf;
use std::process::Command;

fn main() -> Result<(), Box<dyn std::error::Error>> {
maybe_generate_stubs()?;
Ok(())
}

/// Generate stubs if we’re compiling the library
/// Returns `true` if stubs were generated
fn maybe_generate_stubs() -> Result<bool, Box<dyn std::error::Error>> {
if env::var("CARGO_BIN_NAME") != Err(env::VarError::NotPresent) {
return Ok(false);
}

// Find an existing `stub_gen` binary or exit silently
let Some(bin_path) = ["debug", "release"]
.into_iter()
.filter_map(|mode| {
let p = PathBuf::from(format!("target/{mode}/stub_gen"));
p.exists().then_some(p)
})
.next()
else {
return Ok(false);
};

// If we’re compiling the library, generate stubs first
Command::new(bin_path).spawn()?.wait()?;
Ok(true)
}
10 changes: 10 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,13 @@ pytest -n auto
```

for parallelized tests. Most tests have been copied from the `zarr-python` repository with the exception of `test_pipeline.py` which we have written.

## Type hints

When authoring Python code, your IDE will not be able to analyze the extension module `zarrs._internal`.
But thanks to [`pyo3-stub-gen`][], we can generate type stubs for it!

To build the stub generator, run `cargo build --bin stub_gen`.
Afterwards, whenever you `cargo build`, `maturin build` or interact with your editor’s rust language server (e.g. `rust-analyzer`), the type hints will be updated.

[`pyo3-stub-gen`]: https://github.com/Jij-Inc/pyo3-stub-gen
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Typing :: Typed",
]
dynamic = ["version"]
dependencies = [
Expand Down Expand Up @@ -41,9 +42,9 @@ test = [
"requests",
"mypy",
"hypothesis",
"pytest-xdist"
"pytest-xdist",
]
dev = ["maturin"]
dev = ["maturin", "pip"]
doc = ["sphinx>=7.4.6", "myst-parser"]

[tool.maturin]
Expand Down
Empty file added python/zarrs/py.typed
Empty file.
7 changes: 7 additions & 0 deletions src/bin/stub_gen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use pyo3_stub_gen::Result;

fn main() -> Result<()> {
let stub = zarrs_python::stub_info()?;
stub.generate()?;
Ok(())
}
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use numpy::npyffi::PyArrayObject;
use numpy::{IntoPyArray, PyArray1, PyUntypedArray, PyUntypedArrayMethods};
use pyo3::exceptions::{PyRuntimeError, PyTypeError, PyValueError};
use pyo3::prelude::*;
use pyo3_stub_gen::define_stub_info_gatherer;
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rayon_iter_concurrent_limit::iter_concurrent_limit;
use std::borrow::Cow;
Expand Down Expand Up @@ -37,6 +39,7 @@ trait CodecPipelineStore: Send + Sync {
}

// TODO: Use a OnceLock for store with get_or_try_init when stabilised?
#[gen_stub_pyclass]
#[pyclass]
pub struct CodecPipelineImpl {
pub(crate) codec_chain: Arc<CodecChain>,
Expand Down Expand Up @@ -234,6 +237,7 @@ impl CodecPipelineImpl {
}
}

#[gen_stub_pymethods]
#[pymethods]
impl CodecPipelineImpl {
#[pyo3(signature = (
Expand Down Expand Up @@ -531,3 +535,5 @@ fn _internal(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<CodecPipelineImpl>()?;
Ok(())
}

define_stub_info_gatherer!(stub_info);