From 3f2ac87afb4c6bc308c6f17b935dd9c094e58aa6 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 08:47:28 -0400 Subject: [PATCH 01/19] feat: use pyproject.toml for build --- rustfst-python/pyproject.toml | 48 +++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/rustfst-python/pyproject.toml b/rustfst-python/pyproject.toml index 84f037aaf..07354fea6 100644 --- a/rustfst-python/pyproject.toml +++ b/rustfst-python/pyproject.toml @@ -1,6 +1,44 @@ [build-system] -requires = [ - "setuptools>=62.1,<63", - "setuptools_rust>=1.3,<1.4", - "wheel>=0.34,<0.35", -] \ No newline at end of file +requires = ["setuptools", "setuptools-rust"] +build-backend = "setuptools.build_meta" + +[project] +name = "rustfst-python" +version = "1.1.1" +authors = [ + { name = "Alexandre Caulier", email = "alexandre.caulier.a@gmail.com" }, + { name = "Emrick Sinitambirivoutin", email = "emrick.sinitambirivoutin@sonos.com" }, +] +description = "Library for constructing, combining, optimizing, and searching weighted finite-state transducers (FSTs). Re-implementation of OpenFst in Rust." +# readme = "../README.md" +requires-python = ">=3.8" +keywords = ["fst", "openfst", "graph", "transducer", "acceptor", + "shortest-path", "minimize", "determinize", "wfst"] +license = { text="Apache License, Version 2.0" } +classifiers = [ + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Rust", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Topic :: Text Processing", + "License :: OSI Approved :: Apache Software License", +] + +[project.optional-dependencies] +tests = [ "pytest>=6,<7", "pylint" ] + +# Not sure about this one... +# options={"bdist_wheel": {"universal": True}}, + +[tool.setuptools.packages.find] +include = ["rustfst"] + +[[tool.setuptools-rust.ext-modules]] +target = "rustfst.dylib.dylib" +path = "../rustfst-ffi/Cargo.toml" +binding = "NoBinding" From 2070eef2644e84afbba75b1b7ac416d664dc0594 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 09:43:30 -0400 Subject: [PATCH 02/19] fix: move pyproject.toml up and make rustfst-python buildable from source --- MANIFEST.in | 4 + .../pyproject.toml => pyproject.toml | 10 +-- rustfst-python/setup.py | 82 ------------------- 3 files changed, 9 insertions(+), 87 deletions(-) create mode 100644 MANIFEST.in rename rustfst-python/pyproject.toml => pyproject.toml (88%) delete mode 100644 rustfst-python/setup.py diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 000000000..bfa251520 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,4 @@ +include Cargo.toml +recursive-include rustfst *.toml *.rs +recursive-include rustfst-cli *.toml *.rs +recursive-include rustfst-ffi *.toml *.rs diff --git a/rustfst-python/pyproject.toml b/pyproject.toml similarity index 88% rename from rustfst-python/pyproject.toml rename to pyproject.toml index 07354fea6..f2a951d1b 100644 --- a/rustfst-python/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ authors = [ { name = "Emrick Sinitambirivoutin", email = "emrick.sinitambirivoutin@sonos.com" }, ] description = "Library for constructing, combining, optimizing, and searching weighted finite-state transducers (FSTs). Re-implementation of OpenFst in Rust." -# readme = "../README.md" +readme = "README.md" requires-python = ">=3.8" keywords = ["fst", "openfst", "graph", "transducer", "acceptor", "shortest-path", "minimize", "determinize", "wfst"] @@ -32,13 +32,13 @@ classifiers = [ [project.optional-dependencies] tests = [ "pytest>=6,<7", "pylint" ] -# Not sure about this one... +# This was in setup.py but is no longer relevant (it's not for Mac OS X) # options={"bdist_wheel": {"universal": True}}, -[tool.setuptools.packages.find] -include = ["rustfst"] +[tool.setuptools] +package-dir = {"rustfst" = "rustfst-python/rustfst"} [[tool.setuptools-rust.ext-modules]] target = "rustfst.dylib.dylib" -path = "../rustfst-ffi/Cargo.toml" +path = "rustfst-ffi/Cargo.toml" binding = "NoBinding" diff --git a/rustfst-python/setup.py b/rustfst-python/setup.py deleted file mode 100644 index 365d3fc85..000000000 --- a/rustfst-python/setup.py +++ /dev/null @@ -1,82 +0,0 @@ -import os -import sys -from pathlib import Path - -from setuptools import setup, find_packages -from setuptools_rust import Binding, RustExtension - -packages = [p for p in find_packages() if "tests" not in p] - -root = Path(__file__).resolve().parent.parent - -readme_path = root / "README.md" -readme = None -if readme_path.exists(): - with readme_path.open() as f: - readme = f.read() - -PACKAGE_NAME = "rustfst-python" -RUST_EXTENSION_NAME = "rustfst.dylib.dylib" -VERSION = "1.1.2" -REPO_ROOT_PATH = Path(__file__).resolve().parents[1] -CARGO_ROOT_PATH = REPO_ROOT_PATH / "rustfst-ffi" -CARGO_FILE_PATH = CARGO_ROOT_PATH / "Cargo.toml" -CARGO_TARGET_DIR = REPO_ROOT_PATH / "target" -os.environ["CARGO_TARGET_DIR"] = str(CARGO_TARGET_DIR) - -if "PROFILE" in os.environ: - if os.environ.get("PROFILE") == "release": - is_debug_profile = False - elif os.environ.get("PROFILE") == "debug": - is_debug_profile = True - else: - print("Invalid PROFILE %s" % os.environ.get("PROFILE")) - sys.exit(1) -else: - is_debug_profile = "develop" in sys.argv - -setup( - name=PACKAGE_NAME, - version=VERSION, - description="Library for constructing, combining, optimizing, and searching weighted finite-state " - "transducers (FSTs). Re-implementation of OpenFst in Rust.", - long_description=readme, - long_description_content_type="text/markdown", - extras_require={"tests": ["pytest>=6,<7"]}, - options={"bdist_wheel": {"universal": True}}, - classifiers=[ - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Rust", - "Topic :: Scientific/Engineering :: Mathematics", - "Topic :: Scientific/Engineering :: Artificial Intelligence", - "Topic :: Text Processing", - "License :: OSI Approved :: Apache Software License", - ], - packages=packages, - package_data={"rustfst": ["py.typed"]}, - include_package_data=True, - rust_extensions=[ - RustExtension( - RUST_EXTENSION_NAME, - str(CARGO_FILE_PATH), - debug=is_debug_profile, - binding=Binding.NoBinding, - ) - ], - zip_safe=False, - url="https://github.com/garvys-org/rustfst", - author="Alexandre Caulier, Emrick Sinitambirivoutin", - author_email="alexandre.caulier.a@gmail.com, emrick.sinitambirivoutin@sonos.com", - keywords="fst openfst graph transducer acceptor shortest-path minimize determinize wfst", - project_urls={ - "Documentation": "https://garvys-org.github.io/rustfst/", - "Source": "https://github.com/garvys-org/rustfst", - }, - python_requires=">=3.7", - license="Apache License, Version 2.0", -) From c97b94627338dd2192775b607f4fb047ddf1fcc1 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 09:43:36 -0400 Subject: [PATCH 03/19] chore: ignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5e0c102b0..28b1127e3 100644 --- a/.gitignore +++ b/.gitignore @@ -53,4 +53,5 @@ rustfst-python/mkdocs/site rustfst-python/mkdocs/docs/reference site -rustfst/proptest-regressions/ \ No newline at end of file +rustfst/proptest-regressions/ +*~ From 25f556bfa06cd794259efef71a4b79964f906aee Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 09:43:52 -0400 Subject: [PATCH 04/19] ci: update cibuildwheel, which probably still works --- .github/workflows/native.yml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index dd0990723..5430c19a9 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -352,12 +352,11 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} # Version range or exact version of a Python version to use, using SemVer's version range syntax - architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Build and publish + - name: Checkout + uses: actions/checkout@v4 + + - name: Build wheels + uses: pypa/cibuildwheel@v2.20.0 env: CIBW_SKIP: cp*-musllinux_i686 CIBW_ENVIRONMENT: PATH="$HOME/.cargo/bin:$PATH" @@ -372,11 +371,11 @@ jobs: CIBW_ARCHS_MACOS: "x86_64 arm64" # On an Linux Intel runner with qemu installed, build Intel and ARM wheels CIBW_ARCHS_LINUX: "auto" - run: | - python3.9 -m pip install twine cibuildwheel==2.13.1 - mkdir -p wheels - python3.9 -m cibuildwheel --output-dir wheels rustfst-python - python3.9 -m twine upload -u "__token__" -p ${{ secrets.PYPI_PASSWORD }} -r pypi --verbose wheels/* - + - name: Setup Python + uses: actions/setup-python@v5 + - name: Upload + run: | + python -m pip install twine + python -m twine upload -u "__token__" -p ${{ secrets.PYPI_PASSWORD }} -r pypi --verbose wheelhouse/* From 08df1f60164100cbdcc773d32ba337e887a242ce Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 09:59:57 -0400 Subject: [PATCH 05/19] fix: update tests/docs to use pyproject defs --- .ci/native.sh | 3 +- .github/workflows/native.yml | 21 ++--- pyproject.toml | 10 +++ rustfst-python/requirements-mkdocs.in | 8 -- rustfst-python/requirements-mkdocs.txt | 102 ------------------------- rustfst-python/requirements-setup.in | 1 - rustfst-python/requirements-setup.txt | 15 ---- 7 files changed, 18 insertions(+), 142 deletions(-) delete mode 100644 rustfst-python/requirements-mkdocs.in delete mode 100644 rustfst-python/requirements-mkdocs.txt delete mode 100644 rustfst-python/requirements-setup.in delete mode 100644 rustfst-python/requirements-setup.txt diff --git a/.ci/native.sh b/.ci/native.sh index 16e47e59b..f34d71980 100755 --- a/.ci/native.sh +++ b/.ci/native.sh @@ -45,8 +45,7 @@ echo $PYTHON_VERSION $PYTHON_VERSION --version ($PYTHON_VERSION -m pip freeze | grep black 1>/dev/null 2>&1) || $PYTHON_VERSION -m pip install black==21.7b0 -$PYTHON_VERSION -m pip install pylint==2.6.0 pytest==6.2.5 -$PYTHON_VERSION -m pip install -r rustfst-python/requirements-setup.txt +$PYTHON_VERSION -m pip install -e '.[tests]' cd rustfst-python $PYTHON_VERSION -m setup.py develop diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 5430c19a9..27364a7cc 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -232,11 +232,9 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Build rustfst-python + - name: Build rustfst-python and install test tools run: | - pip install pylint==2.6.0 pytest==6.2.5 - pip install -r rustfst-python/requirements-setup.txt - pip install -e rustfst-python + pip install -e ".[tests]" - name: Test rustfst-python run: python -m pytest -s --cache-clear --disable-warnings rustfst-python @@ -255,16 +253,13 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Build rustfst-python + - name: Build rustfst-python and install docs tools run: | - pip install -r rustfst-python/requirements-setup.txt - pip install -e rustfst-python - - name: Install mkdocs - run: pip install -r rustfst-python/requirements-mkdocs.txt + pip install -e ".[docs]" - name: Test doc generation run: | cd rustfst-python - mkdocs build -s + mkdocs build publish-python-doc: name: Publish rustfst-python's doc @@ -290,13 +285,11 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - run: pip install -r rustfst-python/requirements-setup.txt - - run: pip install -e rustfst-python - - run: pip install -r rustfst-python/requirements-mkdocs.txt + - run: pip install -e ".[docs]" - run: git config user.name ${{ env.GIT_COMMITTER_NAME }} - run: git config user.email ${{ env.GIT_COMMITTER_EMAIL }} - run: git fetch origin gh-pages --depth=1 - - run: cd rustfst-python && mkdocs build -s + - run: cd rustfst-python && mkdocs build - name: Deploy Doc to latest if: github.ref == 'refs/heads/main' run: cd rustfst-python && mike deploy --push latest diff --git a/pyproject.toml b/pyproject.toml index f2a951d1b..17744f68e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,16 @@ classifiers = [ [project.optional-dependencies] tests = [ "pytest>=6,<7", "pylint" ] +docs = [ + "mike", + "mkdocstrings[python]", + "mkdocs-material", + "mkdocs-literate-nav", + "mkdocs-gen-files", + "mkdocs-section-index", + "mkdocs-macros-plugin", +] + # This was in setup.py but is no longer relevant (it's not for Mac OS X) # options={"bdist_wheel": {"universal": True}}, diff --git a/rustfst-python/requirements-mkdocs.in b/rustfst-python/requirements-mkdocs.in deleted file mode 100644 index 08d6bb88d..000000000 --- a/rustfst-python/requirements-mkdocs.in +++ /dev/null @@ -1,8 +0,0 @@ -jinja2<3.2.0 -mkdocstrings[python] -mkdocs-material -mkdocs-literate-nav -mkdocs-gen-files -mkdocs-section-index -mkdocs-macros-plugin -mike \ No newline at end of file diff --git a/rustfst-python/requirements-mkdocs.txt b/rustfst-python/requirements-mkdocs.txt deleted file mode 100644 index f91bffe26..000000000 --- a/rustfst-python/requirements-mkdocs.txt +++ /dev/null @@ -1,102 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --output-file=requirements-mkdocs.txt requirements-mkdocs.in -# -click==8.1.3 - # via mkdocs -ghp-import==2.1.0 - # via mkdocs -griffe==0.19.1 - # via mkdocstrings-python -importlib-metadata==4.11.3 - # via - # markdown - # mkdocs -jinja2==3.1.4 - # via - # -r requirements-mkdocs.in - # mike - # mkdocs - # mkdocs-macros-plugin - # mkdocs-material - # mkdocstrings -markdown==3.3.7 - # via - # mkdocs - # mkdocs-autorefs - # mkdocs-material - # mkdocstrings - # pymdown-extensions -markupsafe==2.1.1 - # via - # jinja2 - # mkdocstrings -mergedeep==1.3.4 - # via mkdocs -mike==1.1.2 - # via -r requirements-mkdocs.in -mkdocs==1.3.1 - # via - # mike - # mkdocs-autorefs - # mkdocs-gen-files - # mkdocs-literate-nav - # mkdocs-macros-plugin - # mkdocs-material - # mkdocs-section-index - # mkdocstrings -mkdocs-autorefs==0.4.1 - # via mkdocstrings -mkdocs-gen-files==0.3.4 - # via -r requirements-mkdocs.in -mkdocs-literate-nav==0.4.1 - # via -r requirements-mkdocs.in -mkdocs-macros-plugin==0.7.0 - # via -r requirements-mkdocs.in -mkdocs-material==8.2.14 - # via -r requirements-mkdocs.in -mkdocs-material-extensions==1.0.3 - # via mkdocs-material -mkdocs-section-index==0.3.4 - # via -r requirements-mkdocs.in -mkdocstrings[python]==0.19.0 - # via - # -r requirements-mkdocs.in - # mkdocstrings-python -mkdocstrings-python==0.7.1 - # via mkdocstrings -packaging==21.3 - # via mkdocs -pygments==2.15.0 - # via mkdocs-material -pymdown-extensions==10.0 - # via - # mkdocs-material - # mkdocstrings -pyparsing==3.0.9 - # via packaging -python-dateutil==2.8.2 - # via - # ghp-import - # mkdocs-macros-plugin -pyyaml==6.0 - # via - # mike - # mkdocs - # mkdocs-macros-plugin - # pymdown-extensions - # pyyaml-env-tag -pyyaml-env-tag==0.1 - # via mkdocs -six==1.16.0 - # via python-dateutil -termcolor==1.1.0 - # via mkdocs-macros-plugin -verspec==0.1.0 - # via mike -watchdog==2.1.7 - # via mkdocs -zipp==3.8.0 - # via importlib-metadata diff --git a/rustfst-python/requirements-setup.in b/rustfst-python/requirements-setup.in deleted file mode 100644 index 0e548794d..000000000 --- a/rustfst-python/requirements-setup.in +++ /dev/null @@ -1 +0,0 @@ -setuptools_rust==1.1.2 \ No newline at end of file diff --git a/rustfst-python/requirements-setup.txt b/rustfst-python/requirements-setup.txt deleted file mode 100644 index b5bcce099..000000000 --- a/rustfst-python/requirements-setup.txt +++ /dev/null @@ -1,15 +0,0 @@ -# -# This file is autogenerated by pip-compile with python 3.7 -# To update, run: -# -# pip-compile --no-emit-index-url requirements-setup.in -# -semantic-version==2.10.0 - # via setuptools-rust -setuptools-rust==1.1.2 - # via -r requirements-setup.in -typing-extensions==4.3.0 - # via setuptools-rust - -# The following packages are considered to be unsafe in a requirements file: -# setuptools From b9d0e658ed73cce2535a57e248033048770d26c0 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 10:24:13 -0400 Subject: [PATCH 06/19] fix(test): fix linting test for good --- pyproject.toml | 18 +- rustfst-python/linting/linting_test.py | 6 +- rustfst-python/linting/pylintrc | 326 ------------------------- rustfst-python/linting/pytest.ini | 2 - 4 files changed, 19 insertions(+), 333 deletions(-) delete mode 100644 rustfst-python/linting/pylintrc delete mode 100644 rustfst-python/linting/pytest.ini diff --git a/pyproject.toml b/pyproject.toml index 17744f68e..00393af1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ classifiers = [ ] [project.optional-dependencies] -tests = [ "pytest>=6,<7", "pylint" ] +tests = [ "pytest", "pylint" ] docs = [ "mike", "mkdocstrings[python]", @@ -52,3 +52,19 @@ package-dir = {"rustfst" = "rustfst-python/rustfst"} target = "rustfst.dylib.dylib" path = "rustfst-ffi/Cargo.toml" binding = "NoBinding" + +[tool.pytest.ini_options] +markers = ["rustfst"] + +[tool.pylint.main] +ignore = ["scripts"] +persistent = true +py-version = "3.8" + +[tool.pylint."messages control"] +enable = ["indexing-exception", "old-raise-syntax"] +disable = ["design","similarities","no-self-use","attribute-defined-outside-init","locally-disabled","star-args","pointless-except","bad-option-value","global-statement","fixme","suppressed-message","useless-suppression","locally-enabled","no-member","no-name-in-module","import-error","unsubscriptable-object","unbalanced-tuple-unpacking","undefined-variable","not-context-manager","missing-docstring","cyclic-import","redefined-builtin","ungrouped-imports","wrong-import-order","bad-continuation","import-outside-toplevel","line-too-long"] + +[tool.pylint.reports] +output-format = "text" +reports = "no" diff --git a/rustfst-python/linting/linting_test.py b/rustfst-python/linting/linting_test.py index 4c7a170d0..c3cb523a4 100644 --- a/rustfst-python/linting/linting_test.py +++ b/rustfst-python/linting/linting_test.py @@ -1,16 +1,14 @@ import os from pathlib import Path -import pytest from pylint.lint import Run -ROOT_PATH = Path(__file__).parents[1] +ROOT_PATH = Path(__file__).parent.parent RCFILEPATH = ROOT_PATH / "linting" / "pylintrc" def run_linting_test(package): - args = ["--rcfile", str(RCFILEPATH)] - args += all_python_files(package) + args = all_python_files(package) run = Run(args, exit=False) assert run.linter.msg_status == 0 diff --git a/rustfst-python/linting/pylintrc b/rustfst-python/linting/pylintrc deleted file mode 100644 index af6e296c1..000000000 --- a/rustfst-python/linting/pylintrc +++ /dev/null @@ -1,326 +0,0 @@ -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Profiled execution. -profile=no - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=scripts - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - - -[MESSAGES CONTROL] - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time. See also the "--disable" option for examples. -enable=indexing-exception,old-raise-syntax - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -disable=design,similarities,no-self-use,attribute-defined-outside-init,locally-disabled,star-args,pointless-except,bad-option-value,global-statement,fixme,suppressed-message,useless-suppression,locally-enabled,no-member,no-name-in-module,import-error,unsubscriptable-object,unbalanced-tuple-unpacking,undefined-variable,not-context-manager,missing-docstring,cyclic-import,redefined-builtin,ungrouped-imports,wrong-import-order,bad-continuation,import-outside-toplevel - - -# Set the cache size for astng objects. -cache-size=500 - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Tells whether to display a full report or only the messages -reports=no - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Add a comment according to your evaluation note. This is used by the global -# evaluation report (RP0004). -comment=no - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of classes names for which member attributes should not be checked -# (useful for classes with attributes dynamically set). -ignored-classes=SQLObject - -# When zope mode is activated, add a predefined set of Zope acquired attributes -# to generated-members. -zope=no - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E0201 when accessed. Python regular -# expressions are accepted. -generated-members=REQUEST,acl_users,aq_parent - -# List of decorators that create context managers from functions, such as -# contextlib.contextmanager. -contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the beginning of the name of dummy variables -# (i.e. not used). -dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_) - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - - -[BASIC] - -# Required attributes for module, separated by a comma -required-attributes= - -# List of builtins function names that should not be used, separated by a comma -bad-functions=apply,input,reduce - - -# Disable the report(s) with the given id(s). -# All non-Google reports are disabled by default. -# disable-report=R0001,R0002,R0003,R0004,R0101,R0102,R0201,R0202,R0220,R0401,R0402,R0701,R0801,R0901,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0921,R0922,R0923 - -# Regular expression which should only match correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression which should only match correct module level names -const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ - -# Regular expression which should only match correct class names -class-rgx=^_?[A-Z][a-zA-Z0-9]*$ - -# Regular expression which should only match correct function names -function-rgx=^(?:(?P_?[A-Z][a-zA-Z0-9]*)|(?P_?[a-z][a-z0-9_]*))$ - -# Regular expression which should only match correct method names -method-rgx=^(?:(?P__[a-z0-9_]+__|next)|(?P_{0,2}[A-Z][a-zA-Z0-9]*)|(?P_{0,2}[a-z][a-z0-9_]*))$ - -# Regular expression which should only match correct instance attribute names -attr-rgx=^_{0,2}[a-z][a-z0-9_]*$ - -# Regular expression which should only match correct argument names -argument-rgx=^[a-z][a-z0-9_]*$ - -# Regular expression which should only match correct variable names -variable-rgx=^[a-z][a-z0-9_]*$ - -# Regular expression which should only match correct attribute names in class -# bodies -class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ - -# Regular expression which should only match correct list comprehension / -# generator expression variable names -inlinevar-rgx=^[a-z][a-z0-9_]*$ - -# Good variable names which should always be accepted, separated by a comma -good-names=main,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=(__.*__|main) - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=10 - - -[FORMAT] - -# Maximum number of characters on a single line. -# We set a high value here as we rely on black for code formatting -max-line-length=240 - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=y - -# List of optional constructs for which whitespace checking is disabled -# no-space-check= - -# Maximum number of lines in a module -max-module-lines=99999 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes= - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,TERMIOS,Bastion,rexec,sets - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - - -[CLASSES] - -# List of interface methods to ignore, separated by a comma. This is used for -# instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls,class_ - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception,StandardError,BaseException - - -[AST] - -# Maximum line length for lambdas -short-func-length=1 - -# List of module members that should be marked as deprecated. -# All of the string functions are listed in 4.1.4 Deprecated string functions -# in the Python 2.4 docs. -deprecated-members=string.atof,string.atoi,string.atol,string.capitalize,string.expandtabs,string.find,string.rfind,string.index,string.rindex,string.count,string.lower,string.split,string.rsplit,string.splitfields,string.join,string.joinfields,string.lstrip,string.rstrip,string.strip,string.swapcase,string.translate,string.upper,string.ljust,string.rjust,string.center,string.zfill,string.replace,sys.exitfunc - - -[DOCSTRING] - -# List of exceptions that do not need to be mentioned in the Raises section of -# a docstring. -ignore-exceptions=AssertionError,NotImplementedError,StopIteration,TypeError - - - -[TOKENS] - -# Number of spaces of indent required when the last token on the preceding line -# is an open (, [, or {. -indent-after-paren=4 - - -[SNIPS LINES] - -# Regexp for a proper copyright notice. -copyright=Copyright \d{4} The Snips NLU Authors\. +All [Rr]ights [Rr]eserved\.< diff --git a/rustfst-python/linting/pytest.ini b/rustfst-python/linting/pytest.ini deleted file mode 100644 index 03b6302f8..000000000 --- a/rustfst-python/linting/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -markers = rustfst From e701bc8f3f967ed355b8f5f66c68fcdf5bf9ff4c Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 10:49:11 -0400 Subject: [PATCH 07/19] ci: Update cibuildwheel configuration and build source distribution --- .github/workflows/native.yml | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 27364a7cc..5491a446c 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -330,9 +330,28 @@ jobs: cd .. + build-python-sdist: + name: Build source distribution + runs-on: ubuntu-latest + needs: [ rust-clippy, rust-doc, rust-tests, rustfst-python-bench, rustfst-python, python-doc ] + if: startsWith(github.ref, 'refs/tags/rustfst-v') + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build source distribution + run: pipx run build --sdist + + - name: Upload source distribution as artifact + uses: actions/upload-artifact@v4 + with: + name: cibw-sdist + path: dist/*.tar.gz + + publish-python-wheels: name: Publish Python Wheels to PyPI - needs: [ rust-clippy, rust-doc, rust-tests, rustfst-python-bench, rustfst-python, python-doc ] + needs: [ build-python-sdist ] if: startsWith(github.ref, 'refs/tags/rustfst-v') strategy: @@ -365,10 +384,18 @@ jobs: # On an Linux Intel runner with qemu installed, build Intel and ARM wheels CIBW_ARCHS_LINUX: "auto" + - name: Upload wheels as artifacts + uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl + - name: Setup Python uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} - - name: Upload + - name: Upload sdist and wheels to PyPI run: | python -m pip install twine - python -m twine upload -u "__token__" -p ${{ secrets.PYPI_PASSWORD }} -r pypi --verbose wheelhouse/* + python -m twine upload -u "__token__" -p ${{ secrets.PYPI_PASSWORD }} -r pypi --verbose wheelhouse/* dist/*.tar.gz From b244aec33b93cba4083fdcce53e026d9cf3dd3fa Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 16:09:15 -0400 Subject: [PATCH 08/19] fix: watch is a toplevel mkdocs option since longtime now --- rustfst-python/mkdocs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rustfst-python/mkdocs.yml b/rustfst-python/mkdocs.yml index 0efc059b8..a07f0e06a 100644 --- a/rustfst-python/mkdocs.yml +++ b/rustfst-python/mkdocs.yml @@ -82,9 +82,9 @@ plugins: show_object_full_path: false show_signature_annotations: true show_submodules: true - watch: - - rustfst - - docs +watch: + - rustfst + - docs repo_name: rustfst repo_url: https://github.com/garvys-org/rustfst site_name: rustfst-python From 26638249120e37a2c7e72be5bfcfcccfd419d793 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 16:10:17 -0400 Subject: [PATCH 09/19] fix(docs): fix all the docstrings. Up-to-date versions of mkdocstrings now are stricter about dostring syntax and *require* blank lines between sections. See: https://mkdocstrings.github.io/griffe/reference/docstrings/#google-syntax --- rustfst-python/rustfst/algorithms/__init__.py | 9 ++++ rustfst-python/rustfst/algorithms/compose.py | 4 ++ rustfst-python/rustfst/algorithms/concat.py | 3 ++ .../rustfst/algorithms/determinize.py | 5 ++ .../rustfst/algorithms/isomorphic.py | 2 + rustfst-python/rustfst/algorithms/minimize.py | 4 ++ rustfst-python/rustfst/algorithms/optimize.py | 2 + rustfst-python/rustfst/algorithms/project.py | 2 + rustfst-python/rustfst/algorithms/reverse.py | 2 + .../rustfst/algorithms/rm_epsilon.py | 2 + .../rustfst/algorithms/shortest_path.py | 4 ++ rustfst-python/rustfst/algorithms/top_sort.py | 1 + .../rustfst/algorithms/tr_unique.py | 1 + rustfst-python/rustfst/algorithms/union.py | 5 +- rustfst-python/rustfst/fst/__init__.py | 27 ++++++++++ rustfst-python/rustfst/fst/const_fst.py | 14 +++++ rustfst-python/rustfst/fst/vector_fst.py | 53 +++++++++++++++++++ .../rustfst/string_paths_iterator.py | 1 + rustfst-python/rustfst/symbol_table.py | 25 +++++++++ rustfst-python/rustfst/tr.py | 1 + rustfst-python/rustfst/trs.py | 2 + rustfst-python/rustfst/weight.py | 2 + 22 files changed, 170 insertions(+), 1 deletion(-) diff --git a/rustfst-python/rustfst/algorithms/__init__.py b/rustfst-python/rustfst/algorithms/__init__.py index 3a1b3336b..ab246a8dd 100644 --- a/rustfst-python/rustfst/algorithms/__init__.py +++ b/rustfst-python/rustfst/algorithms/__init__.py @@ -18,13 +18,16 @@ def acceptor( ) -> VectorFst: """ Creates an acceptor from a string. + This function creates a FST which accepts its input with a fixed weight (defaulting to semiring One). + Args: astring: The input string. weight: A Weight or weight string indicating the desired path weight. If omitted or null, the path weight is set to semiring One. symbol_table: SymbolTable to be used to encode the string. + Returns: An FST acceptor. """ @@ -52,14 +55,17 @@ def transducer( ) -> VectorFst: """ Creates a transducer from a pair of strings or acceptor FSTs. + This function creates a FST which transduces from the first string to the second with a fixed weight (defaulting to semiring One). + Args: istring: The input string ostring: The output string weight: A Weight as float. isymt: SymbolTable to be used to encode the string. osymt: SymbolTable to be used to encode the string. + Returns: An FST transducer. """ @@ -85,10 +91,13 @@ def transducer( def epsilon_machine(weight: Optional[float] = None) -> VectorFst: """ Constructs a single-state, no-arc FST accepting epsilon. + This function creates an unweighted FST with a single state which is both initial and final. + Args: weight: A Weight. Default semiring One. + Returns: An FST. """ diff --git a/rustfst-python/rustfst/algorithms/compose.py b/rustfst-python/rustfst/algorithms/compose.py index c145d5071..80161da9b 100644 --- a/rustfst-python/rustfst/algorithms/compose.py +++ b/rustfst-python/rustfst/algorithms/compose.py @@ -110,9 +110,11 @@ def __del__(self): def compose(fst: VectorFst, other_fst: VectorFst) -> VectorFst: """ Compute the composition of two FSTs. + Args: fst: Left fst. other_fst: Right fst. + Returns: Resulting fst. """ @@ -130,10 +132,12 @@ def compose_with_config( ) -> VectorFst: """ Compute the composition of two FSTs parametrized with a config. + Args: fst: Left fst. other_fst: Right fst. config: Config parameters of the composition. + Returns: Resulting fst. """ diff --git a/rustfst-python/rustfst/algorithms/concat.py b/rustfst-python/rustfst/algorithms/concat.py index 592a74a67..718c652a6 100644 --- a/rustfst-python/rustfst/algorithms/concat.py +++ b/rustfst-python/rustfst/algorithms/concat.py @@ -13,9 +13,11 @@ def concat(fst: VectorFst, other_fst: VectorFst) -> VectorFst: """ Compute the concatenation of two Fsts. + Args: fst: Left fst. other_fst: Right fst. + Returns: Resulting fst. """ @@ -30,6 +32,7 @@ def concat(fst: VectorFst, other_fst: VectorFst) -> VectorFst: def concat_list(fsts: List[VectorFst]) -> VectorFst: """ Compute the concatenation of a list of Fsts. + Args: fsts: List of Fsts to concatenated diff --git a/rustfst-python/rustfst/algorithms/determinize.py b/rustfst-python/rustfst/algorithms/determinize.py index caa52b230..cc0084628 100644 --- a/rustfst-python/rustfst/algorithms/determinize.py +++ b/rustfst-python/rustfst/algorithms/determinize.py @@ -41,6 +41,7 @@ class DeterminizeConfig: def __init__(self, det_type: DeterminizeType, delta: Optional[float] = None): """ Creates the configuration object. + Args: det_type: Type of determinization to perform. delta: @@ -62,8 +63,10 @@ def __init__(self, det_type: DeterminizeType, delta: Optional[float] = None): def determinize(fst: VectorFst) -> VectorFst: """ Make an Fst deterministic + Args: fst: The Fst to make deterministic. + Returns: The resulting Fst. """ @@ -78,9 +81,11 @@ def determinize(fst: VectorFst) -> VectorFst: def determinize_with_config(fst: VectorFst, config: DeterminizeConfig) -> VectorFst: """ Make an Fst deterministic + Args: fst: The Fst to make deterministic. config: Configuration of the determinization algorithm to use. + Returns: The resulting Fst. """ diff --git a/rustfst-python/rustfst/algorithms/isomorphic.py b/rustfst-python/rustfst/algorithms/isomorphic.py index 29a7d5e56..e666bf2b5 100644 --- a/rustfst-python/rustfst/algorithms/isomorphic.py +++ b/rustfst-python/rustfst/algorithms/isomorphic.py @@ -11,9 +11,11 @@ def isomorphic(fst: VectorFst, other_fst: VectorFst) -> bool: """ Check if two Fsts are isomorphic. + Args: fst: First Fst. other_fst: Second Fst. + Returns: Whether both Fsts are equal. """ diff --git a/rustfst-python/rustfst/algorithms/minimize.py b/rustfst-python/rustfst/algorithms/minimize.py index c04297d87..0a751930f 100644 --- a/rustfst-python/rustfst/algorithms/minimize.py +++ b/rustfst-python/rustfst/algorithms/minimize.py @@ -32,8 +32,10 @@ def __init__(self, delta=None, allow_nondet=False): def minimize(fst: VectorFst) -> VectorFst: """ Minimize an FST in-place + Params: fst: Fst + Returns: fst """ @@ -47,9 +49,11 @@ def minimize(fst: VectorFst) -> VectorFst: def minimize_with_config(fst: VectorFst, config: MinimizeConfig) -> VectorFst: """ Minimize an FST in-place + Params: fst: Fst config: Configuration + Returns: fst """ diff --git a/rustfst-python/rustfst/algorithms/optimize.py b/rustfst-python/rustfst/algorithms/optimize.py index 13b8bd168..bd0a51545 100644 --- a/rustfst-python/rustfst/algorithms/optimize.py +++ b/rustfst-python/rustfst/algorithms/optimize.py @@ -13,6 +13,7 @@ def optimize(fst: VectorFst): """ Optimize an fst in-place + Args: fst: Fst to optimize. """ @@ -24,6 +25,7 @@ def optimize(fst: VectorFst): def optimize_in_log(fst: VectorFst): """ Optimize an fst in-place in the log semiring. + Args: fst: Fst to optimize. """ diff --git a/rustfst-python/rustfst/algorithms/project.py b/rustfst-python/rustfst/algorithms/project.py index 75926cb49..f7e00d30d 100644 --- a/rustfst-python/rustfst/algorithms/project.py +++ b/rustfst-python/rustfst/algorithms/project.py @@ -27,9 +27,11 @@ class ProjectType(Enum): def project(fst: VectorFst, proj_type: ProjectType) -> VectorFst: """ Convert a Fst to an acceptor using input or output labels. + Args: fst: Fst on which to apply the algorithm. proj_type: Whether to replace input labels or output labels. + Returns: The resulting Fst. """ diff --git a/rustfst-python/rustfst/algorithms/reverse.py b/rustfst-python/rustfst/algorithms/reverse.py index ba6ddee90..fa944f698 100644 --- a/rustfst-python/rustfst/algorithms/reverse.py +++ b/rustfst-python/rustfst/algorithms/reverse.py @@ -15,8 +15,10 @@ def reverse(fst: VectorFst) -> VectorFst: Not to be confused with `inverse`, which does something totally different! + Args: fst: Fst to reverse + Returns: Newly created, reversed Fst. """ diff --git a/rustfst-python/rustfst/algorithms/rm_epsilon.py b/rustfst-python/rustfst/algorithms/rm_epsilon.py index f619ab185..226c277aa 100644 --- a/rustfst-python/rustfst/algorithms/rm_epsilon.py +++ b/rustfst-python/rustfst/algorithms/rm_epsilon.py @@ -11,8 +11,10 @@ def rm_epsilon(fst: VectorFst) -> VectorFst: """ Return an equivalent FST with epsilon transitions removed. + Args: fst: Fst + Returns: Newly created FST with epsilon transitions removed. """ diff --git a/rustfst-python/rustfst/algorithms/shortest_path.py b/rustfst-python/rustfst/algorithms/shortest_path.py index ac8d4561d..c3ca8f4de 100644 --- a/rustfst-python/rustfst/algorithms/shortest_path.py +++ b/rustfst-python/rustfst/algorithms/shortest_path.py @@ -41,8 +41,10 @@ def __init__( def shortestpath(fst: VectorFst) -> VectorFst: """ Construct a FST containing the shortest path of the input FST + Args: fst: Fst + Returns: Newly-created FST containing only the shortest path of the input FST. """ @@ -58,9 +60,11 @@ def shortestpath(fst: VectorFst) -> VectorFst: def shortestpath_with_config(fst: VectorFst, config: ShortestPathConfig) -> VectorFst: """ Construct a FST containing the shortest path of the input FST + Args: fst: Fst config: Configuration for shortest-path operation. + Returns: Newly-created FST containing only the shortest path of the input FST. """ diff --git a/rustfst-python/rustfst/algorithms/top_sort.py b/rustfst-python/rustfst/algorithms/top_sort.py index cdbf1c368..46d8bfa4e 100644 --- a/rustfst-python/rustfst/algorithms/top_sort.py +++ b/rustfst-python/rustfst/algorithms/top_sort.py @@ -24,6 +24,7 @@ def top_sort(fst: VectorFst) -> VectorFst: Args: fst: Fst to top_sort. + Returns: Equivalent top sorted Fst. Modification also happens in-place. """ diff --git a/rustfst-python/rustfst/algorithms/tr_unique.py b/rustfst-python/rustfst/algorithms/tr_unique.py index a7d3c210d..836fba708 100644 --- a/rustfst-python/rustfst/algorithms/tr_unique.py +++ b/rustfst-python/rustfst/algorithms/tr_unique.py @@ -11,6 +11,7 @@ def tr_unique(fst: VectorFst): """ Keep a single instance of trs leaving the same state, going to the same state and with the same input labels, output labels and weight. + Args: fst: Fst to modify """ diff --git a/rustfst-python/rustfst/algorithms/union.py b/rustfst-python/rustfst/algorithms/union.py index e3407d28e..5431dc103 100644 --- a/rustfst-python/rustfst/algorithms/union.py +++ b/rustfst-python/rustfst/algorithms/union.py @@ -12,7 +12,9 @@ def union(fst: VectorFst, other_fst: VectorFst) -> VectorFst: """ - Performs the union of two wFSTs. If A transduces string `x` to `y` with weight `a` + Performs the union of two wFSTs. + + If A transduces string `x` to `y` with weight `a` and `B` transduces string `w` to `v` with weight `b`, then their union transduces `x` to `y` with weight `a` and `w` to `v` with weight `b`. @@ -32,6 +34,7 @@ def union(fst: VectorFst, other_fst: VectorFst) -> VectorFst: Args: fst: other_fst: + Returns: The resulting Fst. diff --git a/rustfst-python/rustfst/fst/__init__.py b/rustfst-python/rustfst/fst/__init__.py index 9a05b8b45..ac25a2b56 100644 --- a/rustfst-python/rustfst/fst/__init__.py +++ b/rustfst-python/rustfst/fst/__init__.py @@ -23,6 +23,7 @@ def __init__(self, ptr, isymt=None, osymt=None): def start(self) -> Optional[int]: """ Returns the start state. + Returns : The start state or None. """ @@ -38,10 +39,13 @@ def start(self) -> Optional[int]: def final(self, state: int) -> Optional[float]: """ Returns the final weight of a state. + Args: state: The integer index of a state. + Returns: The final Weight of that state. + Raises: Exception: If State index out of range. """ @@ -60,12 +64,16 @@ def final(self, state: int) -> Optional[float]: def num_trs(self, state: int) -> int: """ Returns the number of trs leaving a state. + Args: state: The integer index of a state. + Returns: The number of trs leaving that state. + Raises: Exception: If State index out of range. + See also: `num_states`. """ num_trs = ctypes.c_size_t() @@ -79,10 +87,13 @@ def num_trs(self, state: int) -> int: def trs(self, state: int) -> TrsIterator: """ Returns an iterator over trs leaving the specified state. + Args: state: The source state ID. + Returns: An TrsIterator. + See also: `mutable_trs`, `states`. """ return TrsIterator(self, state) @@ -90,8 +101,10 @@ def trs(self, state: int) -> TrsIterator: def is_final(self, state_id: int) -> bool: """ Check if a state is final + Args : state_id: + Returns : bool """ @@ -107,8 +120,10 @@ def is_final(self, state_id: int) -> bool: def is_start(self, state_id: int) -> bool: """ Check if a state is a start state. + Args : state_id: Integer index of the state. + Returns : bool """ @@ -124,8 +139,10 @@ def is_start(self, state_id: int) -> bool: def input_symbols(self) -> Optional[SymbolTable]: """ Returns the Fst's input symbol table, or None if none is present. + Returns : The Fst's input symbol table, or None if none is present. + See also: `output_symbols`. """ if self._input_symbols: @@ -143,8 +160,10 @@ def input_symbols(self) -> Optional[SymbolTable]: def output_symbols(self) -> Optional[SymbolTable]: """ Returns the Fst's output symbol table, or None if none is present. + Returns : The Fst's output symbol table, or None if none is present. + See also: `input_symbols`. """ if self._output_symbols: @@ -164,10 +183,13 @@ def set_input_symbols(self, syms: Optional[SymbolTable]) -> Fst: """ Sets the input symbol table. Passing None as a value will delete the input symbol table. + Args: syms: A SymbolTable. + Returns: self. + See also: `set_output_symbols`. """ if syms is None: @@ -192,10 +214,13 @@ def set_output_symbols(self, syms: Optional[SymbolTable]) -> Fst: """ Sets the output symbol table. Passing None as a value will delete the output symbol table. + Args: syms: A SymbolTable. + Returns: self. + See also: `set_input_symbols`. """ if syms is None: @@ -221,6 +246,7 @@ def remove_input_symbols(self, symbols: list[int]) -> Fst: """ Args: symbols: List[int] + Returns: self. """ @@ -236,6 +262,7 @@ def remove_output_symbols(self, symbols: list[int]) -> Fst: """ Args: symbols: List[int] + Returns: self. """ diff --git a/rustfst-python/rustfst/fst/const_fst.py b/rustfst-python/rustfst/fst/const_fst.py index d4607a666..8a1690630 100644 --- a/rustfst-python/rustfst/fst/const_fst.py +++ b/rustfst-python/rustfst/fst/const_fst.py @@ -32,13 +32,16 @@ def draw( ): """ Writes out the FST in Graphviz text format. + This method writes out the FST in the dot graph description language. The graph can be rendered using the `dot` executable provided by Graphviz. + Args: filename: The string location of the output dot/Graphviz file. isymbols: An optional symbol table used to label input symbols. osymbols: An optional symbol table used to label output symbols. drawing_config: Drawing configuration to use. + See also: `text`. """ @@ -90,10 +93,13 @@ def draw( def read(cls, filename: Union[str, Path]) -> ConstFst: """ Read a Fst at a given path. + Args: filename: The string location of the input file. + Returns: An FST. + Raises: ValueError: Read failed. """ @@ -110,10 +116,13 @@ def read(cls, filename: Union[str, Path]) -> ConstFst: def from_vector_fst(cls, fst: VectorFst) -> ConstFst: """ Converts a given `VectorFst` to `ConstFst` + Args: fst: The `VectorFst` that should be converted + Returns: A `ConstFst` + Raises: ValueError: Conversion failed """ @@ -127,9 +136,12 @@ def from_vector_fst(cls, fst: VectorFst) -> ConstFst: def write(self, filename: Union[str, Path]): """ Serializes FST to a file. + This method writes the FST to a file in binary format. + Args: filename: The string location of the output file. + Raises: ValueError: Write failed. """ @@ -140,8 +152,10 @@ def write(self, filename: Union[str, Path]): def equals(self, other: Fst) -> bool: """ Check if this Fst is equal to the other + Args : other: Fst instance + Returns: bool """ diff --git a/rustfst-python/rustfst/fst/vector_fst.py b/rustfst-python/rustfst/fst/vector_fst.py index 06f5b5919..77ed90f42 100644 --- a/rustfst-python/rustfst/fst/vector_fst.py +++ b/rustfst-python/rustfst/fst/vector_fst.py @@ -67,13 +67,17 @@ def add_tr(self, state: int, tr: Tr) -> Fst: """ Adds a new tr to the FST and return self. Note the tr should be considered consumed and is not safe to use it after. + Args: state: The integer index of the source state. tr: The tr to add. + Returns: self. + Raises: SnipsFstException: If State index out of range. + See also: `add_state`. """ ret_code = lib.vec_fst_add_tr(self.ptr, ctypes.c_size_t(state), tr.ptr) @@ -85,8 +89,10 @@ def add_tr(self, state: int, tr: Tr) -> Fst: def add_state(self) -> int: """ Adds a new state to the FST and returns the state ID. + Returns: The integer index of the new state. + See also: `add_tr`, `set_start`, `set_final`. """ state_id = ctypes.c_size_t() @@ -100,12 +106,15 @@ def add_state(self) -> int: def set_final(self, state: int, weight: Union[float, None] = None): """ Sets the final weight for a state. + Args: state: The integer index of a state. weight: A float indicating the desired final weight; if omitted, it is set to semiring One. + Raises: ValueError: State index out of range or Incompatible or invalid weight. + See also: `set_start`. """ if weight is None: @@ -121,8 +130,10 @@ def set_final(self, state: int, weight: Union[float, None] = None): def unset_final(self, state: int): """ Unset the final weight of a state. As a result, the state is no longer final. + Args: state: The integer index of a state + Raises: ValueError: State index out of range. """ @@ -134,10 +145,13 @@ def unset_final(self, state: int): def mutable_trs(self, state: int) -> MutableTrsIterator: """ Returns a mutable iterator over trs leaving the specified state. + Args: state: The source state ID. + Returns: A MutableTrsIterator. + See also: `trs`, `states`. """ return MutableTrsIterator(self, state) @@ -153,6 +167,7 @@ def delete_states(self): def num_states(self) -> int: """ Returns the number of states. + Returns: Number of states present in the Fst. """ @@ -166,10 +181,13 @@ def num_states(self) -> int: def set_start(self, state: int): """ Sets a state to be the initial state state. + Args: state: The integer index of a state. + Raises: ValueError: If State index out of range. + See also: `set_final`. """ state_id = ctypes.c_size_t(state) @@ -180,8 +198,10 @@ def set_start(self, state: int): def states(self) -> StateIterator: """ Returns an iterator over all states in the FST. + Returns: A StateIterator object for the FST. + See also: `trs`, `mutable_trs`. """ return StateIterator(self) @@ -253,13 +273,16 @@ def draw( ): """ Writes out the FST in Graphviz text format. + This method writes out the FST in the dot graph description language. The graph can be rendered using the `dot` executable provided by Graphviz. + Args: filename: The string location of the output dot/Graphviz file. isymbols: An optional symbol table used to label input symbols. osymbols: An optional symbol table used to label output symbols. drawing_config: Drawing configuration to use. + See also: `text`. """ @@ -311,10 +334,13 @@ def draw( def read(cls, filename: Union[str, Path]) -> VectorFst: """ Read a Fst at a given path. + Args: filename: The string location of the input file. + Returns: An Fst. + Raises: ValueError: Read failed. """ @@ -330,9 +356,12 @@ def read(cls, filename: Union[str, Path]) -> VectorFst: def write(self, filename: Union[str, Path]): """ Serializes FST to a file. + This method writes the FST to a file in vector binary format. + Args: filename: The string location of the output file. + Raises: ValueError: Write failed. """ @@ -344,6 +373,7 @@ def write(self, filename: Union[str, Path]): def from_bytes(cls, data: bytes) -> VectorFst: """ Load a `VectorFst` from a sequence of bytes. + Args: data: Sequence of bytes. @@ -367,6 +397,7 @@ class BytesArray(ctypes.Structure): def to_bytes(self) -> bytes: """ Turns the `VectorFst` into bytes. + Returns: Sequence of bytes. """ @@ -390,8 +421,10 @@ class BytesArray(ctypes.Structure): def equals(self, other: Fst) -> bool: """ Check if this Fst is equal to the other. + Args: other: Fst instance + Returns: Whether both Fst are equals. """ @@ -421,9 +454,11 @@ def compose( """ Compute composition of this Fst with another Fst, returning the resulting Fst. + Args: other: Fst to compose with. config: Config parameters of the composition. + Returns: The composed Fst. """ @@ -438,6 +473,7 @@ def concat(self, other: VectorFst) -> VectorFst: """ Compute Fst Concatenation of this Fst with another Fst, returning the resulting Fst. + Args: other: Fst to concatenate with. @@ -496,8 +532,10 @@ def top_sort(self) -> VectorFst: def determinize(self, config: Union[DeterminizeConfig, None] = None) -> VectorFst: """ Make an Fst deterministic + Args: config: Configuration for the determinization operation. + Returns: The resulting Fst. """ @@ -510,8 +548,10 @@ def determinize(self, config: Union[DeterminizeConfig, None] = None) -> VectorFs def minimize(self, config: Union[MinimizeConfig, None] = None) -> VectorFst: """ Minimize an FST in place + Args: config: Configuration for the minimization operation. + Returns: self """ @@ -524,8 +564,10 @@ def minimize(self, config: Union[MinimizeConfig, None] = None) -> VectorFst: def project(self, proj_type: Union[ProjectType, None] = None) -> VectorFst: """ Convert a Fst to an acceptor using input or output labels. + Args: proj_type: Whether to replace input labels or output labels. + Returns: self """ @@ -610,6 +652,7 @@ def reverse(self) -> VectorFst: def rm_epsilon(self) -> VectorFst: """ Return an equivalent FST with epsilon transitions removed. + Returns: Newly created FST with epsilon transitions removed. """ @@ -622,8 +665,10 @@ def shortest_path( ) -> VectorFst: """ Construct a FST containing the shortest path of the input FST + Args: config: Configuration for shortest-path operation. + Returns: Newly-created FST containing only the shortest path of the input FST. """ @@ -657,6 +702,7 @@ def union(self, other_fst: VectorFst) -> VectorFst: Args: other_fst: Fst to perform union with this one. + Returns: The resulting newly-created Fst. @@ -668,6 +714,7 @@ def union(self, other_fst: VectorFst) -> VectorFst: def optimize(self) -> VectorFst: """ Optimize an FST in-place. + Returns: self """ @@ -679,6 +726,7 @@ def optimize(self) -> VectorFst: def optimize_in_log(self) -> VectorFst: """ Optimize an fst in-place in the log semiring. + Returns: self """ @@ -714,8 +762,10 @@ def tr_unique(self): def isomorphic(self, other: VectorFst) -> bool: """ Check if this Fst is isomorphic with another + Args: other: Other Fst. + Returns: Whether both Fsts are equal. """ @@ -726,6 +776,7 @@ def isomorphic(self, other: VectorFst) -> bool: def __add__(self, other: VectorFst) -> VectorFst: """ `fst_1 + fst_2` is a shortcut to perform the concatenation of `fst_1` and `fst_2`. + Args: other: VectorFst to concatenate after the current Fst. @@ -739,6 +790,7 @@ def __add__(self, other: VectorFst) -> VectorFst: def __mul__(self, other: VectorFst) -> VectorFst: """ `fst_1 * fst_2` is a shortcut to perform the composition of `fst_1` and `fst_2`. + Args: other: VectorFst to compose with. @@ -751,6 +803,7 @@ def __mul__(self, other: VectorFst) -> VectorFst: def __or__(self, other: VectorFst) -> VectorFst: """ `fst_1 | fst_2` is a shortcut to perform the union of `fst_1` and `fst_2`. + Args: other: VectorFst to perform the union with. diff --git a/rustfst-python/rustfst/string_paths_iterator.py b/rustfst-python/rustfst/string_paths_iterator.py index 4d49b3b7b..53b9b0ac3 100644 --- a/rustfst-python/rustfst/string_paths_iterator.py +++ b/rustfst-python/rustfst/string_paths_iterator.py @@ -51,6 +51,7 @@ def __next__(self) -> StringPath: def done(self) -> bool: """ Returns whether we're at the end of the Iterator. + Returns: True or False """ diff --git a/rustfst-python/rustfst/symbol_table.py b/rustfst-python/rustfst/symbol_table.py index bf8a74c15..7936b436d 100644 --- a/rustfst-python/rustfst/symbol_table.py +++ b/rustfst-python/rustfst/symbol_table.py @@ -32,6 +32,7 @@ def add_symbol(self, symbol: str) -> int: Args: symbol: A symbol unicode string. + Returns: The integer key of the new symbol. """ @@ -51,6 +52,7 @@ def add_table(self, syms: SymbolTable): """ This method merges another symbol table into the current table. All key values will be offset by the current available key. + Args: syms: A `SymbolTable` to be merged with the current table. """ @@ -74,13 +76,17 @@ def copy(self) -> SymbolTable: def find(self, key: Union[int, str]) -> Union[int, str]: """ Given a symbol or index, finds the other one. + This method returns the index associated with a symbol key, or the symbol associated with a index key. + Args: key: Either a string or an index. + Returns: If key is a string, the associated index; if key is an integer, the associated symbol. + Raises: KeyError: Key not found. """ @@ -114,8 +120,10 @@ def member(self, key: Union[int, str]) -> bool: This method returns a boolean indicating whether the given symbol or index is present in the table. If one intends to perform subsequent lookup, it is better to simply call the find method, catching the KeyError. + Args: key: Either a string or an index. + Returns: Whether or not the key is present (as a string or a index) in the table. """ @@ -156,10 +164,13 @@ def read(cls, filename: Union[str, Path]) -> SymbolTable: """ Reads symbol table from binary file. This class method creates a new SymbolTable from a symbol table binary file. + Args: filename: The string location of the input binary file. + Returns: A new SymbolTable instance. + See also: `SymbolTable.read_fst`, `SymbolTable.read_text`. """ symt = ctypes.pointer(ctypes.c_void_p()) @@ -176,12 +187,15 @@ def read(cls, filename: Union[str, Path]) -> SymbolTable: def read_text(cls, filename: Union[str, Path]) -> SymbolTable: """ Reads symbol table from text file. + This class method creates a new SymbolTable from a symbol table text file. + Args: filename: The string location of the input text file. Returns: A new SymbolTable instance. + See also: `SymbolTable.read`, `SymbolTable.read_fst`. """ symt = ctypes.pointer(ctypes.c_void_p()) @@ -197,9 +211,12 @@ def read_text(cls, filename: Union[str, Path]) -> SymbolTable: def write(self, filename: Union[str, Path]): """ Serializes symbol table to a file. + This methods writes the SymbolTable to a file in binary format. + Args: filename: The string location of the output file. + Raises: FstIOError: Write failed. """ @@ -213,9 +230,12 @@ def write(self, filename: Union[str, Path]): def write_text(self, filename: Union[str, Path]): """ Writes symbol table to text file. + This method writes the SymbolTable to a file in human-readable format. + Args: filename: The string location of the output file. + Raises: FstIOError: Write failed. """ @@ -232,6 +252,7 @@ def equals(self, other: SymbolTable) -> bool: Params: other: SymbolTable instance + Returns: bool """ @@ -249,6 +270,7 @@ def __eq__(self, other: SymbolTable) -> bool: Params: other: SymbolTable instance + Returns: bool """ @@ -257,6 +279,7 @@ def __eq__(self, other: SymbolTable) -> bool: def __iter__(self) -> SymbolTableIterator: """ Returns an Iterator over the SymbolTable. + Returns: An iterator over the SymbolTable. """ @@ -292,6 +315,7 @@ class SymbolTableIterator: def __init__(self, symbol_table: SymbolTable): """ Constructs an iterator from the `Symboltable`. + Args: symbol_table: """ @@ -302,6 +326,7 @@ def __init__(self, symbol_table: SymbolTable): def __next__(self) -> Tuple[int, str]: """ Iterator over the symbols in the `SymbolTable`. + Returns: A pair label (int) and symbol (str). """ diff --git a/rustfst-python/rustfst/tr.py b/rustfst-python/rustfst/tr.py index f91b21647..b0380d518 100644 --- a/rustfst-python/rustfst/tr.py +++ b/rustfst-python/rustfst/tr.py @@ -17,6 +17,7 @@ class Tr: """ Structure representing a transition from a state to another state in a FST. + Attributes: ilabel: The input label. olabel: The output label. diff --git a/rustfst-python/rustfst/trs.py b/rustfst-python/rustfst/trs.py index f9ee3867d..ad0cb7c6d 100755 --- a/rustfst-python/rustfst/trs.py +++ b/rustfst-python/rustfst/trs.py @@ -26,6 +26,7 @@ def __init__(self, ptr=None) -> Trs: def push(self, tr: Tr): """ Add a new transition to the list. + Args: tr: The transition to add. """ @@ -45,6 +46,7 @@ def remove(self, index: int) -> Tr: def len(self) -> int: """ Compute the number of transitions in the list. + Returns: The number of transitions. diff --git a/rustfst-python/rustfst/weight.py b/rustfst-python/rustfst/weight.py index baeaea1a4..f56345594 100644 --- a/rustfst-python/rustfst/weight.py +++ b/rustfst-python/rustfst/weight.py @@ -8,6 +8,7 @@ def weight_one() -> float: """ Compute One() in the Tropical Semiring. + Returns: Float value corresponding to One() in the Tropical Semiring. """ @@ -21,6 +22,7 @@ def weight_one() -> float: def weight_zero() -> float: """ Compute Zero() in the Tropical Semiring. + Returns: Float value corresponding to Zero() in the Tropical Semiring. """ From 3fcd149804e27b978e76501a375d24408390e83b Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 16 Aug 2024 21:35:46 -0400 Subject: [PATCH 10/19] fix: mkdocs build -s works again --- .github/workflows/native.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 5491a446c..0a7813818 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -259,7 +259,7 @@ jobs: - name: Test doc generation run: | cd rustfst-python - mkdocs build + mkdocs build -s publish-python-doc: name: Publish rustfst-python's doc @@ -289,7 +289,7 @@ jobs: - run: git config user.name ${{ env.GIT_COMMITTER_NAME }} - run: git config user.email ${{ env.GIT_COMMITTER_EMAIL }} - run: git fetch origin gh-pages --depth=1 - - run: cd rustfst-python && mkdocs build + - run: cd rustfst-python && mkdocs build -s - name: Deploy Doc to latest if: github.ref == 'refs/heads/main' run: cd rustfst-python && mike deploy --push latest From 8af32677edef0905beb39d38cd6c64a5d23b8e53 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Tue, 8 Apr 2025 17:51:05 -0400 Subject: [PATCH 11/19] chore: add Python 3.13 to tags --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 00393af1f..8cf3362a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Rust", "Topic :: Scientific/Engineering :: Mathematics", "Topic :: Scientific/Engineering :: Artificial Intelligence", From ff31cee910cb2994c45a87c4b7a10d31f3573676 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Tue, 8 Apr 2025 18:01:02 -0400 Subject: [PATCH 12/19] chore: bump python version as well --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8cf3362a0..029032aba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "rustfst-python" -version = "1.1.1" +version = "1.1.2" authors = [ { name = "Alexandre Caulier", email = "alexandre.caulier.a@gmail.com" }, { name = "Emrick Sinitambirivoutin", email = "emrick.sinitambirivoutin@sonos.com" }, From 365c4b6eb65976850ecf3ff120e5c1f668548227 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Wed, 9 Apr 2025 08:15:31 -0400 Subject: [PATCH 13/19] fix: bring back requirements files --- rustfst-python/requirements-mkdocs.txt | 155 +++++++++++++++++++++++++ rustfst-python/requirements-setup.txt | 13 +++ 2 files changed, 168 insertions(+) create mode 100644 rustfst-python/requirements-mkdocs.txt create mode 100644 rustfst-python/requirements-setup.txt diff --git a/rustfst-python/requirements-mkdocs.txt b/rustfst-python/requirements-mkdocs.txt new file mode 100644 index 000000000..f7b2e20f2 --- /dev/null +++ b/rustfst-python/requirements-mkdocs.txt @@ -0,0 +1,155 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --extra=docs --output-file=rustfst-python/requirements-mkdocs.txt pyproject.toml +# +babel==2.17.0 + # via mkdocs-material +backrefs==5.8 + # via mkdocs-material +certifi==2025.1.31 + # via requests +charset-normalizer==3.4.1 + # via requests +click==8.1.8 + # via mkdocs +colorama==0.4.6 + # via + # griffe + # mkdocs-material +ghp-import==2.1.0 + # via mkdocs +griffe==1.7.2 + # via mkdocstrings-python +hjson==3.1.0 + # via + # mkdocs-macros-plugin + # super-collections +idna==3.10 + # via requests +importlib-metadata==8.6.1 + # via + # markdown + # mike + # mkdocs + # mkdocs-get-deps + # mkdocstrings +importlib-resources==6.5.2 + # via mike +jinja2==3.1.6 + # via + # mike + # mkdocs + # mkdocs-macros-plugin + # mkdocs-material + # mkdocstrings +markdown==3.7 + # via + # mkdocs + # mkdocs-autorefs + # mkdocs-material + # mkdocstrings + # pymdown-extensions +markupsafe==3.0.2 + # via + # jinja2 + # mkdocs + # mkdocs-autorefs + # mkdocstrings +mergedeep==1.3.4 + # via + # mkdocs + # mkdocs-get-deps +mike==2.1.3 + # via rustfst-python (pyproject.toml) +mkdocs==1.6.1 + # via + # mike + # mkdocs-autorefs + # mkdocs-gen-files + # mkdocs-literate-nav + # mkdocs-macros-plugin + # mkdocs-material + # mkdocs-section-index + # mkdocstrings +mkdocs-autorefs==1.4.1 + # via + # mkdocstrings + # mkdocstrings-python +mkdocs-gen-files==0.5.0 + # via rustfst-python (pyproject.toml) +mkdocs-get-deps==0.2.0 + # via mkdocs +mkdocs-literate-nav==0.6.2 + # via rustfst-python (pyproject.toml) +mkdocs-macros-plugin==1.3.7 + # via rustfst-python (pyproject.toml) +mkdocs-material==9.6.11 + # via rustfst-python (pyproject.toml) +mkdocs-material-extensions==1.3.1 + # via mkdocs-material +mkdocs-section-index==0.3.10 + # via rustfst-python (pyproject.toml) +mkdocstrings[python]==0.29.1 + # via + # mkdocstrings-python + # rustfst-python (pyproject.toml) +mkdocstrings-python==1.16.10 + # via mkdocstrings +packaging==24.2 + # via + # mkdocs + # mkdocs-macros-plugin +paginate==0.5.7 + # via mkdocs-material +pathspec==0.12.1 + # via + # mkdocs + # mkdocs-macros-plugin +platformdirs==4.3.7 + # via mkdocs-get-deps +pygments==2.19.1 + # via mkdocs-material +pymdown-extensions==10.14.3 + # via + # mkdocs-material + # mkdocstrings +pyparsing==3.2.3 + # via mike +python-dateutil==2.9.0.post0 + # via + # ghp-import + # mkdocs-macros-plugin +pyyaml==6.0.2 + # via + # mike + # mkdocs + # mkdocs-get-deps + # mkdocs-macros-plugin + # pymdown-extensions + # pyyaml-env-tag +pyyaml-env-tag==0.1 + # via + # mike + # mkdocs +requests==2.32.3 + # via mkdocs-material +six==1.17.0 + # via python-dateutil +super-collections==0.5.3 + # via mkdocs-macros-plugin +termcolor==3.0.1 + # via mkdocs-macros-plugin +typing-extensions==4.13.1 + # via mkdocstrings-python +urllib3==2.3.0 + # via requests +verspec==0.1.0 + # via mike +watchdog==6.0.0 + # via mkdocs +zipp==3.21.0 + # via + # importlib-metadata + # importlib-resources diff --git a/rustfst-python/requirements-setup.txt b/rustfst-python/requirements-setup.txt new file mode 100644 index 000000000..ca61d9f36 --- /dev/null +++ b/rustfst-python/requirements-setup.txt @@ -0,0 +1,13 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --all-build-deps --only-build-deps --output-file=rustfst-python/requirements-setup.txt +# +semantic-version==2.10.0 + # via setuptools-rust +setuptools-rust==1.11.1 + # via rustfst-python (pyproject.toml::build-system.requires) + +# The following packages are considered to be unsafe in a requirements file: +# setuptools From 0e78c2e909a88cab67bdbf78a6f1cc6cbc43451a Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Wed, 9 Apr 2025 08:15:36 -0400 Subject: [PATCH 14/19] chore: changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e8e55430..e8c7b7458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `TrivialWeight` - Implement `WeaklyDivisibleSemiring` for `BooleanWeight` +## Changed +- Update to pyproject.toml configuration for Python build +- Use pyproject.toml to generate requirements files +- Support Python 3.12 and 3.13 +- Correct documentation for various Python methods + ## [0.8.0] - 2020-16-10 ## Added From d771c3a5cea35bbe39463895078905a46d53638e Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Wed, 9 Apr 2025 08:17:49 -0400 Subject: [PATCH 15/19] fix: minimize changes from main --- .github/workflows/native.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 0a7813818..3b3396fea 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -232,8 +232,9 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Build rustfst-python and install test tools + - name: Build rustfst-python run: | + pip install -r rustfst-python/requirements-setup.txt pip install -e ".[tests]" - name: Test rustfst-python run: python -m pytest -s --cache-clear --disable-warnings rustfst-python @@ -253,9 +254,12 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - - name: Build rustfst-python and install docs tools + - name: Build rustfst-python run: | - pip install -e ".[docs]" + pip install -r rustfst-python/requirements-setup.txt + pip install -e . + - name: Install mkdocs + run: pip install -r rustfst-python/requirements-mkdocs.txt - name: Test doc generation run: | cd rustfst-python @@ -285,7 +289,9 @@ jobs: - uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - - run: pip install -e ".[docs]" + - run: pip install -r rustfst-python/requirements-setup.txt + - run: pip install -e . + - run: pip install -r rustfst-python/requirements-mkdocs.txt - run: git config user.name ${{ env.GIT_COMMITTER_NAME }} - run: git config user.email ${{ env.GIT_COMMITTER_EMAIL }} - run: git fetch origin gh-pages --depth=1 From a6e1e98844d4f24e7c2902fe6cea414280af5285 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Wed, 9 Apr 2025 08:22:58 -0400 Subject: [PATCH 16/19] fix: raise exceptions not strings --- rustfst-python/rustfst/symbol_table.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rustfst-python/rustfst/symbol_table.py b/rustfst-python/rustfst/symbol_table.py index 7936b436d..6ba1b6fc9 100644 --- a/rustfst-python/rustfst/symbol_table.py +++ b/rustfst-python/rustfst/symbol_table.py @@ -89,12 +89,13 @@ def find(self, key: Union[int, str]) -> Union[int, str]: Raises: KeyError: Key not found. + TypeError: Key is not a string or integer. """ if isinstance(key, int): return self._find_index(key) if isinstance(key, str): return self._find_symbol(key) - raise f"key can only be a string or integer. Not {type(key)}" + raise TypeError(f"key can only be a string or integer. Not {type(key)}") def _find_index(self, key: int) -> str: key = ctypes.c_size_t(key) @@ -126,6 +127,9 @@ def member(self, key: Union[int, str]) -> bool: Returns: Whether or not the key is present (as a string or a index) in the table. + + Raises: + TypeError: Key is not a string or integer. """ is_present = ctypes.c_size_t() @@ -140,7 +144,7 @@ def member(self, key: Union[int, str]) -> bool: self.ptr, symbol, ctypes.byref(is_present) ) else: - raise f"key can only be a string or integer. Not {type(key)}" + raise TypeError(f"key can only be a string or integer. Not {type(key)}") err_msg = "`member` failed" check_ffi_error(ret_code, err_msg) From 9ebe6ce786a2fb5423d994be6c9bd68c5c273e53 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Wed, 9 Apr 2025 08:39:31 -0400 Subject: [PATCH 17/19] fix(docs): update mkdocs configuration --- rustfst-python/mkdocs.yml | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/rustfst-python/mkdocs.yml b/rustfst-python/mkdocs.yml index 1581e1f35..66fa4cac8 100644 --- a/rustfst-python/mkdocs.yml +++ b/rustfst-python/mkdocs.yml @@ -74,16 +74,17 @@ plugins: default_handler: python handlers: python: - rendering: - enable_inventory: true - heading_level: 3 - members_order: source - separate_signature: false - show_category_heading: true - show_if_no_docstring: false - show_object_full_path: false - show_signature_annotations: true - show_submodules: true + options: + extra: + enable_inventory: true + heading_level: 3 + members_order: source + separate_signature: false + show_category_heading: true + show_if_no_docstring: false + show_object_full_path: false + show_signature_annotations: true + show_submodules: true watch: - rustfst - docs @@ -91,4 +92,5 @@ repo_name: rustfst repo_url: https://github.com/garvys-org/rustfst site_name: rustfst-python site_url: https://github.com/garvys-org/rustfst -theme: material +theme: + name: material From ad69230da09057fdf12892772b138c7e1f116404 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Wed, 9 Apr 2025 08:46:32 -0400 Subject: [PATCH 18/19] fix: remove setup.py from .ci/native.sh --- .ci/native.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/native.sh b/.ci/native.sh index f34d71980..3876a7990 100755 --- a/.ci/native.sh +++ b/.ci/native.sh @@ -45,10 +45,10 @@ echo $PYTHON_VERSION $PYTHON_VERSION --version ($PYTHON_VERSION -m pip freeze | grep black 1>/dev/null 2>&1) || $PYTHON_VERSION -m pip install black==21.7b0 +$PYTHON_VERSION -m pip install -r rustfst-python/requirements-setup.txt $PYTHON_VERSION -m pip install -e '.[tests]' cd rustfst-python -$PYTHON_VERSION -m setup.py develop # Check format $PYTHON_VERSION -m black --check . || fail "Format your code by running black ." 1 From 781efc6261900f33ccba9b5cb6cb73d0e769e391 Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Wed, 9 Apr 2025 09:21:47 -0400 Subject: [PATCH 19/19] fix: add a requirements file for tests to lock pylint --- .ci/native.sh | 3 ++- .github/workflows/native.yml | 3 ++- rustfst-python/requirements-tests.txt | 38 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 rustfst-python/requirements-tests.txt diff --git a/.ci/native.sh b/.ci/native.sh index 3876a7990..6e96e4a3e 100755 --- a/.ci/native.sh +++ b/.ci/native.sh @@ -46,7 +46,8 @@ $PYTHON_VERSION --version ($PYTHON_VERSION -m pip freeze | grep black 1>/dev/null 2>&1) || $PYTHON_VERSION -m pip install black==21.7b0 $PYTHON_VERSION -m pip install -r rustfst-python/requirements-setup.txt -$PYTHON_VERSION -m pip install -e '.[tests]' +$PYTHON_VERSION -m pip install -r rustfst-python/requirements-tests.txt +$PYTHON_VERSION -m pip install -e . cd rustfst-python diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 3b3396fea..a1a6c2b42 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -235,7 +235,8 @@ jobs: - name: Build rustfst-python run: | pip install -r rustfst-python/requirements-setup.txt - pip install -e ".[tests]" + pip install -r rustfst-python/requirements-tests.txt + pip install -e . - name: Test rustfst-python run: python -m pytest -s --cache-clear --disable-warnings rustfst-python diff --git a/rustfst-python/requirements-tests.txt b/rustfst-python/requirements-tests.txt new file mode 100644 index 000000000..99a3ee6f4 --- /dev/null +++ b/rustfst-python/requirements-tests.txt @@ -0,0 +1,38 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --extra=tests --output-file=rustfst-python/requirements-tests.txt pyproject.toml +# +astroid==3.3.9 + # via pylint +dill==0.3.9 + # via pylint +exceptiongroup==1.2.2 + # via pytest +iniconfig==2.1.0 + # via pytest +isort==6.0.1 + # via pylint +mccabe==0.7.0 + # via pylint +packaging==24.2 + # via pytest +platformdirs==4.3.7 + # via pylint +pluggy==1.5.0 + # via pytest +pylint==3.3.6 + # via rustfst-python (pyproject.toml) +pytest==8.3.5 + # via rustfst-python (pyproject.toml) +tomli==2.2.1 + # via + # pylint + # pytest +tomlkit==0.13.2 + # via pylint +typing-extensions==4.13.1 + # via + # astroid + # pylint