diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ca199873..96163fd6 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 as devcontainer +FROM ubuntu:22.04 # Install prerequisites RUN set -x \ @@ -23,23 +23,22 @@ ENV LANG ja_JP.UTF-8 ENV LC_ALL ja_JP.UTF-8 ENV LC_CTYPE ja_JP.UTF-8 -# ミラーは遅いのが混じっているので好きなリポジトリに変更すべき RUN set -x \ - && sed -i.bak -r 's!(deb|deb-src) \S+!\1 mirror://mirrors.ubuntu.com/mirrors.txt!' /etc/apt/sources.list + && sed -i.bak -r 's!(deb|deb-src) \S+!\1 http://jp.archive.ubuntu.com/ubuntu/!' /etc/apt/sources.list # Install Ubuntu packages RUN set -x \ - # Add repositories # for docker && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - \ && add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \ + # Python3.11をインストールするために、deadsnakes PPAを追加 + && add-apt-repository ppa:deadsnakes/ppa \ # Install packages && apt-get update \ && apt-get install -y --no-install-recommends \ - # docker docker-ce-cli \ # python - python3.10-dev \ + python3.11-dev \ python3-pip \ # common tools bash-completion \ @@ -61,27 +60,17 @@ RUN set -x \ && apt-get -y clean \ && rm -rf /var/lib/apt/lists/* -# docker compose -# 1系はさすがにバージョン古すぎ、docker compose自体オワコンなので推奨しない -# 使用しない場合は、docker / docker-compose hack in devcontainerのところも変更が必要 -# 2系はbash completionスクリプトが存在しないので修正が必要 -ARG COMPOSE_VERSION=1.29.2 -RUN set -x \ - && curl -fsSL "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \ - && chmod +x /usr/local/bin/docker-compose \ - && curl -fsSL -o /etc/bash_completion.d/docker-compose "https://raw.githubusercontent.com/docker/compose/${COMPOSE_VERSION}/contrib/completion/bash/docker-compose" -# docker / docker-compose hack in devcontainer +# docker hack in devcontainer RUN set -x \ && mkdir -p /usr/local/devcontainer-tool/bin \ && curl -fsSL -o /usr/local/devcontainer-tool/bin/docker https://github.com/thamaji/devcontainer-docker/releases/download/v1.0.3/docker \ - && chmod +x /usr/local/devcontainer-tool/bin/docker \ - && curl -fsSL -o /usr/local/devcontainer-tool/bin/docker-compose https://github.com/thamaji/devcontainer-compose/releases/download/v1.0.3/docker-compose \ - && chmod +x /usr/local/devcontainer-tool/bin/docker-compose + && chmod +x /usr/local/devcontainer-tool/bin/docker ENV PATH=/usr/local/devcontainer-tool/bin:${PATH} + # Python / pip -RUN ln -s $(which python3.10) /usr/bin/python +RUN ln -s $(which python3.11) /usr/bin/python ENV PYTHONDONTWRITEBYTECODE=1 \ PIP_DEFAULT_TIMEOUT=100 \ PIP_NO_CACHE_DIR=on \ @@ -102,17 +91,8 @@ RUN useradd -m -s /bin/bash -u 5000 -U vscode \ && groupadd --gid 999 docker \ && usermod -aG docker vscode -ADD entrypoint.sh /entrypoint.sh - USER vscode RUN poetry config virtualenvs.in-project true -# vscode extensions cache -# https://code.visualstudio.com/docs/remote/containers-advanced#_avoiding-extension-reinstalls-on-container-rebuild -RUN set -x \ - && mkdir -p /home/vscode/.vscode-server/extensions /home/vscode/.vscode-server-insiders \ - && ln -s /home/vscode/.vscode-server/extensions /home/vscode/.vscode-server-insiders/extensions - - -ENTRYPOINT [ "bash", "/entrypoint.sh" ] \ No newline at end of file +ENTRYPOINT [ "bash", "/entrypoint.sh" ] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 01b1d82b..1262374a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,18 +6,15 @@ "dockerfile": "Dockerfile", "context": ".", "args": {}, - "target": "devcontainer" }, "containerUser": "vscode", "remoteUser": "vscode", "updateRemoteUserUID": true, - "overrideCommand": false, - // 事前にマウントするディレクトリを作成する + // マウント対象のディレクトリを事前に作成する "initializeCommand": "mkdir -p ${localWorkspaceFolder}/.devcontainer/venv", "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", - "source=${localWorkspaceFolder}/.devcontainer/.extensions,target=/home/vscode/.vscode-server/extensions,type=bind", - //ホスト側のvenvとコンテナ側のvenvを分離して、ホスト側でもpoetryコマンドを実行できるようにする + // ホスト側のvenvとコンテナ側のvenvを分類して、ホスト側でpoetryコマンドを利用できるようにする "source=${localWorkspaceFolder}/.devcontainer/venv,target=${containerWorkspaceFolder}/.venv,type=bind" ], "forwardPorts": [], @@ -31,17 +28,20 @@ "CONTAINER_WORKSPACE": "${containerWorkspaceFolder}", "LOCAL_WORKSPACE": "${localWorkspaceFolder}" }, + "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces,type=bind,consistency=cached", + "workspaceFolder": "/workspaces", "postStartCommand": "poetry install --all-extras", - "customizations":{ - "vscode":{ + "customizations": { + "vscode": { "extensions": [ "mosapride.zenkaku", "ms-python.python", "ms-python.vscode-pylance", + "charliermarsh.ruff", "streetsidesoftware.code-spell-checker", "bungcip.better-toml", "njpwerner.autodocstring", - "dawhite.mustache", + "mechatroner.rainbow-csv", "lextudio.restructuredtext" ] } diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 24609efc..00000000 --- a/.flake8 +++ /dev/null @@ -1,11 +0,0 @@ -[flake8] -max-line-length = 120 - -# formatter 'black'と競合するため、チェックを無視する -# https://black.readthedocs.io/en/stable/the_black_code_style.html#line-length -extend-ignore = E203, W503 - -exclude = test_*.py - -# Python3.12環境だとなぜか警告が出るので、一時的に無視する。将来的にflake8は捨ててruffに移行する予定なので、この設定はそのままにしておく。 -ignore = W604, E231 diff --git a/.travis.yml b/.travis.yml index e24ee912..52565088 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,10 @@ jobs: - python: 3.8 - python: 3.9 - python: 3.10 + - python: 3.11 script: # 開発環境と同じPythonバージョンのみlintを実行する - make lint - - python: 3.11 - python: 3.12 diff --git a/Makefile b/Makefile index 22f805bc..2c4f409a 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,29 @@ +ifndef SOURCE_FILES + export SOURCE_FILES:=annofabapi +endif +ifndef TEST_FILES + export TEST_FILES:=tests +endif + .PHONY: docs lint test format test publish format: - poetry run autoflake --in-place --remove-all-unused-imports --ignore-init-module-imports --recursive annofabapi tests - poetry run isort annofabapi tests - poetry run black annofabapi tests + poetry run ruff format ${SOURCE_FILES} ${TEST_FILES} + poetry run ruff check ${SOURCE_FILES} ${TEST_FILES} --fix-only --exit-zero lint: - poetry run mypy annofabapi tests - poetry run flake8 annofabapi tests - poetry run pylint --jobs=0 annofabapi + poetry run ruff check ${SOURCE_FILES} + # テストコードはチェックを緩和する + # pygrep-hooks, flake8-datetimez, line-too-long, flake8-annotations, unused-noqa + poetry run ruff check ${TEST_FILES} --ignore PGH,DTZ,E501,ANN,RUF100,G004 + poetry run mypy ${SOURCE_FILES} ${TEST_FILES} + # テストコードはチェックを緩和するためpylintは実行しない + poetry run pylint --jobs=0 ${SOURCE_FILES} + test: # 並列で実行するとエラーになるので、シーケンシャルで実行する - poetry run pytest --cov=annofabapi --cov-report=html tests + poetry run pytest --cov=${SOURCE_FILES} --cov-report=html ${TEST_FILES} publish: poetry publish --build diff --git a/annofabapi/_utils.py b/annofabapi/_utils.py index 47d7d1c1..b80548c1 100644 --- a/annofabapi/_utils.py +++ b/annofabapi/_utils.py @@ -4,9 +4,7 @@ from typing import Optional -def _issue_deprecated_warning_with_class( - cls, stacklevel: int, deprecated_date: str, new_class_name: Optional[str] = None -): +def _issue_deprecated_warning_with_class(cls, stacklevel: int, deprecated_date: str, new_class_name: Optional[str] = None): # noqa: ANN001 """非推奨なクラスに対する警告メッセージを出力する。""" old_class_name = f"{cls.__module__}.{cls.__name__}" message = f"deprecated: '{old_class_name}'は{deprecated_date}以降に廃止します。" @@ -15,36 +13,32 @@ def _issue_deprecated_warning_with_class( warnings.warn(message, FutureWarning, stacklevel=stacklevel) -def _process_class(cls, deprecated_date: str, new_class_name: Optional[str] = None): - def decorator(function): +def _process_class(cls, deprecated_date: str, new_class_name: Optional[str] = None): # noqa: ANN001 + def decorator(function): # noqa: ANN001 @wraps(function) def wrapped(*args, **kwargs): - _issue_deprecated_warning_with_class( - cls, stacklevel=3, deprecated_date=deprecated_date, new_class_name=new_class_name - ) + _issue_deprecated_warning_with_class(cls, stacklevel=3, deprecated_date=deprecated_date, new_class_name=new_class_name) return function(*args, **kwargs) return wrapped - cls.__init__ = decorator(cls.__init__) # type: ignore + cls.__init__ = decorator(cls.__init__) return cls -def _process_enum_class(cls, deprecated_date: str, new_class_name: Optional[str] = None): - def getattribute(self, name): - _issue_deprecated_warning_with_class( - cls, stacklevel=4, deprecated_date=deprecated_date, new_class_name=new_class_name - ) +def _process_enum_class(cls, deprecated_date: str, new_class_name: Optional[str] = None): # noqa: ANN001 + def getattribute(self, name): # noqa: ANN001 + _issue_deprecated_warning_with_class(cls, stacklevel=4, deprecated_date=deprecated_date, new_class_name=new_class_name) return super(type(self), self).__getattribute__(name) cls.__getattribute__ = getattribute return cls -def deprecated_class(_cls=None, *, deprecated_date: str, new_class_name: Optional[str] = None): +def deprecated_class(_cls=None, *, deprecated_date: str, new_class_name: Optional[str] = None): # noqa: ANN001 """クラスを非推奨にします。""" - def wrap(cls): + def wrap(cls): # noqa: ANN001 if issubclass(cls, enum.Enum): return _process_enum_class(cls, deprecated_date=deprecated_date, new_class_name=new_class_name) else: diff --git a/annofabapi/api.py b/annofabapi/api.py index ae5fef97..77588c1c 100644 --- a/annofabapi/api.py +++ b/annofabapi/api.py @@ -55,7 +55,7 @@ def _log_error_response(arg_logger: logging.Logger, response: requests.Response) """ - def mask_key(d, key: str): + def mask_key(d, key: str): # noqa: ANN001 if key in d: d[key] = "***" @@ -96,7 +96,7 @@ def mask_key(d, key: str): ) -def _create_request_body_for_logger(data: Any) -> Any: +def _create_request_body_for_logger(data: Any) -> Any: # noqa: ANN401 """ ログに出力するためのreqest_bodyを生成する。 * パスワードやトークンなどの機密情報をマスクする @@ -110,7 +110,7 @@ def _create_request_body_for_logger(data: Any) -> Any: ログ出力用のrequest_body """ - def mask_key(d, key: str): + def mask_key(d, key: str): # noqa: ANN001 if key in d: d[key] = "***" @@ -145,7 +145,7 @@ def _create_query_params_for_logger(params: Dict[str, Any]) -> Dict[str, Any]: ログ出力用のparams """ - def mask_key(d, key: str): + def mask_key(d, key: str): # noqa: ANN001 if key in d: d[key] = "***" @@ -174,14 +174,14 @@ def _should_retry_with_status(status_code: int) -> bool: return False -def my_backoff(function): +def my_backoff(function): # noqa: ANN001 """ HTTP Status Codeが429 or 5XXのときはリトライする. 最大5分間リトライする。 """ @wraps(function) def wrapped(*args, **kwargs): - def fatal_code(e): + def fatal_code(e): # noqa: ANN001 """ リトライするかどうか status codeが5xxのとき、またはToo many Requests(429)のときはリトライする。429以外の4XXはリトライしない @@ -230,7 +230,7 @@ class AnnofabApi(AbstractAnnofabApi): cookies: Signed Cookie情報 """ - def __init__(self, login_user_id: str, login_password: str, endpoint_url: str = DEFAULT_ENDPOINT_URL): + def __init__(self, login_user_id: str, login_password: str, endpoint_url: str = DEFAULT_ENDPOINT_URL) -> None: if not login_user_id or not login_password: raise ValueError("login_user_id or login_password is empty.") @@ -254,10 +254,10 @@ class _MyToken(AuthBase): http://docs.python-requests.org/en/master/user/advanced/#custom-authentication """ - def __init__(self, id_token: str): + def __init__(self, id_token: str) -> None: self.id_token = id_token - def __call__(self, req): + def __call__(self, req): # noqa: ANN001, ANN204 req.headers["Authorization"] = self.id_token return req @@ -288,7 +288,7 @@ def _create_kwargs( self, params: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, Any]] = None, - request_body: Optional[Any] = None, + request_body: Optional[Any] = None, # noqa: ANN401 ) -> Dict[str, Any]: """ requestsモジュールのget,...メソッドに渡すkwargsを生成する。 @@ -329,7 +329,7 @@ def _create_kwargs( return kwargs @staticmethod - def _response_to_content(response: requests.Response) -> Any: + def _response_to_content(response: requests.Response) -> Any: # noqa: ANN401 """ Responseのcontentを、Content-Typeに対応した型に変換する。 @@ -364,8 +364,8 @@ def _execute_http_request( url: str, *, params: Optional[Dict[str, Any]] = None, - data: Optional[Any] = None, - json: Optional[Any] = None, # pylint: disable=redefined-outer-name + data: Optional[Any] = None, # noqa: ANN401 + json: Optional[Any] = None, # pylint: disable=redefined-outer-name # noqa: ANN401 headers: Optional[Dict[str, Any]] = None, raise_for_status: bool = True, **kwargs, @@ -384,9 +384,7 @@ def _execute_http_request( requests.exceptions.HTTPError: http status codeが4XXX,5XXXのとき """ - response = self.session.request( - method=http_method, url=url, params=params, data=data, headers=headers, json=json, **kwargs - ) + response = self.session.request(method=http_method, url=url, params=params, data=data, headers=headers, json=json, **kwargs) # response.requestよりメソッド引数のrequest情報の方が分かりやすいので、メソッド引数のrequest情報を出力する。 logger.debug( @@ -410,11 +408,7 @@ def _execute_http_request( # リクエスト過多の場合、待ってから再度アクセスする if response.status_code == requests.codes.too_many_requests: retry_after_value = response.headers.get("Retry-After") - waiting_time_seconds = ( - float(retry_after_value) - if retry_after_value is not None - else DEFAULT_WAITING_TIME_SECONDS_WITH_429_STATUS_CODE - ) + waiting_time_seconds = float(retry_after_value) if retry_after_value is not None else DEFAULT_WAITING_TIME_SECONDS_WITH_429_STATUS_CODE logger.warning( "HTTPステータスコードが'%s'なので、%s秒待ってからリトライします。 :: %s", @@ -461,7 +455,7 @@ def _request_wrapper( *, query_params: Optional[Dict[str, Any]] = None, header_params: Optional[Dict[str, Any]] = None, - request_body: Optional[Any] = None, + request_body: Optional[Any] = None, # noqa: ANN401 raise_for_status: bool = True, ) -> Tuple[Any, requests.Response]: """ @@ -523,11 +517,7 @@ def _request_wrapper( ) elif response.status_code == requests.codes.too_many_requests: retry_after_value = response.headers.get("Retry-After") - waiting_time_seconds = ( - float(retry_after_value) - if retry_after_value is not None - else DEFAULT_WAITING_TIME_SECONDS_WITH_429_STATUS_CODE - ) + waiting_time_seconds = float(retry_after_value) if retry_after_value is not None else DEFAULT_WAITING_TIME_SECONDS_WITH_429_STATUS_CODE logger.warning( "HTTPステータスコードが'%s'なので、%s秒待ってからリトライします。 :: %s", @@ -567,9 +557,7 @@ def _request_wrapper( return content, response - def _get_signed_cookie( - self, project_id, query_params: Optional[Dict[str, Any]] = None - ) -> Tuple[Dict[str, Any], requests.Response]: + def _get_signed_cookie(self, project_id, query_params: Optional[Dict[str, Any]] = None) -> Tuple[Dict[str, Any], requests.Response]: # noqa: ANN001 """ アノテーション仕様の履歴情報を取得するために、非公開APIにアクセスする。 変更される可能性あり. diff --git a/annofabapi/api2.py b/annofabapi/api2.py index 27eb89b1..44b94cf4 100644 --- a/annofabapi/api2.py +++ b/annofabapi/api2.py @@ -31,7 +31,7 @@ class AnnofabApi2(AbstractAnnofabApi2): """ - def __init__(self, api: AnnofabApi): + def __init__(self, api: AnnofabApi) -> None: self.api = api self.url_prefix = f"{api.endpoint_url}/api/v2" @@ -50,7 +50,7 @@ def _request_wrapper( *, query_params: Optional[Dict[str, Any]] = None, header_params: Optional[Dict[str, Any]] = None, - request_body: Optional[Any] = None, + request_body: Optional[Any] = None, # noqa: ANN401 raise_for_status: bool = True, ) -> Tuple[Any, requests.Response]: """ @@ -102,9 +102,7 @@ def _request_wrapper( "url": url, "query_params": query_params, "header_params": header_params, - "request_body": _create_request_body_for_logger(request_body) - if request_body is not None - else None, + "request_body": _create_request_body_for_logger(request_body) if request_body is not None else None, }, "response": { "status_code": response.status_code, @@ -128,9 +126,7 @@ def _request_wrapper( elif response.status_code == requests.codes.too_many_requests: retry_after_value = response.headers.get("Retry-After") waiting_time_seconds = ( - float(retry_after_value) - if retry_after_value is not None - else DEFAULT_WAITING_TIME_SECONDS_WITH_429_STATUS_CODE + float(retry_after_value) if retry_after_value is not None else DEFAULT_WAITING_TIME_SECONDS_WITH_429_STATUS_CODE ) logger.warning( diff --git a/annofabapi/dataclass/annotation.py b/annofabapi/dataclass/annotation.py index 6fc00429..ee6dd5fb 100644 --- a/annofabapi/dataclass/annotation.py +++ b/annofabapi/dataclass/annotation.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,12 +9,12 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, List, Optional, Union # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin +# ruff: noqa: E501 from annofabapi.models import ( AdditionalDataDefinitionType, AnnotationDataHoldingType, diff --git a/annofabapi/dataclass/annotation_specs.py b/annofabapi/dataclass/annotation_specs.py index 497815dd..96803e74 100644 --- a/annofabapi/dataclass/annotation_specs.py +++ b/annofabapi/dataclass/annotation_specs.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, List, Optional, Union # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/comment.py b/annofabapi/dataclass/comment.py index d016cd48..75fe0127 100644 --- a/annofabapi/dataclass/comment.py +++ b/annofabapi/dataclass/comment.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, List, Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/input.py b/annofabapi/dataclass/input.py index 676d0e13..a4f0732e 100644 --- a/annofabapi/dataclass/input.py +++ b/annofabapi/dataclass/input.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/job.py b/annofabapi/dataclass/job.py index bbbb1624..7028b542 100644 --- a/annofabapi/dataclass/job.py +++ b/annofabapi/dataclass/job.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/organization.py b/annofabapi/dataclass/organization.py index 950cc4d3..2db600a8 100644 --- a/annofabapi/dataclass/organization.py +++ b/annofabapi/dataclass/organization.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/organization_member.py b/annofabapi/dataclass/organization_member.py index 7743a65f..35b245ea 100644 --- a/annofabapi/dataclass/organization_member.py +++ b/annofabapi/dataclass/organization_member.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/project.py b/annofabapi/dataclass/project.py index 513c17c6..4f755e12 100644 --- a/annofabapi/dataclass/project.py +++ b/annofabapi/dataclass/project.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,19 +9,12 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import List, Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin -from annofabapi.models import ( - AssigneeRuleOfResubmittedTask, - InputDataType, - ProjectStatus, - TaskAssignmentProperty, - TaskAssignmentType, -) +from annofabapi.models import AssigneeRuleOfResubmittedTask, InputDataType, ProjectStatus, TaskAssignmentProperty, TaskAssignmentType @dataclass diff --git a/annofabapi/dataclass/project_member.py b/annofabapi/dataclass/project_member.py index 4f0e47ea..184ed8f1 100644 --- a/annofabapi/dataclass/project_member.py +++ b/annofabapi/dataclass/project_member.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/supplementary.py b/annofabapi/dataclass/supplementary.py index 287ce190..b0f65651 100644 --- a/annofabapi/dataclass/supplementary.py +++ b/annofabapi/dataclass/supplementary.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/dataclass/task.py b/annofabapi/dataclass/task.py index ed896080..9dc586c9 100644 --- a/annofabapi/dataclass/task.py +++ b/annofabapi/dataclass/task.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,9 +9,8 @@ oneOf, allOfなどは正しく表現できない可能性がある。 """ -import warnings # pylint: disable=unused-import from dataclasses import dataclass -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, List, Optional # pylint: disable=unused-import from dataclasses_json import DataClassJsonMixin diff --git a/annofabapi/exceptions.py b/annofabapi/exceptions.py index d75e23fd..b5a275fa 100644 --- a/annofabapi/exceptions.py +++ b/annofabapi/exceptions.py @@ -29,11 +29,11 @@ class AnnotationOuterFileNotFoundError(AnnofabApiException): """ - def __init__(self, outer_file_path: str, zipfile_path: Optional[str] = None): + def __init__(self, outer_file_path: str, zipfile_path: Optional[str] = None) -> None: if zipfile_path is None: message = f"No such file or directory: '{outer_file_path}'" else: - message = f"There is no item named '{str(outer_file_path)}' in the archive '{zipfile_path}'" + message = f"There is no item named '{outer_file_path!s}' in the archive '{zipfile_path}'" super().__init__(message) @@ -48,7 +48,7 @@ class NotLoggedInError(AnnofabApiException): """ - def __init__(self, message: Optional[str] = None): + def __init__(self, message: Optional[str] = None) -> None: if message is None: message = "You are not logged in." super().__init__(message) @@ -67,7 +67,7 @@ class CheckSumError(AnnofabApiException): response_etag: アップロードしたときのレスポンスヘッダ'ETag'の値 """ - def __init__(self, message: str, uploaded_data_hash: str, response_etag: str): + def __init__(self, message: str, uploaded_data_hash: str, response_etag: str) -> None: self.uploaded_data_hash = uploaded_data_hash self.response_etag = response_etag @@ -79,6 +79,6 @@ class MfaEnabledUserExecutionError(Exception): MFAが有効化されたユーザーが実行したことを示すエラー """ - def __init__(self, user_id: str): + def __init__(self, user_id: str) -> None: message = f"User (User ID: {user_id}) cannot use annofab-api-python-client because MFA is enabled." super().__init__(message) diff --git a/annofabapi/generated_api.py b/annofabapi/generated_api.py index 44bdc974..6a418438 100644 --- a/annofabapi/generated_api.py +++ b/annofabapi/generated_api.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501, ANN401 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -10,12 +10,10 @@ import abc import warnings # pylint: disable=unused-import -from typing import Any, Dict, List, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, Optional, Tuple # pylint: disable=unused-import import requests -import annofabapi # pylint: disable=unused-import - class AbstractAnnofabApi(abc.ABC): """ @@ -39,11 +37,7 @@ def _request_wrapper( ######################################### def batch_update_annotations( - self, - project_id: str, - query_params: Optional[Dict[str, Any]] = None, - request_body: Optional[Any] = None, - **kwargs, + self, project_id: str, query_params: Optional[Dict[str, Any]] = None, request_body: Optional[Any] = None, **kwargs ) -> Tuple[Any, requests.Response]: """アノテーション一括更新 https://annofab.com/docs/api/#operation/batchUpdateAnnotations @@ -75,9 +69,7 @@ def batch_update_annotations( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_annotation( - self, project_id: str, task_id: str, input_data_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_annotation(self, project_id: str, task_id: str, input_data_id: str, **kwargs) -> Tuple[Any, requests.Response]: """Simpleアノテーションの取得 https://annofab.com/docs/api/#operation/getAnnotation @@ -127,9 +119,7 @@ def get_annotation_archive(self, project_id: str, **kwargs) -> Tuple[Any, reques keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_annotation_list( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_annotation_list(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """アノテーション一括取得 https://annofab.com/docs/api/#operation/getAnnotationList @@ -182,11 +172,7 @@ def get_archive_full_with_pro_id(self, project_id: str, **kwargs) -> Tuple[Any, """ - warnings.warn( - "annofabapi.AnnofabApi.get_archive_full_with_pro_id() is deprecated and will be removed.", - FutureWarning, - stacklevel=2, - ) + warnings.warn("annofabapi.AnnofabApi.get_archive_full_with_pro_id() is deprecated and will be removed.", FutureWarning, stacklevel=2) url_path = f"/projects/{project_id}/archive/full" http_method = "GET" keyword_params: Dict[str, Any] = {} @@ -296,9 +282,7 @@ def put_annotation( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def get_annotation_specs( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_annotation_specs(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """アノテーション仕様取得 https://annofab.com/docs/api/#operation/getAnnotationSpecs @@ -352,11 +336,7 @@ def get_annotation_specs_histories(self, project_id: str, **kwargs) -> Tuple[Any return self._request_wrapper(http_method, url_path, **keyword_params) def put_annotation_specs( - self, - project_id: str, - query_params: Optional[Dict[str, Any]] = None, - request_body: Optional[Any] = None, - **kwargs, + self, project_id: str, query_params: Optional[Dict[str, Any]] = None, request_body: Optional[Any] = None, **kwargs ) -> Tuple[Any, requests.Response]: """アノテーション仕様更新 https://annofab.com/docs/api/#operation/putAnnotationSpecs @@ -471,9 +451,7 @@ def get_comments( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def batch_update_inputs( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def batch_update_inputs(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """入力データの一括更新 https://annofab.com/docs/api/#operation/batchUpdateInputs @@ -575,9 +553,7 @@ def get_input_data(self, project_id: str, input_data_id: str, **kwargs) -> Tuple keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_input_data_list( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_input_data_list(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """入力データの一括取得 https://annofab.com/docs/api/#operation/getInputDataList @@ -612,9 +588,7 @@ def get_input_data_list( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_input_data( - self, project_id: str, input_data_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_input_data(self, project_id: str, input_data_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """入力データの作成/更新 https://annofab.com/docs/api/#operation/putInputData @@ -673,11 +647,7 @@ def batch_update_inspections( """ - warnings.warn( - "annofabapi.AnnofabApi.batch_update_inspections() is deprecated and will be removed.", - FutureWarning, - stacklevel=2, - ) + warnings.warn("annofabapi.AnnofabApi.batch_update_inspections() is deprecated and will be removed.", FutureWarning, stacklevel=2) url_path = f"/projects/{project_id}/tasks/{task_id}/inputs/{input_data_id}/inspections" http_method = "POST" keyword_params: Dict[str, Any] = { @@ -686,9 +656,7 @@ def batch_update_inspections( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_inspections( - self, project_id: str, task_id: str, input_data_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_inspections(self, project_id: str, task_id: str, input_data_id: str, **kwargs) -> Tuple[Any, requests.Response]: """検査コメント一括取得 https://annofab.com/docs/api/#operation/getInspections @@ -709,9 +677,7 @@ def get_inspections( """ - warnings.warn( - "annofabapi.AnnofabApi.get_inspections() is deprecated and will be removed.", FutureWarning, stacklevel=2 - ) + warnings.warn("annofabapi.AnnofabApi.get_inspections() is deprecated and will be removed.", FutureWarning, stacklevel=2) url_path = f"/projects/{project_id}/tasks/{task_id}/inputs/{input_data_id}/inspections" http_method = "GET" keyword_params: Dict[str, Any] = {} @@ -748,9 +714,7 @@ def delete_instruction_image(self, project_id: str, image_id: str, **kwargs) -> keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_instruction( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_instruction(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """作業ガイドの取得 https://annofab.com/docs/api/#operation/getInstruction @@ -778,9 +742,7 @@ def get_instruction( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_instruction_history( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_instruction_history(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """作業ガイドの編集履歴の取得 https://annofab.com/docs/api/#operation/getInstructionHistory @@ -808,9 +770,7 @@ def get_instruction_history( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_instruction_image_url_for_put( - self, project_id: str, image_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_instruction_image_url_for_put(self, project_id: str, image_id: str, **kwargs) -> Tuple[Any, requests.Response]: """作業ガイドの画像登録・更新用URL取得 https://annofab.com/docs/api/#operation/getInstructionImageUrlForPut @@ -859,9 +819,7 @@ def get_instruction_images(self, project_id: str, **kwargs) -> Tuple[Any, reques keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_instruction( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_instruction(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """作業ガイドの更新 https://annofab.com/docs/api/#operation/putInstruction @@ -894,9 +852,7 @@ def put_instruction( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def delete_project_job( - self, project_id: str, job_type: str, job_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def delete_project_job(self, project_id: str, job_type: str, job_id: str, **kwargs) -> Tuple[Any, requests.Response]: """プロジェクトのバックグラウンドジョブ情報削除 https://annofab.com/docs/api/#operation/deleteProjectJob @@ -922,9 +878,7 @@ def delete_project_job( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_organization_job( - self, organization_name: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_organization_job(self, organization_name: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """組織のバックグラウンドジョブ情報取得 https://annofab.com/docs/api/#operation/getOrganizationJob @@ -954,9 +908,7 @@ def get_organization_job( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_project_job( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_project_job(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """プロジェクトのバックグラウンドジョブ情報取得 https://annofab.com/docs/api/#operation/getProjectJob @@ -1008,7 +960,7 @@ def get_my_account(self, **kwargs) -> Tuple[Any, requests.Response]: """ - url_path = f"/my/account" + url_path = "/my/account" http_method = "GET" keyword_params: Dict[str, Any] = {} keyword_params.update(**kwargs) @@ -1062,9 +1014,7 @@ def get_my_notification_message(self, message_id: str, **kwargs) -> Tuple[Any, r keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_my_notification_messages( - self, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_my_notification_messages(self, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """自分に届いている通知メッセージの一括取得 https://annofab.com/docs/api/#operation/getMyNotificationMessages @@ -1084,7 +1034,7 @@ def get_my_notification_messages( """ - url_path = f"/my/messages" + url_path = "/my/messages" http_method = "GET" keyword_params: Dict[str, Any] = { "query_params": query_params, @@ -1109,7 +1059,7 @@ def get_my_notification_unread_messages_count(self, **kwargs) -> Tuple[Any, requ """ - url_path = f"/my/unread-messages-count" + url_path = "/my/unread-messages-count" http_method = "GET" keyword_params: Dict[str, Any] = {} keyword_params.update(**kwargs) @@ -1132,7 +1082,7 @@ def get_my_organizations(self, **kwargs) -> Tuple[Any, requests.Response]: """ - url_path = f"/my/organizations" + url_path = "/my/organizations" http_method = "GET" keyword_params: Dict[str, Any] = {} keyword_params.update(**kwargs) @@ -1155,7 +1105,7 @@ def get_my_project_members(self, **kwargs) -> Tuple[Any, requests.Response]: """ - url_path = f"/my/project-members" + url_path = "/my/project-members" http_method = "GET" keyword_params: Dict[str, Any] = {} keyword_params.update(**kwargs) @@ -1186,7 +1136,7 @@ def get_my_projects(self, query_params: Optional[Dict[str, Any]] = None, **kwarg """ - url_path = f"/my/projects" + url_path = "/my/projects" http_method = "GET" keyword_params: Dict[str, Any] = { "query_params": query_params, @@ -1213,7 +1163,7 @@ def put_my_account(self, request_body: Optional[Any] = None, **kwargs) -> Tuple[ """ - url_path = f"/my/account" + url_path = "/my/account" http_method = "PUT" keyword_params: Dict[str, Any] = { "request_body": request_body, @@ -1221,9 +1171,7 @@ def put_my_account(self, request_body: Optional[Any] = None, **kwargs) -> Tuple[ keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_my_notification_message_opened( - self, message_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_my_notification_message_opened(self, message_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """通知メッセージのステータス更新 https://annofab.com/docs/api/#operation/putMyNotificationMessageOpened @@ -1275,7 +1223,7 @@ def create_new_organization(self, request_body: Optional[Any] = None, **kwargs) """ - url_path = f"/organizations" + url_path = "/organizations" http_method = "POST" keyword_params: Dict[str, Any] = { "request_body": request_body, @@ -1393,9 +1341,7 @@ def get_projects_of_organization( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_organization( - self, organization_name: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_organization(self, organization_name: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """組織の更新 https://annofab.com/docs/api/#operation/putOrganization @@ -1456,9 +1402,7 @@ def delete_organization_input_data( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_input_data_set( - self, organization_name: str, input_data_set_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_input_data_set(self, organization_name: str, input_data_set_id: str, **kwargs) -> Tuple[Any, requests.Response]: """入力データセット情報取得 https://annofab.com/docs/api/#operation/getInputDataSet @@ -1640,9 +1584,7 @@ def accept_organization_invitation( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def delete_organization_member( - self, organization_name: str, user_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def delete_organization_member(self, organization_name: str, user_id: str, **kwargs) -> Tuple[Any, requests.Response]: """組織メンバーの削除 https://annofab.com/docs/api/#operation/deleteOrganizationMember @@ -1783,9 +1725,7 @@ def update_organization_member_role( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def delete_organization_plugin( - self, organization_name: str, plugin_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def delete_organization_plugin(self, organization_name: str, plugin_id: str, **kwargs) -> Tuple[Any, requests.Response]: """プラグインの削除 https://annofab.com/docs/api/#operation/deleteOrganizationPlugin @@ -1810,9 +1750,7 @@ def delete_organization_plugin( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_organization_plugin( - self, organization_name: str, plugin_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_organization_plugin(self, organization_name: str, plugin_id: str, **kwargs) -> Tuple[Any, requests.Response]: """プラグインの取得 https://annofab.com/docs/api/#operation/getOrganizationPlugin @@ -2036,11 +1974,7 @@ def get_project_inspections_url(self, project_id: str, **kwargs) -> Tuple[Any, r """ - warnings.warn( - "annofabapi.AnnofabApi.get_project_inspections_url() is deprecated and will be removed.", - FutureWarning, - stacklevel=2, - ) + warnings.warn("annofabapi.AnnofabApi.get_project_inspections_url() is deprecated and will be removed.", FutureWarning, stacklevel=2) url_path = f"/projects/{project_id}/rawdata/inspections" http_method = "GET" keyword_params: Dict[str, Any] = {} @@ -2090,11 +2024,7 @@ def get_project_task_history_events_url(self, project_id: str, **kwargs) -> Tupl """ - warnings.warn( - "annofabapi.AnnofabApi.get_project_task_history_events_url() is deprecated and will be removed.", - FutureWarning, - stacklevel=2, - ) + warnings.warn("annofabapi.AnnofabApi.get_project_task_history_events_url() is deprecated and will be removed.", FutureWarning, stacklevel=2) url_path = f"/projects/{project_id}/rawdata/task_history_events" http_method = "GET" keyword_params: Dict[str, Any] = {} @@ -2125,9 +2055,7 @@ def get_project_tasks_url(self, project_id: str, **kwargs) -> Tuple[Any, request keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def initiate_project_copy( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def initiate_project_copy(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """プロジェクトのコピー https://annofab.com/docs/api/#operation/initiateProjectCopy @@ -2204,11 +2132,7 @@ def post_project_tasks_update(self, project_id: str, **kwargs) -> Tuple[Any, req return self._request_wrapper(http_method, url_path, **keyword_params) def put_project( - self, - project_id: str, - query_params: Optional[Dict[str, Any]] = None, - request_body: Optional[Any] = None, - **kwargs, + self, project_id: str, query_params: Optional[Dict[str, Any]] = None, request_body: Optional[Any] = None, **kwargs ) -> Tuple[Any, requests.Response]: """プロジェクト作成/更新 https://annofab.com/docs/api/#operation/putProject @@ -2270,9 +2194,7 @@ def get_project_member(self, project_id: str, user_id: str, **kwargs) -> Tuple[A keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_project_members( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_project_members(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """プロジェクトメンバー一括取得 https://annofab.com/docs/api/#operation/getProjectMembers @@ -2300,9 +2222,7 @@ def get_project_members( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_project_member( - self, project_id: str, user_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_project_member(self, project_id: str, user_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """プロジェクトメンバー追加/更新 https://annofab.com/docs/api/#operation/putProjectMember @@ -2336,9 +2256,7 @@ def put_project_member( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def get_account_daily_statistics( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_account_daily_statistics(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """メンバー別作業時間の取得 https://annofab.com/docs/api/#operation/getAccountDailyStatistics @@ -2446,9 +2364,7 @@ def get_markers(self, project_id: str, **kwargs) -> Tuple[Any, requests.Response keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_phase_daily_statistics( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_phase_daily_statistics(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """フェーズ別作業時間の取得 https://annofab.com/docs/api/#operation/getPhaseDailyStatistics @@ -2501,9 +2417,7 @@ def get_statistics_available_dates(self, project_id: str, **kwargs) -> Tuple[Any keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_task_daily_statistics( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_task_daily_statistics(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """フェーズ別タスク数の取得 https://annofab.com/docs/api/#operation/getTaskDailyStatistics @@ -2595,9 +2509,7 @@ def get_worktime_daily_statistics_by_account( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_markers( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_markers(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """統計グラフマーカー更新 https://annofab.com/docs/api/#operation/putMarkers @@ -2630,9 +2542,7 @@ def put_markers( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def delete_supplementary_data( - self, project_id: str, input_data_id: str, supplementary_data_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def delete_supplementary_data(self, project_id: str, input_data_id: str, supplementary_data_id: str, **kwargs) -> Tuple[Any, requests.Response]: """補助情報削除 https://annofab.com/docs/api/#operation/deleteSupplementaryData @@ -2658,9 +2568,7 @@ def delete_supplementary_data( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_supplementary_data_list( - self, project_id: str, input_data_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_supplementary_data_list(self, project_id: str, input_data_id: str, **kwargs) -> Tuple[Any, requests.Response]: """補助情報一括取得 https://annofab.com/docs/api/#operation/getSupplementaryDataList @@ -2686,12 +2594,7 @@ def get_supplementary_data_list( return self._request_wrapper(http_method, url_path, **keyword_params) def put_supplementary_data( - self, - project_id: str, - input_data_id: str, - supplementary_data_id: str, - request_body: Optional[Any] = None, - **kwargs, + self, project_id: str, input_data_id: str, supplementary_data_id: str, request_body: Optional[Any] = None, **kwargs ) -> Tuple[Any, requests.Response]: """補助情報作成/更新 https://annofab.com/docs/api/#operation/putSupplementaryData @@ -2727,9 +2630,7 @@ def put_supplementary_data( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def assign_tasks( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def assign_tasks(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスク割当 https://annofab.com/docs/api/#operation/assignTasks @@ -2757,9 +2658,7 @@ def assign_tasks( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def batch_update_tasks( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def batch_update_tasks(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスク一括更新 https://annofab.com/docs/api/#operation/batchUpdateTasks @@ -2862,9 +2761,7 @@ def get_task_histories(self, project_id: str, task_id: str, **kwargs) -> Tuple[A keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_tasks( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_tasks(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスクの一括取得 https://annofab.com/docs/api/#operation/getTasks @@ -2908,9 +2805,7 @@ def get_tasks( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def initiate_tasks_generation( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def initiate_tasks_generation(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスク一括作成 https://annofab.com/docs/api/#operation/initiateTasksGeneration @@ -2938,9 +2833,7 @@ def initiate_tasks_generation( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def operate_task( - self, project_id: str, task_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def operate_task(self, project_id: str, task_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスク状態変更 https://annofab.com/docs/api/#operation/operateTask @@ -2969,9 +2862,7 @@ def operate_task( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def patch_tasks_metadata( - self, project_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def patch_tasks_metadata(self, project_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスクメタデータの一括更新 https://annofab.com/docs/api/#operation/patchTasksMetadata @@ -2999,9 +2890,7 @@ def patch_tasks_metadata( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_task( - self, project_id: str, task_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_task(self, project_id: str, task_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスク作成/更新 https://annofab.com/docs/api/#operation/putTask @@ -3035,9 +2924,7 @@ def put_task( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def get_organization_usage_status( - self, organization_name: str, year_month: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_organization_usage_status(self, organization_name: str, year_month: str, **kwargs) -> Tuple[Any, requests.Response]: """利用状況を取得 https://annofab.com/docs/api/#operation/getOrganizationUsageStatus @@ -3062,9 +2949,7 @@ def get_organization_usage_status( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_organization_usage_status_detail( - self, organization_name: str, year_month: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_organization_usage_status_detail(self, organization_name: str, year_month: str, **kwargs) -> Tuple[Any, requests.Response]: """利用状況の詳細情報を取得 https://annofab.com/docs/api/#operation/getOrganizationUsageStatusDetail @@ -3174,9 +3059,7 @@ def get_webhooks(self, project_id: str, **kwargs) -> Tuple[Any, requests.Respons keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def put_webhook( - self, project_id: str, webhook_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def put_webhook(self, project_id: str, webhook_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """Webhookの作成/更新 https://annofab.com/docs/api/#operation/putWebhook @@ -3205,9 +3088,7 @@ def put_webhook( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def test_webhook( - self, project_id: str, webhook_id: str, request_body: Optional[Any] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def test_webhook(self, project_id: str, webhook_id: str, request_body: Optional[Any] = None, **kwargs) -> Tuple[Any, requests.Response]: """Webhookのテスト実行 https://annofab.com/docs/api/#operation/testWebhook diff --git a/annofabapi/generated_api2.py b/annofabapi/generated_api2.py index 1f6b5068..cbcd8b95 100644 --- a/annofabapi/generated_api2.py +++ b/annofabapi/generated_api2.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501, ANN401 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -9,13 +9,10 @@ """ import abc -import warnings # pylint: disable=unused-import -from typing import Any, Dict, List, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, Optional, Tuple # pylint: disable=unused-import import requests -import annofabapi # pylint: disable=unused-import - class AbstractAnnofabApi2(abc.ABC): """ @@ -38,9 +35,7 @@ def _request_wrapper( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def get_annotation_specs_v2( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_annotation_specs_v2(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """アノテーション仕様取得 https://annofab.com/docs/api/#operation/getAnnotationSpecsV2 @@ -219,9 +214,7 @@ def get_organization_cache_v2(self, organization_id: str, **kwargs) -> Tuple[Any keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_organization_v2( - self, organization_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_organization_v2(self, organization_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """組織IDで組織情報取得 https://annofab.com/docs/api/#operation/getOrganizationV2 @@ -249,9 +242,7 @@ def get_organization_v2( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_project_task_count_v2( - self, organization_id: str, project_id: str, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_project_task_count_v2(self, organization_id: str, project_id: str, **kwargs) -> Tuple[Any, requests.Response]: """プロジェクトのタスク件数取得 https://annofab.com/docs/api/#operation/getProjectTaskCountV2 @@ -312,9 +303,7 @@ def get_project_member_v2( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_project_members_v2( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_project_members_v2(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """プロジェクトメンバー検索 https://annofab.com/docs/api/#operation/getProjectMembersV2 @@ -439,9 +428,7 @@ def get_inspection_daily_statistics_v2( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_label_statistics_v2( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_label_statistics_v2(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """ラベル別アノテーション数集計取得 https://annofab.com/docs/api/#operation/getLabelStatisticsV2 @@ -500,9 +487,7 @@ def get_phase_daily_statistics_v2( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_task_daily_statistics_v2( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_task_daily_statistics_v2(self, project_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """タスク集計取得 https://annofab.com/docs/api/#operation/getTaskDailyStatisticsV2 @@ -599,9 +584,7 @@ def get_worktime_daily_statistics_v2( # NOTE: This method is auto generated by OpenAPI Generator ######################################### - def get_account_v2( - self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_account_v2(self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """ユーザーアカウント情報取得 https://annofab.com/docs/api/#operation/getAccountV2 @@ -653,9 +636,7 @@ def get_user_cache_v2(self, account_id: str, **kwargs) -> Tuple[Any, requests.Re keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_user_organizations_v2( - self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_user_organizations_v2(self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """個人の所属組織検索 https://annofab.com/docs/api/#operation/getUserOrganizationsV2 @@ -683,9 +664,7 @@ def get_user_organizations_v2( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_user_project_members_v2( - self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_user_project_members_v2(self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """個人のプロジェクトメンバー情報一括取得 https://annofab.com/docs/api/#operation/getUserProjectMembersV2 @@ -713,9 +692,7 @@ def get_user_project_members_v2( keyword_params.update(**kwargs) return self._request_wrapper(http_method, url_path, **keyword_params) - def get_user_projects_v2( - self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs - ) -> Tuple[Any, requests.Response]: + def get_user_projects_v2(self, account_id: str, query_params: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[Any, requests.Response]: """自分のプロジェクトメンバー情報検索 https://annofab.com/docs/api/#operation/getUserProjectsV2 diff --git a/annofabapi/models.py b/annofabapi/models.py index e078bbd0..dc38be72 100644 --- a/annofabapi/models.py +++ b/annofabapi/models.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501, W293, W291 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -10,9 +10,8 @@ このファイルはopenapi-generatorで自動生成される。詳細は generate/README.mdを参照 """ -import warnings # pylint: disable=unused-import from enum import Enum -from typing import Any, Dict, List, NewType, Optional, Tuple, Union # pylint: disable=unused-import +from typing import Any, Dict, NewType # pylint: disable=unused-import from annofabapi._utils import deprecated_class # pylint: disable=unused-import @@ -23,7 +22,7 @@ Example: ``12345678-abcd-1234-abcd-1234abcd5678`` - + """ UserId = NewType("UserId", str) diff --git a/annofabapi/parser.py b/annofabapi/parser.py index 115cd40e..3bf58342 100644 --- a/annofabapi/parser.py +++ b/annofabapi/parser.py @@ -3,7 +3,7 @@ import os import zipfile from pathlib import Path -from typing import Any, Callable, Dict, Iterator, List, Optional +from typing import Any, Callable, Dict, Iterator, List, Optional, Type, Union from annofabapi.dataclass.annotation import FullAnnotation, SimpleAnnotation from annofabapi.exceptions import AnnotationOuterFileNotFoundError @@ -32,7 +32,7 @@ class SimpleAnnotationParser(abc.ABC): """ - def __init__(self, json_file_path: str): + def __init__(self, json_file_path: str) -> None: p = Path(json_file_path) self.__json_file_path = json_file_path self.__task_id = p.parent.name @@ -85,14 +85,14 @@ def parse(self, convert_detail_data_func: Optional[CONVERT_ANNOTATION_DETAIL_DAT SimpleAnnotationインスタンス """ - simple_annotation = SimpleAnnotation.from_dict(self.load_json()) # type: ignore + simple_annotation = SimpleAnnotation.from_dict(self.load_json()) if convert_detail_data_func is not None: for detail in simple_annotation.details: detail.data = convert_detail_data_func(detail.data) return simple_annotation @abc.abstractmethod - def load_json(self) -> Any: + def load_json(self) -> Any: # noqa: ANN401 """ JSONファイルをloadします。 """ @@ -115,7 +115,7 @@ class FullAnnotationParser(abc.ABC): """ - def __init__(self, json_file_path: str): + def __init__(self, json_file_path: str) -> None: p = Path(json_file_path) self.__json_file_path = json_file_path self.__task_id = p.parent.name @@ -157,7 +157,7 @@ def open_outer_file(self, data_uri: str): """ @abc.abstractmethod - def load_json(self) -> Any: + def load_json(self) -> Any: # noqa: ANN401 """ JSONファイルをloadします。 """ @@ -173,7 +173,7 @@ def parse(self, convert_detail_data_func: Optional[CONVERT_ANNOTATION_DETAIL_DAT FullAnnotationインスタンス """ - full_annotation = FullAnnotation.from_dict(self.load_json()) # type: ignore + full_annotation = FullAnnotation.from_dict(self.load_json()) if convert_detail_data_func is not None: for detail in full_annotation.details: detail.data = convert_detail_data_func(detail.data) @@ -198,11 +198,11 @@ class SimpleAnnotationZipParser(SimpleAnnotationParser): """ - def __init__(self, zip_file: zipfile.ZipFile, json_file_path: str): + def __init__(self, zip_file: zipfile.ZipFile, json_file_path: str) -> None: self.__zip_file = zip_file super().__init__(json_file_path) - def load_json(self) -> Any: + def load_json(self) -> Any: # noqa: ANN401 with self.__zip_file.open(self.json_file_path) as entry: return json.load(entry) @@ -212,9 +212,7 @@ def open_outer_file(self, data_uri: str): return self.__zip_file.open(outer_file_path, mode="r") except KeyError as e: # mypyの `error: "ZipFile" has no attribute "filename"` という警告を無視する - raise AnnotationOuterFileNotFoundError( - str(outer_file_path), self.__zip_file.filename - ) from e # type: ignore + raise AnnotationOuterFileNotFoundError(str(outer_file_path), self.__zip_file.filename) from e class SimpleAnnotationDirParser(SimpleAnnotationParser): @@ -232,10 +230,10 @@ class SimpleAnnotationDirParser(SimpleAnnotationParser): """ - def __init__(self, json_file_path: Path): + def __init__(self, json_file_path: Path) -> None: super().__init__(str(json_file_path)) - def load_json(self) -> Any: + def load_json(self) -> Any: # noqa: ANN401 with open(self.json_file_path, encoding="utf-8") as f: return json.load(f) @@ -265,11 +263,11 @@ class FullAnnotationZipParser(FullAnnotationParser): """ - def __init__(self, zip_file: zipfile.ZipFile, json_file_path: str): + def __init__(self, zip_file: zipfile.ZipFile, json_file_path: str) -> None: self.__zip_file = zip_file super().__init__(json_file_path) - def load_json(self) -> Any: + def load_json(self) -> Any: # noqa: ANN401 with self.__zip_file.open(self.json_file_path) as entry: return json.load(entry) @@ -279,9 +277,7 @@ def open_outer_file(self, data_uri: str): return self.__zip_file.open(outer_file_path, mode="r") except KeyError as e: # mypyの `error: "ZipFile" has no attribute "filename"` という警告を無視する - raise AnnotationOuterFileNotFoundError( - str(outer_file_path), self.__zip_file.filename - ) from e # type: ignore + raise AnnotationOuterFileNotFoundError(str(outer_file_path), self.__zip_file.filename) from e class FullAnnotationDirParser(FullAnnotationParser): @@ -300,10 +296,10 @@ class FullAnnotationDirParser(FullAnnotationParser): """ - def __init__(self, json_file_path: Path): + def __init__(self, json_file_path: Path) -> None: super().__init__(str(json_file_path)) - def load_json(self) -> Any: + def load_json(self) -> Any: # noqa: ANN401 with open(self.json_file_path, encoding="utf-8") as f: return json.load(f) @@ -324,7 +320,7 @@ class SimpleAnnotationParserByTask(abc.ABC): task_id: タスクID """ - def __init__(self, task_id: str): + def __init__(self, task_id: str) -> None: self.__task_id = task_id @property @@ -395,13 +391,9 @@ def _match_task_id_and_contain_input_data_json(zip_info: zipfile.ZipInfo) -> boo return False return True - return [ - zip_info.filename - for zip_info in self.__zip_file.infolist() - if _match_task_id_and_contain_input_data_json(zip_info) - ] + return [zip_info.filename for zip_info in self.__zip_file.infolist() if _match_task_id_and_contain_input_data_json(zip_info)] - def __init__(self, zip_file: zipfile.ZipFile, task_id: str, json_path_list: Optional[List[str]] = None): + def __init__(self, zip_file: zipfile.ZipFile, task_id: str, json_path_list: Optional[List[str]] = None) -> None: self.__zip_file = zip_file if json_path_list is not None: self.__json_path_list = json_path_list @@ -440,15 +432,13 @@ class SimpleAnnotationDirParserByTask(SimpleAnnotationParserByTask): """ - def __init__(self, task_dir_path: Path): + def __init__(self, task_dir_path: Path) -> None: self.__task_dir_path = task_dir_path task_id = task_dir_path.name super().__init__(task_id) def lazy_parse(self) -> Iterator[SimpleAnnotationDirParser]: - return ( - SimpleAnnotationDirParser(e) for e in self.__task_dir_path.iterdir() if e.is_file() and e.suffix == ".json" - ) + return (SimpleAnnotationDirParser(e) for e in self.__task_dir_path.iterdir() if e.is_file() and e.suffix == ".json") @property def json_file_path_list(self) -> List[str]: @@ -461,7 +451,7 @@ def get_parser(self, json_file_path: str) -> SimpleAnnotationParser: raise ValueError(f"json_file_path '{json_file_path}' は `json_file_path_list` に含まれていません。") -def __parse_annotation_dir(annotation_dir_path: Path, clazz) -> Iterator[Any]: +def __parse_annotation_dir(annotation_dir_path: Path, clazz: Type[Union[SimpleAnnotationDirParser, FullAnnotationDirParser]]) -> Iterator[Any]: for task_dir in annotation_dir_path.iterdir(): if not task_dir.is_dir(): continue @@ -583,8 +573,8 @@ def lazy_parse_simple_annotation_dir_by_task(annotation_dir_path: Path) -> Itera yield task_parser -def __parse_annotation_zip(zip_file_path: Path, clazz) -> Iterator[Any]: - def lazy_parser(zip_file: zipfile.ZipFile, info: zipfile.ZipInfo) -> Optional[Any]: +def __parse_annotation_zip(zip_file_path: Path, clazz: Type[Union[SimpleAnnotationZipParser, FullAnnotationZipParser]]) -> Iterator[Any]: + def lazy_parser(zip_file: zipfile.ZipFile, info: zipfile.ZipInfo) -> Optional[Any]: # noqa: ANN401 paths = [p for p in info.filename.split("/") if len(p) != 0] if len(paths) != 2: return None diff --git a/annofabapi/resource.py b/annofabapi/resource.py index 535bdb93..fc7ef5f9 100644 --- a/annofabapi/resource.py +++ b/annofabapi/resource.py @@ -22,7 +22,7 @@ class Resource: """ - def __init__(self, login_user_id: str, login_password: str, endpoint_url: str = DEFAULT_ENDPOINT_URL): + def __init__(self, login_user_id: str, login_password: str, endpoint_url: str = DEFAULT_ENDPOINT_URL) -> None: #: AnnofabApi Instance self.api = AnnofabApi(login_user_id=login_user_id, login_password=login_password, endpoint_url=endpoint_url) @@ -32,14 +32,10 @@ def __init__(self, login_user_id: str, login_password: str, endpoint_url: str = #: AnnofabApi2 Instance self.api2 = AnnofabApi2(self.api) - logger.debug( - "Create annofabapi resource instance :: %s", {"login_user_id": login_user_id, "endpoint_url": endpoint_url} - ) + logger.debug("Create annofabapi resource instance :: %s", {"login_user_id": login_user_id, "endpoint_url": endpoint_url}) -def build( - login_user_id: Optional[str] = None, login_password: Optional[str] = None, endpoint_url: str = DEFAULT_ENDPOINT_URL -) -> Resource: +def build(login_user_id: Optional[str] = None, login_password: Optional[str] = None, endpoint_url: str = DEFAULT_ENDPOINT_URL) -> Resource: """ AnnofabApi, Wrapperのインスタンスを保持するインスタンスを生成する。 diff --git a/annofabapi/segmentation.py b/annofabapi/segmentation.py index 7ca12991..b7bd0164 100644 --- a/annofabapi/segmentation.py +++ b/annofabapi/segmentation.py @@ -3,7 +3,7 @@ from PIL import Image -def read_binary_image(fp) -> numpy.ndarray: +def read_binary_image(fp) -> numpy.ndarray: # noqa: ANN001 """ アノテーションZIP(ディレクトリ)に格納されている塗りつぶし画像を読み込みます。 @@ -18,7 +18,7 @@ def read_binary_image(fp) -> numpy.ndarray: return numpy.array(image, dtype=bool) -def write_binary_image(array: npt.ArrayLike, fp) -> None: +def write_binary_image(array: npt.ArrayLike, fp) -> None: # noqa: ANN001 """ booleanの2次元配列から、Annofab用の塗りつぶし画像を書き出します。 diff --git a/annofabapi/utils.py b/annofabapi/utils.py index 050bea54..0219b3ec 100644 --- a/annofabapi/utils.py +++ b/annofabapi/utils.py @@ -24,7 +24,7 @@ def str_now() -> str: ISO 8601 formatの現在日時 """ - return to_iso8601_extension(datetime.datetime.now()) + return to_iso8601_extension(datetime.datetime.now(tz=datetime.timezone(datetime.timedelta(hours=9)))) def to_iso8601_extension(d: datetime.datetime, tz: Optional[datetime.tzinfo] = None) -> str: diff --git a/annofabapi/wrapper.py b/annofabapi/wrapper.py index ec1fde25..630c3832 100644 --- a/annofabapi/wrapper.py +++ b/annofabapi/wrapper.py @@ -129,7 +129,7 @@ class Wrapper: """ - def __init__(self, api: AnnofabApi): + def __init__(self, api: AnnofabApi) -> None: self.api = api ######################################### @@ -151,7 +151,10 @@ def _get_mime_type(file_path: str) -> str: if content_type is not None: return content_type - logger.info("ファイルパス '%s' からMIME Typeを推測できませんでした。MIME Typeは `application/octet-stream' とみなします。", file_path) + logger.info( + "ファイルパス '%s' からMIME Typeを推測できませんでした。MIME Typeは `application/octet-stream' とみなします。", + file_path, + ) return "application/octet-stream" @staticmethod @@ -178,7 +181,10 @@ def _get_all_objects(func_get_list: Callable, limit: int, **kwargs_for_func_get_ content, _ = func_get_list(**kwargs_for_func_get_list) if content["over_limit"]: - logger.warning("calling %s :: 検索結果が10,000件を超えています。Web APIの都合上10,000件までしか取得できません。", func_get_list.__name__) + logger.warning( + "calling %s :: 検索結果が10,000件を超えています。Web APIの都合上10,000件までしか取得できません。", + func_get_list.__name__, + ) all_objects.extend(content["list"]) @@ -212,7 +218,7 @@ def execute_http_get(self, url: str) -> requests.Response: * HTTPステータスコードが4XX,5XXならば、HTTPErrorがスローされます - """ + """ # noqa: E501 return self.api._execute_http_request(http_method="get", url=url) def download(self, url: str, dest_path: Union[str, Path]) -> requests.Response: @@ -236,7 +242,7 @@ def download(self, url: str, dest_path: Union[str, Path]) -> requests.Response: * 必要に応じてリトライします * HTTPステータスコードが4XX,5XXならば、HTTPErrorがスローされます - """ + """ # noqa: E501 response = self.api._execute_http_request(http_method="get", url=url) p = dest_path if isinstance(dest_path, Path) else Path(dest_path) @@ -263,9 +269,7 @@ def get_editor_annotation_or_none( Returns: アノテーション """ - content, response = self.api.get_editor_annotation( - project_id, task_id, input_data_id, query_params=query_params, raise_for_status=False - ) + content, response = self.api.get_editor_annotation(project_id, task_id, input_data_id, query_params=query_params, raise_for_status=False) if response.status_code == requests.codes.not_found: return None @@ -331,9 +335,7 @@ def download_full_annotation_archive(self, project_id: str, dest_path: Union[str ) return url - def get_all_annotation_list( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None - ) -> List[Dict[str, Any]]: + def get_all_annotation_list(self, project_id: str, query_params: Optional[Dict[str, Any]] = None) -> List[Dict[str, Any]]: """ すべてのアノテーション情報を取得する。 @@ -344,14 +346,10 @@ def get_all_annotation_list( Returns:l すべてのアノテーション一覧 """ - return self._get_all_objects( - self.api.get_annotation_list, limit=200, project_id=project_id, query_params=query_params - ) + return self._get_all_objects(self.api.get_annotation_list, limit=200, project_id=project_id, query_params=query_params) @staticmethod - def __replace_annotation_specs_id( - detail: Dict[str, Any], annotation_specs_relation: AnnotationSpecsRelation - ) -> Optional[Dict[str, Any]]: + def __replace_annotation_specs_id(detail: Dict[str, Any], annotation_specs_relation: AnnotationSpecsRelation) -> Optional[Dict[str, Any]]: """ アノテーション仕様関係のIDを、新しいIDに置換する。 @@ -373,17 +371,13 @@ def __replace_annotation_specs_id( new_additional_data_list = [] for additional_data in additional_data_list: additional_data_definition_id = additional_data["additional_data_definition_id"] - new_additional_data_definition_id = annotation_specs_relation.additional_data_definition_id.get( - additional_data_definition_id - ) + new_additional_data_definition_id = annotation_specs_relation.additional_data_definition_id.get(additional_data_definition_id) if new_additional_data_definition_id is None: continue additional_data["additional_data_definition_id"] = new_additional_data_definition_id if additional_data["choice"] is not None: - new_choice = annotation_specs_relation.choice_id.get( - ChoiceKey(additional_data_definition_id, additional_data["choice"]) - ) + new_choice = annotation_specs_relation.choice_id.get(ChoiceKey(additional_data_definition_id, additional_data["choice"])) additional_data["choice"] = new_choice.choice_id if new_choice is not None else None new_additional_data_list.append(additional_data) @@ -407,16 +401,14 @@ def __to_dest_annotation_detail( Raises: CheckSumError: アップロードした外部アノテーションファイルのMD5ハッシュ値が、S3にアップロードしたときのレスポンスのETagに一致しない - """ + """ # noqa: E501 dest_detail = detail dest_detail["account_id"] = account_id if detail["data_holding_type"] == AnnotationDataHoldingType.OUTER.value: try: outer_file_url = detail["url"] src_response = self.api._execute_http_request("get", outer_file_url) - s3_path = self.upload_data_to_s3( - dest_project_id, data=src_response.content, content_type=src_response.headers["Content-Type"] - ) + s3_path = self.upload_data_to_s3(dest_project_id, data=src_response.content, content_type=src_response.headers["Content-Type"]) dest_detail["path"] = s3_path dest_detail["url"] = None dest_detail["etag"] = None @@ -424,11 +416,9 @@ def __to_dest_annotation_detail( except CheckSumError as e: message = ( f"外部アノテーションファイル {outer_file_url} のレスポンスのMD5ハッシュ値('{e.uploaded_data_hash}')が、" - f"AWS S3にアップロードしたときのレスポンスのETag('{e.response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" + f"AWS S3にアップロードしたときのレスポンスのETag('{e.response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" # noqa: E501 ) - raise CheckSumError( - message=message, uploaded_data_hash=e.uploaded_data_hash, response_etag=e.response_etag - ) from e + raise CheckSumError(message=message, uploaded_data_hash=e.uploaded_data_hash, response_etag=e.response_etag) from e return dest_detail @@ -450,7 +440,7 @@ def _create_request_body_for_copy_annotation( tmp_detail = self.__replace_annotation_specs_id(src_detail, annotation_specs_relation) if tmp_detail is None: continue - src_detail = tmp_detail + src_detail = tmp_detail # noqa: PLW2901 dest_detail = self.__to_dest_annotation_detail(project_id, src_detail, account_id=account_id) dest_details.append(dest_detail) @@ -506,17 +496,13 @@ def copy_annotation( self.api.put_annotation(dest.project_id, dest.task_id, dest.input_data_id, request_body=request_body) return True - def __get_label_info_from_label_name( - self, label_name: str, annotation_specs_labels: List[LabelV1] - ) -> Optional[LabelV1]: + def __get_label_info_from_label_name(self, label_name: str, annotation_specs_labels: List[LabelV1]) -> Optional[LabelV1]: for label in annotation_specs_labels: if self.__get_label_name_en(label) == label_name: return label return None - def __get_additional_data_from_attribute_name( - self, attribute_name: str, label_info: LabelV1 - ) -> Optional[AdditionalDataDefinitionV1]: + def __get_additional_data_from_attribute_name(self, attribute_name: str, label_info: LabelV1) -> Optional[AdditionalDataDefinitionV1]: for additional_data in label_info["additional_data_definitions"]: if self.__get_additional_data_definition_name_en(additional_data) == attribute_name: return additional_data @@ -550,7 +536,9 @@ def __to_additional_data_list(self, attributes: Dict[str, Any], label_info: Labe specs_additional_data = self.__get_additional_data_from_attribute_name(key, label_info) if specs_additional_data is None: logger.warning( - "アノテーション仕様の '%s' ラベルに、attribute_name='%s' である属性が存在しません。", self.__get_label_name_en(label_info), key + "アノテーション仕様の '%s' ラベルに、attribute_name='%s' である属性が存在しません。", + self.__get_label_name_en(label_info), + key, ) continue @@ -645,17 +633,13 @@ def __to_annotation_detail_for_request( except CheckSumError as e: message = ( f"アップロードした外部アノテーションファイル'{outer_file_path}'のMD5ハッシュ値('{e.uploaded_data_hash}')が、" - f"AWS S3にアップロードしたときのレスポンスのETag('{e.response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" + f"AWS S3にアップロードしたときのレスポンスのETag('{e.response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" # noqa: E501 ) - raise CheckSumError( - message=message, uploaded_data_hash=e.uploaded_data_hash, response_etag=e.response_etag - ) from e + raise CheckSumError(message=message, uploaded_data_hash=e.uploaded_data_hash, response_etag=e.response_etag) from e return dest_obj - def __convert_annotation_specs_labels_v2_to_v1( - self, labels_v2: List[Dict[str, Any]], additionals_v2: List[Dict[str, Any]] - ) -> List[LabelV1]: + def __convert_annotation_specs_labels_v2_to_v1(self, labels_v2: List[Dict[str, Any]], additionals_v2: List[Dict[str, Any]]) -> List[LabelV1]: """アノテーション仕様のV2版からV1版に変換する。V1版の方が扱いやすいので。 Args: @@ -667,11 +651,9 @@ def __convert_annotation_specs_labels_v2_to_v1( """ def get_additional(additional_data_definition_id: str) -> Optional[Dict[str, Any]]: - return more_itertools.first_true( - additionals_v2, pred=lambda e: e["additional_data_definition_id"] == additional_data_definition_id - ) + return more_itertools.first_true(additionals_v2, pred=lambda e: e["additional_data_definition_id"] == additional_data_definition_id) - def to_label_v1(label_v2) -> LabelV1: + def to_label_v1(label_v2: Dict[str, Any]) -> LabelV1: additional_data_definition_id_list = label_v2["additional_data_definitions"] new_additional_data_definitions = [] for additional_data_definition_id in additional_data_definition_id_list: @@ -736,9 +718,7 @@ def put_annotation_for_simple_annotation_json( else annotation_specs_labels ) for detail in details: - request_detail = self.__to_annotation_detail_for_request( - project_id, parser, detail, annotation_specs_labels_v1 - ) + request_detail = self.__to_annotation_detail_for_request(project_id, parser, detail, annotation_specs_labels_v1) if request_detail is not None: request_details.append(request_detail) if len(request_details) == 0: @@ -773,19 +753,19 @@ def put_annotation_for_simple_annotation_json( def __get_label_name_en(label: Dict[str, Any]) -> str: """label情報から英語名を取得する""" label_name_messages = label["label_name"]["messages"] - return [e["message"] for e in label_name_messages if e["lang"] == "en-US"][0] + return next(e["message"] for e in label_name_messages if e["lang"] == "en-US") @staticmethod def __get_additional_data_definition_name_en(additional_data_definition: Dict[str, Any]) -> str: """additional_data_definitionから英語名を取得する""" messages = additional_data_definition["name"]["messages"] - return [e["message"] for e in messages if e["lang"] == "en-US"][0] + return next(e["message"] for e in messages if e["lang"] == "en-US") @staticmethod def __get_choice_name_en(choice: Dict[str, Any]) -> str: """choiceから英語名を取得する""" messages = choice["name"]["messages"] - return [e["message"] for e in messages if e["lang"] == "en-US"][0] + return next(e["message"] for e in messages if e["lang"] == "en-US") def __get_dest_additional( self, @@ -809,15 +789,13 @@ def __get_dest_additional( break dest_label = more_itertools.first_true( - dest_labels, pred=lambda e: e["label_id"] == dest_label_id # pylint: disable=cell-var-from-loop + dest_labels, + pred=lambda e: e["label_id"] == dest_label_id, # pylint: disable=cell-var-from-loop # noqa: B023 ) if dest_label is None: dest_label_contains_dest_additional = False break - if ( - dest_additional["additional_data_definition_id"] - not in dest_label["additional_data_definitions"] - ): + if dest_additional["additional_data_definition_id"] not in dest_label["additional_data_definitions"]: dest_label_contains_dest_additional = False break @@ -851,7 +829,7 @@ def get_annotation_specs_relation(self, src_project_id: str, dest_project_id: st src_label_name_en = self.__get_label_name_en(src_label) dest_label = more_itertools.first_true( dest_labels, - pred=lambda e: self.__get_label_name_en(e) == src_label_name_en, # pylint: disable=cell-var-from-loop + pred=lambda e: self.__get_label_name_en(e) == src_label_name_en, # pylint: disable=cell-var-from-loop # noqa: B023 ) if dest_label is not None: dict_label_id[src_label["label_id"]] = dest_label["label_id"] @@ -869,22 +847,19 @@ def get_annotation_specs_relation(self, src_project_id: str, dest_project_id: st if dest_additional is None: continue - dict_additional_data_definition_id[src_additional["additional_data_definition_id"]] = dest_additional[ - "additional_data_definition_id" - ] + dict_additional_data_definition_id[src_additional["additional_data_definition_id"]] = dest_additional["additional_data_definition_id"] dest_choices = dest_additional["choices"] for src_choice in src_additional["choices"]: src_choice_name_en = self.__get_choice_name_en(src_choice) dest_choice = more_itertools.first_true( dest_choices, - pred=lambda e: self.__get_choice_name_en(e) - == src_choice_name_en, # pylint: disable=cell-var-from-loop + pred=lambda e: self.__get_choice_name_en(e) == src_choice_name_en, # pylint: disable=cell-var-from-loop # noqa: B023 ) if dest_choice is not None: - dict_choice_id[ - ChoiceKey(src_additional["additional_data_definition_id"], src_choice["choice_id"]) - ] = ChoiceKey(dest_additional["additional_data_definition_id"], dest_choice["choice_id"]) + dict_choice_id[ChoiceKey(src_additional["additional_data_definition_id"], src_choice["choice_id"])] = ChoiceKey( + dest_additional["additional_data_definition_id"], dest_choice["choice_id"] + ) return AnnotationSpecsRelation( label_id=dict_label_id, @@ -915,9 +890,7 @@ def get_input_data_or_none(self, project_id: str, input_data_id: str) -> Optiona _raise_for_status(response) return content - def get_all_input_data_list( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None - ) -> List[InputData]: + def get_all_input_data_list(self, project_id: str, query_params: Optional[Dict[str, Any]] = None) -> List[InputData]: """ すべての入力データを取得する。 @@ -928,9 +901,7 @@ def get_all_input_data_list( Returns: 入力データ一覧 """ - return self._get_all_objects( - self.api.get_input_data_list, limit=200, project_id=project_id, query_params=query_params - ) + return self._get_all_objects(self.api.get_input_data_list, limit=200, project_id=project_id, query_params=query_params) def upload_file_to_s3(self, project_id: str, file_path: str, content_type: Optional[str] = None) -> str: """ @@ -957,13 +928,11 @@ def upload_file_to_s3(self, project_id: str, file_path: str, content_type: Optio except CheckSumError as e: message = ( f"アップロードしたファイル'{file_path}'のMD5ハッシュ値('{e.uploaded_data_hash}')が、" - f"AWS S3にアップロードしたときのレスポンスのETag('{e.response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" + f"AWS S3にアップロードしたときのレスポンスのETag('{e.response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" # noqa: E501 ) - raise CheckSumError( - message=message, uploaded_data_hash=e.uploaded_data_hash, response_etag=e.response_etag - ) from e + raise CheckSumError(message=message, uploaded_data_hash=e.uploaded_data_hash, response_etag=e.response_etag) from e - def upload_data_to_s3(self, project_id: str, data: Any, content_type: str) -> str: + def upload_data_to_s3(self, project_id: str, data: Any, content_type: str) -> str: # noqa: ANN401 """ createTempPath APIを使ってアップロード用のURLとS3パスを取得して、"data" をアップロードする。 @@ -977,9 +946,9 @@ def upload_data_to_s3(self, project_id: str, data: Any, content_type: str) -> st Raises: CheckSumError: アップロードしたデータのMD5ハッシュ値が、S3にアップロードしたときのレスポンスのETagと一致しない - """ + """ # noqa: E501 - def get_md5_value_from_file(fp): + def get_md5_value_from_file(fp): # noqa: ANN001 md5_obj = hashlib.md5() while True: chunk = fp.read(2048 * md5_obj.block_size) @@ -998,9 +967,7 @@ def get_md5_value_from_file(fp): s3_url = content["url"].split("?")[0] # アップロード - res_put = self.api._execute_http_request( - http_method="put", url=s3_url, params=query_dict, data=data, headers={"content-type": content_type} - ) + res_put = self.api._execute_http_request(http_method="put", url=s3_url, params=query_dict, data=data, headers={"content-type": content_type}) # アップロードしたファイルが破損していなかをチェックする if hasattr(data, "read"): @@ -1016,7 +983,7 @@ def get_md5_value_from_file(fp): if f'"{uploaded_data_hash}"' != response_etag: message = ( f"アップロードしたデータのMD5ハッシュ値('{uploaded_data_hash}')が、" - f"AWS S3にアップロードしたときのレスポンスのETag('{response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" + f"AWS S3にアップロードしたときのレスポンスのETag('{response_etag}')に一致しませんでした。アップロード時にデータが破損した可能性があります。" # noqa: E501 ) raise CheckSumError(message=message, uploaded_data_hash=uploaded_data_hash, response_etag=response_etag) @@ -1059,7 +1026,7 @@ def put_input_data_from_file( ######################################### # Public Method : Statistics ######################################### - def _get_statistics_content(self, content: Any, response: requests.Response) -> Optional[Any]: + def _get_statistics_content(self, content: Any, response: requests.Response) -> Optional[Any]: # noqa: ANN401 """ 統計情報webapiのレスポンス情報に格納されているURLにアクセスして、統計情報の中身を取得する。 統計情報webapiのレスポンス'url'にアクセスする。 @@ -1148,7 +1115,7 @@ def _get_from_and_to_date_for_statistics_webapi( project, _ = self.api.get_project(project_id) from_date = project["created_datetime"][0:10] # "YYYY-MM-DD"の部分を抽出 if to_date is None: - to_date = str(datetime.datetime.today().date()) + to_date = str(datetime.datetime.now(tz=datetime.timezone(datetime.timedelta(hours=9))).date()) if from_date is None or to_date is None: dates, _ = self.api.get_statistics_available_dates(project_id) @@ -1159,8 +1126,8 @@ def _get_from_and_to_date_for_statistics_webapi( to_date = dates[-1]["to"] DATE_FORMAT = "%Y-%m-%d" - dt_from_date = datetime.datetime.strptime(from_date, DATE_FORMAT).date() - dt_to_date = datetime.datetime.strptime(to_date, DATE_FORMAT).date() + dt_from_date = datetime.datetime.strptime(from_date, DATE_FORMAT).date() # noqa: DTZ007 + dt_to_date = datetime.datetime.strptime(to_date, DATE_FORMAT).date() # noqa: DTZ007 return dt_from_date, dt_to_date def get_account_daily_statistics( @@ -1177,7 +1144,7 @@ def get_account_daily_statistics( ユーザ別タスク集計データ """ - def decorator(f, project_id: str): + def decorator(f, project_id: str): # noqa: ANN001 @functools.wraps(f) def wrapper(*args, **kwargs): content, _ = f(project_id, *args, **kwargs) @@ -1185,9 +1152,7 @@ def wrapper(*args, **kwargs): return wrapper - dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi( - project_id, from_date=from_date, to_date=to_date - ) + dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi(project_id, from_date=from_date, to_date=to_date) func = decorator(self.api.get_account_daily_statistics, project_id) result = self._get_statistics_daily_xxx(func, dt_from_date=dt_from_date, dt_to_date=dt_to_date) @@ -1213,7 +1178,7 @@ def get_inspection_daily_statistics( """ - def decorator(f, project_id: str): + def decorator(f, project_id: str): # noqa: ANN001 @functools.wraps(f) def wrapper(*args, **kwargs): content, _ = f(project_id, *args, **kwargs) @@ -1221,15 +1186,11 @@ def wrapper(*args, **kwargs): return wrapper - dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi( - project_id, from_date=from_date, to_date=to_date - ) + dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi(project_id, from_date=from_date, to_date=to_date) func = decorator(self.api.get_inspection_daily_statistics, project_id) return self._get_statistics_daily_xxx(func, dt_from_date=dt_from_date, dt_to_date=dt_to_date) - def get_phase_daily_statistics( - self, project_id: str, *, from_date: Optional[str] = None, to_date: Optional[str] = None - ) -> List[Dict[str, Any]]: + def get_phase_daily_statistics(self, project_id: str, *, from_date: Optional[str] = None, to_date: Optional[str] = None) -> List[Dict[str, Any]]: """指定した期間の フェーズ別タスク集計データ を取得します。 Args: @@ -1242,7 +1203,7 @@ def get_phase_daily_statistics( """ - def decorator(f, project_id: str): + def decorator(f, project_id: str): # noqa: ANN001 @functools.wraps(f) def wrapper(*args, **kwargs): content, _ = f(project_id, *args, **kwargs) @@ -1250,15 +1211,11 @@ def wrapper(*args, **kwargs): return wrapper - dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi( - project_id, from_date=from_date, to_date=to_date - ) + dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi(project_id, from_date=from_date, to_date=to_date) func = decorator(self.api.get_phase_daily_statistics, project_id) return self._get_statistics_daily_xxx(func, dt_from_date=dt_from_date, dt_to_date=dt_to_date) - def get_task_daily_statistics( - self, project_id: str, *, from_date: Optional[str] = None, to_date: Optional[str] = None - ) -> List[Dict[str, Any]]: + def get_task_daily_statistics(self, project_id: str, *, from_date: Optional[str] = None, to_date: Optional[str] = None) -> List[Dict[str, Any]]: """指定した期間の タスク集計データ を取得します。 Args: @@ -1271,7 +1228,7 @@ def get_task_daily_statistics( """ - def decorator(f, project_id: str): + def decorator(f, project_id: str): # noqa: ANN001 @functools.wraps(f) def wrapper(*args, **kwargs): content, _ = f(project_id, *args, **kwargs) @@ -1279,15 +1236,11 @@ def wrapper(*args, **kwargs): return wrapper - dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi( - project_id, from_date=from_date, to_date=to_date - ) + dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi(project_id, from_date=from_date, to_date=to_date) func = decorator(self.api.get_task_daily_statistics, project_id) return self._get_statistics_daily_xxx(func, dt_from_date=dt_from_date, dt_to_date=dt_to_date) - def get_worktime_daily_statistics( - self, project_id: str, *, from_date: Optional[str] = None, to_date: Optional[str] = None - ) -> Dict[str, Any]: + def get_worktime_daily_statistics(self, project_id: str, *, from_date: Optional[str] = None, to_date: Optional[str] = None) -> Dict[str, Any]: """プロジェクト全体のタスク作業時間集計データを取得します。 Args: @@ -1299,7 +1252,7 @@ def get_worktime_daily_statistics( プロジェクト全体のタスク作業時間集計データ """ - def decorator(f, project_id: str): + def decorator(f, project_id: str): # noqa: ANN001 @functools.wraps(f) def wrapper(*args, **kwargs): content, _ = f(project_id, *args, **kwargs) @@ -1307,9 +1260,7 @@ def wrapper(*args, **kwargs): return wrapper - dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi( - project_id, from_date=from_date, to_date=to_date - ) + dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi(project_id, from_date=from_date, to_date=to_date) func = decorator(self.api.get_worktime_daily_statistics, project_id) result = self._get_statistics_daily_xxx(func, dt_from_date=dt_from_date, dt_to_date=dt_to_date) return {"project_id": project_id, "data_series": result} @@ -1329,7 +1280,7 @@ def get_worktime_daily_statistics_by_account( プロジェクトメンバーのタスク作業時間集計データ """ - def decorator(f, project_id: str, account_id: str): + def decorator(f, project_id: str, account_id: str): # noqa: ANN001 @functools.wraps(f) def wrapper(*args, **kwargs): content, _ = f(project_id, account_id, *args, **kwargs) @@ -1337,9 +1288,7 @@ def wrapper(*args, **kwargs): return wrapper - dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi( - project_id, from_date=from_date, to_date=to_date - ) + dt_from_date, dt_to_date = self._get_from_and_to_date_for_statistics_webapi(project_id, from_date=from_date, to_date=to_date) func = decorator(self.api.get_worktime_daily_statistics_by_account, project_id, account_id) result = self._get_statistics_daily_xxx(func, dt_from_date=dt_from_date, dt_to_date=dt_to_date) return {"project_id": project_id, "account_id": account_id, "data_series": result} @@ -1348,9 +1297,7 @@ def wrapper(*args, **kwargs): # Public Method : Supplementary ######################################### - def get_supplementary_data_list_or_none( - self, project_id: str, input_data_id: str - ) -> Optional[List[Dict[str, Any]]]: + def get_supplementary_data_list_or_none(self, project_id: str, input_data_id: str) -> Optional[List[Dict[str, Any]]]: """ 補助情報一覧を取得する。存在しない場合(HTTP 404 Error)はNoneを返す。 @@ -1371,7 +1318,7 @@ def get_supplementary_data_list_or_none( def put_supplementary_data_from_file( self, - project_id, + project_id: str, input_data_id: str, supplementary_data_id: str, file_path: str, @@ -1417,9 +1364,7 @@ def put_supplementary_data_from_file( raise AnnofabApiException(f"File type not supported. Content-Type={new_content_type}") copied_request_body["supplementary_data_type"] = supplementary_data_type - return self.api.put_supplementary_data( - project_id, input_data_id, supplementary_data_id, request_body=copied_request_body - )[0] + return self.api.put_supplementary_data(project_id, input_data_id, supplementary_data_id, request_body=copied_request_body)[0] ######################################### # Public Method : Inspection @@ -1461,9 +1406,7 @@ def get_organization_or_none(self, organization_name: str) -> Optional[Organizat _raise_for_status(response) return content - def get_all_projects_of_organization( - self, organization_name: str, query_params: Optional[Dict[str, Any]] = None - ) -> List[Project]: + def get_all_projects_of_organization(self, organization_name: str, query_params: Optional[Dict[str, Any]] = None) -> List[Project]: """ 組織配下のすべてのプロジェクト一覧を取得する @@ -1662,7 +1605,7 @@ def download_project_task_history_events_url(self, project_id: str, dest_path: U """ with warnings.catch_warnings(): - # `get_project_task_history_events_url`関数は非推奨だが、タスク履歴イベントでしか取得できない情報があるため、annofab-cliなどではよく利用する + # `get_project_task_history_events_url`関数は非推奨だが、タスク履歴イベントでしか取得できない情報があるため、annofab-cliなどではよく利用する # noqa: E501 # `get_project_task_history_events_url`関数がいつ廃止さるのかは未定なので、`get_project_task_history_events_url`関数実行時の警告を無視する warnings.simplefilter("ignore", category=FutureWarning) content, _ = self.api.get_project_task_history_events_url(project_id) @@ -1726,9 +1669,7 @@ def get_project_member_or_none(self, project_id: str, user_id: str) -> Optional[ _raise_for_status(response) return content - def get_all_project_members( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None - ) -> List[ProjectMember]: + def get_all_project_members(self, project_id: str, query_params: Optional[Dict[str, Any]] = None) -> List[ProjectMember]: """ すべてのプロジェクトメンバを取得する. @@ -1819,9 +1760,7 @@ def get_all_tasks(self, project_id: str, query_params: Optional[Dict[str, Any]] """ return self._get_all_objects(self.api.get_tasks, limit=200, project_id=project_id, query_params=query_params) - def change_task_status_to_working( - self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None - ) -> Task: + def change_task_status_to_working(self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None) -> Task: """ タスクのステータスを「作業中」に変更します。 @@ -1836,7 +1775,7 @@ def change_task_status_to_working( Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -1848,9 +1787,7 @@ def change_task_status_to_working( updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body) return updated_task - def change_task_status_to_break( - self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None - ) -> Task: + def change_task_status_to_break(self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None) -> Task: """ タスクのステータスを「休憩中」に変更します。 @@ -1865,7 +1802,7 @@ def change_task_status_to_break( Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -1878,9 +1815,7 @@ def change_task_status_to_break( updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body) return updated_task - def change_task_status_to_on_hold( - self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None - ) -> Task: + def change_task_status_to_on_hold(self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None) -> Task: """ タスクのステータスを「保留」に変更します。 @@ -1895,7 +1830,7 @@ def change_task_status_to_on_hold( Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -1926,7 +1861,7 @@ def complete_task(self, project_id: str, task_id: str, *, last_updated_datetime: Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -1939,9 +1874,7 @@ def complete_task(self, project_id: str, task_id: str, *, last_updated_datetime: updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body) return updated_task - def cancel_submitted_task( - self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None - ) -> Task: + def cancel_submitted_task(self, project_id: str, task_id: str, *, last_updated_datetime: Optional[str] = None) -> Task: """ タスクの提出を取り消します。 「提出されたタスク」とは、以下の状態のタスクのことです。 @@ -1961,7 +1894,7 @@ def cancel_submitted_task( Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -1998,7 +1931,7 @@ def cancel_completed_task( Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -2034,7 +1967,7 @@ def change_task_operator( Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -2047,9 +1980,7 @@ def change_task_operator( updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body) return updated_task - def reject_task( - self, project_id: str, task_id: str, *, force: bool = False, last_updated_datetime: Optional[str] = None - ) -> Dict[str, Any]: + def reject_task(self, project_id: str, task_id: str, *, force: bool = False, last_updated_datetime: Optional[str] = None) -> Dict[str, Any]: """ タスクを差し戻します。 このメソッドを実行すると、`phase`は`annotation`になります。 @@ -2071,7 +2002,7 @@ def reject_task( Returns: 変更後のタスク - """ + """ # noqa: E501 if last_updated_datetime is None: task, _ = self.api.get_task(project_id, task_id) last_updated_datetime = task["updated_datetime"] @@ -2105,9 +2036,7 @@ def get_latest_instruction(self, project_id: str) -> Optional[Instruction]: latest_history_id = histories[0]["history_id"] return self.api.get_instruction(project_id, {"history_id": latest_history_id})[0] - def upload_instruction_image( - self, project_id: str, image_id: str, file_path: str, content_type: Optional[str] = None - ) -> str: + def upload_instruction_image(self, project_id: str, image_id: str, file_path: str, content_type: Optional[str] = None) -> str: """ 作業ガイドの画像をアップロードする。 @@ -2125,7 +2054,7 @@ def upload_instruction_image( with open(file_path, "rb") as f: return self.upload_data_as_instruction_image(project_id, image_id, data=f, content_type=new_content_type) - def upload_data_as_instruction_image(self, project_id: str, image_id: str, data: Any, content_type: str) -> str: + def upload_data_as_instruction_image(self, project_id: str, image_id: str, data: Any, content_type: str) -> str: # noqa: ANN401 """ data を作業ガイドの画像としてアップロードする。 @@ -2148,9 +2077,7 @@ def upload_data_as_instruction_image(self, project_id: str, image_id: str, data: s3_url = content["url"].split("?")[0] # アップロード - self.api._execute_http_request( - http_method="put", url=s3_url, params=query_dict, data=data, headers={"content-type": content_type} - ) + self.api._execute_http_request(http_method="put", url=s3_url, params=query_dict, data=data, headers={"content-type": content_type}) return content["path"] ######################################### @@ -2176,9 +2103,7 @@ def delete_all_succeeded_job(self, project_id: str, job_type: ProjectJobType) -> return deleted_jobs - def get_all_project_job( - self, project_id: str, query_params: Optional[Dict[str, Any]] = None - ) -> List[ProjectJobInfo]: + def get_all_project_job(self, project_id: str, query_params: Optional[Dict[str, Any]] = None) -> List[ProjectJobInfo]: """ すべてのバックグランドジョブを取得する。 @@ -2239,9 +2164,7 @@ def wait_for_completion( Falseならば、ジョブが失敗 or ``max_job_access`` 回アクセスしても、ジョブが完了しなかった。 """ - job_status = self.wait_until_job_finished( - project_id, job_type, job_access_interval=job_access_interval, max_job_access=max_job_access - ) + job_status = self.wait_until_job_finished(project_id, job_type, job_access_interval=job_access_interval, max_job_access=max_job_access) if job_status is None: # 実行中のジョブが存在しない return True @@ -2292,13 +2215,20 @@ def get_job_from_job_id(arg_job_id: str) -> Optional[ProjectJobInfo]: # 初回のみ job = get_latest_job() if job is None or job["job_status"] != JobStatus.PROGRESS.value: - logger.info("project_id='%s', job_type='%s' である進行中のジョブは存在しません。", project_id, job_type.value) + logger.info( + "project_id='%s', job_type='%s' である進行中のジョブは存在しません。", + project_id, + job_type.value, + ) return None job_id = job["job_id"] if job is None: logger.info( - "project_id='%s', job_id='%s', job_type='%s' のジョブは存在しません。", project_id, job_type.value, job_id + "project_id='%s', job_id='%s', job_type='%s' のジョブは存在しません。", + project_id, + job_type.value, + job_id, ) return None @@ -2306,7 +2236,10 @@ def get_job_from_job_id(arg_job_id: str) -> Optional[ProjectJobInfo]: if job["job_status"] == JobStatus.SUCCEEDED.value: logger.info( - "project_id='%s', job_id='%s', job_type='%s' のジョブが成功しました。", project_id, job_id, job_type.value + "project_id='%s', job_id='%s', job_type='%s' のジョブが成功しました。", + project_id, + job_id, + job_type.value, ) return JobStatus.SUCCEEDED @@ -2354,9 +2287,7 @@ async def _wait_until_job_finished_async( max_job_access: int, ) -> Optional[JobStatus]: loop = asyncio.get_event_loop() - return await loop.run_in_executor( - None, self.wait_until_job_finished, project_id, job_type, job_id, job_access_interval, max_job_access - ) + return await loop.run_in_executor(None, self.wait_until_job_finished, project_id, job_type, job_id, job_access_interval, max_job_access) def can_execute_job(self, project_id: str, job_type: ProjectJobType) -> bool: """ diff --git a/generate/partial-header/dataclass/annotation.py b/generate/partial-header/dataclass/annotation.py index 85e26e07..c08ad264 100644 --- a/generate/partial-header/dataclass/annotation.py +++ b/generate/partial-header/dataclass/annotation.py @@ -1,3 +1,4 @@ +# ruff: noqa: E501 from annofabapi.models import ( AdditionalDataDefinitionType, AnnotationDataHoldingType, diff --git a/generate/partial-header/dataclass/common.py b/generate/partial-header/dataclass/common.py index d9b265e1..c8b5bdfb 100644 --- a/generate/partial-header/dataclass/common.py +++ b/generate/partial-header/dataclass/common.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501 # pylint: disable=too-many-lines,trailing-whitespace """ diff --git a/generate/partial-header/generated_api_partial_header_v1.py b/generate/partial-header/generated_api_partial_header_v1.py index 9f4301ee..1f091030 100644 --- a/generate/partial-header/generated_api_partial_header_v1.py +++ b/generate/partial-header/generated_api_partial_header_v1.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501, ANN401 # pylint: disable=too-many-lines,trailing-whitespace """ diff --git a/generate/partial-header/generated_api_partial_header_v2.py b/generate/partial-header/generated_api_partial_header_v2.py index 8f050f56..621b833e 100644 --- a/generate/partial-header/generated_api_partial_header_v2.py +++ b/generate/partial-header/generated_api_partial_header_v2.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501, ANN401 # pylint: disable=too-many-lines,trailing-whitespace """ diff --git a/generate/partial-header/models_partial_header_v1.py b/generate/partial-header/models_partial_header_v1.py index 98dbea0a..fedd6fd2 100644 --- a/generate/partial-header/models_partial_header_v1.py +++ b/generate/partial-header/models_partial_header_v1.py @@ -1,4 +1,4 @@ -# flake8: noqa: W291 +# ruff: noqa: E501, W293, W291 # pylint: disable=too-many-lines,trailing-whitespace """ @@ -23,7 +23,7 @@ Example: ``12345678-abcd-1234-abcd-1234abcd5678`` - + """ UserId = NewType("UserId", str) diff --git a/poetry.lock b/poetry.lock index 73585ef2..74e8068e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -27,29 +27,26 @@ files = [ [[package]] name = "appnope" -version = "0.1.3" +version = "0.1.4" description = "Disable App Nap on macOS >= 10.9" optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, ] [[package]] name = "astroid" -version = "3.0.2" +version = "3.1.0" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.8.0" files = [ - {file = "astroid-3.0.2-py3-none-any.whl", hash = "sha256:d6e62862355f60e716164082d6b4b041d38e2a8cf1c7cd953ded5108bac8ff5c"}, - {file = "astroid-3.0.2.tar.gz", hash = "sha256:4a61cf0a59097c7bb52689b0fd63717cd2a8a14dc9f1eee97b82d814881c8c91"}, + {file = "astroid-3.1.0-py3-none-any.whl", hash = "sha256:951798f922990137ac090c53af473db7ab4e70c770e6d7fae0cec59f74411819"}, + {file = "astroid-3.1.0.tar.gz", hash = "sha256:ac248253bfa4bd924a0de213707e7ebeeb3138abeb48d798784ead1e56d419d4"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} - [[package]] name = "asttokens" version = "2.4.1" @@ -68,21 +65,6 @@ six = ">=1.12.0" astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] -[[package]] -name = "autoflake" -version = "2.2.1" -description = "Removes unused imports and unused variables" -optional = false -python-versions = ">=3.8" -files = [ - {file = "autoflake-2.2.1-py3-none-any.whl", hash = "sha256:265cde0a43c1f44ecfb4f30d95b0437796759d07be7706a2f70e4719234c0f79"}, - {file = "autoflake-2.2.1.tar.gz", hash = "sha256:62b7b6449a692c3c9b0c916919bbc21648da7281e8506bcf8d3f8280e431ebc1"}, -] - -[package.dependencies] -pyflakes = ">=3.0.0" -tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""} - [[package]] name = "babel" version = "2.14.0" @@ -124,77 +106,34 @@ files = [ [[package]] name = "beautifulsoup4" -version = "4.12.2" +version = "4.12.3" description = "Screen-scraping library" optional = false python-versions = ">=3.6.0" files = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, ] [package.dependencies] soupsieve = ">1.2" [package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] html5lib = ["html5lib"] lxml = ["lxml"] -[[package]] -name = "black" -version = "23.12.1" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, - {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, - {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, - {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, - {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, - {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, - {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, - {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, - {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, - {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, - {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, - {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, - {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, - {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, - {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, - {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, - {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, - {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, - {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, - {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, - {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, - {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - [[package]] name = "certifi" -version = "2023.11.17" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] @@ -296,20 +235,6 @@ files = [ {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - [[package]] name = "colorama" version = "0.4.6" @@ -323,63 +248,63 @@ files = [ [[package]] name = "coverage" -version = "7.4.0" +version = "7.4.3" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"}, - {file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"}, - {file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"}, - {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"}, - {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"}, - {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"}, - {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"}, - {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"}, - {file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"}, - {file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"}, - {file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"}, - {file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"}, - {file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"}, - {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"}, - {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"}, - {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"}, - {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"}, - {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"}, - {file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"}, - {file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"}, - {file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"}, - {file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"}, - {file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"}, - {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"}, - {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"}, - {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"}, - {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"}, - {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"}, - {file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"}, - {file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"}, - {file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"}, - {file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"}, - {file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"}, - {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"}, - {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"}, - {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"}, - {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"}, - {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"}, - {file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"}, - {file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"}, - {file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"}, - {file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"}, - {file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"}, - {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"}, - {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"}, - {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"}, - {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"}, - {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"}, - {file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"}, - {file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"}, - {file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"}, - {file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, + {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, + {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, + {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, + {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, + {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, + {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, + {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, + {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, + {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, + {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, + {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, + {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, ] [package.dependencies] @@ -390,13 +315,13 @@ toml = ["tomli"] [[package]] name = "dataclasses-json" -version = "0.6.3" +version = "0.6.4" description = "Easily serialize dataclasses to and from JSON." optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "dataclasses_json-0.6.3-py3-none-any.whl", hash = "sha256:4aeb343357997396f6bca1acae64e486c3a723d8f5c76301888abeccf0c45176"}, - {file = "dataclasses_json-0.6.3.tar.gz", hash = "sha256:35cb40aae824736fdf959801356641836365219cfe14caeb115c39136f775d2a"}, + {file = "dataclasses_json-0.6.4-py3-none-any.whl", hash = "sha256:f90578b8a3177f7552f4e1a6e535e84293cd5da421fcce0642d49c0d7bdf8df2"}, + {file = "dataclasses_json-0.6.4.tar.gz", hash = "sha256:73696ebf24936560cca79a2430cbc4f3dd23ac7bf46ed17f38e5e5e7657a6377"}, ] [package.dependencies] @@ -416,27 +341,28 @@ files = [ [[package]] name = "dill" -version = "0.3.7" +version = "0.3.8" description = "serialize all of Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, - {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, ] [package.extras] graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "docutils" -version = "0.19" +version = "0.20.1" description = "Docutils -- Python Documentation Utilities" optional = false python-versions = ">=3.7" files = [ - {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, - {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] [[package]] @@ -481,22 +407,6 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] -[[package]] -name = "flake8" -version = "7.0.0" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"}, - {file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.2.0,<3.3.0" - [[package]] name = "idna" version = "3.6" @@ -640,91 +550,90 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] name = "marshmallow" -version = "3.20.2" +version = "3.21.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.8" files = [ - {file = "marshmallow-3.20.2-py3-none-any.whl", hash = "sha256:c21d4b98fee747c130e6bc8f45c4b3199ea66bc00c12ee1f639f0aeca034d5e9"}, - {file = "marshmallow-3.20.2.tar.gz", hash = "sha256:4c1daff273513dc5eb24b219a8035559dc573c8f322558ef85f5438ddd1236dd"}, + {file = "marshmallow-3.21.1-py3-none-any.whl", hash = "sha256:f085493f79efb0644f270a9bf2892843142d80d7174bbbd2f3713f2a589dc633"}, + {file = "marshmallow-3.21.1.tar.gz", hash = "sha256:4e65e9e0d80fc9e609574b9983cf32579f305c718afb30d7233ab818571768c3"}, ] [package.dependencies] packaging = ">=17.0" [package.extras] -dev = ["pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"] -docs = ["alabaster (==0.7.15)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"] -lint = ["pre-commit (>=2.4,<4.0)"] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +docs = ["alabaster (==0.7.16)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==4.0.0)", "sphinx-version-warning (==1.1.2)"] tests = ["pytest", "pytz", "simplejson"] [[package]] @@ -801,7 +710,6 @@ files = [ [package.dependencies] mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = ">=4.1.0" [package.extras] @@ -860,47 +768,47 @@ files = [ [[package]] name = "numpy" -version = "1.26.3" +version = "1.26.4" description = "Fundamental package for array computing in Python" optional = true python-versions = ">=3.9" files = [ - {file = "numpy-1.26.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:806dd64230dbbfaca8a27faa64e2f414bf1c6622ab78cc4264f7f5f028fee3bf"}, - {file = "numpy-1.26.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f98011ba4ab17f46f80f7f8f1c291ee7d855fcef0a5a98db80767a468c85cd"}, - {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d45b3ec2faed4baca41c76617fcdcfa4f684ff7a151ce6fc78ad3b6e85af0a6"}, - {file = "numpy-1.26.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd2b45bf079d9ad90377048e2747a0c82351989a2165821f0c96831b4a2a54b"}, - {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:211ddd1e94817ed2d175b60b6374120244a4dd2287f4ece45d49228b4d529178"}, - {file = "numpy-1.26.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1240f767f69d7c4c8a29adde2310b871153df9b26b5cb2b54a561ac85146485"}, - {file = "numpy-1.26.3-cp310-cp310-win32.whl", hash = "sha256:21a9484e75ad018974a2fdaa216524d64ed4212e418e0a551a2d83403b0531d3"}, - {file = "numpy-1.26.3-cp310-cp310-win_amd64.whl", hash = "sha256:9e1591f6ae98bcfac2a4bbf9221c0b92ab49762228f38287f6eeb5f3f55905ce"}, - {file = "numpy-1.26.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b831295e5472954104ecb46cd98c08b98b49c69fdb7040483aff799a755a7374"}, - {file = "numpy-1.26.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e87562b91f68dd8b1c39149d0323b42e0082db7ddb8e934ab4c292094d575d6"}, - {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c66d6fec467e8c0f975818c1796d25c53521124b7cfb760114be0abad53a0a2"}, - {file = "numpy-1.26.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f25e2811a9c932e43943a2615e65fc487a0b6b49218899e62e426e7f0a57eeda"}, - {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:af36e0aa45e25c9f57bf684b1175e59ea05d9a7d3e8e87b7ae1a1da246f2767e"}, - {file = "numpy-1.26.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:51c7f1b344f302067b02e0f5b5d2daa9ed4a721cf49f070280ac202738ea7f00"}, - {file = "numpy-1.26.3-cp311-cp311-win32.whl", hash = "sha256:7ca4f24341df071877849eb2034948459ce3a07915c2734f1abb4018d9c49d7b"}, - {file = "numpy-1.26.3-cp311-cp311-win_amd64.whl", hash = "sha256:39763aee6dfdd4878032361b30b2b12593fb445ddb66bbac802e2113eb8a6ac4"}, - {file = "numpy-1.26.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a7081fd19a6d573e1a05e600c82a1c421011db7935ed0d5c483e9dd96b99cf13"}, - {file = "numpy-1.26.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12c70ac274b32bc00c7f61b515126c9205323703abb99cd41836e8125ea0043e"}, - {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f784e13e598e9594750b2ef6729bcd5a47f6cfe4a12cca13def35e06d8163e3"}, - {file = "numpy-1.26.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f24750ef94d56ce6e33e4019a8a4d68cfdb1ef661a52cdaee628a56d2437419"}, - {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:77810ef29e0fb1d289d225cabb9ee6cf4d11978a00bb99f7f8ec2132a84e0166"}, - {file = "numpy-1.26.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8ed07a90f5450d99dad60d3799f9c03c6566709bd53b497eb9ccad9a55867f36"}, - {file = "numpy-1.26.3-cp312-cp312-win32.whl", hash = "sha256:f73497e8c38295aaa4741bdfa4fda1a5aedda5473074369eca10626835445511"}, - {file = "numpy-1.26.3-cp312-cp312-win_amd64.whl", hash = "sha256:da4b0c6c699a0ad73c810736303f7fbae483bcb012e38d7eb06a5e3b432c981b"}, - {file = "numpy-1.26.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1666f634cb3c80ccbd77ec97bc17337718f56d6658acf5d3b906ca03e90ce87f"}, - {file = "numpy-1.26.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18c3319a7d39b2c6a9e3bb75aab2304ab79a811ac0168a671a62e6346c29b03f"}, - {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b7e807d6888da0db6e7e75838444d62495e2b588b99e90dd80c3459594e857b"}, - {file = "numpy-1.26.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d362e17bcb0011738c2d83e0a65ea8ce627057b2fdda37678f4374a382a137"}, - {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b8c275f0ae90069496068c714387b4a0eba5d531aace269559ff2b43655edd58"}, - {file = "numpy-1.26.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cc0743f0302b94f397a4a65a660d4cd24267439eb16493fb3caad2e4389bccbb"}, - {file = "numpy-1.26.3-cp39-cp39-win32.whl", hash = "sha256:9bc6d1a7f8cedd519c4b7b1156d98e051b726bf160715b769106661d567b3f03"}, - {file = "numpy-1.26.3-cp39-cp39-win_amd64.whl", hash = "sha256:867e3644e208c8922a3be26fc6bbf112a035f50f0a86497f98f228c50c607bb2"}, - {file = "numpy-1.26.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3c67423b3703f8fbd90f5adaa37f85b5794d3366948efe9a5190a5f3a83fc34e"}, - {file = "numpy-1.26.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f47ee566d98849323f01b349d58f2557f02167ee301e5e28809a8c0e27a2d0"}, - {file = "numpy-1.26.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8474703bffc65ca15853d5fd4d06b18138ae90c17c8d12169968e998e448bb5"}, - {file = "numpy-1.26.3.tar.gz", hash = "sha256:697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] [[package]] @@ -929,17 +837,6 @@ files = [ qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] testing = ["docopt", "pytest (<6.0.0)"] -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - [[package]] name = "pexpect" version = "4.9.0" @@ -1052,28 +949,28 @@ xmp = ["defusedxml"] [[package]] name = "platformdirs" -version = "4.1.0" +version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"}, - {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"}, + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" -version = "1.3.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] [package.extras] @@ -1119,17 +1016,6 @@ files = [ [package.extras] tests = ["pytest"] -[[package]] -name = "pycodestyle" -version = "2.11.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, -] - [[package]] name = "pydata-sphinx-theme" version = "0.14.4" @@ -1157,17 +1043,6 @@ dev = ["nox", "pre-commit", "pydata-sphinx-theme[doc,test]", "pyyaml"] doc = ["ablog (>=0.11.0rc2)", "colorama", "ipykernel", "ipyleaflet", "jupyter_sphinx", "jupyterlite-sphinx", "linkify-it-py", "matplotlib", "myst-parser", "nbsphinx", "numpy", "numpydoc", "pandas", "plotly", "rich", "sphinx-autoapi (>=3.0.0)", "sphinx-copybutton", "sphinx-design", "sphinx-favicon (>=1.0.1)", "sphinx-sitemap", "sphinx-togglebutton", "sphinxcontrib-youtube (<1.4)", "sphinxext-rediraffe", "xarray"] test = ["pytest", "pytest-cov", "pytest-regressions"] -[[package]] -name = "pyflakes" -version = "3.2.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, - {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, -] - [[package]] name = "pygments" version = "2.17.2" @@ -1185,27 +1060,25 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" -version = "3.0.3" +version = "3.1.0" description = "python code static checker" optional = false python-versions = ">=3.8.0" files = [ - {file = "pylint-3.0.3-py3-none-any.whl", hash = "sha256:7a1585285aefc5165db81083c3e06363a27448f6b467b3b0f30dbd0ac1f73810"}, - {file = "pylint-3.0.3.tar.gz", hash = "sha256:58c2398b0301e049609a8429789ec6edf3aabe9b6c5fec916acd18639c16de8b"}, + {file = "pylint-3.1.0-py3-none-any.whl", hash = "sha256:507a5b60953874766d8a366e8e8c7af63e058b26345cfcb5f91f89d987fd6b74"}, + {file = "pylint-3.1.0.tar.gz", hash = "sha256:6a69beb4a6f63debebaab0a3477ecd0f559aa726af4954fc948c51f7a2549e23"}, ] [package.dependencies] -astroid = ">=3.0.1,<=3.1.0-dev0" +astroid = ">=3.1.0,<=3.2.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ - {version = ">=0.2", markers = "python_version < \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} tomlkit = ">=0.10.1" [package.extras] @@ -1274,13 +1147,13 @@ testing = ["filelock"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -1288,13 +1161,13 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2023.3.post1" +version = "2024.1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, - {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] [[package]] @@ -1318,6 +1191,32 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "ruff" +version = "0.3.0" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.3.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:7deb528029bacf845bdbb3dbb2927d8ef9b4356a5e731b10eef171e3f0a85944"}, + {file = "ruff-0.3.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e1e0d4381ca88fb2b73ea0766008e703f33f460295de658f5467f6f229658c19"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f7dbba46e2827dfcb0f0cc55fba8e96ba7c8700e0a866eb8cef7d1d66c25dcb"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23dbb808e2f1d68eeadd5f655485e235c102ac6f12ad31505804edced2a5ae77"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ef655c51f41d5fa879f98e40c90072b567c666a7114fa2d9fe004dffba00932"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d0d3d7ef3d4f06433d592e5f7d813314a34601e6c5be8481cccb7fa760aa243e"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b08b356d06a792e49a12074b62222f9d4ea2a11dca9da9f68163b28c71bf1dd4"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9343690f95710f8cf251bee1013bf43030072b9f8d012fbed6ad702ef70d360a"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1f3ed501a42f60f4dedb7805fa8d4534e78b4e196f536bac926f805f0743d49"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:cc30a9053ff2f1ffb505a585797c23434d5f6c838bacfe206c0e6cf38c921a1e"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5da894a29ec018a8293d3d17c797e73b374773943e8369cfc50495573d396933"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:755c22536d7f1889be25f2baf6fedd019d0c51d079e8417d4441159f3bcd30c2"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dd73fe7f4c28d317855da6a7bc4aa29a1500320818dd8f27df95f70a01b8171f"}, + {file = "ruff-0.3.0-py3-none-win32.whl", hash = "sha256:19eacceb4c9406f6c41af806418a26fdb23120dfe53583df76d1401c92b7c14b"}, + {file = "ruff-0.3.0-py3-none-win_amd64.whl", hash = "sha256:128265876c1d703e5f5e5a4543bd8be47c73a9ba223fd3989d4aa87dd06f312f"}, + {file = "ruff-0.3.0-py3-none-win_arm64.whl", hash = "sha256:e3a4a6d46aef0a84b74fcd201a4401ea9a6cd85614f6a9435f2d33dd8cefbf83"}, + {file = "ruff-0.3.0.tar.gz", hash = "sha256:0886184ba2618d815067cf43e005388967b67ab9c80df52b32ec1152ab49f53a"}, +] + [[package]] name = "six" version = "1.16.0" @@ -1353,20 +1252,20 @@ files = [ [[package]] name = "sphinx" -version = "6.2.1" +version = "7.1.2" description = "Python documentation generator" optional = false python-versions = ">=3.8" files = [ - {file = "Sphinx-6.2.1.tar.gz", hash = "sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b"}, - {file = "sphinx-6.2.1-py3-none-any.whl", hash = "sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912"}, + {file = "sphinx-7.1.2-py3-none-any.whl", hash = "sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe"}, + {file = "sphinx-7.1.2.tar.gz", hash = "sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f"}, ] [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.20" +docutils = ">=0.18.1,<0.21" imagesize = ">=1.3" importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" @@ -1507,13 +1406,13 @@ files = [ [[package]] name = "tomlkit" -version = "0.12.3" +version = "0.12.4" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"}, - {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"}, + {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, + {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, ] [[package]] @@ -1555,13 +1454,13 @@ files = [ [[package]] name = "types-requests" -version = "2.31.0.20240106" +version = "2.31.0.20240218" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.31.0.20240106.tar.gz", hash = "sha256:0e1c731c17f33618ec58e022b614a1a2ecc25f7dc86800b36ef341380402c612"}, - {file = "types_requests-2.31.0.20240106-py3-none-any.whl", hash = "sha256:da997b3b6a72cc08d09f4dba9802fdbabc89104b35fe24ee588e674037689354"}, + {file = "types-requests-2.31.0.20240218.tar.gz", hash = "sha256:f1721dba8385958f504a5386240b92de4734e047a08a40751c1654d1ac3349c5"}, + {file = "types_requests-2.31.0.20240218-py3-none-any.whl", hash = "sha256:a82807ec6ddce8f00fe0e949da6d6bc1fbf1715420218a9640d695f70a9e5a9b"}, ] [package.dependencies] @@ -1569,13 +1468,13 @@ urllib3 = ">=2" [[package]] name = "typing-extensions" -version = "4.9.0" +version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, - {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] @@ -1595,17 +1494,18 @@ typing-extensions = ">=3.7.4" [[package]] name = "urllib3" -version = "2.1.0" +version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, - {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -1641,4 +1541,4 @@ segmentation = ["numpy", "numpy", "pillow"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "bcf3536bfbdf479263ea06bfab09fec53ce5d165e22e2e1125bd1cf37040bd24" +content-hash = "31751e693e079aa24e82b5ddc2bb807b19a621cf431ec83da7a40ce04cb782f9" diff --git a/pyproject.toml b/pyproject.toml index d3911996..471c7230 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,16 +40,12 @@ pytest = "^7" pytest-xdist = "*" pytest-cov = "*" -[tool.poetry.group.formatter.dependencies] -isort = "*" -autoflake = "*" -black = "^23" [tool.poetry.group.linter.dependencies] # pythonバージョンを指定している理由:lintは開発環境と同じPythonバージョンで実行するため。また古いPythonバージョンにサポートしていないライブラリのバージョンがあるため -mypy = {version="^1", python = ">=3.10"} -flake8 = {version="^7", python = ">=3.10"} -pylint = {version="^3", python = ">=3.10"} +ruff = {version="^0.3", python = ">=3.11"} +mypy = {version="^1", python = ">=3.11"} +pylint = {version="^3", python = ">=3.11"} # type stub package types-requests = "*" @@ -58,7 +54,7 @@ types-dataclasses = "*" [tool.poetry.group.documentation.dependencies] -sphinx = "^6" +sphinx = "^7" pydata-sphinx-theme = ">=0.13.3" @@ -70,14 +66,6 @@ optional = true ipython = "*" -[tool.black] -line-length = 120 - -[tool.isort] -profile = "black" -line_length = 120 -skip="annofabapi/__init__.py" - [tool.mypy] # スタブが無いパッケージのエラーは無視させる.サードパーティのライブラリに型情報がないケースもあるため ignore_missing_imports = true @@ -86,6 +74,70 @@ check_untyped_defs = true plugins = ["numpy.typing.mypy_plugin"] +[tool.ruff] +target-version = "py38" +line-length = 150 +exclude = ["annofabapi/__init__.py"] + +[tool.ruff.lint] +ignore = [ +# "G004", # `logging-f-string` : loggingでf-stringを使いたいので無視する + "FA100", # `future-rewritable-type-annotation` : Python3.8をサポートしている間は無視する。 + "PD002", #すでにpandasで`inplace=True`はいろんなところで使っているため + "RUF001", # 全角記号など`ambiguous unicode character`も使いたいため + "RUF002",# 全角記号など`ambiguous unicode character`も使いたいため + "RUF003",# 全角記号など`ambiguous unicode character`も使いたいため + "PLC1901", # compare-to-empty-string : `if a == "`のように空文字列で直接比較したいときがあるため + "PLR2004", # magic-value-comparison: listのサイズで判定するときがよくあるため + "ANN101", # missing-type-self: 引数selfには型ヒントは付けていないため + "ANN102", # missing-type-cls: 引数clsには型ヒントは付けていないため + "ANN002", # missing-type-args + "ANN003", # missing-type-kwargs + "ERA", # : 役立つこともあるが、コメントアウトしていないコードも警告されるので無視する + "TD", # flake8-todos + "FIX", # flake8-fixme + + # いずれ無視しないようにする + "ANN201", # missing-return-type-public-function: + "ANN202", # missing-return-type-private-function: + "PLR", # pylint Refactor + + # 以下のルールはコードに合っていないので無効化した + "RSE", # flake8-raise + "D", # pydocstyle, Docstringを中途半端にしか書いていないので、除外する + "C90", # mccabe + "T20", # flake8-print + "SLF", # flake8-self + "BLE", # flake8-blind-except + "FBT", # flake8-boolean-trap + "TRY", # tryceratops + "COM", # flake8-commas + "S", # flake8-bandit + "EM",#flake8-errmsg + "EXE", # flake8-executable + "ICN", # flake8-import-conventions + "RET",#flake8-return + "SIM",#flake8-simplify + "TCH", # flake8-type-checking + "PTH", #pathlibを使わないコードが多いので、除外する + "ISC", #flake8-implicit-str-concat + "N", # pep8-naming + "PT", # flake8-pytest-style +] + +select = [ + "ALL" +] + + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.lint.pylint] +max-args = 10 + + + [tool.poetry-dynamic-versioning] enable = true format = "{base}" diff --git a/tests/create_test_project.py b/tests/create_test_project.py index 7fb574ae..824e3ea3 100644 --- a/tests/create_test_project.py +++ b/tests/create_test_project.py @@ -94,19 +94,13 @@ def create_input_data(self, project_id: str, input_data_id: str, image_path: str "input_data_name": "Annofab Logo Image", "input_data_path": "https://annofab.com/images/logo.png", } - self.service.wrapper.put_input_data_from_file( - project_id, input_data_id=input_data_id, file_path=image_path, request_body=request_body - ) + self.service.wrapper.put_input_data_from_file(project_id, input_data_id=input_data_id, file_path=image_path, request_body=request_body) logger.debug(f"入力データを登録しました。input_data_id={input_data_id}") return - def create_supplementary_data( - self, project_id: str, input_data_id: str, supplementary_data_id: str, supplementary_data_path: str - ): + def create_supplementary_data(self, project_id: str, input_data_id: str, supplementary_data_id: str, supplementary_data_path: str): supplementary_data_list, _ = self.service.api.get_supplementary_data_list(project_id, input_data_id) - old_supplementary_data = first_true( - supplementary_data_list, pred=lambda e: e["supplementary_data_id"] == supplementary_data_id - ) + old_supplementary_data = first_true(supplementary_data_list, pred=lambda e: e["supplementary_data_id"] == supplementary_data_id) if old_supplementary_data is not None: logger.debug(f"補助情報はすでに存在していたので、登録しません。supplementary_data_id={supplementary_data_id}") return @@ -145,9 +139,7 @@ def upload_instruction(self, project_id: str): logger.debug("作業ガイドはすでに登録されているので、登録しません。") return - image_url = self.service.wrapper.upload_instruction_image( - project_id, image_id=str(uuid.uuid4()), file_path="tests/data/lenna.png" - ) + image_url = self.service.wrapper.upload_instruction_image(project_id, image_id=str(uuid.uuid4()), file_path="tests/data/lenna.png") html_data = f"Test Instruction " last_updated_datetime = histories[0]["updated_datetime"] if len(histories) > 0 else None put_request_body = {"html": html_data, "last_updated_datetime": last_updated_datetime} @@ -218,9 +210,7 @@ def add_inspection_comment( } ] - return self.service.api.batch_update_inspections( - project_id, task["task_id"], input_data_id, request_body=req_inspection - )[0] + return self.service.api.batch_update_inspections(project_id, task["task_id"], input_data_id, request_body=req_inspection)[0] def create_inspection_comment(self, project_id: str, task_id: str, input_data_id: str): """ @@ -237,9 +227,7 @@ def create_inspection_comment(self, project_id: str, task_id: str, input_data_id task, _ = self.service.api.get_task(project_id, task_id) if task["phase"] != TaskPhase.ACCEPTANCE.value: # 受け入れフェーズに移行する - self.service.wrapper.change_task_operator( - project_id, task_id, operator_account_id=self.service.api.account_id - ) + self.service.wrapper.change_task_operator(project_id, task_id, operator_account_id=self.service.api.account_id) self.service.wrapper.change_task_status_to_working(project_id, task_id) self.service.wrapper.complete_task(project_id, task_id) @@ -292,11 +280,17 @@ def main(self, organization_name: str, project_title: Optional[str] = None) -> N def parse_args(): parser = ArgumentParser( - description="annofabapiのテスト用プロジェクトを生成します。", formatter_class=argparse.ArgumentDefaultsHelpFormatter + description="annofabapiのテスト用プロジェクトを生成します。", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) parser.add_argument("-org", "--organization", type=str, required=True, help="プロジェクトを作成する対象の組織を指定してください。") - parser.add_argument("--project_title", type=str, default=DEFAULT_PROJECT_TITLE, help="作成するプロジェクトのタイトルを指定してください。") + parser.add_argument( + "--project_title", + type=str, + default=DEFAULT_PROJECT_TITLE, + help="作成するプロジェクトのタイトルを指定してください。", + ) return parser.parse_args() diff --git a/tests/test_api.py b/tests/test_api.py index e6038832..fd3bacd0 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2,6 +2,7 @@ AnnofabApi, Wrapperのテストコード """ + from __future__ import annotations import configparser @@ -68,15 +69,13 @@ def test_wrapper_get_all_annotation_list(self): def test_get_annotation(self): annotation, _ = api.get_annotation(project_id, task_id, self.input_data_id) - assert type(annotation) == dict + assert type(annotation) == dict # noqa: E721 # dataclassに変換できることの確認 SimpleAnnotation.from_dict(annotation) def test_get_editor_annotation(self): - editor_annotation, _ = api.get_editor_annotation( - project_id, task_id, self.input_data_id, query_params={"v": "2"} - ) - assert type(editor_annotation) == dict + editor_annotation, _ = api.get_editor_annotation(project_id, task_id, self.input_data_id, query_params={"v": "2"}) + assert type(editor_annotation) == dict # noqa: E721 # dataclassに変換できることの確認 AnnotationV2Output.from_dict(editor_annotation) @@ -97,7 +96,7 @@ def test_wrapper_copy_annotation(self): src = TaskFrameKey(project_id, task_id, self.input_data_id) dest = TaskFrameKey(project_id, task_id, self.input_data_id) result = wrapper.copy_annotation(src, dest) - assert result == True + assert result == True # noqa: E712 def test_wrapper_put_annotation_for_simple_annotation_json(self): input_data_id = test_wrapper.get_first_input_data_id_in_task(project_id, task_id) @@ -115,7 +114,7 @@ def test_wrapper_put_annotation_for_simple_annotation_json(self): class TestAnnotationSpecs: def test_get_annotation_specs(self): annotation_spec, _ = api.get_annotation_specs(project_id, query_params={"v": "3"}) - assert type(annotation_spec) == dict + assert type(annotation_spec) == dict # noqa: E721 # dataclassに変換できることの確認 AnnotationSpecsV3.from_dict(annotation_spec) @@ -130,11 +129,11 @@ def test_put_annotation_specs(self): "last_updated_datetime": last_updated_datetime, } puted_annotation_spec, _ = api.put_annotation_specs(project_id, request_body=request_body) - assert type(puted_annotation_spec) == dict + assert type(puted_annotation_spec) == dict # noqa: E721 def test_get_annotation_specs_histories(self): annotation_specs_histories = api.get_annotation_specs_histories(project_id)[0] - assert type(annotation_specs_histories) == list + assert type(annotation_specs_histories) == list # noqa: E721 def test_get_annotation_specs_relation(self): result = wrapper.get_annotation_specs_relation(project_id, project_id) @@ -182,7 +181,7 @@ def test_put_get_delete_comment(self): comments, _ = api.get_comments(project_id, task_id, input_data_id) # dataclassに変換できることの確認 - dc_comments = Comment.schema().load(comments, many=True) + Comment.schema().load(comments, many=True) assert first_true(comments, pred=lambda e: e["comment_id"] == comment_id) is not None @@ -212,11 +211,11 @@ def setup_class(cls): cls.input_data_id = test_wrapper.get_first_input_data_id_in_task(project_id, task_id) def test_wrapper_get_input_data_list(self): - assert type(wrapper.get_all_input_data_list(project_id, {"input_data_name": "foo"})) == list + assert type(wrapper.get_all_input_data_list(project_id, {"input_data_name": "foo"})) == list # noqa: E721 def test_get_input_data(self): dict_input_data, _ = api.get_input_data(project_id, self.input_data_id) - assert type(dict_input_data) == dict + assert type(dict_input_data) == dict # noqa: E721 # dataclassに変換できることの確認 InputData.from_dict(dict_input_data) @@ -224,8 +223,8 @@ def test_wrapper_put_input_data_from_file_and_delete_input_data(self): test_input_data_id = str(uuid.uuid4()) print("") print(f"put_input_data: input_data_id={test_input_data_id}") - assert type(wrapper.put_input_data_from_file(project_id, test_input_data_id, f"{test_dir}/lenna.png")) == dict - assert type(api.delete_input_data(project_id, test_input_data_id)[0]) == dict + assert type(wrapper.put_input_data_from_file(project_id, test_input_data_id, f"{test_dir}/lenna.png")) == dict # noqa: E721 + assert type(api.delete_input_data(project_id, test_input_data_id)[0]) == dict # noqa: E721 def test_put_input_data_from_file_and_batch_update_inputs(self): test_input_data_id = str(uuid.uuid4()) @@ -234,12 +233,12 @@ def test_put_input_data_from_file_and_batch_update_inputs(self): wrapper.put_input_data_from_file(project_id, test_input_data_id, f"{test_dir}/lenna.png") request_body = [{"project_id": project_id, "input_data_id": test_input_data_id, "_type": "Delete"}] - assert type(api.batch_update_inputs(project_id, request_body=request_body)[0]) == list + assert type(api.batch_update_inputs(project_id, request_body=request_body)[0]) == list # noqa: E721 class TestInstruction: def test_wrapper_get_latest_instruction(self): - assert type(wrapper.get_latest_instruction(project_id)) == dict + assert type(wrapper.get_latest_instruction(project_id)) == dict # noqa: E721 def test_get_instruction_history(self): histories = api.get_instruction_history(project_id)[0] @@ -255,7 +254,7 @@ def test_wrapper_upload_instruction_image_and_delete_instruction_image(self): def test_get_instruction_images(self): image_list = api.get_instruction_images(project_id)[0] - assert type(image_list) == list + assert type(image_list) == list # noqa: E721 def test_put_instruction(self): str_now = datetime.datetime.now().isoformat() @@ -263,7 +262,7 @@ def test_put_instruction(self): histories = api.get_instruction_history(project_id)[0] put_request_body = {"html": html_data, "last_updated_datetime": histories[0]["updated_datetime"]} - assert type(api.put_instruction(project_id, request_body=put_request_body)[0]) == dict + assert type(api.put_instruction(project_id, request_body=put_request_body)[0]) == dict # noqa: E721 class TestJob: @@ -276,11 +275,11 @@ def test_scenario(self): job_id = job["job_id"] job_list = wrapper.get_all_project_job(project_id, {"type": job_type}) - assert wrapper.can_execute_job(project_id, ProjectJobType.GEN_TASKS_LIST) == False - assert wrapper.job_in_progress(project_id, ProjectJobType.GEN_TASKS_LIST) == True + assert wrapper.can_execute_job(project_id, ProjectJobType.GEN_TASKS_LIST) == False # noqa: E712 + assert wrapper.job_in_progress(project_id, ProjectJobType.GEN_TASKS_LIST) == True # noqa: E712 # dataclassに変換できることの確認 - dc_job_list = ProjectJobInfo.schema().load(job_list, many=True) + dc_job_list = ProjectJobInfo.schema().load(job_list, many=True) # noqa: F841 assert first_true(job_list, pred=lambda e: e["job_id"] == job_id) is not None # ジョブが終了するまで待つ @@ -308,7 +307,7 @@ def test_login(self): class TestMy: def test_get_my_account(self): my_account, _ = api.get_my_account() - assert type(my_account) == dict + assert type(my_account) == dict # noqa: E721 def test_get_my_project_members(self): my_project_members, _ = api.get_my_project_members() @@ -324,7 +323,7 @@ def test_get_my_projects(self): def test_get_my_member_in_project(self): my_member_in_project, _ = api.get_my_member_in_project(project_id) - assert type(my_member_in_project) == dict + assert type(my_member_in_project) == dict # noqa: E721 class TestOrganization: @@ -336,12 +335,12 @@ def setup_class(cls): def test_get_organization(self): organization, _ = api.get_organization(self.organization_name) - assert type(organization) == dict + assert type(organization) == dict # noqa: E721 # dataclassに変換できることの確認 Organization.from_dict(organization) def test_get_organization_activity(self): - assert type(api.get_organization_activity(self.organization_name)[0]) == dict + assert type(api.get_organization_activity(self.organization_name)[0]) == dict # noqa: E721 def test_wrapper_get_all_projects_of_organization(self): assert len(wrapper.get_all_projects_of_organization(self.organization_name)) > 0 @@ -362,7 +361,7 @@ def test_wrapper_get_all_organization_members(self): def test_get_organization_member(self): organization_member = api.get_organization_member(self.organization_name, api.login_user_id)[0] - assert type(organization_member) == dict + assert type(organization_member) == dict # noqa: E721 def test_update_organization_member_role(self): organization_member = api.get_organization_member(self.organization_name, api.login_user_id)[0] @@ -373,16 +372,16 @@ def test_update_organization_member_role(self): class TestProject: def test_get_project(self): dict_project, _ = api.get_project(project_id) - assert type(dict_project) == dict + assert type(dict_project) == dict # noqa: E721 # dataclassに変換できることの確認 Project.from_dict(dict_project) def test_get_organization_of_project(self): - assert type(api.get_organization_of_project(project_id)[0]) == dict + assert type(api.get_organization_of_project(project_id)[0]) == dict # noqa: E721 @pytest.mark.submitting_job def test_post_project_tasks_update(self): - assert type(api.post_project_tasks_update(project_id)[0]) == dict + assert type(api.post_project_tasks_update(project_id)[0]) == dict # noqa: E721 def test_wrapper_download_project_inputs_url(self): assert wrapper.download_project_inputs_url(project_id, f"{out_dir}/inputs.json").startswith("https://") @@ -391,14 +390,10 @@ def test_wrapper_download_project_tasks_url(self): assert wrapper.download_project_tasks_url(project_id, f"{out_dir}/tasks.json").startswith("https://") def test_wrapper_download_project_task_history_events_url(self): - assert wrapper.download_project_task_history_events_url( - project_id, f"{out_dir}/task_history_events.json" - ).startswith("https://") + assert wrapper.download_project_task_history_events_url(project_id, f"{out_dir}/task_history_events.json").startswith("https://") def test_wrapper_download_project_task_histories_url(self): - assert wrapper.download_project_task_histories_url(project_id, f"{out_dir}/task_histories.json").startswith( - "https://" - ) + assert wrapper.download_project_task_histories_url(project_id, f"{out_dir}/task_histories.json").startswith("https://") def test_wrapper_download_project_comments_url(self): assert wrapper.download_project_comments_url(project_id, f"{out_dir}/comments.json").startswith("https://") @@ -407,7 +402,7 @@ def test_wrapper_download_project_comments_url(self): class TestProjectMember: def test_get_project_member(self): my_member = api.get_project_member(project_id, api.login_user_id)[0] - assert type(my_member) == dict + assert type(my_member) == dict # noqa: E721 def test_wrapper_get_all_project_members(self): member_list = wrapper.get_all_project_members(project_id) @@ -418,86 +413,82 @@ def test_wrapper_get_all_project_members(self): class TestStatistics: def test_wrapper_get_account_daily_statistics(self): actual = wrapper.get_account_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-06-30") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 最大取得期間の3ヶ月を超えている場合 actual = wrapper.get_account_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-07-01") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 開始日と終了日を指定しない場合 actual = wrapper.get_account_daily_statistics(project_id) - assert type(actual) == list + assert type(actual) == list # noqa: E721 def test_wrapper_get_inspection_daily_statistics(self): actual = wrapper.get_inspection_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-06-30") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 最大取得期間の3ヶ月を超えている場合 actual = wrapper.get_inspection_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-07-01") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 開始日と終了日を指定しない場合 actual = wrapper.get_inspection_daily_statistics(project_id) - assert type(actual) == list + assert type(actual) == list # noqa: E721 def test_wrapper_get_phase_daily_statistics(self): actual = wrapper.get_phase_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-06-30") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 最大取得期間の3ヶ月を超えている場合 actual = wrapper.get_phase_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-07-01") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 開始日と終了日を指定しない場合 actual = wrapper.get_phase_daily_statistics(project_id) - assert type(actual) == list + assert type(actual) == list # noqa: E721 def test_wrapper_get_task_daily_statistics(self): actual = wrapper.get_task_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-06-30") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 最大取得期間の3ヶ月を超えている場合 actual = wrapper.get_task_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-07-01") - assert type(actual) == list + assert type(actual) == list # noqa: E721 # 開始日と終了日を指定しない場合 actual = wrapper.get_task_daily_statistics(project_id) - assert type(actual) == list + assert type(actual) == list # noqa: E721 def test_wrapper_get_worktime_daily_statistics(self): actual = wrapper.get_worktime_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-06-30") - assert type(actual) == dict + assert type(actual) == dict # noqa: E721 # 最大取得期間の3ヶ月を超えている場合 actual = wrapper.get_worktime_daily_statistics(project_id, from_date="2021-04-01", to_date="2021-07-01") - assert type(actual) == dict + assert type(actual) == dict # noqa: E721 # 開始日と終了日を指定しない場合 actual = wrapper.get_worktime_daily_statistics(project_id) - assert type(actual) == dict + assert type(actual) == dict # noqa: E721 def test_wrapper_get_worktime_daily_statistics_by_account(self): - actual = wrapper.get_worktime_daily_statistics_by_account( - project_id, account_id=api.account_id, from_date="2021-04-01", to_date="2021-06-30" - ) - assert type(actual) == dict + actual = wrapper.get_worktime_daily_statistics_by_account(project_id, account_id=api.account_id, from_date="2021-04-01", to_date="2021-06-30") + assert type(actual) == dict # noqa: E721 # 最大取得期間の3ヶ月を超えている場合 - actual = wrapper.get_worktime_daily_statistics_by_account( - project_id, account_id=api.account_id, from_date="2021-04-01", to_date="2021-07-01" - ) - assert type(actual) == dict + actual = wrapper.get_worktime_daily_statistics_by_account(project_id, account_id=api.account_id, from_date="2021-04-01", to_date="2021-07-01") + assert type(actual) == dict # noqa: E721 # 開始日と終了日を指定しない場合 actual = wrapper.get_worktime_daily_statistics_by_account( project_id, account_id=api.account_id, ) - assert type(actual) == dict + assert type(actual) == dict # noqa: E721 def test_wrapper_get_label_statistics(self): actual = wrapper.get_label_statistics(project_id) - assert type(actual) == list + assert type(actual) == list # noqa: E721 def test_graph_marker(self): old_markers, _ = api.get_markers(project_id) @@ -523,7 +514,7 @@ def test_graph_marker(self): def test_get_statistics_available_dates(self): content, _ = api.get_statistics_available_dates(project_id) - assert type(content) == list + assert type(content) == list # noqa: E721 class Testsupplementary: @@ -563,7 +554,7 @@ def setup_class(cls): cls.input_data_id = test_wrapper.get_first_input_data_id_in_task(project_id, task_id) def test_wraper_get_all_tasks(self): - assert type(wrapper.get_all_tasks(project_id, query_params={"task_id": "foo"})) == list + assert type(wrapper.get_all_tasks(project_id, query_params={"task_id": "foo"})) == list # noqa: E721 @pytest.mark.submitting_job def test_initiate_tasks_generation_by_csv(self): @@ -571,13 +562,13 @@ def test_initiate_tasks_generation_by_csv(self): test_task_id = str(uuid.uuid4()) create_csv_for_task(csv_file_path, test_task_id, self.input_data_id) content = wrapper.initiate_tasks_generation_by_csv(project_id, csv_file_path) - assert type(content) == dict + assert type(content) == dict # noqa: E721 def test_get_task(self): dict_task, _ = api.get_task(project_id, task_id) - assert type(dict_task) == dict + assert type(dict_task) == dict # noqa: E721 # dataclassに変換できることの確認 - task = Task.from_dict(dict_task) + task = Task.from_dict(dict_task) # noqa: F841 def test_put_task_and_delete_task(self): test_task_id = str(uuid.uuid4()) @@ -585,14 +576,14 @@ def test_put_task_and_delete_task(self): print("") print(f"put_task: task_id={task_id}") test_task_data = api.put_task(project_id, test_task_id, request_body=request_body)[0] - assert type(test_task_data) == dict + assert type(test_task_data) == dict # noqa: E721 - assert type(api.delete_task(project_id, test_task_id)[0]) == dict + assert type(api.delete_task(project_id, test_task_id)[0]) == dict # noqa: E721 @pytest.mark.side_effect def test_assign_task(self): request_body = {"request_type": {"phase": "annotation", "_type": "Random"}} - assert type(api.assign_tasks(project_id, request_body=request_body)[0]) == list + assert type(api.assign_tasks(project_id, request_body=request_body)[0]) == list # noqa: E721 def test_operate_task_in_change_task_status_to_break(self): task = wrapper.change_task_status_to_break(project_id, task_id) @@ -609,16 +600,16 @@ def test_batch_update_tasks(self): request_body = {"input_data_id_list": [self.input_data_id]} print("") print(f"put_task: task_id={task_id}") - test_task_data = api.put_task(project_id, test_task_id, request_body=request_body)[0] + test_task_data = api.put_task(project_id, test_task_id, request_body=request_body)[0] # noqa: F841 request_body2 = [{"project_id": project_id, "task_id": test_task_id, "_type": "Delete"}] content = api.batch_update_tasks(project_id, request_body=request_body2)[0] - assert type(content) == list + assert type(content) == list # noqa: E721 def test_patch_tasks_metadata(self): request_body = {task_id: {"alice": "foo", "bob": 1.23, "charlie": False}} content, _ = api.patch_tasks_metadata(project_id, request_body) - assert type(content) == dict + assert type(content) == dict # noqa: E721 class TestWebhook: @@ -646,9 +637,7 @@ def test_scenario(self): assert first_true(webhook_list, pred=lambda e: e["webhook_id"] == test_webhook_id) is not None # Webhookのテスト実行 - test_webhook_response, _ = api.test_webhook( - project_id, test_webhook_id, request_body={"placeholders": {"PROJECT_ID": "foo"}} - ) + test_webhook_response, _ = api.test_webhook(project_id, test_webhook_id, request_body={"placeholders": {"PROJECT_ID": "foo"}}) assert test_webhook_response["result"] == "success" assert test_webhook_response["response_status"] == 200 @@ -672,38 +661,38 @@ def setup_class(cls): cls.input_data_id = test_wrapper.get_first_input_data_id_in_task(project_id, task_id) def test_get_input_data_or_none(self): - assert type(wrapper.get_input_data_or_none(project_id, self.input_data_id)) == dict + assert type(wrapper.get_input_data_or_none(project_id, self.input_data_id)) == dict # noqa: E721 assert wrapper.get_input_data_or_none(project_id, "not-exists") is None assert wrapper.get_input_data_or_none("not-exists", self.input_data_id) is None def test_get_organization_or_none(self): - assert type(wrapper.get_organization_or_none(self.organization_name)) == dict + assert type(wrapper.get_organization_or_none(self.organization_name)) == dict # noqa: E721 assert wrapper.get_organization_or_none("not-exists") is None def test_get_organization_member_or_none(self): - assert type(wrapper.get_organization_member_or_none(self.organization_name, api.login_user_id)) == dict + assert type(wrapper.get_organization_member_or_none(self.organization_name, api.login_user_id)) == dict # noqa: E721 assert wrapper.get_organization_member_or_none("not-exists", api.login_user_id) is None assert wrapper.get_organization_member_or_none(self.organization_name, "not-exists") is None def test_get_project_or_none(self): - assert type(wrapper.get_project_or_none(project_id)) == dict + assert type(wrapper.get_project_or_none(project_id)) == dict # noqa: E721 assert wrapper.get_project_or_none("not-exists") is None def test_get_project_member_or_none(self): - assert type(wrapper.get_project_member_or_none(project_id, api.login_user_id)) == dict + assert type(wrapper.get_project_member_or_none(project_id, api.login_user_id)) == dict # noqa: E721 assert wrapper.get_project_member_or_none(project_id, "not-exists") is None assert wrapper.get_project_member_or_none("not-exists", api.login_user_id) is None def test_get_task_or_none(self): - assert type(wrapper.get_task_or_none(project_id, task_id)) == dict + assert type(wrapper.get_task_or_none(project_id, task_id)) == dict # noqa: E721 assert wrapper.get_task_or_none(project_id, "not-exists") is None @@ -751,4 +740,4 @@ def test_request_get_with_cookie_failed(self): class TestProperty: def test_account_id(self): account_id = api.account_id - assert type(account_id) == str and len(account_id) > 0 + assert type(account_id) == str and len(account_id) > 0 # noqa: E721 diff --git a/tests/test_api2.py b/tests/test_api2.py index 9958d971..bbaa12ef 100644 --- a/tests/test_api2.py +++ b/tests/test_api2.py @@ -2,6 +2,7 @@ AnnofabApi2のテストメソッド """ + import configparser import os @@ -29,4 +30,4 @@ def test_project(): content, _ = service.api2.get_project_cache_v2(project_id) - assert type(content) == dict + assert type(content) == dict # noqa: E721 diff --git a/tests/test_local_parser.py b/tests/test_local_parser.py index f8f28431..c09678e6 100644 --- a/tests/test_local_parser.py +++ b/tests/test_local_parser.py @@ -56,7 +56,7 @@ def test_parse_for_zip(self): parser = SimpleAnnotationZipParser(zip_file, "sample_1/c86205d1-bdd4-4110-ae46-194e661d622b.json") simple_annotation = parser.parse() - assert type(simple_annotation.details[0].data) == dict + assert type(simple_annotation.details[0].data) == dict # noqa: E721 simple_annotation2 = parser.parse(self.convert_deitail_data) assert type(simple_annotation2.details[0].data) == FullAnnotationDataPoints @@ -87,13 +87,9 @@ def test_SimpleAnnotationDirParserByTask(self): assert str(annotation_dir / "sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json") in json_file_path_list assert str(annotation_dir / "sample_1/c86205d1-bdd4-4110-ae46-194e661d622b.json") in json_file_path_list - input_data_parser = task_parser.get_parser( - str(annotation_dir / "sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json") - ) + input_data_parser = task_parser.get_parser(str(annotation_dir / "sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json")) assert input_data_parser.input_data_id == "c6e1c2ec-6c7c-41c6-9639-4244c2ed2839" - assert input_data_parser.json_file_path == str( - test_dir / "simple-annotation/sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json" - ) + assert input_data_parser.json_file_path == str(test_dir / "simple-annotation/sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json") def test_SimpleAnnotationZipParserByTask(self): with zipfile.ZipFile(test_dir / "simple-annotation.zip") as zip_file: @@ -106,7 +102,7 @@ def test_SimpleAnnotationZipParserByTask(self): input_data_parser = task_parser.get_parser("sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json") assert input_data_parser.input_data_id == "c6e1c2ec-6c7c-41c6-9639-4244c2ed2839" - assert input_data_parser.json_file_path == str("sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json") + assert input_data_parser.json_file_path == "sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json" class TestSimpleAnnotation: @@ -121,7 +117,7 @@ def test_simple_annotation_zip(self): index += 1 dict_simple_annotation = parser.load_json() - assert type(dict_simple_annotation) == dict + assert type(dict_simple_annotation) == dict # noqa: E721 assert "details" in dict_simple_annotation assert index == 4 @@ -137,7 +133,7 @@ def test_simple_annotation_dir(self): index += 1 dict_simple_annotation = parser.load_json() - assert type(dict_simple_annotation) == dict + assert type(dict_simple_annotation) == dict # noqa: E721 assert "details" in dict_simple_annotation assert index == 4 @@ -150,7 +146,7 @@ def test_lazy_parse_simple_annotation_zip_by_task(self): assert len([e for e in task_parser_list if e.task_id == "sample_1"]) == 1 assert len([e for e in task_parser_list if e.task_id == "sample_0"]) == 1 - task_parser = [e for e in task_parser_list if e.task_id == "sample_1"][0] + task_parser = [e for e in task_parser_list if e.task_id == "sample_1"][0] # noqa: RUF015 parser_list = list(task_parser.lazy_parse()) assert len(parser_list) == 2 assert len([e for e in parser_list if e.input_data_id == "c6e1c2ec-6c7c-41c6-9639-4244c2ed2839"]) == 1 @@ -164,7 +160,7 @@ def test_lazy_parse_simple_annotation_dir_by_task(self): assert len([e for e in task_parser_list if e.task_id == "sample_1"]) == 1 assert len([e for e in task_parser_list if e.task_id == "sample_0"]) == 1 - task_parser = [e for e in task_parser_list if e.task_id == "sample_1"][0] + task_parser = [e for e in task_parser_list if e.task_id == "sample_1"][0] # noqa: RUF015 parser_list = list(task_parser.lazy_parse()) assert len(parser_list) == 2 assert len([e for e in parser_list if e.input_data_id == "c6e1c2ec-6c7c-41c6-9639-4244c2ed2839"]) == 1 @@ -190,7 +186,7 @@ def test_full_annotation_zip(self): assert parser.input_data_id == "c86205d1-bdd4-4110-ae46-194e661d622b" dict_simple_annotation = parser.load_json() - assert type(dict_simple_annotation) == dict + assert type(dict_simple_annotation) == dict # noqa: E721 assert "details" in dict_simple_annotation with pytest.raises(AnnotationOuterFileNotFoundError): @@ -208,14 +204,12 @@ def test_full_annotation_dir(self): assert index == 4 - parser_full = FullAnnotationDirParser( - Path(f"{test_dir}/full-annotation/sample_1/c86205d1-bdd4-4110-ae46-194e661d622b.json") - ) + parser_full = FullAnnotationDirParser(Path(f"{test_dir}/full-annotation/sample_1/c86205d1-bdd4-4110-ae46-194e661d622b.json")) assert parser_full.task_id == "sample_1" assert parser_full.input_data_id == "c86205d1-bdd4-4110-ae46-194e661d622b" dict_simple_annotation = parser_full.load_json() - assert type(dict_simple_annotation) == dict + assert type(dict_simple_annotation) == dict # noqa: E721 assert "details" in dict_simple_annotation with pytest.raises(AnnotationOuterFileNotFoundError): @@ -234,7 +228,7 @@ def test_parse_for_zip(self): parser = FullAnnotationZipParser(zip_file, "sample_1/c86205d1-bdd4-4110-ae46-194e661d622b.json") full_annotation = parser.parse() - assert type(full_annotation.details[0].data) == dict + assert type(full_annotation.details[0].data) == dict # noqa: E721 full_annotation2 = parser.parse(self.convert_deitail_data) assert type(full_annotation2.details[0].data) == FullAnnotationDataPoints diff --git a/tests/test_local_resource.py b/tests/test_local_resource.py index 945866fd..4f9c7a46 100644 --- a/tests/test_local_resource.py +++ b/tests/test_local_resource.py @@ -1,6 +1,7 @@ """ resource.pyのテストコード """ + import os import pytest diff --git a/tests/test_local_utils.py b/tests/test_local_utils.py index 03ed7d56..4c5a8cd5 100644 --- a/tests/test_local_utils.py +++ b/tests/test_local_utils.py @@ -38,7 +38,7 @@ def test_get_task_history_index_skipped_acceptance_検査0回_受入スキップ actual = get_task_history_index_skipped_acceptance(task_history_list) expected = [1] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_acceptance_検査0回_受入スキップ後に受入取消(self): task_history_list: list[dict[str, Any]] = [ @@ -70,7 +70,7 @@ def test_get_task_history_index_skipped_acceptance_検査0回_受入スキップ actual = get_task_history_index_skipped_acceptance(task_history_list) expected = [1] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_acceptance_検査0回_教師付で提出取消(self): task_history_list: list[dict[str, Any]] = [ @@ -101,7 +101,7 @@ def test_get_task_history_index_skipped_acceptance_検査0回_教師付で提出 ] actual = get_task_history_index_skipped_acceptance(task_history_list) expected: list[int] = [] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_acceptance_検査1回_検査で提出取消(self): task_history_list: list[dict[str, Any]] = [ @@ -141,7 +141,7 @@ def test_get_task_history_index_skipped_acceptance_検査1回_検査で提出取 actual = get_task_history_index_skipped_acceptance(task_history_list) expected: list[int] = [] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_inspection_検査1回_検査スキップ(self): task_history_list: list[dict[str, Any]] = [ @@ -173,7 +173,7 @@ def test_get_task_history_index_skipped_inspection_検査1回_検査スキップ actual = get_task_history_index_skipped_inspection(task_history_list) expected = [1] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_inspection_検査1回_教師付で提出取消(self): task_history_list: list[dict[str, Any]] = [ @@ -204,7 +204,7 @@ def test_get_task_history_index_skipped_inspection_検査1回_教師付で提出 ] actual = get_task_history_index_skipped_inspection(task_history_list) expected: list[int] = [] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_inspection_検査2回_検査1回目で提出取消(self): task_history_list: list[dict[str, Any]] = [ @@ -243,12 +243,10 @@ def test_get_task_history_index_skipped_inspection_検査2回_検査1回目で ] actual = get_task_history_index_skipped_inspection(task_history_list) expected: list[int] = [] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_number_of_rejections_教師付1回目(self): - task_history_short_list: list[dict[str, Any]] = [ - {"account_id": self.ACCOUNT_ID, "phase": "annotation", "phase_stage": 1, "worked": True} - ] + task_history_short_list: list[dict[str, Any]] = [{"account_id": self.ACCOUNT_ID, "phase": "annotation", "phase_stage": 1, "worked": True}] actual = get_number_of_rejections(task_history_short_list, TaskPhase.ACCEPTANCE) assert actual == 0 @@ -337,7 +335,7 @@ def test_get_task_history_index_skipped_acceptance_検査0回_受入スキップ actual = get_task_history_index_skipped_acceptance(task_history_list) expected = [2] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_acceptance_検査0回_受入スキップ後に受入取消(self): task_history_list: list[dict[str, Any]] = [ @@ -389,7 +387,7 @@ def test_get_task_history_index_skipped_acceptance_検査0回_受入スキップ actual = get_task_history_index_skipped_acceptance(task_history_list) expected = [2] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_acceptance_検査0回_教師付で提出取消(self): task_history_list: list[dict[str, Any]] = [ @@ -441,7 +439,7 @@ def test_get_task_history_index_skipped_acceptance_検査0回_教師付で提出 actual = get_task_history_index_skipped_acceptance(task_history_list) expected: list[int] = [] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_acceptance_検査1回_検査で提出取消(self): task_history_list: list[dict[str, Any]] = [ @@ -515,7 +513,7 @@ def test_get_task_history_index_skipped_acceptance_検査1回_検査で提出取 actual = get_task_history_index_skipped_acceptance(task_history_list) expected: list[int] = [] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_inspection_検査1回_検査スキップ(self): task_history_list: list[dict[str, Any]] = [ @@ -567,7 +565,7 @@ def test_get_task_history_index_skipped_inspection_検査1回_検査スキップ actual = get_task_history_index_skipped_inspection(task_history_list) expected = [2] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_task_history_index_skipped_inspection_検査1回_教師付で提出取消(self): task_history_list: list[dict[str, Any]] = [ @@ -618,7 +616,7 @@ def test_get_task_history_index_skipped_inspection_検査1回_教師付で提出 ] actual = get_task_history_index_skipped_inspection(task_history_list) expected: list[int] = [] - assert all([a == b for a, b in zip(actual, expected)]) + assert all([a == b for a, b in zip(actual, expected)]) # noqa: C419 def test_get_message_for_i18n(): diff --git a/tests/test_sandbox.py b/tests/test_sandbox.py index bdf419c7..1ad99b9e 100644 --- a/tests/test_sandbox.py +++ b/tests/test_sandbox.py @@ -1,6 +1,7 @@ """ Annofabプロジェクトやタスクに大きく依存したテストコードです。 """ + import configparser import os @@ -35,9 +36,7 @@ def test_wrapper_put_annotation_for_simple_annotation_json_v1(self): project_id=project_id, task_id="sample_0", input_data_id="0733d1e1-ef85-455e-aec0-ff05c499b711", - simple_annotation_json=str( - test_dir + "/simple-annotation/sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json" - ), + simple_annotation_json=str(test_dir + "/simple-annotation/sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json"), annotation_specs_labels=annotation_specs_v1["labels"], ) @@ -48,9 +47,7 @@ def test_wrapper_put_annotation_for_simple_annotation_json_v2(self): project_id=project_id, task_id="sample_0", input_data_id="0733d1e1-ef85-455e-aec0-ff05c499b711", - simple_annotation_json=str( - test_dir + "/simple-annotation/sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json" - ), + simple_annotation_json=str(test_dir + "/simple-annotation/sample_1/c6e1c2ec-6c7c-41c6-9639-4244c2ed2839.json"), annotation_specs_labels=annotation_specs_v2["labels"], annotation_specs_additionals=annotation_specs_v2["additionals"], ) diff --git a/tests/tests_local_api.py b/tests/tests_local_api.py index 300b8d1c..bb148b05 100644 --- a/tests/tests_local_api.py +++ b/tests/tests_local_api.py @@ -27,7 +27,7 @@ def test_assert_retry(self): assert self.requestexception_connectionerror_then_true(log) is True assert 2 == len(log) print(log) - assert isinstance(type((log[0])), requests.exceptions.RequestException) + assert isinstance(type(log[0]), requests.exceptions.RequestException) assert isinstance(type(log[1]), ConnectionError) @my_backoff @@ -97,9 +97,7 @@ def test_assert_not_retry(self): class Test__create_request_body_for_logger: def test_data_dict(self): - actual = _create_request_body_for_logger( - {"foo": "1", "password": "x", "new_password": "y", "old_password": "z"} - ) + actual = _create_request_body_for_logger({"foo": "1", "password": "x", "new_password": "y", "old_password": "z"}) assert actual == {"foo": "1", "password": "***", "new_password": "***", "old_password": "***"} def test_data_dict2(self):