diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index ed74d3f..b413f04 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -50,6 +50,8 @@ jobs: needs: - quick-test runs-on: ubuntu-latest + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing steps: - name: Checkout # see https://github.com/actions/checkout @@ -70,7 +72,4 @@ jobs: run: python -m build - name: Publish package # see https://github.com/pypa/gh-action-pypi-publish - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 # v1.4.2 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} \ No newline at end of file + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..92aec27 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,20 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## Unreleased + + + +## v1.1.0 - 2025-07-18 + +Original release: + +* Features + * Added add support for IRI-reference and absolute-IRI +* Bugs + * Fixed single quote sub-delimiter + +## v1.0.0 - 2025-05-18 + +Original release: \ No newline at end of file diff --git a/CITATION.cff b/CITATION.cff deleted file mode 100644 index f062222..0000000 --- a/CITATION.cff +++ /dev/null @@ -1,71 +0,0 @@ -cff-version: 1.2.0 -title: rfc3987-syntax -message: >- - If you use this software, please cite it using the - metadata from this file. -type: software -authors: - - given-names: Will - family-names: Riley - email: wanderingwill@gmail.com - orcid: "https://orcid.org/0000-0003-1822-6756" - - given-names: Jan - family-names: Kowalleck -repository-code: >- - https://github.com/willynilly/rfc3987-syntax -abstract: >- - Helper functions to syntactically validate strings according to RFC 3987 -keywords: - - RFC 3987 - - RFC3987 - - validator - - syntax - - parser -license: MIT -version: "1.1.0" -date-released: "2025-07-18" -references: - - title: "abnf-to-regexp" - type: software - version: "1.1.3" - license: MIT - authors: - - given-names: Marko - family-names: Ristin - email: marko@ristin.ch - orcid: "" - - given-names: Oliver Steensen-Bech - family-names: Haagh - email: oliver@dmc.international - orcid: "" - - given-names: Sebastian - family-names: Heppner - email: s.heppner@iat.rwth-aachen.de - orcid: "" - repository-code: https://github.com/aas-core-works/abnf-to-regexp - - title: "lark" - type: software - version: 1.2.2 - license: MIT - authors: - - family-names: Shinan - given-names: Erez - email: erezshin@gmail.com - repository-code: https://github.com/lark-parser/lark - - title: "Internationalized Resource Identifiers (IRIs)" - authors: - - family-names: DΓΌrst - given-names: Martin - - family-names: Suignard - given-names: Michel - date-released: 2005-01-01 - doi: "10.17487/RFC3987" - url: "https://www.rfc-editor.org/info/rfc3987" - type: standard - - title: "ChatGPT" - authors: - - name: OpenAI - type: software - version: "GPT-4o" - url: "https://chat.openai.com/chat" - \ No newline at end of file diff --git a/LICENSE b/LICENSE index dbc72c3..6efa3e6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2025 Will Riley +Copyright (c) 2026 Jan Kowalleck β€” modifications and maintenance. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 2e4d2e2..4623b0e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ -# rfc3987-syntax +# rfc3987-syntax2 Helper functions to parse and validate the **syntax** of terms defined in **[RFC 3987](https://www.rfc-editor.org/info/rfc3987)** β€” the IETF standard for Internationalized Resource Identifiers (IRIs). +> [!NOTE] +> This is a maintained fork of . ## 🎯 Purpose -The goal of `rfc3987-syntax` 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**. These helpers are: - βœ… Strictly aligned with the **syntax rules of RFC 3987** - βœ… Built using a **permissive MIT license** @@ -17,7 +19,7 @@ The goal of `rfc3987-syntax` is to provide a **lightweight, permissively license ## πŸ“„ License, Attribution, and Citation -**`rfc3987-syntax`** is licensed under the [MIT License](LICENSE), which allows reuse in both open source and commercial software. +**`rfc3987-syntax2`** is licensed under the [MIT License](LICENSE), which allows reuse in both open source and commercial software. This project: @@ -46,7 +48,7 @@ ChatGPT 40 was used during the original development process. Errors may exist du ## πŸ“¦ Installation ```bash -pip install rfc3987-syntax +pip install rfc3987-syntax2 ``` ## πŸ›  Usage @@ -54,7 +56,7 @@ pip install rfc3987-syntax ### 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_syntax import RFC3987_SYNTAX_TERMS +from rfc3987_syntax2 import RFC3987_SYNTAX_TERMS print("Supported terms:") for term in RFC3987_SYNTAX_TERMS: @@ -64,7 +66,7 @@ for term in RFC3987_SYNTAX_TERMS: ### Syntactically validate a string using the general-purpose validator ```python -from rfc3987_syntax import is_valid_syntax +from rfc3987_syntax2 import is_valid_syntax if is_valid_syntax(term='iri', value='http://github.com'): print("βœ“ Valid IRI syntax") @@ -79,8 +81,8 @@ if not is_valid_syntax(term='iri_reference', value='bob'): ### Alternatively, use term-specific helpers to validate RFC 3987 syntax. ```python -from rfc3987_syntax import is_valid_syntax_iri -from rfc3987_syntax import is_valid_syntax_iri_reference +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") @@ -95,7 +97,7 @@ if is_valid_syntax_iri_reference('bob'): ### Get the Lark parse tree for a syntax validation (useful for additional semantic validation) ```python -from rfc3987_syntax import parse +from rfc3987_syntax2 import parse ptree: ParseTree = parse(term="iri", value="http://github.com") diff --git a/pyproject.toml b/pyproject.toml index e0e1c16..da96c4f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,8 +3,8 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "rfc3987-syntax" -version = "1.1.0" +name = "rfc3987-syntax2" +version = "1.1.0rc2" description = "Helper functions to syntactically validate strings according to RFC 3987." readme = "README.md" requires-python = ">=3.9" @@ -12,21 +12,21 @@ license = "MIT" license-files = ["LICEN[CS]E*"] keywords = ["RFC 3987", "RFC3987", "validator", "syntax", "parser"] authors = [ - { name = "Will Riley", email = "wanderingwill@gmail.com" }, - { name = "Jan Kowalleck" } + { name = "Jan Kowalleck" }, + { name = "Will Riley", email = "wanderingwill@gmail.com" } ] classifiers = [ + # ALPHA - not all features of RFC 3987 are implemented, yet "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "Intended Audience :: System Administrators", - "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Topic :: Scientific/Engineering", "Topic :: Software Development", "Topic :: Utilities" @@ -34,10 +34,10 @@ classifiers = [ dependencies = ["lark>=1.2.2"] [project.urls] -Homepage = "https://github.com/willynilly/rfc3987-syntax" -Documentation = "https://github.com/willynilly/rfc3987-syntax#readme" -Issues = "https://github.com/willynilly/rfc3987-syntax/issues" -Source = "https://github.com/willynilly/rfc3987-syntax" +Homepage = "https://github.com/jkowalleck/rfc3987-syntax2" +Documentation = "https://github.com/jkowalleck/rfc3987-syntax2#readme" +Issues = "https://github.com/jkowalleck/rfc3987-syntax2/issues" +Source = "https://github.com/jkowalleck/rfc3987-syntax2" [project.optional-dependencies] testing = [ @@ -45,9 +45,17 @@ testing = [ ] [tool.pytest.ini_options] -pythonpath = [ - "src" +pythonpath = ["src"] + +[tool.hatch.build.targets.sdist] +exclude = [ + "/.*", + "/_*", +] +include = [ + "/src", + "/tests" ] -[tool.hatch.build.targets.sdist.force-include] -"CITATION.cff" = "src/rfc3987_syntax/CITATION.cff" \ No newline at end of file +[tool.hatch.build.targets.wheel] +packages = ["src/rfc3987_syntax2"] diff --git a/src/rfc3987_syntax/__init__.py b/src/rfc3987_syntax2/__init__.py similarity index 100% rename from src/rfc3987_syntax/__init__.py rename to src/rfc3987_syntax2/__init__.py diff --git a/src/rfc3987_syntax/syntax_helpers.py b/src/rfc3987_syntax2/syntax_helpers.py similarity index 98% rename from src/rfc3987_syntax/syntax_helpers.py rename to src/rfc3987_syntax2/syntax_helpers.py index fcb3f32..117a2ce 100644 --- a/src/rfc3987_syntax/syntax_helpers.py +++ b/src/rfc3987_syntax2/syntax_helpers.py @@ -2,7 +2,7 @@ from pathlib import Path -from rfc3987_syntax.utils import load_grammar +from .utils import load_grammar RFC3987_SYNTAX_PARSER_TYPE: str = "earley" RFC3987_SYNTAX_GRAMMAR_PATH: Path = Path(__file__).parent / "syntax_rfc3987.lark" diff --git a/src/rfc3987_syntax/syntax_rfc3987.lark b/src/rfc3987_syntax2/syntax_rfc3987.lark similarity index 100% rename from src/rfc3987_syntax/syntax_rfc3987.lark rename to src/rfc3987_syntax2/syntax_rfc3987.lark diff --git a/src/rfc3987_syntax/utils.py b/src/rfc3987_syntax2/utils.py similarity index 100% rename from src/rfc3987_syntax/utils.py rename to src/rfc3987_syntax2/utils.py diff --git a/tests/test_syntax.py b/tests/test_syntax.py index d71923c..4974ae2 100644 --- a/tests/test_syntax.py +++ b/tests/test_syntax.py @@ -1,8 +1,9 @@ from pathlib import Path -import rfc3987_syntax as h import json import pytest +import rfc3987_syntax2 as sut + @pytest.fixture def valid_syntax_data(): @@ -19,13 +20,13 @@ def invalid_syntax_data(): def test_is_valid_syntax(valid_syntax_data): for term, valid_examples in valid_syntax_data.items(): for valid_example in valid_examples: - actual = h.is_valid_syntax(term=term, value=valid_example["value"]) + actual = sut.is_valid_syntax(term=term, value=valid_example["value"]) print("") print( f"Testing {term} with {valid_example['value']} : {valid_example['reason']}" ) assert ( - actual is True + actual is True ), f"Failed term: {term} for '{valid_example['value']}' : {valid_example['reason']}" assert True @@ -33,7 +34,7 @@ def test_is_valid_syntax(valid_syntax_data): def test_not_is_valid_syntax(invalid_syntax_data): for term, invalid_examples in invalid_syntax_data.items(): for invalid_example in invalid_examples: - actual = h.is_valid_syntax(term=term, value=invalid_example["value"]) + actual = sut.is_valid_syntax(term=term, value=invalid_example["value"]) print("") print( f"Testing {term} with {invalid_example['value']} : {invalid_example['reason']}"