Skip to main content

nameparser-py — native Python binding

import nameparser gives you the Rust nameparser core's parse() directly, as a PyO3 extension module. Unlike bindings/java (which crosses the JVM/native boundary via java.lang.foreign, either JSON or a flat struct on the wire), there is no C-ABI or marshalling floor here: PyO3 wraps the core nameparser::model::ParsedName struct directly, with one getter per field mapping it straight to its idiomatic Python type — no JVM, no JSON round-trip, no separately-installed native library to locate at runtime.

Field parity with the core is validated over this repo's full ~11,302-name test corpus, cross-checked against the independent Java name-parser oracle: 0 diffs (see crates/nameparser-py/python/tests/test_parity.py).

Install

pip install gbif-name-parser   # → import nameparser

Prebuilt abi3 wheels are on PyPI for Linux (x86_64 / aarch64), macOS (Apple Silicon), and Windows (x64), covering CPython 3.9+. On other platforms (e.g. Intel macOS) pip builds from the sdist, which needs a Rust toolchain (cargo/rustc) on the machine.

(The PyPI distribution name is gbif-name-parser — matching the Rust core crate on crates.io, so it's one name across both registries — but the importable module stays nameparser either way; see pyproject.toml.)

From source (development)

python3 -m venv .venv && . .venv/bin/activate
pip install maturin
maturin develop --release -m crates/nameparser-py/Cargo.toml

maturin develop compiles the Rust cdylib and installs it into the active virtualenv as an editable nameparser package (including the nameparser.pyi type stub and a py.typed marker — this package is fully typed; see Editors / type checkers below).

Usage

import nameparser

pn = nameparser.parse("Vulpes vulpes silaceus Miller, 1907")
print(pn.rank, pn.genus, pn.specific_epithet, pn.infraspecific_epithet)   # SUBSPECIES Vulpes vulpes silaceus
print(pn.combination_authorship.authors, pn.combination_authorship.year)  # ['Miller'] 1907
print(pn.to_dict()["type"])                                               # SCIENTIFIC — full dict, wire (JSON/Java) field names

results = nameparser.parse_all(["Abies alba", "Tobacco mosaic virus"])    # batch: never raises
print(results)                                                            # [ParsedName(...), None]

try:
    nameparser.parse("Tobacco mosaic virus")
except nameparser.UnparsableNameError as e:
    print(e.name_type, e.code, e.name)   # OTHER VIRUS Tobacco mosaic virus
    print(str(e))                        # Unparsable OTHER name: Tobacco mosaic virus

Every one of ParsedName's 30 core fields is exposed as a Python property (snake_case, e.g. specific_epithet, combination_authorship, published_in_year); enum-typed fields (rank, code, type, state, and each element of notho) come across as plain SCREAMING_SNAKE_CASE strings ("SPECIES", "ZOOLOGICAL", …) — the same convention the JSON/Java wire format uses — not a Python enum.Enum. rank/code inputs to parse()/parse_all() accept those same strings (or None). to_dict() (on both ParsedName and the nested Authorship) returns the complete structure straight from the core's own serde::Serialize impl, keyed by the JSON/Java wire field names (specificEpithet, not specific_epithet) — the escape hatch for anything a typed getter doesn't surface, and the parity oracle the corpus test itself diffs against.

UnparsableNameError.name_type/.code/.name mirror Java's org.gbif.nameparser.api.UnparsableNameException's getType()/getCode()/getName(); str(e) is still exactly the core's own message, unchanged.

Editors / type checkers

nameparser.pyi (shipped inside the package, alongside a py.typed marker) gives Pyright/mypy/ your editor full attribute-level types for parse/parse_all/ParsedName/Authorship/ UnparsableNameError — no more "unknown attribute" noise on pn.specific_epithet or e.name_type. It's hand-written (the compiled extension has no Python source for a stub generator to read) and kept in sync by hand with src/lib.rs's getters; see its own module docstring.

Native, no JDK required

This binding never starts a JVM and needs no java/JAVA_HOME on the machine that runs it — unlike bindings/java (which requires JDK 22+ for java.lang.foreign) — because it compiles directly against the Rust core, in-process, with PyO3 doing the Rust↔Python marshalling at the Rust/CPython C-API level rather than crossing a JVM boundary at all. Performance-wise it inherits the native CLI's batch-throughput profile (see the root BENCHMARKS.md): there is no per-call FFM downcall or JSON re-serialization step the way the Java binding's NameParserRust has, since parse()/parse_all() call nameparser::parse directly.

Development

. .venv/bin/activate
maturin develop --release -m crates/nameparser-py/Cargo.toml
pytest crates/nameparser-py/python/tests/ -v

Three test files under python/tests/:

  • test_api.py — unit tests for the binding surface itself (getters, to_dict(), parse_all()'s none-on-unparsable contract, UnparsableNameError's structured attributes).
  • test_getter_consistency.py — checks every #[getter] agrees with to_dict() over a representative sample (a path test_parity.py alone can't exercise, since it only ever calls to_dict()).
  • test_parity.py — the corpus parity gate: diffs nameparser.parse(name).to_dict(), and UnparsableNameError's message/name_type/code, against an independent Java-oracle (or Rust-CLI-fallback) row for every one of the ~11,302 corpus names. Needs a JDK on PATH (falls back to the release nameparser-cli binary if the Java shaded jar isn't available).

Build a wheel (not published) with:

maturin build --release -m crates/nameparser-py/Cargo.toml   # → target/wheels/*.whl (git-ignored)

The wheel is abi3 (built against the stable Python C ABI, py39 floor) — one wheel per platform, working across Python 3.9+, not one per Python minor version.

Metadata

Release files for gbif-name-parser 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gbif-name-parser 0.2.1
File Size Uploaded
gbif_name_parser-0.2.1.tar.gz 426.4 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for gbif-name-parser 0.2.1
File
gbif_name_parser-0.2.1-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
gbif_name_parser-0.2.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
gbif_name_parser-0.2.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
gbif_name_parser-0.2.1-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details

Total release size: 6.1 MB

Release files / gbif_name_parser-0.2.1.tar.gz

Download URL gbif_name_parser-0.2.1.tar.gz
Size 426.4 kB
Tags Source
SHA-256 checksum
How to use checksums
327aee771be2adf464ce19ef492130b7be235f3beb62ec97ecc6036bd2f5d22f
BLAKE2b-256 checksum
How to use checksums
976d65fafad7752451b2b99ded5b2085e591f2ea82045255df50a8428a3ef13d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / gbif_name_parser-0.2.1-cp39-abi3-win_amd64.whl

Download URL gbif_name_parser-0.2.1-cp39-abi3-win_amd64.whl
Size 1.3 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
cd4f2da1e3c6bf07d440417f3c103e53c12958e41441c044b4101b93ed96e557
BLAKE2b-256 checksum
How to use checksums
913b32696252b5f78fab383929da389281d7a6dcb649fcd7d185594068656b73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / gbif_name_parser-0.2.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL gbif_name_parser-0.2.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.5 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
94a5da49adba1b4cb57c2db90d4d11e8c11d6c194186ea7cfce3669241acb3cf
BLAKE2b-256 checksum
How to use checksums
1aec10d7a3a09ad7b76ef18ccfaf800b682852436fb8f128f9a3cab02e9db3bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / gbif_name_parser-0.2.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL gbif_name_parser-0.2.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.5 MB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
2a611744e66557924b23f40a6986c8d8a68b5efa5c12c264f67b8c2a0133c6de
BLAKE2b-256 checksum
How to use checksums
1c6dbe81bbc1a602b2584ad8a10fa3f26f75406ebb7c3a48000f15fdc1fb157c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / gbif_name_parser-0.2.1-cp39-abi3-macosx_11_0_arm64.whl

Download URL gbif_name_parser-0.2.1-cp39-abi3-macosx_11_0_arm64.whl
Size 1.4 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c24a1a017c82f1ac909711722a11f24e474f8c201873f153f25dda74150425cb
BLAKE2b-256 checksum
How to use checksums
ca2cf1cfa457e5f2f9f390d33a6ff478eca165cfd94bcc6d4e85acb112280044
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.2

5 release files

This release

0.2.1 This release

5 release files

0.2.0

5 release files

0.1.0

5 release 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