Skip to content

Commit

Permalink
Drop support for Python 3.8 (#591)
Browse files Browse the repository at this point in the history
* build: Python 3.8 removed as not supported

* build: some improvements

* tests: fixed dynamic Werkzeug version using in User-Agent header

* tests: fix import eqmock

* tests: convert request.headers to dict to allow serialisation of JSON

* tests: updated value of content-length header

* tests: deleted extra file
  • Loading branch information
alexted authored Oct 28, 2024
1 parent dd8c991 commit f5d60c5
Show file tree
Hide file tree
Showing 24 changed files with 91 additions and 103 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/on_update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pre_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
39 changes: 0 additions & 39 deletions Dockerfile.py38.test

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 0 additions & 8 deletions bin/docker-compose-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
10 changes: 0 additions & 10 deletions docker-compose.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion examples/javascript/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"}
license = {file = "LICENSE.txt"}
authors = [{name = "Nycholas Oliveira", email = "[email protected]"}]
maintainers = [{name = "Cenobit Technologies Inc.", email = "[email protected]"}]
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion examples/minimal-async/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"}
license = {file = "LICENSE.txt"}
authors = [{name = "Nycholas Oliveira", email = "[email protected]"}]
maintainers = [{name = "Cenobit Technologies Inc.", email = "[email protected]"}]
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]
Expand Down
2 changes: 1 addition & 1 deletion examples/minimal-async/src/minimal_async/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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': dict(request.headers)}
15 changes: 9 additions & 6 deletions examples/minimal-async/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

from werkzeug.datastructures import Headers

from tests.utils import EqMock

if t.TYPE_CHECKING:
from flask.testing import FlaskClient

Expand Down Expand Up @@ -166,16 +168,17 @@ 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(
[('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

Expand Down
25 changes: 25 additions & 0 deletions examples/minimal-async/tests/utils.py
Original file line number Diff line number Diff line change
@@ -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__()
2 changes: 1 addition & 1 deletion examples/minimal/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"}
license = {file = "LICENSE.txt"}
authors = [{name = "Nycholas Oliveira", email = "[email protected]"}]
maintainers = [{name = "Cenobit Technologies Inc.", email = "[email protected]"}]
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion examples/minimal/src/minimal/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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': dict(request.headers)}
18 changes: 10 additions & 8 deletions examples/minimal/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -166,16 +167,17 @@ 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(
[('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

Expand Down
25 changes: 25 additions & 0 deletions examples/minimal/tests/utils.py
Original file line number Diff line number Diff line change
@@ -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__()
2 changes: 1 addition & 1 deletion examples/modular/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"}
license = {file = "LICENSE.txt"}
authors = [{name = "Nycholas Oliveira", email = "[email protected]"}]
maintainers = [{name = "Cenobit Technologies Inc.", email = "[email protected]"}]
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion examples/multiplesite/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"}
license = {file = "LICENSE.txt"}
authors = [{name = "Nycholas Oliveira", email = "[email protected]"}]
maintainers = [{name = "Cenobit Technologies Inc.", email = "[email protected]"}]
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion examples/openrpc/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ readme = {file = "README.md", content-type = "text/markdown"}
license = {file = "LICENSE.txt"}
authors = [{name = "Nycholas Oliveira", email = "[email protected]"}]
maintainers = [{name = "Cenobit Technologies Inc.", email = "[email protected]"}]
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = ["Flask-JSONRPC@git+https://github.com/cenobites/flask-jsonrpc"]

[project.optional-dependencies]
Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ 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",
"Programming Language :: Python :: 3.12",
"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",
Expand Down Expand Up @@ -95,7 +94,7 @@ fix = true
show-fixes = true
output-format = "concise"
line-length = 120
target-version = "py38"
target-version = "py39"

[tool.ruff.lint]
select = [
Expand Down
4 changes: 1 addition & 3 deletions requirements/tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +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 # https://github.com/nedbat/coveragepy

# Tools
# ------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.6 Python/3.13.0',
'date': 'Fri, 15 Nov 2013 20:15:18 GMT',
'data': {
'jsonrpc': '2.0',
Expand Down
3 changes: 1 addition & 2 deletions src/flask_jsonrpc/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
Loading

0 comments on commit f5d60c5

Please sign in to comment.