diff --git a/.ci/native.sh b/.ci/native.sh index 16e47e59b..6e96e4a3e 100755 --- a/.ci/native.sh +++ b/.ci/native.sh @@ -45,11 +45,11 @@ 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 -r rustfst-python/requirements-tests.txt +$PYTHON_VERSION -m pip install -e . cd rustfst-python -$PYTHON_VERSION -m setup.py develop # Check format $PYTHON_VERSION -m black --check . || fail "Format your code by running black ." 1 diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index dd0990723..a1a6c2b42 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -234,9 +234,9 @@ jobs: architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - name: Build rustfst-python 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 -r rustfst-python/requirements-tests.txt + pip install -e . - name: Test rustfst-python run: python -m pytest -s --cache-clear --disable-warnings rustfst-python @@ -258,7 +258,7 @@ jobs: - name: Build rustfst-python run: | pip install -r rustfst-python/requirements-setup.txt - pip install -e rustfst-python + pip install -e . - name: Install mkdocs run: pip install -r rustfst-python/requirements-mkdocs.txt - name: Test doc generation @@ -291,7 +291,7 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} - run: pip install -r rustfst-python/requirements-setup.txt - - run: pip install -e rustfst-python + - 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 }} @@ -337,9 +337,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: @@ -352,12 +371,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 +390,19 @@ 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: 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 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/* dist/*.tar.gz 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/ +*~ 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 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/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..029032aba --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,71 @@ +[build-system] +requires = ["setuptools", "setuptools-rust"] +build-backend = "setuptools.build_meta" + +[project] +name = "rustfst-python" +version = "1.1.2" +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 :: Python :: 3.13", + "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", "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}}, + +[tool.setuptools] +package-dir = {"rustfst" = "rustfst-python/rustfst"} + +[[tool.setuptools-rust.ext-modules]] +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 diff --git a/rustfst-python/mkdocs.yml b/rustfst-python/mkdocs.yml index ce9658625..66fa4cac8 100644 --- a/rustfst-python/mkdocs.yml +++ b/rustfst-python/mkdocs.yml @@ -74,21 +74,23 @@ 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 - watch: - - rustfst - - docs + 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 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 diff --git a/rustfst-python/pyproject.toml b/rustfst-python/pyproject.toml deleted file mode 100644 index 84f037aaf..000000000 --- a/rustfst-python/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[build-system] -requires = [ - "setuptools>=62.1,<63", - "setuptools_rust>=1.3,<1.4", - "wheel>=0.34,<0.35", -] \ No newline at end of file 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 index f91bffe26..f7b2e20f2 100644 --- a/rustfst-python/requirements-mkdocs.txt +++ b/rustfst-python/requirements-mkdocs.txt @@ -2,42 +2,68 @@ # 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 +# pip-compile --extra=docs --output-file=rustfst-python/requirements-mkdocs.txt pyproject.toml # -click==8.1.3 +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==0.19.1 +griffe==1.7.2 # via mkdocstrings-python -importlib-metadata==4.11.3 +hjson==3.1.0 + # via + # mkdocs-macros-plugin + # super-collections +idna==3.10 + # via requests +importlib-metadata==8.6.1 # via # markdown + # mike # mkdocs -jinja2==3.1.4 + # mkdocs-get-deps + # mkdocstrings +importlib-resources==6.5.2 + # via mike +jinja2==3.1.6 # via - # -r requirements-mkdocs.in # mike # mkdocs # mkdocs-macros-plugin # mkdocs-material # mkdocstrings -markdown==3.3.7 +markdown==3.7 # via # mkdocs # mkdocs-autorefs # mkdocs-material # mkdocstrings # pymdown-extensions -markupsafe==2.1.1 +markupsafe==3.0.2 # via # jinja2 + # mkdocs + # mkdocs-autorefs # mkdocstrings mergedeep==1.3.4 - # via mkdocs -mike==1.1.2 - # via -r requirements-mkdocs.in -mkdocs==1.3.1 + # via + # mkdocs + # mkdocs-get-deps +mike==2.1.3 + # via rustfst-python (pyproject.toml) +mkdocs==1.6.1 # via # mike # mkdocs-autorefs @@ -47,56 +73,83 @@ mkdocs==1.3.1 # 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 +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.4 - # via -r requirements-mkdocs.in -mkdocstrings[python]==0.19.0 +mkdocs-section-index==0.3.10 + # via rustfst-python (pyproject.toml) +mkdocstrings[python]==0.29.1 # via - # -r requirements-mkdocs.in # mkdocstrings-python -mkdocstrings-python==0.7.1 + # rustfst-python (pyproject.toml) +mkdocstrings-python==1.16.10 # via mkdocstrings -packaging==21.3 - # via mkdocs -pygments==2.15.0 +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.0 +pymdown-extensions==10.14.3 # via # mkdocs-material # mkdocstrings -pyparsing==3.0.9 - # via packaging -python-dateutil==2.8.2 +pyparsing==3.2.3 + # via mike +python-dateutil==2.9.0.post0 # via # ghp-import # mkdocs-macros-plugin -pyyaml==6.0 +pyyaml==6.0.2 # via # mike # mkdocs + # mkdocs-get-deps # mkdocs-macros-plugin # pymdown-extensions # pyyaml-env-tag pyyaml-env-tag==0.1 - # via mkdocs -six==1.16.0 + # via + # mike + # mkdocs +requests==2.32.3 + # via mkdocs-material +six==1.17.0 # via python-dateutil -termcolor==1.1.0 +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==2.1.7 +watchdog==6.0.0 # via mkdocs -zipp==3.8.0 - # via importlib-metadata +zipp==3.21.0 + # via + # importlib-metadata + # importlib-resources 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 index b5bcce099..ca61d9f36 100644 --- a/rustfst-python/requirements-setup.txt +++ b/rustfst-python/requirements-setup.txt @@ -1,15 +1,13 @@ # -# This file is autogenerated by pip-compile with python 3.7 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: # -# pip-compile --no-emit-index-url requirements-setup.in +# 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.1.2 - # via -r requirements-setup.in -typing-extensions==4.3.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 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 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 0e657f8b5..b710982b3 100644 --- a/rustfst-python/rustfst/algorithms/optimize.py +++ b/rustfst-python/rustfst/algorithms/optimize.py @@ -13,6 +13,7 @@ def optimize(fst: VectorFst) -> VectorFst: """ Optimize an fst in-place + Args: fst: Fst to optimize. """ @@ -25,6 +26,7 @@ def optimize(fst: VectorFst) -> VectorFst: def optimize_in_log(fst: VectorFst) -> 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/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/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 7d5781195..86be3a592 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 """ @@ -622,8 +664,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 +701,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 +713,7 @@ def union(self, other_fst: VectorFst) -> VectorFst: def optimize(self) -> VectorFst: """ Optimize an FST in-place. + Returns: self """ @@ -678,6 +724,7 @@ def optimize(self) -> VectorFst: def optimize_in_log(self) -> VectorFst: """ Optimize an fst in-place in the log semiring. + Returns: self """ @@ -717,8 +764,10 @@ def tr_unique(self) -> VectorFst: def isomorphic(self, other: VectorFst) -> bool: """ Check if this Fst is isomorphic with another + Args: other: Other Fst. + Returns: Whether both Fsts are equal. """ @@ -741,6 +790,7 @@ def invert(self) -> VectorFst: 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. @@ -754,6 +804,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. @@ -766,6 +817,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..6ba1b6fc9 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,21 +76,26 @@ 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. + 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) @@ -114,10 +121,15 @@ 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. + + Raises: + TypeError: Key is not a string or integer. """ is_present = ctypes.c_size_t() @@ -132,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) @@ -156,10 +168,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 +191,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 +215,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 +234,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 +256,7 @@ def equals(self, other: SymbolTable) -> bool: Params: other: SymbolTable instance + Returns: bool """ @@ -249,6 +274,7 @@ def __eq__(self, other: SymbolTable) -> bool: Params: other: SymbolTable instance + Returns: bool """ @@ -257,6 +283,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 +319,7 @@ class SymbolTableIterator: def __init__(self, symbol_table: SymbolTable): """ Constructs an iterator from the `Symboltable`. + Args: symbol_table: """ @@ -302,6 +330,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. """ 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", -)