diff --git a/.github/workflows/check_format.yml b/.github/workflows/check_format.yml index b96dc2c..28d81e8 100644 --- a/.github/workflows/check_format.yml +++ b/.github/workflows/check_format.yml @@ -6,12 +6,15 @@ on: - all pull_request: { } jobs: - black: + ruff: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Install uv uses: astral-sh/setup-uv@v7 - - name: "Black Code Formatter" + - name: "Ruff format check" run: | - uv run black . --check + uv run ruff format --check . + - name: "Ruff import sorting check" + run: | + uv run ruff check . diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9369268..f778dd9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,5 +12,6 @@ Rules are easy. You can Writing code ------------ -All files must be formatted using [Black](https://black.readthedocs.io). Easier is not possible. +All files must be formatted using [ruff](https://docs.astral.sh/ruff/) +(`ruff format` for code style, `ruff check` for import sorting). Easier is not possible. For bigger features it is recommended to create an own branch. diff --git a/Makefile b/Makefile index 47ede0a..84e510f 100644 --- a/Makefile +++ b/Makefile @@ -16,5 +16,13 @@ test: mypy: uv run mypy --pretty pydifact +format: + uv run ruff format . + uv run ruff check --fix . + +check-format: + uv run ruff format --check . + uv run ruff check . + test-extended: uv run pytest diff --git a/README.md b/README.md index 26b388c..d8e2870 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,12 @@ This installs all the python packages needed for development and testing. ### Code formatting -Format all python files using [black](https://black.readthedocs.io) before committing: +Format all python files and sort imports using [ruff](https://docs.astral.sh/ruff/) +before committing: ```bash -uv run black . +uv run ruff format . +uv run ruff check --fix . ``` Happy coding, PR are more than welcome to make this library better, or to add a feature that matches your needs. diff --git a/pydifact/exceptions.py b/pydifact/exceptions.py index f6afd96..d60d2d8 100644 --- a/pydifact/exceptions.py +++ b/pydifact/exceptions.py @@ -1,5 +1,4 @@ class EDISyntaxError(Exception): - def __init__( self, message: str, line_number: int = None, column_number: int = None ): diff --git a/pydifact/generator/create_directory_urls.py b/pydifact/generator/create_directory_urls.py index 698bc40..88a853d 100644 --- a/pydifact/generator/create_directory_urls.py +++ b/pydifact/generator/create_directory_urls.py @@ -1,6 +1,5 @@ import sys -import black from bs4 import BeautifulSoup # This file parses the https://unece.org/trade/uncefact/unedifact/download page diff --git a/pydifact/generator/edcd.py b/pydifact/generator/edcd.py index 55cedd3..050eb8a 100644 --- a/pydifact/generator/edcd.py +++ b/pydifact/generator/edcd.py @@ -1,8 +1,8 @@ import re from os import PathLike -from xml.etree import ElementTree from pathlib import Path -from typing import List, Dict, Any +from typing import Any, Dict, List +from xml.etree import ElementTree from pydifact.generator.base import UntidBaseParser diff --git a/pydifact/generator/eded.py b/pydifact/generator/eded.py index 260107e..4d3f04a 100644 --- a/pydifact/generator/eded.py +++ b/pydifact/generator/eded.py @@ -1,7 +1,7 @@ import re from os import PathLike -from xml.etree import ElementTree from pathlib import Path +from xml.etree import ElementTree from pydifact.generator.base import UntidBaseParser diff --git a/pydifact/generator/edmd.py b/pydifact/generator/edmd.py index e351631..ecce8ef 100644 --- a/pydifact/generator/edmd.py +++ b/pydifact/generator/edmd.py @@ -1,8 +1,8 @@ import re from os import PathLike -from xml.etree import ElementTree from pathlib import Path -from typing import List, Dict, Any, Optional +from typing import Any, Dict, List, Optional +from xml.etree import ElementTree from pydifact.generator.base import UntidBaseParser @@ -207,7 +207,6 @@ def _process(self, file_path: PathLike | str) -> None: # Handle level changes if parts[1] != "" and "Segment group" not in parts[2] and "-" in parts[5]: - level = parts[5].replace("-", "") levels_to_remove = level.count("+") current_level -= levels_to_remove diff --git a/pydifact/generator/edsd.py b/pydifact/generator/edsd.py index b3ac93d..539388d 100644 --- a/pydifact/generator/edsd.py +++ b/pydifact/generator/edsd.py @@ -1,8 +1,8 @@ import re from os import PathLike -from xml.etree import ElementTree from pathlib import Path -from typing import List, Dict, Any +from typing import Any, Dict, List +from xml.etree import ElementTree from pydifact.generator.base import UntidBaseParser diff --git a/pydifact/generator/runner.py b/pydifact/generator/runner.py index a249e96..2ce6068 100644 --- a/pydifact/generator/runner.py +++ b/pydifact/generator/runner.py @@ -1,28 +1,26 @@ -import sys import os +import re +import sys import zipfile -from xml.etree import ElementTree +from os import PathLike from pathlib import Path -import re - +from xml.etree import ElementTree from pydifact.generator.base import UntidBaseParser -from pydifact.generator.edsd import EDSDParser -from pydifact.generator.edcd import EDCDParser -from pydifact.generator.eded import EDEDParser -from pydifact.generator.uncl import UNCLParser -from pydifact.generator.edmd import EDMDParser -from pydifact.generator.unsl import UNSLParser from pydifact.generator.constants import ( - directories_urls, V3_SERVICE_CODE_LISTS, V4_SERVICE_CODE_LISTS, - services_map, + directories_urls, renames, + services_map, ) -from pydifact.generator.utils import is_prehistoric, download_file - -from os import PathLike +from pydifact.generator.edcd import EDCDParser +from pydifact.generator.eded import EDEDParser +from pydifact.generator.edmd import EDMDParser +from pydifact.generator.edsd import EDSDParser +from pydifact.generator.uncl import UNCLParser +from pydifact.generator.unsl import UNSLParser +from pydifact.generator.utils import download_file, is_prehistoric V4_RELEASE_NUMBER = "40219" zips_directory = Path(__file__).parent / "zips" @@ -189,7 +187,6 @@ def extract_edifact_data( """ print(f"Parsing {parser.name}... for release '{release}'") try: - with open(output_file, "w", encoding="utf-8") as f: f.write(parser.get_xml()) @@ -313,7 +310,6 @@ def parse_messages(source_dir, target_dir) -> None: def generate_service_codes( syntax_version: str, extended_syntax_version: str, service_subrelease: str ): - specific_release = service_subrelease.lower() version_dir = f"v{extended_syntax_version}" generator_base_dir = Path(__file__).parent diff --git a/pydifact/generator/uncl.py b/pydifact/generator/uncl.py index a32cf2c..6ca1af4 100644 --- a/pydifact/generator/uncl.py +++ b/pydifact/generator/uncl.py @@ -1,8 +1,8 @@ import re from os import PathLike -from xml.etree import ElementTree from pathlib import Path from typing import List +from xml.etree import ElementTree from pydifact.generator.base import UntidBaseParser from pydifact.generator.constants import MAX_LINE_LENGTH @@ -249,7 +249,6 @@ def _process(self, file_path: PathLike | str) -> None: else: # no additional line found, break break else: - match2 = re.match(r"^[\s]{14}(.*)", lines[i]) if match2: if value_description: diff --git a/pydifact/generator/unsl.py b/pydifact/generator/unsl.py index e2362d2..a9a504d 100644 --- a/pydifact/generator/unsl.py +++ b/pydifact/generator/unsl.py @@ -1,8 +1,8 @@ import re from os import PathLike -from xml.etree import ElementTree from pathlib import Path -from typing import List, Dict +from typing import Dict, List +from xml.etree import ElementTree from pydifact.generator.base import UntidBaseParser diff --git a/pydifact/parser.py b/pydifact/parser.py index f21a060..33e8694 100644 --- a/pydifact/parser.py +++ b/pydifact/parser.py @@ -20,21 +20,21 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from collections.abc import Iterator, Iterable +import logging +from collections.abc import Iterable, Iterator from pydifact.constants import ( - EDI_DEFAULT_VERSION, + EDI_DEFAULT_DIRECTORY, EDI_DEFAULT_SYNTAX, + EDI_DEFAULT_VERSION, Element, Elements, - EDI_DEFAULT_DIRECTORY, ) +from pydifact.control import Characters from pydifact.exceptions import EDISyntaxError -from pydifact.tokenizer import Tokenizer -from pydifact.token import Token from pydifact.segments import Segment, SegmentFactory -from pydifact.control import Characters -import logging +from pydifact.token import Token +from pydifact.tokenizer import Tokenizer logger = logging.getLogger(__name__) @@ -122,7 +122,7 @@ def parse( if una_found: idx_begin = idx_una + len(una_pattern) idx_end = idx_begin + 6 - characters = Characters.from_str(f"UNA{message[idx_begin: idx_end]}") + characters = Characters.from_str(f"UNA{message[idx_begin:idx_end]}") # remove the UNA segment from the string, # ignore everything before UNA because it should be the first segment if una_found. diff --git a/pydifact/segmentcollection.py b/pydifact/segmentcollection.py index 31bb0d2..6d973fd 100644 --- a/pydifact/segmentcollection.py +++ b/pydifact/segmentcollection.py @@ -25,11 +25,11 @@ from collections.abc import Callable, Iterable, Iterator, Sequence from typing import Type, TypeVar -from pydifact.exceptions import EDISyntaxError, ValidationError +from pydifact.constants import Element, Elements from pydifact.control import Characters +from pydifact.exceptions import EDISyntaxError, ValidationError from pydifact.parser import Parser from pydifact.segments import Segment -from pydifact.constants import Element, Elements from pydifact.serializer import Serializer T = TypeVar("T", bound="AbstractSegmentsContainer") diff --git a/pydifact/segments.py b/pydifact/segments.py index b2b92d7..7198ab0 100644 --- a/pydifact/segments.py +++ b/pydifact/segments.py @@ -19,27 +19,27 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -import warnings import logging -from typing import overload +import warnings +import xml.etree.ElementTree as ET from functools import lru_cache from pathlib import Path -import xml.etree.ElementTree as ET +from typing import overload from pydifact.constants import ( - EDI_DEFAULT_VERSION, - M, + EDI_DEFAULT_DIRECTORY, EDI_DEFAULT_SYNTAX, + EDI_DEFAULT_VERSION, Element, - EDI_DEFAULT_DIRECTORY, + M, service_segments, ) from pydifact.exceptions import ( - ValidationError, - MissingImplementationWarning, EDISyntaxError, + MissingImplementationWarning, + ValidationError, ) -from pydifact.syntax.common import DataElement, CompositeDataElement +from pydifact.syntax.common import CompositeDataElement, DataElement from pydifact.utils import get_syntax_release_version logger = logging.getLogger(__name__) diff --git a/pydifact/serializer.py b/pydifact/serializer.py index 86afbed..5d62d0a 100644 --- a/pydifact/serializer.py +++ b/pydifact/serializer.py @@ -19,9 +19,9 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from pydifact.control.characters import Characters import re +from pydifact.control.characters import Characters from pydifact.segments import Segment diff --git a/pydifact/syntax/common.py b/pydifact/syntax/common.py index 313e1a4..90df30c 100644 --- a/pydifact/syntax/common.py +++ b/pydifact/syntax/common.py @@ -12,14 +12,13 @@ import re import warnings -from typing import Optional, Type, TypeAlias, TypeVar, NamedTuple +from typing import NamedTuple, Optional, Type, TypeAlias, TypeVar from pydifact.constants import EDI_DEFAULT_VERSION, M from pydifact.exceptions import ValidationError allowed_alphanum_chars = set( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*-./:()'&=+\"?," - "!_\\ " + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*-./:()'&=+\"?,!_\\ " ) diff --git a/pydifact/syntax/v1/__init__.py b/pydifact/syntax/v1/__init__.py index 6866374..13d9e7b 100644 --- a/pydifact/syntax/v1/__init__.py +++ b/pydifact/syntax/v1/__init__.py @@ -1,15 +1,15 @@ +from pydifact.constants import C, M +from pydifact.segments import Segment from pydifact.syntax.common import ( - DataElement, CompositeDataElement, + DataElement, SyntaxVersionNumber, ) -from pydifact.constants import M, C -from pydifact.segments import Segment __version__ = 1 -from .data import partner_identification_codes from ... import Characters +from .data import partner_identification_codes class ServiceStringAdvice(DataElement): diff --git a/pydifact/syntax/v4/__init__.py b/pydifact/syntax/v4/__init__.py index 3825ce1..b9ad12e 100644 --- a/pydifact/syntax/v4/__init__.py +++ b/pydifact/syntax/v4/__init__.py @@ -1,14 +1,15 @@ from typing import NamedTuple -from pydifact.constants import M, C +from pydifact.constants import C, M from pydifact.syntax import v1, v2, v3 from pydifact.syntax.common import ( - DataElement, CompositeDataElement, + DataElement, SyntaxVersionNumber, ) -from .data import partner_identification_codes + from ... import Segment +from .data import partner_identification_codes __version__ = 4 diff --git a/pydifact/tokenizer.py b/pydifact/tokenizer.py index 23b7233..420bf56 100644 --- a/pydifact/tokenizer.py +++ b/pydifact/tokenizer.py @@ -21,9 +21,9 @@ # THE SOFTWARE. from collections.abc import Iterator +from pydifact.control.characters import Characters from pydifact.exceptions import EDISyntaxError from pydifact.token import Token -from pydifact.control.characters import Characters class Tokenizer: diff --git a/pyproject.toml b/pyproject.toml index 23f8552..20d8066 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,15 +28,20 @@ dev = [ "Sphinx>=7.2.0", "setuptools>=69.1.0", "wheel>=0.42.0", - "black>=25.1.0", + "ruff>=0.11.0", "sphinx-rtd-theme>=2.0.0", "build", "twine", "mypy>=1.15.0" ] -[tool.black] -target_version = ["py310", "py311", "py312", "py313"] +[tool.ruff] +target-version = "py310" + +[tool.ruff.lint] +# Limit linting to import sorting (isort) for now; ruff format handles +# code style. Additional rule sets (e.g. "F" for pyflakes) can be enabled later. +select = ["I"] [project.urls] Documentation = "https://pydifact.readthedocs.io" diff --git a/tests/test_characters.py b/tests/test_characters.py index 5b60505..9abbcd9 100644 --- a/tests/test_characters.py +++ b/tests/test_characters.py @@ -15,6 +15,7 @@ # along with this program. If not, see . import pytest + from pydifact.control import Characters diff --git a/tests/test_parser.py b/tests/test_parser.py index f18504d..1002fba 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -13,12 +13,13 @@ # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +import pytest + +from pydifact.control.characters import Characters from pydifact.exceptions import EDISyntaxError from pydifact.parser import Parser, TokenIterator from pydifact.segments import Segment -from pydifact.control.characters import Characters from pydifact.token import Token -import pytest # @pytest.fixture # def mocked_tokenizer(mocker): @@ -107,9 +108,9 @@ def test_compare_equal_segments(parser, default_una_segment): a = Segment("RFF", ["PD", "50515"]) b = Segment("RFF", ["PD", "50515"]) assert a == b - assert ( - a is not b - ), "Two separatedly, but visually identically created Segment objects may not be the same object." + assert a is not b, ( + "Two separatedly, but visually identically created Segment objects may not be the same object." + ) def test_una_parser1(parser): diff --git a/tests/test_sage_coala.py b/tests/test_sage_coala.py index 86d82f3..91ff933 100644 --- a/tests/test_sage_coala.py +++ b/tests/test_sage_coala.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import os + from pydifact.segmentcollection import Interchange from pydifact.segments import Segment diff --git a/tests/test_segmentcollection.py b/tests/test_segmentcollection.py index 5e56fb9..5e9e0ba 100644 --- a/tests/test_segmentcollection.py +++ b/tests/test_segmentcollection.py @@ -218,7 +218,7 @@ def test_empty_interchange_w_una(): Segment("UNZ", "0", "42"), ] ) - assert str(i) == ("UNA:+,? '" "UNB+UNOC:1+1234+3333+200102:2212+42'UNZ+0+42'") + assert str(i) == ("UNA:+,? 'UNB+UNOC:1+1234+3333+200102:2212+42'UNZ+0+42'") def test_interchange_messages(interchange, message): @@ -252,7 +252,7 @@ def test_interchange_from_str_multi_messages(): def test_faulty_interchange__UNH_not_closed(): """creates a message with an opening UNH message, without closing UNT""" i = Interchange.from_str( - "UNB+UNOC:1+1234+3333+200102:2212+42'" "UNH+42z42+PAORES:93:1:IA'" "UNZ+2+42'" + "UNB+UNOC:1+1234+3333+200102:2212+42'UNH+42z42+PAORES:93:1:IA'UNZ+2+42'" ) with pytest.raises(EDISyntaxError): @@ -275,7 +275,7 @@ def test_faulty_interchange__nested_UNH_not_closed(): def test_faulty_interchange__UNT_without_UNH(): """creates a message with an cloding UNT, without UNH""" i = Interchange.from_str( - "UNB+UNOC:1+1234+3333+200102:2212+42'" "UNT+2+42z42'" "UNZ+2+42'" + "UNB+UNOC:1+1234+3333+200102:2212+42'UNT+2+42z42'UNZ+2+42'" ) with pytest.raises(EDISyntaxError): diff --git a/tests/test_serializer.py b/tests/test_serializer.py index 91b3715..7bbaf2a 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -15,9 +15,10 @@ # along with this program. If not, see . import copy import datetime + import pytest -from pydifact.segmentcollection import RawSegmentCollection, Interchange +from pydifact.segmentcollection import Interchange, RawSegmentCollection from pydifact.segments import Segment from pydifact.serializer import Serializer diff --git a/tests/test_syntax_v1.py b/tests/test_syntax_v1.py index 522a064..88e567c 100644 --- a/tests/test_syntax_v1.py +++ b/tests/test_syntax_v1.py @@ -1,8 +1,8 @@ +import pytest + from pydifact import Serializer from pydifact.exceptions import ValidationError from pydifact.segments import Segment -import pytest - from pydifact.syntax.v1 import UNASegment default_characters = ":+,? '" diff --git a/tests/test_tokenizer.py b/tests/test_tokenizer.py index d4515da..98aa255 100644 --- a/tests/test_tokenizer.py +++ b/tests/test_tokenizer.py @@ -183,8 +183,10 @@ def test_escaped_newline_char(): with pytest.raises(EDISyntaxError) as excinfo: # must raise a EDISyntaxError as there is no newline after an escape char # "?" allowed. - list(Tokenizer().get_tokens("""UNB+? -FOO'""")) + list( + Tokenizer().get_tokens("""UNB+? +FOO'""") + ) assert "Newlines after escape characters are not allowed." in str(excinfo.value) assert "line 0, column 5" in str(excinfo.value) diff --git a/uv.lock b/uv.lock index 873218d..3142136 100644 --- a/uv.lock +++ b/uv.lock @@ -74,50 +74,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", size = 30181, upload-time = "2024-05-28T17:01:53.112Z" }, ] -[[package]] -name = "black" -version = "26.5.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "mypy-extensions" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "platformdirs" }, - { name = "pytokens" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", version = "4.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c0/37/5628dd55bf2b34257fc7603f0fe97c40e3aaf24265f416a9c85c95ca1436/black-26.5.1.tar.gz", hash = "sha256:dd321f668053961824bcc1be1cc1df748b2d7e4fa28086b08331e577b0100a73", size = 679439, upload-time = "2026-05-18T16:53:36.107Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/be/84/b3f55026206a9e8820a91503308075ca48eadc515e436731ca01dbe043b3/black-26.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9942db8888e06943c5dde66ca0037dcff82a2a4ec1ad0ada9e0d2ee9d9823893", size = 1987719, upload-time = "2026-05-18T17:05:02.757Z" }, - { url = "https://files.pythonhosted.org/packages/c6/34/7db312c5e5783d6e76cffd9d5ac8972a32badae4c6e3288dac0eed8d3bed/black-26.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:89c93167a74d3a75dfaa38a5c7cca015537d5820dd7f17d63267d674a61cae90", size = 1810083, upload-time = "2026-05-18T17:05:04.302Z" }, - { url = "https://files.pythonhosted.org/packages/33/e2/e0101e73c2c8727634e2efcb35e2b34bd23ad70dfa673789f5773a591b21/black-26.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22f2cd76d069cc54c71f10360744ba8983fbb616903b4304a85b734915c8e1b4", size = 1860633, upload-time = "2026-05-18T17:05:06.391Z" }, - { url = "https://files.pythonhosted.org/packages/b0/4c/e15c0c5b23cf3651035fe5addcce90e283af3548a3f91bb03d81b83106ab/black-26.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:87ed5c6f450580a2f6790bc7cbfb016dfc73bc750249762268a3695361315eef", size = 1477886, upload-time = "2026-05-18T17:05:07.96Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3f/59d43ade98d2ce5c8dc34a4e46cbecd177e6d55d7d4092969c6003ccc655/black-26.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:58b4bd92cf88aacf83d88479c8f9caee044b1ec55f2451a337354a7ea2590a22", size = 1277111, upload-time = "2026-05-18T17:05:09.473Z" }, - { url = "https://files.pythonhosted.org/packages/4b/96/3c3e09f09f44a37aac36b178a279cd19aa7001bd796187a7b162a294c81f/black-26.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:96ae2c733b2aabdd9986e2c5df628ff3473676cd1c5faded1ff496cf6d74083c", size = 1970639, upload-time = "2026-05-18T17:05:11.461Z" }, - { url = "https://files.pythonhosted.org/packages/83/ea/5ad117b9ee3ecd933c712bcbae610006e5b7cc9f41c526cd7ed3b6c4124c/black-26.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0e48b87e03bf109288e55cfceadcfa15ff5470aca2851a851950ed2926f450d7", size = 1792130, upload-time = "2026-05-18T17:05:12.983Z" }, - { url = "https://files.pythonhosted.org/packages/06/3a/7c448bc623fcdfa96672531beb5a616ea5e64f6975955254d7731ffb0ad9/black-26.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5119fa92ae61f786e8c3662fd60aece1d0a2dd5cca5d0c79417a95e7a4272a59", size = 1846134, upload-time = "2026-05-18T17:05:14.506Z" }, - { url = "https://files.pythonhosted.org/packages/a1/5b/0b39b3a5917f0657ac014ad2edb58c139553a478adfe7f817abf1622ff6e/black-26.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:30d3c14661f2792e9142cce3eeeb1cbc175b3eb5f733be0c8eeb99651e52b0c3", size = 1478883, upload-time = "2026-05-18T17:05:16.542Z" }, - { url = "https://files.pythonhosted.org/packages/4c/48/dc222692e0f95030db1bbfb6c857e76858bad09058221ea7aae815255327/black-26.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:1ef92b76f7733f282fd096ea406200b5a286c42947412b0eaff3a74e3616cefe", size = 1277776, upload-time = "2026-05-18T17:05:18.029Z" }, - { url = "https://files.pythonhosted.org/packages/24/99/7744b906703228264ef73bdd534df88ec1ef3de45c4e78f6d31b9e32d0c9/black-26.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4ad6fa01f941920f54f2bbb35f3df7673428a0ef98a0b0840c2eaef3b110efa8", size = 2012518, upload-time = "2026-05-18T17:05:20.108Z" }, - { url = "https://files.pythonhosted.org/packages/b7/c0/c5a3b1636dfd09c42534f2b3cf33506814f6d3e066fb0879ffa16c1ae860/black-26.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3915f256e75a2d7cf88d8953d37f780455dc586cc72dee059c528fe77f581217", size = 1816016, upload-time = "2026-05-18T17:05:21.84Z" }, - { url = "https://files.pythonhosted.org/packages/1f/0e/36044316b65ca471d3bb6d3703fd06fb50c6b727c3562f6a5a3153634f88/black-26.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d98d4137277c75dfb898ec8d846c4fd68ba1e9cf77f95e2865c203dc18f4c3d", size = 1884150, upload-time = "2026-05-18T17:05:23.546Z" }, - { url = "https://files.pythonhosted.org/packages/b3/33/dafc5808c2af43672912111d7c3354af1615f7e2be3bed7a878461abbe4d/black-26.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:a1dca32d9f1784af512a13410ec204c6f7f0aa9797a111c42e1c03449821c264", size = 1486825, upload-time = "2026-05-18T17:05:25.004Z" }, - { url = "https://files.pythonhosted.org/packages/82/14/b965ee6ad2a311f28bdbf692def3ee9848d2ae289dab28b27657fcee3e78/black-26.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:1037d5ac7b7b310b2632ad867ec8d0e4c4819dcdb0b820f63135da746a24e418", size = 1288646, upload-time = "2026-05-18T17:05:26.477Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5c/c384363980e11e25ca6b93205949bb331fbf35f4e0dbec376dfa6326cec8/black-26.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2b36cf2ddf5566e205f6535f782a62194a184d33e175b64ae8c40b1737522be3", size = 2009020, upload-time = "2026-05-18T17:05:28.132Z" }, - { url = "https://files.pythonhosted.org/packages/0b/df/9f31c5e0babbfed77d505fc5d120beb98b21b33feaeded3924ea941fe360/black-26.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f7ea64ebfa01b50f693508fc39f875e264446d3b097088f84f203b9d09618a0", size = 1813335, upload-time = "2026-05-18T17:05:31.266Z" }, - { url = "https://files.pythonhosted.org/packages/fb/24/8e7b9a2fa61b0afd82209efe937557d180a1fa055bd7f6161eb9defc3719/black-26.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecb3e624844c798144e9bd986954e0adc81d8911a1f30f375e1252fe26e8c294", size = 1881614, upload-time = "2026-05-18T17:05:32.718Z" }, - { url = "https://files.pythonhosted.org/packages/49/ad/b4e0d9365ba8ac34f6bbab62a4b1b2dd5d618fac3fa1b8db968c844201b5/black-26.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:e1a26503279b6b310669fb0b219c39e4820b77e8189fe80f522bb511f247db0a", size = 1488925, upload-time = "2026-05-18T17:05:34.259Z" }, - { url = "https://files.pythonhosted.org/packages/a1/4b/652b859bf5df88a751c30451b09338f7fd26a77d1271c666992f836b7711/black-26.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c34b25da232ead53a6f335b76dbea124f4d152ad568b9080d6f944bc2b34b52", size = 1289883, upload-time = "2026-05-18T17:05:36.019Z" }, - { url = "https://files.pythonhosted.org/packages/a6/16/a8da8eb208c51c7f4ce74609a45d0dcc6d8a2141e45e81ee5289d1bb0d59/black-26.5.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e88976690a64b0af98312ca958415849cb42423423c5f2ee74af4b49a97a2168", size = 2004800, upload-time = "2026-05-18T17:05:38.182Z" }, - { url = "https://files.pythonhosted.org/packages/11/8a/a479296a19e383b70a725882a6cf3d786540601ff03cabbaaf1cce864c5a/black-26.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32d5ea7f6c8bdfa6e648326ebca1f02b0764e2a029edc6f8dce2627e19d468c3", size = 1815576, upload-time = "2026-05-18T17:05:40.309Z" }, - { url = "https://files.pythonhosted.org/packages/81/6b/cfaf3d39f25132c156a068f6b805576c9103a84086019507c70e1911ee7d/black-26.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea8d16dc41655aa113cd64665e7219446cd7e4ff2248d7178eaa905190c86b18", size = 1877927, upload-time = "2026-05-18T17:05:42.463Z" }, - { url = "https://files.pythonhosted.org/packages/66/76/302e313964bcff7e28df329d39f84f5270095730d85ff0acc260610a0d82/black-26.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:577f21094ea469ef92ec1adaf2c9441a226d2144d01a5be2fa823cecf6543e50", size = 1511860, upload-time = "2026-05-18T17:05:43.943Z" }, - { url = "https://files.pythonhosted.org/packages/27/4e/a3827e35e0e567f9f9ee59e2a0ab979267dca98718f25547ca8c6733afd4/black-26.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:ed1a20af114c301a0269bf01163d51dbef72737fd65f850001e7cbe7f3c7abae", size = 1316632, upload-time = "2026-05-18T17:05:45.521Z" }, - { url = "https://files.pythonhosted.org/packages/94/51/f975cae76d44274cc2868dc9040ac5d58d464784610234455b4e7b19c6ef/black-26.5.1-py3-none-any.whl", hash = "sha256:4ed7f7da04046d2e488437170797d3b4a4ad83906683bcb7dfc68b673bbce5e2", size = 213693, upload-time = "2026-05-18T16:53:33.964Z" }, -] - [[package]] name = "build" version = "1.5.0" @@ -257,18 +213,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767, upload-time = "2024-12-24T18:12:32.852Z" }, ] -[[package]] -name = "click" -version = "8.1.8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, -] - [[package]] name = "colorama" version = "0.4.6" @@ -889,15 +833,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, ] -[[package]] -name = "platformdirs" -version = "4.3.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291, upload-time = "2025-03-19T20:36:10.989Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499, upload-time = "2025-03-19T20:36:09.038Z" }, -] - [[package]] name = "pluggy" version = "1.5.0" @@ -922,13 +857,13 @@ source = { editable = "." } [package.dev-dependencies] dev = [ - { name = "black" }, { name = "build" }, { name = "keyring" }, { name = "mypy" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "pytest-profiling" }, + { name = "ruff" }, { name = "setuptools" }, { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -941,13 +876,13 @@ dev = [ [package.metadata.requires-dev] dev = [ - { name = "black", specifier = ">=25.1.0" }, { name = "build" }, { name = "keyring", specifier = ">=24.3.0" }, { name = "mypy", specifier = ">=1.15.0" }, { name = "pytest", specifier = ">=8.0.1" }, { name = "pytest-cov", specifier = ">=4.1.0" }, { name = "pytest-profiling", specifier = ">=1.7.0" }, + { name = "ruff", specifier = ">=0.11.0" }, { name = "setuptools", specifier = ">=69.1.0" }, { name = "sphinx", specifier = ">=7.2.0" }, { name = "sphinx-rtd-theme", specifier = ">=2.0.0" }, @@ -1019,45 +954,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e3/ac/c428c66241a144617a8af7a28e2e055e1438d23b949b62ac4b401a69fb79/pytest_profiling-1.8.1-py3-none-any.whl", hash = "sha256:3dd8713a96298b42d83de8f5951df3ada3e61b3e5d2a06956684175529e17aea", size = 9929, upload-time = "2024-11-29T19:33:02.111Z" }, ] -[[package]] -name = "pytokens" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/24/f206113e05cb8ef51b3850e7ef88f20da6f4bf932190ceb48bd3da103e10/pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5", size = 161522, upload-time = "2026-01-30T01:02:50.393Z" }, - { url = "https://files.pythonhosted.org/packages/d4/e9/06a6bf1b90c2ed81a9c7d2544232fe5d2891d1cd480e8a1809ca354a8eb2/pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe", size = 246945, upload-time = "2026-01-30T01:02:52.399Z" }, - { url = "https://files.pythonhosted.org/packages/69/66/f6fb1007a4c3d8b682d5d65b7c1fb33257587a5f782647091e3408abe0b8/pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c", size = 259525, upload-time = "2026-01-30T01:02:53.737Z" }, - { url = "https://files.pythonhosted.org/packages/04/92/086f89b4d622a18418bac74ab5db7f68cf0c21cf7cc92de6c7b919d76c88/pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7", size = 262693, upload-time = "2026-01-30T01:02:54.871Z" }, - { url = "https://files.pythonhosted.org/packages/b4/7b/8b31c347cf94a3f900bdde750b2e9131575a61fdb620d3d3c75832262137/pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2", size = 103567, upload-time = "2026-01-30T01:02:56.414Z" }, - { url = "https://files.pythonhosted.org/packages/3d/92/790ebe03f07b57e53b10884c329b9a1a308648fc083a6d4a39a10a28c8fc/pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440", size = 160864, upload-time = "2026-01-30T01:02:57.882Z" }, - { url = "https://files.pythonhosted.org/packages/13/25/a4f555281d975bfdd1eba731450e2fe3a95870274da73fb12c40aeae7625/pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc", size = 248565, upload-time = "2026-01-30T01:02:59.912Z" }, - { url = "https://files.pythonhosted.org/packages/17/50/bc0394b4ad5b1601be22fa43652173d47e4c9efbf0044c62e9a59b747c56/pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d", size = 260824, upload-time = "2026-01-30T01:03:01.471Z" }, - { url = "https://files.pythonhosted.org/packages/4e/54/3e04f9d92a4be4fc6c80016bc396b923d2a6933ae94b5f557c939c460ee0/pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16", size = 264075, upload-time = "2026-01-30T01:03:04.143Z" }, - { url = "https://files.pythonhosted.org/packages/d1/1b/44b0326cb5470a4375f37988aea5d61b5cc52407143303015ebee94abfd6/pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6", size = 103323, upload-time = "2026-01-30T01:03:05.412Z" }, - { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, - { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, - { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, - { url = "https://files.pythonhosted.org/packages/20/01/7436e9ad693cebda0551203e0bf28f7669976c60ad07d6402098208476de/pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9", size = 268076, upload-time = "2026-01-30T01:03:10.957Z" }, - { url = "https://files.pythonhosted.org/packages/2e/df/533c82a3c752ba13ae7ef238b7f8cdd272cf1475f03c63ac6cf3fcfb00b6/pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68", size = 103552, upload-time = "2026-01-30T01:03:12.066Z" }, - { url = "https://files.pythonhosted.org/packages/cb/dc/08b1a080372afda3cceb4f3c0a7ba2bde9d6a5241f1edb02a22a019ee147/pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b", size = 160720, upload-time = "2026-01-30T01:03:13.843Z" }, - { url = "https://files.pythonhosted.org/packages/64/0c/41ea22205da480837a700e395507e6a24425151dfb7ead73343d6e2d7ffe/pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f", size = 254204, upload-time = "2026-01-30T01:03:14.886Z" }, - { url = "https://files.pythonhosted.org/packages/e0/d2/afe5c7f8607018beb99971489dbb846508f1b8f351fcefc225fcf4b2adc0/pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1", size = 268423, upload-time = "2026-01-30T01:03:15.936Z" }, - { url = "https://files.pythonhosted.org/packages/68/d4/00ffdbd370410c04e9591da9220a68dc1693ef7499173eb3e30d06e05ed1/pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4", size = 266859, upload-time = "2026-01-30T01:03:17.458Z" }, - { url = "https://files.pythonhosted.org/packages/a7/c9/c3161313b4ca0c601eeefabd3d3b576edaa9afdefd32da97210700e47652/pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78", size = 103520, upload-time = "2026-01-30T01:03:18.652Z" }, - { url = "https://files.pythonhosted.org/packages/8f/a7/b470f672e6fc5fee0a01d9e75005a0e617e162381974213a945fcd274843/pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321", size = 160821, upload-time = "2026-01-30T01:03:19.684Z" }, - { url = "https://files.pythonhosted.org/packages/80/98/e83a36fe8d170c911f864bfded690d2542bfcfacb9c649d11a9e6eb9dc41/pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa", size = 254263, upload-time = "2026-01-30T01:03:20.834Z" }, - { url = "https://files.pythonhosted.org/packages/0f/95/70d7041273890f9f97a24234c00b746e8da86df462620194cef1d411ddeb/pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d", size = 268071, upload-time = "2026-01-30T01:03:21.888Z" }, - { url = "https://files.pythonhosted.org/packages/da/79/76e6d09ae19c99404656d7db9c35dfd20f2086f3eb6ecb496b5b31163bad/pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324", size = 271716, upload-time = "2026-01-30T01:03:23.633Z" }, - { url = "https://files.pythonhosted.org/packages/79/37/482e55fa1602e0a7ff012661d8c946bafdc05e480ea5a32f4f7e336d4aa9/pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9", size = 104539, upload-time = "2026-01-30T01:03:24.788Z" }, - { url = "https://files.pythonhosted.org/packages/30/e8/20e7db907c23f3d63b0be3b8a4fd1927f6da2395f5bcc7f72242bb963dfe/pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb", size = 168474, upload-time = "2026-01-30T01:03:26.428Z" }, - { url = "https://files.pythonhosted.org/packages/d6/81/88a95ee9fafdd8f5f3452107748fd04c24930d500b9aba9738f3ade642cc/pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3", size = 290473, upload-time = "2026-01-30T01:03:27.415Z" }, - { url = "https://files.pythonhosted.org/packages/cf/35/3aa899645e29b6375b4aed9f8d21df219e7c958c4c186b465e42ee0a06bf/pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975", size = 303485, upload-time = "2026-01-30T01:03:28.558Z" }, - { url = "https://files.pythonhosted.org/packages/52/a0/07907b6ff512674d9b201859f7d212298c44933633c946703a20c25e9d81/pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a", size = 306698, upload-time = "2026-01-30T01:03:29.653Z" }, - { url = "https://files.pythonhosted.org/packages/39/2a/cbbf9250020a4a8dd53ba83a46c097b69e5eb49dd14e708f496f548c6612/pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918", size = 116287, upload-time = "2026-01-30T01:03:30.912Z" }, - { url = "https://files.pythonhosted.org/packages/c6/78/397db326746f0a342855b81216ae1f0a32965deccfd7c830a2dbc66d2483/pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de", size = 13729, upload-time = "2026-01-30T01:03:45.029Z" }, -] - [[package]] name = "pywin32-ctypes" version = "0.2.3" @@ -1140,6 +1036,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl", hash = "sha256:9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c", size = 7742, upload-time = "2025-02-22T07:34:52.422Z" }, ] +[[package]] +name = "ruff" +version = "0.15.17" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/a9/3abdf488f1bf3d24c699415e454ed554a6350d5d89ce183be1ee0a3361ac/ruff-0.15.17.tar.gz", hash = "sha256:2ec446937fd16c8c4de2674a209cc5af64d9c6f17d21fbf1151054fa0bcf5219", size = 4743346, upload-time = "2026-06-11T17:54:47.663Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/4d/e11259f5da07cb6afb2d074c31bf09da9671993f7329d4f15d2fdc458301/ruff-0.15.17-py3-none-linux_armv6l.whl", hash = "sha256:d9feddb927fc68bd295f5eebc587a7e42cfaf9b65f60ca4a2386febff575da8f", size = 10856677, upload-time = "2026-06-11T17:54:49.533Z" }, + { url = "https://files.pythonhosted.org/packages/29/3e/772d679e1a0dc058e58875bd2c0cb713a0530877b4a76fee3c7966df0d49/ruff-0.15.17-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:25805a226d741c47d274a35ad5c10a7dde175fcddfa511d7cf3da0a21eb3eab7", size = 11223443, upload-time = "2026-06-11T17:55:00.573Z" }, + { url = "https://files.pythonhosted.org/packages/68/58/bd41f7688b2fd5623012605130ed70e60aa7f2244baa3d5066bdd61530c8/ruff-0.15.17-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f6ad73b14c2d18a3bf8ad7cb6974294d7f613a7898604826058e6ac64918ef4d", size = 10566458, upload-time = "2026-06-11T17:55:07.52Z" }, + { url = "https://files.pythonhosted.org/packages/d8/5b/733371013fcf1ec339e477ece6ab42bfe10bdd9bba8ee88a9516aa56bfc0/ruff-0.15.17-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ba0c1e4f95bcb3869d0d30cbd5917071ef2e28665abfec970cdab0492c713ed", size = 10914483, upload-time = "2026-06-11T17:55:05.501Z" }, + { url = "https://files.pythonhosted.org/packages/bd/cc/6f24251cc0252f7239391ccb85833f320efad14ebe5b443943f37ced6332/ruff-0.15.17-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:81647960f10bff57d2e51cadd0c3950fe598400c852863a038720ef5b8cca91e", size = 10647497, upload-time = "2026-06-11T17:54:57.733Z" }, + { url = "https://files.pythonhosted.org/packages/68/dd/0d10c17ce1a1624d6fc3156309c3f834fdb5dfaad026ec90c85684f3990e/ruff-0.15.17-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e01a84ddbc8c16c23055ba3924476850f1bbc1917cebbb9376665a63e74260d", size = 11416967, upload-time = "2026-06-11T17:54:51.461Z" }, + { url = "https://files.pythonhosted.org/packages/2f/91/556bfb156f6144f355e831c23db00b2fc4120f86b3ce81cc5f7fd2df51f3/ruff-0.15.17-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fe9f653152f8f294f9f7e03bf3a453d8b4a27f7a59c78c8666167f2b17b96c", size = 12335770, upload-time = "2026-06-11T17:54:45.793Z" }, + { url = "https://files.pythonhosted.org/packages/88/82/8b5999aa13355e926f06d9f42a32dcca862f623bf0363785ff89d607dffd/ruff-0.15.17-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c0fe88a7676e7a05b73174d4d4a59cb2ac21ff8263583f87a81a6018475a978", size = 11575441, upload-time = "2026-06-11T17:54:32.661Z" }, + { url = "https://files.pythonhosted.org/packages/11/93/f10377bb04109ca0e8cbc483ff1982c54b6d418210041776f93e8cdc7fa9/ruff-0.15.17-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecfc3c7878fff94633ab0348524e093f9ce3243080416dd7d14f8ba400174719", size = 11557614, upload-time = "2026-06-11T17:54:34.698Z" }, + { url = "https://files.pythonhosted.org/packages/c7/a6/eeeae7f7d5493df41649ab3db92f086b2d0a30199e4efdf8e3dd7a033f24/ruff-0.15.17-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:b8461180b22420b1bdc289909410930761629fddf2a5aaf60fae1ab26cedc4c4", size = 11544450, upload-time = "2026-06-11T17:54:39.042Z" }, + { url = "https://files.pythonhosted.org/packages/32/88/5991ce565129a24dd4a00db1254b3b5db2e53018cbe4018ea5a89738e727/ruff-0.15.17-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6eccbe50a038b503e7140b441aa9c7fc8c1f36edf23ebef9f4165c2f28f568b7", size = 10892524, upload-time = "2026-06-11T17:55:09.432Z" }, + { url = "https://files.pythonhosted.org/packages/f5/1d/0fdd248313425f55223968af04b0a42125466a8d88d21c1d99c6af0a51e8/ruff-0.15.17-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:382fc0521025f5a8ad447d8bdd523545d0d7646adb718eb1c2dac5065ec27c0f", size = 10659573, upload-time = "2026-06-11T17:54:36.824Z" }, + { url = "https://files.pythonhosted.org/packages/9e/0e/072e8260deb9461062ce9311ced27a8e541229a6ffd483013dd37661e43e/ruff-0.15.17-py3-none-musllinux_1_2_i686.whl", hash = "sha256:456d41fcd1b2777ad63f09a6e7121d43f7b688bbc76a800c10f7f8fb1f912c3f", size = 11127818, upload-time = "2026-06-11T17:55:03.124Z" }, + { url = "https://files.pythonhosted.org/packages/ab/b4/55060a34163121498014696b5f656db5b8c6963768f227dbf0d76b311073/ruff-0.15.17-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b1a04bcc94ae6194e9db05d16ad31f298a7194bfbcb08258bbe589cee1d587b8", size = 11655901, upload-time = "2026-06-11T17:54:53.562Z" }, + { url = "https://files.pythonhosted.org/packages/49/71/9b29d6b87cef468d697f43c6a91e3fae4a80185779d7d5a4ef27d173439f/ruff-0.15.17-py3-none-win32.whl", hash = "sha256:596065960ab1ff593f744220c9fe6580eda00a95003cffa9f4048bb5b1bf0392", size = 10925574, upload-time = "2026-06-11T17:54:55.723Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b2/8fc77f3723228836fa5d12497eb71c808f83782e10d058d2b15cfa14640b/ruff-0.15.17-py3-none-win_amd64.whl", hash = "sha256:6769e5fa1710b179b92e0bfa5a51735b35baea9013dadb06d5f44cbcf9547084", size = 12058788, upload-time = "2026-06-11T17:54:41.042Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c7/c53e8dbff9c9dc4b7928773421ae294a5d28fcb8dcda1a089579d3a7e510/ruff-0.15.17-py3-none-win_arm64.whl", hash = "sha256:f3be1fbb34bcdfd146240d8fb92a709d4c2c8191348580a3c044ec60fa0b4456", size = 11355275, upload-time = "2026-06-11T17:54:43.635Z" }, +] + [[package]] name = "secretstorage" version = "3.3.3"