Skip to content

Add louis-py: Basic Python bindings for the translator (PyO3) - #12

Open
LeonarddeR wants to merge 20 commits into
liblouis:mainfrom
LeonarddeR:pyo3
Open

Add louis-py: Basic Python bindings for the translator (PyO3)#12
LeonarddeR wants to merge 20 commits into
liblouis:mainfrom
LeonarddeR:pyo3

Conversation

@LeonarddeR

@LeonarddeR LeonarddeR commented Jul 9, 2026

Copy link
Copy Markdown
Member

Summary

Adds louis-py, a new Cargo workspace member exposing the translator to Python via PyO3. Closes #1.

  • Translator class (GIL-released translate/translate_with_options), Direction, TranslationMode flags, TranslationResult/EmphasisSpan, and a LouisError/TableParseError/TranslationError exception hierarchy.
  • Type stubs (_louis_py.pyi) + py.typed marker.
  • Built via maturin, abi3-py311 (one wheel covers Python 3.11+).
  • .github/workflows/python-wheels.yml: on PR, lints/tests with uv + ruff, builds wheels (5-platform matrix) + sdist as build artifacts — no publishing.
  • Test suite: translate, options/modes, emphasis spans, errors, table-path resolution, thread-safety.
  • CHANGELOG.md entry under Added.

Test plan

  • cargo test
  • louis-py test suite via uv run pytest
  • python-wheels workflow runs green on PR

Open questions

  • Should we keep the louis_py name for the python package or name it otherwise?
  • Should we reconsider the repo structure now there's an extra crate?

LeonarddeR and others added 19 commits July 9, 2026 16:48
Reshapes the issue liblouis#1 spec against the current API: louis-py/louis_py
naming, EmphasisSpan (not Typeform dict), TranslationOptions builder,
pyo3 0.29, and the fact that TranslationResult fields beyond output are
unpopulated today.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9 TDD tasks. Toolchain verified end-to-end on ARM64 Windows (uv-managed
aarch64 CPython 3.12 + maturin 1.14 + pyo3 0.29 cdylib imports). Bundled
minimal mini.ctb table for hermetic tests. Confirmed louis::Translator is
Send+Sync (no Mutex needed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add LouisError/TableParseError/TranslationError via pyo3::create_exception!
and a to_pyerr(py, louis::TranslationError) converter. TableParseError
carries .errors via setattr on the exception instance, verified to persist
through PyErr::value(py).
Adds the Translator pyclass (frozen) wrapping louis::Translator, with a
constructor and translate() that release the GIL around the Rust call.
Also removes the now-unneeded #[allow(dead_code)] on to_pyerr since
to_pyerr_nogil (added here) exercises it, and adds a compile-time
Send+Sync assertion for louis::Translator.

Deviates from the plan's verbatim snippets: the installed pyo3 0.29.0
renamed Python::with_gil -> Python::attach and Python::allow_threads ->
Python::detach (no deprecated aliases present); semantics are identical
per pyo3's own docs, verified by reading marker.rs.
NVDA moved to a 64-bit build in 2026.1, so the 32-bit Windows wheel is no
longer needed. Removing the x86 matrix leg also eliminates the only CI
target that couldn't be validated without a matching-arch interpreter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rtifacts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@LeonarddeR LeonarddeR changed the title Add louis-py: Python bindings for the translator (PyO3) Add louis-py: Basic Python bindings for the translator (PyO3) Jul 9, 2026
@egli

egli commented Jul 13, 2026

Copy link
Copy Markdown
Member

Hi @LeonarddeR thank you very much for this.

I'm basically on vacation until August, so just a quick feedback: Generally looks excellent. I'm wondering though if this should not be a separate repository. That could under the liblouis organization and would be entirely yours.

Then the function you added to option.rs: I'm not sure if I want to expose such a bit-twiddling interface to the outside world. That prevents us from ever changing the order of the enum. Isn't there a better way?

More detailed review in August.

@LeonarddeR

Copy link
Copy Markdown
Member Author

@egli Thanks for your initial reply.
If you're more comfortable with a separate repo, I'm happy to do that.

@LeonarddeR

Copy link
Copy Markdown
Member Author

@egli I created https://github.com/LeonarddeR/louis-py
Happy to transfer it to the liblouis organization when permitted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python bindings using PyO3

2 participants