From 191d17fec403f1d05966ef6dbfa0b00fdae70469 Mon Sep 17 00:00:00 2001 From: Alex Ted Date: Thu, 24 Oct 2024 18:44:53 +0300 Subject: [PATCH 1/7] build: Python 3.8 removed as not supported --- .github/workflows/on_update.yml | 2 +- .github/workflows/pre_release.yml | 2 +- .github/workflows/tests.yml | 10 ++--- Dockerfile.py38.test | 39 ------------------- README.md | 2 +- bin/docker-compose-test.sh | 8 ---- docker-compose.test.yml | 10 ----- examples/javascript/pyproject.toml | 2 +- examples/minimal-async/pyproject.toml | 2 +- examples/minimal/pyproject.toml | 2 +- examples/modular/pyproject.toml | 2 +- examples/multiplesite/pyproject.toml | 2 +- examples/openrpc/pyproject.toml | 2 +- pyproject.toml | 3 +- requirements/tests.txt | 3 +- .../browse/static/js/apps/browse/services.js | 2 +- src/flask_jsonrpc/types.py | 3 +- src/flask_jsonrpc/typing.py | 8 +--- 18 files changed, 19 insertions(+), 85 deletions(-) delete mode 100644 Dockerfile.py38.test diff --git a/.github/workflows/on_update.yml b/.github/workflows/on_update.yml index 9b893561..dc30b886 100644 --- a/.github/workflows/on_update.yml +++ b/.github/workflows/on_update.yml @@ -21,7 +21,7 @@ jobs: - ubuntu-latest - macos-latest - windows-latest - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - name: Checkout source at ${{ matrix.platform }} uses: actions/checkout@v4 diff --git a/.github/workflows/pre_release.yml b/.github/workflows/pre_release.yml index 19f76bf2..5c9c990a 100644 --- a/.github/workflows/pre_release.yml +++ b/.github/workflows/pre_release.yml @@ -22,7 +22,7 @@ jobs: - ubuntu-latest - macos-latest - windows-latest - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - name: Checkout source at ${{ matrix.platform }} uses: actions/checkout@v4 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 62f350db..728f09c0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,14 +33,14 @@ jobs: - ubuntu-latest steps: - name: Check comment review - if: >- - github.event_name == 'issue_comment' && + if: >- + github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, 'github-actions-workflow-tests') == false uses: action-pack/cancel@v1 - name: Comment about start of workflow - if: >- - github.event_name == 'issue_comment' && + if: >- + github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, 'github-actions-workflow-tests') env: @@ -90,7 +90,7 @@ jobs: matrix: platform: - ubuntu-latest - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - name: Checkout source at ${{ matrix.platform }} uses: actions/checkout@v4 diff --git a/Dockerfile.py38.test b/Dockerfile.py38.test deleted file mode 100644 index 8e2cd39e..00000000 --- a/Dockerfile.py38.test +++ /dev/null @@ -1,39 +0,0 @@ -FROM python:3.8-alpine - -ENV PYTHONUNBUFFERED=1 \ - PRAGMA_VERSION=py3.8 \ - DEBUG=0 - -WORKDIR /code - -COPY requirements/ /code/requirements/ - -RUN set -ex \ - && apk add --no-cache --virtual .build-deps \ - gcc \ - musl-dev \ - python3-dev \ - git \ - && pip install pip setuptools wheel --upgrade \ - && pip install -r requirements/base.txt \ - && pip install -r requirements/style.txt \ - && pip install -r requirements/tests.txt \ - poetry-core>=1.0.0 \ - && apk del .build-deps \ - && addgroup -S kuchulu \ - && adduser \ - --disabled-password \ - --gecos "" \ - --ingroup kuchulu \ - --no-create-home \ - -s /bin/false \ - kuchulu - -ARG VERSION=1 -RUN echo "Vesion: ${VERSION}" - -COPY . /code/ - -RUN chown kuchulu:kuchulu -R /code - -USER kuchulu diff --git a/README.md b/README.md index 5fdfe037..8b2715eb 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Some reasons you might want to use: * Simple, powerful, flexible, and pythonic API. * Support [JSON-RPC 2.0](https://www.jsonrpc.org/specification "JSON-RPC 2.0") version. -* Support Python 3.8 or later. +* Support Python 3.9 or later. * Experimental support to [Mypyc](https://mypyc.readthedocs.io/en/latest/introduction.html), it compiles Python modules to C extensions. * The web browsable API. * Run-time type checking functions defined with [PEP 484](https://www.python.org/dev/peps/pep-0484/ "PEP 484") argument (and return) type annotations. diff --git a/bin/docker-compose-test.sh b/bin/docker-compose-test.sh index 57e6337f..0c38b35a 100755 --- a/bin/docker-compose-test.sh +++ b/bin/docker-compose-test.sh @@ -7,13 +7,6 @@ DOCKER_COMPOSE_FILE_PATH=../${DOCKER_COMPOSE_FILE_NAME} docker compose -f ${DOCKER_COMPOSE_FILE_PATH} -p ci build --build-arg VERSION=$(date +%s) docker compose -f ${DOCKER_COMPOSE_FILE_PATH} -p ci up -d -( - set -e - docker wait ci-python3.8-1 - docker logs ci-python3.8-1 -) -DOCKER_WAIT_FOR_PY38=$? - ( set -e docker wait ci-python3.9-1 @@ -44,7 +37,6 @@ DOCKER_WAIT_FOR_PY312=$? docker compose -f ${DOCKER_COMPOSE_FILE_PATH} -p ci down --remove-orphans -if [ ${DOCKER_WAIT_FOR_PY38} -ne 0 ]; then echo "Test to Python 3.8 failed"; exit 1; fi if [ ${DOCKER_WAIT_FOR_PY39} -ne 0 ]; then echo "Test to Python 3.9 failed"; exit 1; fi if [ ${DOCKER_WAIT_FOR_PY310} -ne 0 ]; then echo "Test to Python 3.10 failed"; exit 1; fi if [ ${DOCKER_WAIT_FOR_PY311} -ne 0 ]; then echo "Test to Python 3.11 failed"; exit 1; fi diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 73872829..8aa76152 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -38,13 +38,3 @@ services: command: > sh -c "ruff check . && pytest" - - python3.8: - build: - context: . - dockerfile: Dockerfile.py38.test - environment: - - PRAGMA_VERSION=py3.8 - command: > - sh -c "ruff check . && - pytest" diff --git a/examples/javascript/pyproject.toml b/examples/javascript/pyproject.toml index 1f5007b3..294adec9 100644 --- a/examples/javascript/pyproject.toml +++ b/examples/javascript/pyproject.toml @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE.txt"} authors = [{name = "Nycholas Oliveira", email = "nycholas@cenobit.es"}] maintainers = [{name = "Cenobit Technologies Inc.", email = "hi@cenobit.es"}] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"] [project.optional-dependencies] diff --git a/examples/minimal-async/pyproject.toml b/examples/minimal-async/pyproject.toml index 0f64aeeb..2f2130a9 100644 --- a/examples/minimal-async/pyproject.toml +++ b/examples/minimal-async/pyproject.toml @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE.txt"} authors = [{name = "Nycholas Oliveira", email = "nycholas@cenobit.es"}] maintainers = [{name = "Cenobit Technologies Inc.", email = "hi@cenobit.es"}] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc", "Flask[async]>=3.0.0,<4.0"] [project.optional-dependencies] diff --git a/examples/minimal/pyproject.toml b/examples/minimal/pyproject.toml index 061e3861..1bf213ea 100644 --- a/examples/minimal/pyproject.toml +++ b/examples/minimal/pyproject.toml @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE.txt"} authors = [{name = "Nycholas Oliveira", email = "nycholas@cenobit.es"}] maintainers = [{name = "Cenobit Technologies Inc.", email = "hi@cenobit.es"}] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"] [project.optional-dependencies] diff --git a/examples/modular/pyproject.toml b/examples/modular/pyproject.toml index bfbf2f0a..576e8f4a 100644 --- a/examples/modular/pyproject.toml +++ b/examples/modular/pyproject.toml @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE.txt"} authors = [{name = "Nycholas Oliveira", email = "nycholas@cenobit.es"}] maintainers = [{name = "Cenobit Technologies Inc.", email = "hi@cenobit.es"}] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"] [project.optional-dependencies] diff --git a/examples/multiplesite/pyproject.toml b/examples/multiplesite/pyproject.toml index 48a215d5..05beb3c2 100644 --- a/examples/multiplesite/pyproject.toml +++ b/examples/multiplesite/pyproject.toml @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE.txt"} authors = [{name = "Nycholas Oliveira", email = "nycholas@cenobit.es"}] maintainers = [{name = "Cenobit Technologies Inc.", email = "hi@cenobit.es"}] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"] [project.optional-dependencies] diff --git a/examples/openrpc/pyproject.toml b/examples/openrpc/pyproject.toml index e00f4a1f..321785eb 100644 --- a/examples/openrpc/pyproject.toml +++ b/examples/openrpc/pyproject.toml @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE.txt"} authors = [{name = "Nycholas Oliveira", email = "nycholas@cenobit.es"}] maintainers = [{name = "Cenobit Technologies Inc.", email = "hi@cenobit.es"}] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"] [project.optional-dependencies] diff --git a/pyproject.toml b/pyproject.toml index 4aa7cb5e..1692928a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -24,7 +23,7 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Application Frameworks", ] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = [ "Flask>=3.0.0,<4.0", "typeguard==4.3.0", diff --git a/requirements/tests.txt b/requirements/tests.txt index 656fcf1d..66700ef3 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -13,8 +13,7 @@ typeguard==4.3.0 # https://github.com/agronholm/typeguard # Code quality # ------------------------------------------------------------------------------ -coverage==7.6.2;python_version>"3.8" # https://github.com/nedbat/coveragepy -coverage==7.6.1;python_version=="3.8" +coverage==7.6.2;python_version>="3.9" # https://github.com/nedbat/coveragepy # Tools diff --git a/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js b/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js index 21d2415c..47296567 100644 --- a/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js +++ b/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js @@ -9,7 +9,7 @@ 'headers': { 'content-type': 'application/json', 'content-length': '113', - 'server': 'Werkzeug/0.8.3 Python/2.7.5', + 'server': 'Werkzeug/3.0.4 Python/3.13.0', 'date': 'Fri, 15 Nov 2013 20:15:18 GMT', 'data': { 'jsonrpc': '2.0', diff --git a/src/flask_jsonrpc/types.py b/src/flask_jsonrpc/types.py index 143c6979..10339ab3 100644 --- a/src/flask_jsonrpc/types.py +++ b/src/flask_jsonrpc/types.py @@ -34,7 +34,6 @@ from typing_extensions import ( Self, # Added in version 3.11. - Literal, # Added in version 3.8. ) from typing_inspect import is_new_type # type: ignore @@ -101,7 +100,7 @@ def check_type(self: Self, o: t.Any) -> bool: # pylint: disable=R0911 # noqa: A if origin_type is t.Tuple or origin_type is tuple: return self is Array - if origin_type is Literal: + if origin_type is t.Literal: return self.check_args_type(expected_type) if origin_type is t.Final: diff --git a/src/flask_jsonrpc/typing.py b/src/flask_jsonrpc/typing.py index 0c8e710d..5edbcc3f 100644 --- a/src/flask_jsonrpc/typing.py +++ b/src/flask_jsonrpc/typing.py @@ -31,12 +31,6 @@ from pydantic.main import BaseModel -# Python 3.8 -if sys.version_info[:2] == (3, 8): # pragma: no cover - from typing import OrderedDict -else: # pragma: no cover - from collections import OrderedDict - class ServiceMethodParamsDescribe(BaseModel): type: str @@ -73,4 +67,4 @@ class ServiceDescribe(BaseModel): name: str description: str | None = None servers: list[ServiceServersDescribe] - methods: OrderedDict[str, ServiceMethodDescribe] + methods: t.OrderedDict[str, ServiceMethodDescribe] From 6018bde12df95a70afbd152fd18efdcc0d9510bf Mon Sep 17 00:00:00 2001 From: Alex Ted Date: Sun, 27 Oct 2024 00:35:10 +0300 Subject: [PATCH 2/7] build: some improvements --- pyproject.toml | 2 +- requirements/tests.txt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1692928a..aa85ee60 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,7 @@ fix = true show-fixes = true output-format = "concise" line-length = 120 -target-version = "py38" +target-version = "py39" [tool.ruff.lint] select = [ diff --git a/requirements/tests.txt b/requirements/tests.txt index 66700ef3..67e6d922 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -13,8 +13,7 @@ typeguard==4.3.0 # https://github.com/agronholm/typeguard # Code quality # ------------------------------------------------------------------------------ -coverage==7.6.2;python_version>="3.9" # https://github.com/nedbat/coveragepy - +coverage~=7.6.2 # https://github.com/nedbat/coveragepy # Tools # ------------------------------------------------------------------------------ From 75d26e078261c98602e3961af980a380807f2391 Mon Sep 17 00:00:00 2001 From: Alex Ted Date: Sun, 27 Oct 2024 14:01:31 +0300 Subject: [PATCH 3/7] tests: fixed dynamic Werkzeug version using in User-Agent header --- .../minimal-async/src/minimal_async/app.py | 2 +- examples/minimal-async/tests/test_app.py | 13 ++++++---- examples/minimal/src/minimal/app.py | 2 +- examples/minimal/tests/test_app.py | 16 ++++++------ .../browse/static/js/apps/browse/services.js | 2 +- tests/utils.py | 25 +++++++++++++++++++ 6 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 tests/utils.py diff --git a/examples/minimal-async/src/minimal_async/app.py b/examples/minimal-async/src/minimal_async/app.py index 081cc5fb..8ec96895 100644 --- a/examples/minimal-async/src/minimal_async/app.py +++ b/examples/minimal-async/src/minimal_async/app.py @@ -152,4 +152,4 @@ async def one_decorator() -> str: @jsonrpc_headers async def multi_decorators() -> t.Dict[str, t.Any]: await asyncio.sleep(0) - return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': str(request.headers)} + return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': request.headers} diff --git a/examples/minimal-async/tests/test_app.py b/examples/minimal-async/tests/test_app.py index 6d46f49a..45ac9b09 100644 --- a/examples/minimal-async/tests/test_app.py +++ b/examples/minimal-async/tests/test_app.py @@ -28,6 +28,8 @@ from werkzeug.datastructures import Headers +from tests.utils import EqMock + if t.TYPE_CHECKING: from flask.testing import FlaskClient @@ -166,12 +168,13 @@ def test_multi_decorators(client: 'FlaskClient') -> None: 'id': 1, 'jsonrpc': '2.0', 'result': { - 'headers': 'User-Agent: Werkzeug/3.0.4\r\n' - 'Host: localhost\r\n' - 'Content-Type: application/json\r\n' - 'Content-Length: 78\r\n' - '\r\n', 'terminal_id': 1, + 'headers': { + 'User-Agent': EqMock(), + 'Host': 'localhost', + 'Content-Type': 'application/json', + 'Content-Length': '78', + } }, } assert rv.headers == Headers( diff --git a/examples/minimal/src/minimal/app.py b/examples/minimal/src/minimal/app.py index 14fa4581..bc291c8d 100644 --- a/examples/minimal/src/minimal/app.py +++ b/examples/minimal/src/minimal/app.py @@ -135,4 +135,4 @@ def one_decorator() -> str: @check_terminal_id @jsonrpc_headers def multi_decorators() -> t.Dict[str, t.Any]: - return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': str(request.headers)} + return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': request.headers} diff --git a/examples/minimal/tests/test_app.py b/examples/minimal/tests/test_app.py index 6d46f49a..1aba62ba 100644 --- a/examples/minimal/tests/test_app.py +++ b/examples/minimal/tests/test_app.py @@ -25,9 +25,10 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. import typing as t - from werkzeug.datastructures import Headers +from tests.utils import EqMock + if t.TYPE_CHECKING: from flask.testing import FlaskClient @@ -87,7 +88,7 @@ def test_not_notify(client: 'FlaskClient') -> None: 'code': -32600, 'data': { 'message': "The method 'App.notNotify' doesn't allow Notification Request " - "object (without an 'id' member)" + "object (without an 'id' member)" }, 'message': 'Invalid Request', 'name': 'InvalidRequestError', @@ -166,12 +167,13 @@ def test_multi_decorators(client: 'FlaskClient') -> None: 'id': 1, 'jsonrpc': '2.0', 'result': { - 'headers': 'User-Agent: Werkzeug/3.0.4\r\n' - 'Host: localhost\r\n' - 'Content-Type: application/json\r\n' - 'Content-Length: 78\r\n' - '\r\n', 'terminal_id': 1, + 'headers': { + 'User-Agent': EqMock(), + 'Host': 'localhost', + 'Content-Type': 'application/json', + 'Content-Length': '78', + } }, } assert rv.headers == Headers( diff --git a/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js b/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js index 47296567..7f3104be 100644 --- a/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js +++ b/src/flask_jsonrpc/contrib/browse/static/js/apps/browse/services.js @@ -9,7 +9,7 @@ 'headers': { 'content-type': 'application/json', 'content-length': '113', - 'server': 'Werkzeug/3.0.4 Python/3.13.0', + 'server': 'Werkzeug/3.0.6 Python/3.13.0', 'date': 'Fri, 15 Nov 2013 20:15:18 GMT', 'data': { 'jsonrpc': '2.0', diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..3ca33dcb --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,25 @@ +from typing import Any + + +class EqMock: + value: Any = None + + def __init__(self, remember: bool = False) -> None: + self.remember: bool = remember + + def __eq__(self, other: Any) -> bool: # noqa: ANN401 + if self.remember and self.value is not None: + return self.value == other + else: + assert other, other + + if self.remember: + self.value = other + + return True + + def __repr__(self) -> str: + return repr(self.value) if self.remember else super().__repr__() + + def __str__(self) -> str: + return str(self.value) if self.remember else super().__str__() From 379d2c7cf627a1ff90833c1ca0ca7a4afb468390 Mon Sep 17 00:00:00 2001 From: Alex Ted Date: Sun, 27 Oct 2024 14:14:11 +0300 Subject: [PATCH 4/7] tests: fix import eqmock --- examples/minimal-async/tests/utils.py | 25 +++++++++++++++++++++++++ examples/minimal/tests/utils.py | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 examples/minimal-async/tests/utils.py create mode 100644 examples/minimal/tests/utils.py diff --git a/examples/minimal-async/tests/utils.py b/examples/minimal-async/tests/utils.py new file mode 100644 index 00000000..3ca33dcb --- /dev/null +++ b/examples/minimal-async/tests/utils.py @@ -0,0 +1,25 @@ +from typing import Any + + +class EqMock: + value: Any = None + + def __init__(self, remember: bool = False) -> None: + self.remember: bool = remember + + def __eq__(self, other: Any) -> bool: # noqa: ANN401 + if self.remember and self.value is not None: + return self.value == other + else: + assert other, other + + if self.remember: + self.value = other + + return True + + def __repr__(self) -> str: + return repr(self.value) if self.remember else super().__repr__() + + def __str__(self) -> str: + return str(self.value) if self.remember else super().__str__() diff --git a/examples/minimal/tests/utils.py b/examples/minimal/tests/utils.py new file mode 100644 index 00000000..3ca33dcb --- /dev/null +++ b/examples/minimal/tests/utils.py @@ -0,0 +1,25 @@ +from typing import Any + + +class EqMock: + value: Any = None + + def __init__(self, remember: bool = False) -> None: + self.remember: bool = remember + + def __eq__(self, other: Any) -> bool: # noqa: ANN401 + if self.remember and self.value is not None: + return self.value == other + else: + assert other, other + + if self.remember: + self.value = other + + return True + + def __repr__(self) -> str: + return repr(self.value) if self.remember else super().__repr__() + + def __str__(self) -> str: + return str(self.value) if self.remember else super().__str__() From 4837be5ca44faf4e3aafe1c806943a7e04bdeae0 Mon Sep 17 00:00:00 2001 From: Alex Ted Date: Sun, 27 Oct 2024 14:31:53 +0300 Subject: [PATCH 5/7] tests: convert request.headers to dict to allow serialisation of JSON --- examples/minimal-async/src/minimal_async/app.py | 2 +- examples/minimal/src/minimal/app.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/minimal-async/src/minimal_async/app.py b/examples/minimal-async/src/minimal_async/app.py index 8ec96895..0cfb5a35 100644 --- a/examples/minimal-async/src/minimal_async/app.py +++ b/examples/minimal-async/src/minimal_async/app.py @@ -152,4 +152,4 @@ async def one_decorator() -> str: @jsonrpc_headers async def multi_decorators() -> t.Dict[str, t.Any]: await asyncio.sleep(0) - return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': request.headers} + return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': dict(request.headers)} diff --git a/examples/minimal/src/minimal/app.py b/examples/minimal/src/minimal/app.py index bc291c8d..503b9544 100644 --- a/examples/minimal/src/minimal/app.py +++ b/examples/minimal/src/minimal/app.py @@ -135,4 +135,4 @@ def one_decorator() -> str: @check_terminal_id @jsonrpc_headers def multi_decorators() -> t.Dict[str, t.Any]: - return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': request.headers} + return {'terminal_id': request.get_json(silent=True).get('terminal_id', 0), 'headers': dict(request.headers)} From 035d2dceddc427f681f75e7bc186dbe764f175a0 Mon Sep 17 00:00:00 2001 From: Alex Ted Date: Sun, 27 Oct 2024 14:53:20 +0300 Subject: [PATCH 6/7] tests: updated value of content-length header --- examples/minimal-async/tests/test_app.py | 2 +- examples/minimal/tests/test_app.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/minimal-async/tests/test_app.py b/examples/minimal-async/tests/test_app.py index 45ac9b09..3773c1b2 100644 --- a/examples/minimal-async/tests/test_app.py +++ b/examples/minimal-async/tests/test_app.py @@ -178,7 +178,7 @@ def test_multi_decorators(client: 'FlaskClient') -> None: }, } assert rv.headers == Headers( - [('Content-Type', 'application/json'), ('Content-Length', '174'), ('X-JSONRPC-Tag', 'JSONRPC 2.0')] + [('Content-Type', 'application/json'), ('Content-Length', '169'), ('X-JSONRPC-Tag', 'JSONRPC 2.0')] ) assert rv.status_code == 200 diff --git a/examples/minimal/tests/test_app.py b/examples/minimal/tests/test_app.py index 1aba62ba..c2ea1658 100644 --- a/examples/minimal/tests/test_app.py +++ b/examples/minimal/tests/test_app.py @@ -177,7 +177,7 @@ def test_multi_decorators(client: 'FlaskClient') -> None: }, } assert rv.headers == Headers( - [('Content-Type', 'application/json'), ('Content-Length', '174'), ('X-JSONRPC-Tag', 'JSONRPC 2.0')] + [('Content-Type', 'application/json'), ('Content-Length', '169'), ('X-JSONRPC-Tag', 'JSONRPC 2.0')] ) assert rv.status_code == 200 From abc0fa742e01172d9ecf2b90345795f744f34546 Mon Sep 17 00:00:00 2001 From: Alex Ted Date: Sun, 27 Oct 2024 15:18:01 +0300 Subject: [PATCH 7/7] tests: deleted extra file --- tests/utils.py | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 tests/utils.py diff --git a/tests/utils.py b/tests/utils.py deleted file mode 100644 index 3ca33dcb..00000000 --- a/tests/utils.py +++ /dev/null @@ -1,25 +0,0 @@ -from typing import Any - - -class EqMock: - value: Any = None - - def __init__(self, remember: bool = False) -> None: - self.remember: bool = remember - - def __eq__(self, other: Any) -> bool: # noqa: ANN401 - if self.remember and self.value is not None: - return self.value == other - else: - assert other, other - - if self.remember: - self.value = other - - return True - - def __repr__(self) -> str: - return repr(self.value) if self.remember else super().__repr__() - - def __str__(self) -> str: - return str(self.value) if self.remember else super().__str__()