Skip to main content

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.3+ as a shared library (1.9.1 has an options-struct ABI break — leptris/leptris#568)
  • libleptris as a shared library (libleptris.dylib / .so / .dll) on the loader path, or pointed to by LEPTRIS_LIB_PATH (which must name the library file — the loader dlopens 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
document-level comments / PIs doc.toplevel_comments() / doc.toplevel_pis() prolog then epilog; requires libleptris 1.9.3+
etree.iterparse leptris.iterparse(source, full_document=False) bounded by the largest subtree; yields ("end", element); elements borrowed until the next yield; tags resolve namespaces (Clark notation, libleptris 1.9.4+). Truncated or malformed input raises ParseError (both modes, libleptris 1.9.15+). full_document=True yields every element in completion order
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, namespaces, and variables supported
etree.XSLT leptris.XSLT(stylesheet) compile once, apply to any Document; full XSLT 1.0 + EXSLT (math/set/str/date) via libleptris, plus XSLT/XPath 3.0 increments (try/catch, xsl:accumulator, let / ! / => / `
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
ATTLIST default attributes applied by lxml's default parser excluded by default (ElementTree-like; XML 1.0 §5 permits either) — Document.parse(xml, attribute_defaults=True) opts in
declared non-UTF-8 bytes (UTF-16, latin-1, …) auto-detected auto-detected — declared encodings route through the converter, others retry on failure (libleptris 1.9.15+)
parser options (remove_blank_text, …) etree.XMLParser(remove_blank_text=True) Document.parse(xml, remove_blank_text=True) — ~35% faster on pretty-printed input; also attribute_defaults=True, recover=True
remove_blank_text on non-blank text lxml drops only whitespace-only nodes the leading boundary whitespace of non-blank text is also trimmed from the tree (libleptris #677)

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 in element.py
  • leptris/element.py, document.py, node.py, xpath.py — the Python surface: queries, walks, documents; node.py exposes the full DOM (comments, CDATA, PIs) beneath the ElementTree shape
  • leptris/api.pyfromstring/parse/tostring/c14n/ iterparse
  • leptris/sax.py — SAX one-shot and streaming
  • tests/ — pytest suite (pytest with LEPTRIS_LIB_PATH set)
  • benchmarks/ — matrix vs lxml/ElementTree/minidom (pip install .[bench], then python -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

leptris-1.24.3.tar.gz (55.7 kB view details)

Uploaded Source

Built Distributions

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

leptris-1.24.3-cp39-abi3-win_amd64.whl (45.4 kB view details)

Uploaded CPython 3.9+Windows x86-64

leptris-1.24.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (101.7 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

leptris-1.24.3-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (97.6 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

leptris-1.24.3-cp39-abi3-macosx_11_0_arm64.whl (43.8 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

leptris-1.24.3-cp39-abi3-macosx_10_9_x86_64.whl (43.2 kB view details)

Uploaded CPython 3.9+macOS 10.9+ x86-64

File details

Details for the file leptris-1.24.3.tar.gz.

File metadata

  • Download URL: leptris-1.24.3.tar.gz
  • Upload date:
  • Size: 55.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for leptris-1.24.3.tar.gz
Algorithm Hash digest
SHA256 349a6f63b6a8a1162fbf69e3454523c8f6ba3901b24f1cc05263ac04f6f5b1ca
MD5 191c989fadf9d23344086f38da5e39d9
BLAKE2b-256 4731b8f00ab4a92d3a61464e14ec6478c8cbf00c72777e73e367730bc895214d

See more details on using hashes here.

Provenance

The following attestation bundles were made for leptris-1.24.3.tar.gz:

Publisher: release.yml on leptris/leptris-py

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

File details

Details for the file leptris-1.24.3-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: leptris-1.24.3-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 45.4 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

Hashes for leptris-1.24.3-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2fa3b4bb46197a7c0f6b10f3d01b60db757c913ccf5300a9570a8f1c2edd1b3a
MD5 17bf77066d335a4ca53c56614cf8becf
BLAKE2b-256 6f7e5ae4e3a04990b78dfda24dcf41022c3fb183477727b05a6b9071ffb1f561

See more details on using hashes here.

Provenance

The following attestation bundles were made for leptris-1.24.3-cp39-abi3-win_amd64.whl:

Publisher: release.yml on leptris/leptris-py

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

File details

Details for the file leptris-1.24.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for leptris-1.24.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7fb7aabbcd9746e94d7b1dd45d1cc26a546d930d4e48a5cd5d14ee727a8c4669
MD5 770176d9c8b6ae9215b4e43a770e0b2b
BLAKE2b-256 a275758578b5f0dca442d9953914b828eb43970e19e890c6044a9bd3c45f9c6a

See more details on using hashes here.

Provenance

The following attestation bundles were made for leptris-1.24.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on leptris/leptris-py

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

File details

Details for the file leptris-1.24.3-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for leptris-1.24.3-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 141f4a02b2807bed74806c6965ed182926fac6694959c10386df3694ca6d63f8
MD5 d6db8b8770e06530f5029ba091bbda91
BLAKE2b-256 a7da8ab359ecae5886f192f7222e0ed11524d52ce9a8aa84cc0a61e617d89070

See more details on using hashes here.

Provenance

The following attestation bundles were made for leptris-1.24.3-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

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

File details

Details for the file leptris-1.24.3-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for leptris-1.24.3-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7ef35192736d9bc7835a60c768e5361bb3ad107f9746f8197c8b89a72306bad1
MD5 028e04c8ce5e891f667673cb89da8087
BLAKE2b-256 8a33484b4b5186cdceb93a57d931e6c01329d27abb4b453f6d6416bc02f20bf0

See more details on using hashes here.

Provenance

The following attestation bundles were made for leptris-1.24.3-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on leptris/leptris-py

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

File details

Details for the file leptris-1.24.3-cp39-abi3-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for leptris-1.24.3-cp39-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 0e01cf8aa10f21b53b4c136c76bb3f38894a973c68f85809beea423553afa608
MD5 b304025edfdde111730e2a50b5b1c85f
BLAKE2b-256 f8004dbf3916be65be17caec06ab6a50f823dc215c55813baa82d71d73a7f9a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for leptris-1.24.3-cp39-abi3-macosx_10_9_x86_64.whl:

Publisher: release.yml on leptris/leptris-py

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

Release history Release notifications | RSS feed

1.27.1

6 files

1.27.0

6 files

1.26.1

6 files

1.26.0

6 files

1.25.4

6 files

1.25.3

6 files

1.25.2

6 files

1.25.1

6 files

1.25.0

6 files

This release

1.24.3 This release

6 files

1.24.2

6 files

1.24.1

6 files

1.24.0

6 files

1.23.3

6 files

1.23.2

6 files

1.23.1

6 files

1.23.0

6 files

1.22.2

6 files

1.22.1

6 files

1.22.0

6 files

1.21.0

6 files

1.20.0

6 files

1.19.0

6 files

1.18.0

6 files

1.17.1

6 files

1.17.0

6 files

1.16.1

6 files

1.16.0

6 files

1.15.1

6 files

1.15.0

6 files

1.14.3

6 files

1.14.2

6 files

1.14.1

6 files

1.14.0

6 files

1.13.3

6 files

1.13.2

6 files

1.13.1

6 files

1.13.0

6 files

1.12.0

6 files

1.11.1

6 files

1.11.0

6 files

1.10.0

6 files

1.9.93.2

6 files

1.9.93.0

6 files

1.9.90.0

6 files

1.9.87.0

6 files

1.9.86.0

6 files

1.9.84.0

6 files

1.9.83.0

6 files

1.9.80.0

6 files

1.9.79.0

6 files

1.9.76.0

6 files

1.9.0

6 files

1.8.0

6 files

1.7.0

6 files

1.6.1

6 files

1.6.0

5 files

1.5.0

2 files

1.4.1

2 files

1.4.0

2 files

1.3.1

2 files

1.3.0

2 files

1.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page