rfc3987-syntax2
Helper functions to parse and validate the syntax of terms defined in RFC 3987 — the IETF standard for Internationalized Resource Identifiers (IRIs).
🎯 Purpose
The goal of rfc3987-syntax2 is to provide a lightweight, permissively licensed Python module for validating that strings conform to the ABNF grammar defined in RFC 3987. These helpers are:
- ✅ Strictly aligned with the syntax rules of RFC 3987
- ✅ Built using a permissive MIT license
- ✅ Designed for both open source and proprietary use
- ✅ Powered by Lark, a fast, EBNF-based parser
🧠 Note: This project focuses on syntax validation only. RFC 3987 specifies additional semantic rules (e.g., Unicode normalization, BiDi constraints, percent-encoding requirements) that are intentionally out of scope.
📄 License, Attribution, and Citation
rfc3987-syntax2 is licensed under the MIT License, which allows reuse in both open source and commercial software.
This project:
- ❌ Does not depend on the
rfc3987Python package (GPL-licensed) - ✅ Uses
lark, licensed under MIT - ✅ Implements grammar from RFC 3987, using RFC 3986 where RFC 3987 delegates syntax
⚠️ This project is not affiliated with or endorsed by the authors of RFC 3987 or the
rfc3987Python package.
⚠️ Limitations
The grammar and parser enforce only the ABNF syntax defined in RFC 3987 (and referenced RFC 3986 productions where applicable).
The following are not validated and must be handled separately for full compliance:
- Unicode Normalization Form C (NFC)
- Bidirectional text (BiDi) constraints (RFC 3987 §4.1)
- Port number ranges (must be 0–65535)
- Context-aware percent-encoding requirements
- Additional host/network semantics beyond ABNF syntax (for example, canonical representation expectations)
ChatGPT 40 was used during the original development process. Errors may exist due to this assistance. Additional review, testing, and bug fixes by human experts is welcome.
📦 Installation
pip install rfc3987-syntax2
📚 Documentation
Complete documentation is available on Read the Docs. This includes:
- Responsibilities & Capabilities
- Install Instructions
- API Reference
- Usage Examples
🛠 Usage
List all supported "terms" (i.e., non-terminals and terminals within ABNF production rules) used to validate the syntax of an IRI according to RFC 3987
from rfc3987_syntax2 import RFC3987_SYNTAX_TERMS
print("Supported terms:")
for term in RFC3987_SYNTAX_TERMS:
print(term)
Syntactically validate a string using the general-purpose validator
from rfc3987_syntax2 import is_valid_syntax
if is_valid_syntax(term='iri', value='http://github.com'):
print("✓ Valid IRI syntax")
if not is_valid_syntax(term='iri', value='bob'):
print("✗ Invalid IRI syntax")
if is_valid_syntax(term='iri_reference', value='bob'):
print("✓ Valid IRI-reference syntax")
Alternatively, use term-specific helpers to validate RFC 3987 syntax.
from rfc3987_syntax2 import is_valid_syntax_iri
from rfc3987_syntax2 import is_valid_syntax_iri_reference
if is_valid_syntax_iri('http://github.com'):
print("✓ Valid IRI syntax")
if not is_valid_syntax_iri('bob'):
print("✗ Invalid IRI syntax")
if is_valid_syntax_iri_reference('bob'):
print("✓ Valid IRI-reference syntax")
Get the Lark parse tree for a syntax validation (useful for additional semantic validation)
from rfc3987_syntax2 import parse
ptree: ParseTree = parse(term="iri", value="http://github.com")
print(ptree)
📚 Sources
This grammar was derived from:
-
RFC 3987 – Internationalized Resource Identifiers (IRIs)
→ Defines IRI syntax and extensions to URI (e.g. Unicode characters,ucschar)
→ https://datatracker.ietf.org/doc/html/rfc3987 -
RFC 3986 – Uniform Resource Identifier (URI): Generic Syntax
→ Provides reusable components likescheme,authority,ipv4address, etc.
→ https://datatracker.ietf.org/doc/html/rfc3986
📝 When
RFC 3986is listed as the source, it is used in accordance with RFC 3987, which explicitly references it for foundational elements.
Rule-to-Source Mapping
| Rule/Component | Source | Notes |
|---|---|---|
iri |
RFC 3987 | Top-level IRI rule |
iri_reference |
RFC 3987 | Top-level IRI Reference rule |
absolute_iri |
RFC 3987 | Top-level Absolute IRI rule |
scheme |
RFC 3986 | Referenced by RFC 3987 §2.2 |
ihier_part |
RFC 3987 | IRI-specific hierarchy |
irelative_ref |
RFC 3987 | IRI-specific relative ref |
irelative_part |
RFC 3987 | IRI-specific relative part |
iauthority |
RFC 3987 | IRI authority production |
iuserinfo |
RFC 3987 | IRI userinfo production |
ihost |
RFC 3987 | IRI host production |
ireg_name |
RFC 3987 | IRI reg-name production |
ipath |
RFC 3987 | Union of IRI path variants |
ipath_abempty |
RFC 3987 | IRI path format variant |
ipath_absolute |
RFC 3987 | Absolute path |
ipath_noscheme |
RFC 3987 | Path disallowing scheme prefix |
ipath_rootless |
RFC 3987 | Used in non-scheme contexts |
ipath_empty |
RFC 3987 | Empty IRI path |
iquery |
RFC 3987 | Query extension to URI |
ifragment |
RFC 3987 | Fragment extension to URI |
ipchar, isegment |
RFC 3987 | IRI path characters and segments |
isegment_nz_nc |
RFC 3987 | IRI-specific path constraint |
iunreserved |
RFC 3987 | Includes ucschar |
ucschar, iprivate |
RFC 3987 | Unicode support |
sub_delims |
RFC 3986 | Reserved characters |
ip_literal |
RFC 3986 | IPv6 or IPvFuture in [] |
ipv6address |
RFC 3986 | RFC 3986 IPv6address production; syntax-level validation only |
ipvfuture |
RFC 3986 | Forward-compatible |
ipv4address |
RFC 3986 | Dotted-decimal IPv4 |
ls32 |
RFC 3986 | Final 32 bits of IPv6 |
h16, dec_octet |
RFC 3986 | Hex and decimal chunks |
port |
RFC 3986 | Optional numeric |
pct_encoded |
RFC 3986 | Percent encoding (e.g. %20) |
alpha, digit, hexdig |
RFC 3986 | Character classes |
non_zero |
Project helper | Local helper token used in dec_octet |
unreserved |
RFC 3986 | Used by ipvfuture production |
Metadata
Release files for rfc3987-syntax2 1.3.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rfc3987_syntax2-1.3.3.tar.gz | 25.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rfc3987_syntax2-1.3.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.8 kB
Release files / rfc3987_syntax2-1.3.3.tar.gz
| Download URL | rfc3987_syntax2-1.3.3.tar.gz |
|---|---|
| Size | 25.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5052d5db3b394023130978494e73a3ad41f005455ed8ddeb5cfebfca157eb749
|
|
BLAKE2b-256 checksum How to use checksums |
225f818f567d676449c8cba44e4a27b07a22bf06209f972ff03f1654720033a3
|
| 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 Oct 5, 2026.
Transparency logRelease files / rfc3987_syntax2-1.3.3-py3-none-any.whl
| Download URL | rfc3987_syntax2-1.3.3-py3-none-any.whl |
|---|---|
| Size | 11.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a6e92c8550974797f5e40b0e4f775aa7402d7ed4531cc85f83d114211f4ccc04
|
|
BLAKE2b-256 checksum How to use checksums |
97bd97aa1fd4fd3fea3d0be19b5fe1a0a8a557714972d5fefa1713efd3125200
|
| 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 Oct 5, 2026.
Transparency log