From bb931c710986f60d5e989e02ff680f461d9d3e08 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 16 Jul 2026 13:15:24 +0200 Subject: [PATCH 1/3] docs: update readme after PR#10 Signed-off-by: Jan Kowalleck --- README.md | 124 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index d000c95..1b780bf 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,17 @@ Helper functions to parse and validate the **syntax** of terms defined in **[RFC ## 🎯 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: +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** (with delegated productions from RFC 3986 where RFC 3987 explicitly reuses them). + +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](https://github.com/lark-parser/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. +> 🧠 **Note:** This project focuses on **syntax validation only**. +> RFC 3987 also defines semantic and processing requirements (for example Unicode normalization expectations, BiDi constraints, and IRI↔URI mapping behavior) that are intentionally out of scope for this package. ## πŸ“„ License, Attribution, and Citation @@ -30,21 +33,23 @@ This project: - ❌ Does **not** depend on the `rfc3987` Python package (GPL-licensed) - βœ… Uses [`lark`](https://github.com/lark-parser/lark), licensed under MIT -- βœ… Implements grammar from **[RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)**, using **[RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986)** where RFC 3987 delegates syntax +- βœ… Implements grammar derived from **[RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)** and its normative dependencies on **[RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986)** > ⚠️ This project is **not affiliated with or endorsed by** the authors of RFC 3987 or the `rfc3987` Python 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: +The grammar/parser enforce **ABNF-level syntax only**. They do **not** enforce all semantic/procedural requirements from RFC 3987 and related specs. + +Examples of intentionally out-of-scope validation include: -- βœ… 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) +- ❌ Unicode **Normalization Form C (NFC)** enforcement +- ❌ Bidirectional text (**BiDi**) rule enforcement (RFC 3987 Β§4.1) +- ❌ Context-aware IRI↔URI mapping policy checks +- ❌ Port range policy checks beyond syntax (e.g., numeric bounds such as 0–65535) +- ❌ Higher-level host/network canonicalization or resolution semantics -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. +ChatGPT-4o was used during parts of original development. Errors may exist. Additional review, testing, and bug fixes by human experts are welcome. ## πŸ“¦ Installation @@ -54,7 +59,7 @@ pip install rfc3987-syntax2 ## πŸ›  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 +### List all supported terms ```python from rfc3987_syntax2 import RFC3987_SYNTAX_TERMS @@ -64,7 +69,7 @@ for term in RFC3987_SYNTAX_TERMS: print(term) ``` -### Syntactically validate a string using the general-purpose validator +### Validate syntax with the generic validator ```python from rfc3987_syntax2 import is_valid_syntax @@ -75,11 +80,11 @@ if is_valid_syntax(term='iri', value='http://github.com'): if not is_valid_syntax(term='iri', value='bob'): print("βœ— Invalid IRI syntax") -if not is_valid_syntax(term='iri_reference', value='bob'): +if is_valid_syntax(term='iri_reference', value='bob'): print("βœ“ Valid IRI-reference syntax") ``` -### Alternatively, use term-specific helpers to validate RFC 3987 syntax. +### Or use term-specific helpers ```python from rfc3987_syntax2 import is_valid_syntax_iri @@ -95,62 +100,85 @@ 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) +### Get a Lark parse tree ```python +from lark import Tree as ParseTree from rfc3987_syntax2 import parse ptree: ParseTree = parse(term="iri", value="http://github.com") - print(ptree) ``` ## πŸ“š Sources -This grammar was derived from: +This grammar is based on: - **RFC 3987 – Internationalized Resource Identifiers (IRIs)** - β†’ Defines IRI syntax and extensions to URI (e.g. Unicode characters, `ucschar`) + β†’ Primary source for `IRI`, `IRI-reference`, and `i*` grammar productions β†’ https://datatracker.ietf.org/doc/html/rfc3987 - **RFC 3986 – Uniform Resource Identifier (URI): Generic Syntax** - β†’ Provides reusable components like `scheme`, `authority`, `ipv4address`, etc. + β†’ Source for foundational URI productions reused by RFC 3987 (e.g., `scheme`, `port`, `ipv4address`, `ipv6address`, `pct-encoded`, character classes) β†’ https://datatracker.ietf.org/doc/html/rfc3986 -> πŸ“ When `RFC 3986` is listed as the source, it is **used in accordance with RFC 3987**, which explicitly references it for foundational elements. +> πŸ“ Attribution policy used in this project: +> - Productions named with `i...` are treated as RFC 3987 productions. +> - Non-`i` foundational productions reused by RFC 3987 are attributed to RFC 3986. -### Rule-to-Source Mapping +### Rule-to-Source Mapping (aligned to current grammar) | 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 3986 | Standard URI authority | -| `ipath_abempty` | RFC 3986 | Path format variant | -| `ipath_absolute` | RFC 3986 | Absolute path | -| `ipath_noscheme` | RFC 3986 | Path disallowing scheme prefix | -| `ipath_rootless` | RFC 3986 | Used in non-scheme contexts | -| `iquery` | RFC 3987 | Query extension to URI | -| `ifragment` | RFC 3987 | Fragment extension to URI | -| `ipchar`, `isegment` | RFC 3986 | Path characters and segments | -| `isegment_nz_nc` | RFC 3987 | IRI-specific path constraint | +| `iri_reference` | RFC 3987 | Top-level IRI-reference rule | +| `absolute_iri` | RFC 3987 | Absolute IRI rule | +| `ihier_part` | RFC 3987 | IRI hierarchy | +| `irelative_ref` | RFC 3987 | Relative IRI-reference | +| `irelative_part` | RFC 3987 | Relative IRI hierarchy | +| `iauthority` | RFC 3987 | IRI authority production | +| `ihost` | RFC 3987 | IRI host production | +| `ireg_name` | RFC 3987 | IRI reg-name (Unicode-capable via `iunreserved`) | +| `iuserinfo` | RFC 3987 | IRI userinfo | +| `ipath` | RFC 3987 | IRI path union | +| `ipath_abempty` | RFC 3987 | IRI path variant | +| `ipath_absolute` | RFC 3987 | IRI path variant | +| `ipath_noscheme` | RFC 3987 | IRI path variant | +| `ipath_rootless` | RFC 3987 | IRI path variant | +| `ipath_empty` | RFC 3987 | Empty IRI path | +| `isegment` | RFC 3987 | IRI segment | +| `isegment_nz` | RFC 3987 | Non-empty IRI segment | +| `isegment_nz_nc` | RFC 3987 | Non-empty, no-colon first segment form | +| `ipchar` | RFC 3987 | IRI path character | +| `iquery` | RFC 3987 | IRI query | +| `ifragment` | RFC 3987 | IRI fragment | | `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 | +| `ucschar` | RFC 3987 | Unicode range class | +| `iprivate` | RFC 3987 | Private-use Unicode range class | +| `scheme` | RFC 3986 | Reused foundational URI production | +| `sub_delims` | RFC 3986 | Reused delimiters | +| `ip_literal` | RFC 3986 | Bracketed literal host | +| `ipvfuture` | RFC 3986 | IPvFuture form | +| `ipv6address` | RFC 3986 | IPv6 ABNF syntax only | +| `ls32` | RFC 3986 | IPv6 helper production | +| `h16` | RFC 3986 | IPv6 helper production | +| `ipv4address` | RFC 3986 | Dotted-decimal IPv4 syntax | +| `dec_octet` | RFC 3986 | IPv4 octet syntax | +| `port` | RFC 3986 | `*DIGIT` syntax only | +| `pct_encoded` | RFC 3986 | Percent-encoded triplet | +| `alpha` | RFC 3986 | Character class | +| `digit` | RFC 3986 | Character class | +| `hexdig` | RFC 3986 | Character class | +| `non_zero` | Project helper | Convenience token used to express `dec_octet` | +| `unreserved` | RFC 3986 | Used by `ipvfuture` branch | + +## βœ… Scope statement (quick reference) + +`rfc3987-syntax2` answers: +**β€œDoes this string match the RFC ABNF syntax for the requested term?”** + +It does **not** answer: +**β€œIs this identifier semantically valid in all RFC processing contexts?”** [shield_gh-workflow-test]: https://img.shields.io/github/actions/workflow/status/jkowalleck/rfc3987-syntax2/python-tests.yml?branch=main&logo=GitHub&logoColor=white "tests" [shield_pypi-version]: https://img.shields.io/pypi/v/rfc3987-syntax2?logo=Python&logoColor=white&label=PyPI "PyPI" From 210c7fd8b441bcebe4197eb798dac4f676678884 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 16 Jul 2026 13:41:46 +0200 Subject: [PATCH 2/3] docs Signed-off-by: Jan Kowalleck --- README.md | 124 +++++++++++++++++++++--------------------------------- 1 file changed, 48 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 1b780bf..d000c95 100644 --- a/README.md +++ b/README.md @@ -13,17 +13,14 @@ Helper functions to parse and validate the **syntax** of terms defined in **[RFC ## 🎯 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** (with delegated productions from RFC 3986 where RFC 3987 explicitly reuses them). - -These helpers are: +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](https://github.com/lark-parser/lark), a fast, EBNF-based parser -> 🧠 **Note:** This project focuses on **syntax validation only**. -> RFC 3987 also defines semantic and processing requirements (for example Unicode normalization expectations, BiDi constraints, and IRI↔URI mapping behavior) that are intentionally out of scope for this package. +> 🧠 **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 @@ -33,23 +30,21 @@ This project: - ❌ Does **not** depend on the `rfc3987` Python package (GPL-licensed) - βœ… Uses [`lark`](https://github.com/lark-parser/lark), licensed under MIT -- βœ… Implements grammar derived from **[RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)** and its normative dependencies on **[RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986)** +- βœ… Implements grammar from **[RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)**, using **[RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986)** where RFC 3987 delegates syntax > ⚠️ This project is **not affiliated with or endorsed by** the authors of RFC 3987 or the `rfc3987` Python package. ## ⚠️ Limitations -The grammar/parser enforce **ABNF-level syntax only**. They do **not** enforce all semantic/procedural requirements from RFC 3987 and related specs. - -Examples of intentionally out-of-scope validation include: +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)** enforcement -- ❌ Bidirectional text (**BiDi**) rule enforcement (RFC 3987 Β§4.1) -- ❌ Context-aware IRI↔URI mapping policy checks -- ❌ Port range policy checks beyond syntax (e.g., numeric bounds such as 0–65535) -- ❌ Higher-level host/network canonicalization or resolution semantics +- βœ… 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-4o was used during parts of original development. Errors may exist. Additional review, testing, and bug fixes by human experts are welcome. +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 @@ -59,7 +54,7 @@ pip install rfc3987-syntax2 ## πŸ›  Usage -### List all supported terms +### 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 ```python from rfc3987_syntax2 import RFC3987_SYNTAX_TERMS @@ -69,7 +64,7 @@ for term in RFC3987_SYNTAX_TERMS: print(term) ``` -### Validate syntax with the generic validator +### Syntactically validate a string using the general-purpose validator ```python from rfc3987_syntax2 import is_valid_syntax @@ -80,11 +75,11 @@ if is_valid_syntax(term='iri', value='http://github.com'): if not is_valid_syntax(term='iri', value='bob'): print("βœ— Invalid IRI syntax") -if is_valid_syntax(term='iri_reference', value='bob'): +if not is_valid_syntax(term='iri_reference', value='bob'): print("βœ“ Valid IRI-reference syntax") ``` -### Or use term-specific helpers +### Alternatively, use term-specific helpers to validate RFC 3987 syntax. ```python from rfc3987_syntax2 import is_valid_syntax_iri @@ -100,85 +95,62 @@ if is_valid_syntax_iri_reference('bob'): print("βœ“ Valid IRI-reference syntax") ``` -### Get a Lark parse tree +### Get the Lark parse tree for a syntax validation (useful for additional semantic validation) ```python -from lark import Tree as ParseTree from rfc3987_syntax2 import parse ptree: ParseTree = parse(term="iri", value="http://github.com") + print(ptree) ``` ## πŸ“š Sources -This grammar is based on: +This grammar was derived from: - **RFC 3987 – Internationalized Resource Identifiers (IRIs)** - β†’ Primary source for `IRI`, `IRI-reference`, and `i*` grammar productions + β†’ 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** - β†’ Source for foundational URI productions reused by RFC 3987 (e.g., `scheme`, `port`, `ipv4address`, `ipv6address`, `pct-encoded`, character classes) + β†’ Provides reusable components like `scheme`, `authority`, `ipv4address`, etc. β†’ https://datatracker.ietf.org/doc/html/rfc3986 -> πŸ“ Attribution policy used in this project: -> - Productions named with `i...` are treated as RFC 3987 productions. -> - Non-`i` foundational productions reused by RFC 3987 are attributed to RFC 3986. +> πŸ“ When `RFC 3986` is listed as the source, it is **used in accordance with RFC 3987**, which explicitly references it for foundational elements. -### Rule-to-Source Mapping (aligned to current grammar) +### 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 | Absolute IRI rule | -| `ihier_part` | RFC 3987 | IRI hierarchy | -| `irelative_ref` | RFC 3987 | Relative IRI-reference | -| `irelative_part` | RFC 3987 | Relative IRI hierarchy | -| `iauthority` | RFC 3987 | IRI authority production | -| `ihost` | RFC 3987 | IRI host production | -| `ireg_name` | RFC 3987 | IRI reg-name (Unicode-capable via `iunreserved`) | -| `iuserinfo` | RFC 3987 | IRI userinfo | -| `ipath` | RFC 3987 | IRI path union | -| `ipath_abempty` | RFC 3987 | IRI path variant | -| `ipath_absolute` | RFC 3987 | IRI path variant | -| `ipath_noscheme` | RFC 3987 | IRI path variant | -| `ipath_rootless` | RFC 3987 | IRI path variant | -| `ipath_empty` | RFC 3987 | Empty IRI path | -| `isegment` | RFC 3987 | IRI segment | -| `isegment_nz` | RFC 3987 | Non-empty IRI segment | -| `isegment_nz_nc` | RFC 3987 | Non-empty, no-colon first segment form | -| `ipchar` | RFC 3987 | IRI path character | -| `iquery` | RFC 3987 | IRI query | -| `ifragment` | RFC 3987 | IRI fragment | +| `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 3986 | Standard URI authority | +| `ipath_abempty` | RFC 3986 | Path format variant | +| `ipath_absolute` | RFC 3986 | Absolute path | +| `ipath_noscheme` | RFC 3986 | Path disallowing scheme prefix | +| `ipath_rootless` | RFC 3986 | Used in non-scheme contexts | +| `iquery` | RFC 3987 | Query extension to URI | +| `ifragment` | RFC 3987 | Fragment extension to URI | +| `ipchar`, `isegment` | RFC 3986 | Path characters and segments | +| `isegment_nz_nc` | RFC 3987 | IRI-specific path constraint | | `iunreserved` | RFC 3987 | Includes `ucschar` | -| `ucschar` | RFC 3987 | Unicode range class | -| `iprivate` | RFC 3987 | Private-use Unicode range class | -| `scheme` | RFC 3986 | Reused foundational URI production | -| `sub_delims` | RFC 3986 | Reused delimiters | -| `ip_literal` | RFC 3986 | Bracketed literal host | -| `ipvfuture` | RFC 3986 | IPvFuture form | -| `ipv6address` | RFC 3986 | IPv6 ABNF syntax only | -| `ls32` | RFC 3986 | IPv6 helper production | -| `h16` | RFC 3986 | IPv6 helper production | -| `ipv4address` | RFC 3986 | Dotted-decimal IPv4 syntax | -| `dec_octet` | RFC 3986 | IPv4 octet syntax | -| `port` | RFC 3986 | `*DIGIT` syntax only | -| `pct_encoded` | RFC 3986 | Percent-encoded triplet | -| `alpha` | RFC 3986 | Character class | -| `digit` | RFC 3986 | Character class | -| `hexdig` | RFC 3986 | Character class | -| `non_zero` | Project helper | Convenience token used to express `dec_octet` | -| `unreserved` | RFC 3986 | Used by `ipvfuture` branch | - -## βœ… Scope statement (quick reference) - -`rfc3987-syntax2` answers: -**β€œDoes this string match the RFC ABNF syntax for the requested term?”** - -It does **not** answer: -**β€œIs this identifier semantically valid in all RFC processing contexts?”** +| `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 | [shield_gh-workflow-test]: https://img.shields.io/github/actions/workflow/status/jkowalleck/rfc3987-syntax2/python-tests.yml?branch=main&logo=GitHub&logoColor=white "tests" [shield_pypi-version]: https://img.shields.io/pypi/v/rfc3987-syntax2?logo=Python&logoColor=white&label=PyPI "PyPI" From 009cf68829358c59031bc5327a1a0e3364c022a6 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Thu, 16 Jul 2026 13:46:38 +0200 Subject: [PATCH 3/3] docs Signed-off-by: Jan Kowalleck --- README.md | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d000c95..1cab710 100644 --- a/README.md +++ b/README.md @@ -36,13 +36,14 @@ This project: ## ⚠️ 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: +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) +- 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. @@ -75,7 +76,7 @@ if is_valid_syntax(term='iri', value='http://github.com'): if not is_valid_syntax(term='iri', value='bob'): print("βœ— Invalid IRI syntax") -if not is_valid_syntax(term='iri_reference', value='bob'): +if is_valid_syntax(term='iri_reference', value='bob'): print("βœ“ Valid IRI-reference syntax") ``` @@ -130,14 +131,19 @@ This grammar was derived from: | `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 3986 | Standard URI authority | -| `ipath_abempty` | RFC 3986 | Path format variant | -| `ipath_absolute` | RFC 3986 | Absolute path | -| `ipath_noscheme` | RFC 3986 | Path disallowing scheme prefix | -| `ipath_rootless` | RFC 3986 | Used in non-scheme contexts | +| `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 3986 | Path characters and segments | +| `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 | @@ -151,6 +157,8 @@ This grammar was derived from: | `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 | [shield_gh-workflow-test]: https://img.shields.io/github/actions/workflow/status/jkowalleck/rfc3987-syntax2/python-tests.yml?branch=main&logo=GitHub&logoColor=white "tests" [shield_pypi-version]: https://img.shields.io/pypi/v/rfc3987-syntax2?logo=Python&logoColor=white&label=PyPI "PyPI"