leptris (Python) — lxml-shaped bindings for libleptris
leptris wraps the libleptris
C API (XML 1.0 parsing, XPath 1.0) using cffi in ABI mode, with a
required C accelerator for Element allocation and the hot accessors
(tag, text, attrib, get, indexing, sibling navigation and
plain-path XPath evaluation). Wheels ship it compiled; sdist builds
require a C compiler.
The pinned libleptris version lives in libleptris-version.txt
(lockstep releases); CI builds it from the release tarball. The
binding loads the shared library from LEPTRIS_LIB_PATH or the
loader path.
Requirements
- Python 3.9+
cffi(installed automatically)- libleptris 1.9.0+ as a shared library
- libleptris as a shared library (
libleptris.dylib/.so/.dll) on the loader path, or pointed to byLEPTRIS_LIB_PATH(which must name the library file — the loaderdlopens it verbatim). For a development checkout:
cmake -B build -S /path/to/leptris -DLEPTRIS_BUILD_SHARED=ON
cmake --build build --target leptris_shared
export LEPTRIS_LIB_PATH=/path/to/leptris/build/src/libleptris.dylib
Quick start
from leptris import fromstring, tostring
root = fromstring("<library><book id='1' lang='en'>Ulysses</book></library>")
root.tag # "library"
root[0].get("id") # "1"
root[0].attrib # {"id": "1", "lang": "en"}
root[0].text # "Ulysses"
root.xpath("count(//book)") # 1.0
[b.text for b in root.findall("book")] # ["Ulysses"]
tostring(root[0], encoding="unicode") # "<book id=\"1\" lang=\"en\">Ulysses</book>"
Documents own the tree; use the context manager or close():
from leptris import parse
with parse("catalog.xml") as doc:
doc.xpath("//book[@lang='en']")
Namespaces, variables, canonical XML and streaming:
root.xpath("//x:item", namespaces={"x": "urn:ex"})
root.xpath("//book[@id=$id]", variables={"id": "2"})
c14n(root, exclusive=True)
from leptris import sax
sax.parse(xml, handler) # one-shot
with sax.StreamingParser(handler) as parser: # push, constant memory
parser.feed(chunk, final=last)
Migrating from lxml
| lxml | leptris | Notes |
|---|---|---|
etree.fromstring / etree.XML |
fromstring / XML |
|
etree.parse |
parse |
paths and file-likes; no URLs |
etree.tostring(elem, …) |
tostring(elem, …) |
bytes by default, encoding="unicode" for str |
elem.tag / .text / .tail |
same | tag uses {uri}local Clark notation; CDATA merges into text (lxml's default parser behavior) |
elem.attrib / .get() / .keys() / .items() |
same | attrib is a read-only Mapping |
elem.getparent/getnext/getprevious |
same | |
elem[i], len(elem), iteration, slices |
same | indexing is child indexing, never attribute lookup |
elem.iter() / .iterdescendants() / .itertext() |
same | elements only (ElementTree semantics); lxml's iter() also yields comments/PIs |
elem.find/findall/findtext |
same | accepts full XPath 1.0 — a superset of ElementPath — including {uri}local names |
elem.xpath(expr, namespaces=…) |
same | plus variables={…} (leptris extension) |
etree.c14n / etree.XInclude |
c14n(…) / doc.process_xinclude() |
|
etree.XMLSyntaxError |
ParseError |
XPath failures raise XPathError; both subclass LeptrisError |
etree.Element, SubElement, append, set, remove |
not exposed | libleptris has partial mutation upstream (node content setters, set_root, remove_children) — not surfaced here; build trees elsewhere |
etree.iterparse |
leptris.iterparse(source) |
bounded by the largest subtree; yields ("end", element); elements borrowed until the next yield (v1: names are QNames as written). Known limitations (leptris/leptris#563): currently ~2× slower than lxml's iterparse, and truncated input ends iteration silently instead of raising — the engine's iterparse has no error channel; use Document.parse when the input fits in memory |
| smart strings | plain str |
XPath string/attribute results |
elem.nsmap |
absent | use elem.namespace / elem.prefix and xpath(namespaces=…) |
etree.XPath compiled objects |
leptris.XPath(expression) |
compile once, evaluate many; contexts and namespaces supported |
parser options (resolve_entities, …) |
absent | libleptris 1.2.0 has no per-parse options |
elem.sourceline |
same | requires libleptris 1.3.0+ |
| undeclared XPath prefix | raises in lxml | evaluates to an empty nodeset here |
Layout
leptris/_ffi.py— cdef mirror of the public headers + loader (the only place libleptris is declared)leptris/_leptrisaccel.c— the C accelerator (abi3): allocates Elements and runs the hot accessors, subtree iteration, the parse and serialization seams, and the per-document element registry; bound to libleptris by the positional protocol inelement.pyleptris/element.py,document.py,node.py,xpath.py— the Python surface: queries, walks, documents;node.pyexposes the full DOM (comments, CDATA, PIs) beneath the ElementTree shapeleptris/api.py—fromstring/parse/tostring/c14n/iterparseleptris/sax.py— SAX one-shot and streamingtests/— pytest suite (pytestwithLEPTRIS_LIB_PATHset)benchmarks/— matrix vs lxml/ElementTree/minidom (pip install .[bench], thenpython -m benchmarks.matrix)
Memory model
The Document owns the whole tree and its pool. Accessor strings
are copied into Python str at the boundary, so nothing depends on
document lifetime after a call returns. Elements keep a reference to
their Document, so the pool cannot be freed while any wrapper is
alive. Prefer explicit close() / the context manager; __del__ is
a refcounting safety net, not a contract. Using an element after its
document is closed raises LeptrisError.
Versioning
libleptris-version.txt pins the library release the binding is
built and tested against. From 1.3.0 the package follows its own
semver: 1.2.0 shipped an interim bespoke API to no adopters, and
1.3.0 replaces it with the lxml-shaped API (breaking, but
pre-adoption). pyproject.toml and leptris/__init__.py must agree
at release time.
Publishing
Releases publish to PyPI via .github/workflows/release.yml, using
PyPI trusted publishing (no stored credentials). The workflow
runs on manual dispatch (ships the version in pyproject.toml) and
is called by the libleptris release flow (publish: true), so every
libleptris release ships the wheel.
Local development
python3 -m venv .venv
./.venv/bin/pip install --upgrade build pytest cffi
./.venv/bin/pip install -e .[test,bench]
LEPTRIS_LIB_PATH=/path/to/libleptris.dylib ./.venv/bin/python -m pytest tests/ -q
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file leptris-1.14.1.tar.gz.
File metadata
- Download URL: leptris-1.14.1.tar.gz
- Upload date:
- Size: 43.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74155d5f5a43dbccb9301bd23f2d1e3b6b045a81e5357b3ad05afbe182e98191
|
|
| MD5 |
97db783fad28c5ad66356606eb8be0df
|
|
| BLAKE2b-256 |
81b16693241d0bb468a8496800d019fdbe469394a1f4a7da87d22233d740a8c3
|
Provenance
The following attestation bundles were made for leptris-1.14.1.tar.gz:
Publisher:
release.yml on leptris/leptris-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leptris-1.14.1.tar.gz -
Subject digest:
74155d5f5a43dbccb9301bd23f2d1e3b6b045a81e5357b3ad05afbe182e98191 - Sigstore transparency entry: 2609040361
- Sigstore integration time:
-
Permalink:
leptris/leptris-py@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/leptris
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file leptris-1.14.1-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: leptris-1.14.1-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 40.0 kB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13b6e6a05ccdb75f277983c01e0424622087d6072efb9f1fff348ae5662760e5
|
|
| MD5 |
47994646251bb2a8ddc1f3bd1e11fc30
|
|
| BLAKE2b-256 |
524becadfa466b0bb6f9edee13f30ad77c6a52bc824c79901c04fdeaa232bcc7
|
Provenance
The following attestation bundles were made for leptris-1.14.1-cp39-abi3-win_amd64.whl:
Publisher:
release.yml on leptris/leptris-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leptris-1.14.1-cp39-abi3-win_amd64.whl -
Subject digest:
13b6e6a05ccdb75f277983c01e0424622087d6072efb9f1fff348ae5662760e5 - Sigstore transparency entry: 2609040824
- Sigstore integration time:
-
Permalink:
leptris/leptris-py@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/leptris
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file leptris-1.14.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: leptris-1.14.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 91.6 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d97bc11cf95a2fb9412328d8078cb88b34f9b23d4958c4ed1de077023dcfc4cf
|
|
| MD5 |
7179d829bb81e395b929b3ce40862b75
|
|
| BLAKE2b-256 |
0930015ecd44042447ede6ec5a391bf5c0dee8d061a658f92496dd10c4eed212
|
Provenance
The following attestation bundles were made for leptris-1.14.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on leptris/leptris-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leptris-1.14.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
d97bc11cf95a2fb9412328d8078cb88b34f9b23d4958c4ed1de077023dcfc4cf - Sigstore transparency entry: 2609040964
- Sigstore integration time:
-
Permalink:
leptris/leptris-py@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/leptris
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file leptris-1.14.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: leptris-1.14.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 87.8 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5388f51bdb3a560594276c719df8db8882b8883504dac8b5e3e135ce6e31af1d
|
|
| MD5 |
1d1834e5d5969a2396e5b9a0ecd55768
|
|
| BLAKE2b-256 |
544f41108c831677c4a0eee84b5d0b453a6678d3721d4daf98a987c8e3ab673b
|
Provenance
The following attestation bundles were made for leptris-1.14.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on leptris/leptris-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leptris-1.14.1-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
5388f51bdb3a560594276c719df8db8882b8883504dac8b5e3e135ce6e31af1d - Sigstore transparency entry: 2609041186
- Sigstore integration time:
-
Permalink:
leptris/leptris-py@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/leptris
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file leptris-1.14.1-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: leptris-1.14.1-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 38.3 kB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12e4eb08130bc1ecce58d71c73878de95e9826ee563a02836a11a10d8a78ecc3
|
|
| MD5 |
39eae7a0a3cfdd22aed0dc9ad3820145
|
|
| BLAKE2b-256 |
ca0ebd059b78e4c1f54d56e416e3bc17ea33564e2f8fdab84b46b555a92d06a0
|
Provenance
The following attestation bundles were made for leptris-1.14.1-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on leptris/leptris-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leptris-1.14.1-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
12e4eb08130bc1ecce58d71c73878de95e9826ee563a02836a11a10d8a78ecc3 - Sigstore transparency entry: 2609040650
- Sigstore integration time:
-
Permalink:
leptris/leptris-py@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/leptris
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file leptris-1.14.1-cp39-abi3-macosx_10_9_x86_64.whl.
File metadata
- Download URL: leptris-1.14.1-cp39-abi3-macosx_10_9_x86_64.whl
- Upload date:
- Size: 37.8 kB
- Tags: CPython 3.9+, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3942fef1deb273d1b71981fc143c722cc4c4f9c5cf72fe050c07bda1850e4173
|
|
| MD5 |
5b36fb8823b54517d8374bd3e5c1eb7a
|
|
| BLAKE2b-256 |
325b9f527368c1e6e5640f067f71c3843695356fc4d0a901cb65ee7dbcd7b1af
|
Provenance
The following attestation bundles were made for leptris-1.14.1-cp39-abi3-macosx_10_9_x86_64.whl:
Publisher:
release.yml on leptris/leptris-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
leptris-1.14.1-cp39-abi3-macosx_10_9_x86_64.whl -
Subject digest:
3942fef1deb273d1b71981fc143c722cc4c4f9c5cf72fe050c07bda1850e4173 - Sigstore transparency entry: 2609040493
- Sigstore integration time:
-
Permalink:
leptris/leptris-py@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/leptris
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ddfec40937f2f71cf4818559f9bdb0ebc15c9867 -
Trigger Event:
workflow_dispatch
-
Statement type: