diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
index 116dc20ff..265b213de 100644
--- a/.github/workflows/build-release.yml
+++ b/.github/workflows/build-release.yml
@@ -13,9 +13,9 @@ jobs:
fail-fast: false
matrix:
include:
- - { name: "3.8", python: "3.8", tox: py38-marshmallow3 }
+ - { name: "3.9", python: "3.9", tox: py39-marshmallow3 }
- { name: "3.12", python: "3.12", tox: py312-marshmallow3 }
- - { name: "lowest", python: "3.8", tox: py38-lowest }
+ - { name: "lowest", python: "3.9", tox: py39-lowest }
- { name: "dev", python: "3.12", tox: py312-marshmallowdev }
steps:
- uses: actions/checkout@v4.0.0
diff --git a/README.rst b/README.rst
index 9a17ee425..d4759e436 100644
--- a/README.rst
+++ b/README.rst
@@ -52,9 +52,6 @@ Install
pip install -U webargs
-webargs supports Python >= 3.8.
-
-
Documentation
=============
diff --git a/docs/install.rst b/docs/install.rst
index 933283db5..43d0b4115 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -1,7 +1,7 @@
Install
=======
-**webargs** requires Python >= 3.8. It depends on `marshmallow `_ >= 3.0.0.
+**webargs** depends on `marshmallow `_ >= 3.0.0.
From the PyPI
-------------
diff --git a/pyproject.toml b/pyproject.toml
index 8955a49f3..df57f0b3c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,7 +16,6 @@ classifiers = [
"License :: OSI Approved :: MIT License",
"Natural Language :: English",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
@@ -40,7 +39,7 @@ keywords = [
"api",
"marshmallow",
]
-requires-python = ">=3.8"
+requires-python = ">=3.9"
dependencies = ["marshmallow>=3.0.0", "packaging>=17.0"]
[project.urls]
diff --git a/src/webargs/core.py b/src/webargs/core.py
index 4152c1dcf..44294e986 100644
--- a/src/webargs/core.py
+++ b/src/webargs/core.py
@@ -28,13 +28,13 @@
Request = typing.TypeVar("Request")
ArgMap = typing.Union[
ma.Schema,
- typing.Type[ma.Schema],
- typing.Mapping[str, typing.Union[ma.fields.Field, typing.Type[ma.fields.Field]]],
+ type[ma.Schema],
+ typing.Mapping[str, typing.Union[ma.fields.Field, type[ma.fields.Field]]],
typing.Callable[[Request], ma.Schema],
]
ValidateArg = typing.Union[None, typing.Callable, typing.Iterable[typing.Callable]]
-CallableList = typing.List[typing.Callable]
+CallableList = list[typing.Callable]
ErrorHandler = typing.Callable[..., typing.NoReturn]
# generic type var with no particular meaning
T = typing.TypeVar("T")
diff --git a/tests/test_core.py b/tests/test_core.py
index 01d35eba4..4b703bb0c 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -75,9 +75,10 @@ def test_load_json_called_by_parse_default(load_json, web_request):
"location", ["querystring", "form", "headers", "cookies", "files"]
)
def test_load_nondefault_called_by_parse_with_location(location, web_request):
- with mock.patch(
- f"webargs.core.Parser.load_{location}"
- ) as mock_loadfunc, mock.patch("webargs.core.Parser.load_json") as load_json:
+ with (
+ mock.patch(f"webargs.core.Parser.load_{location}") as mock_loadfunc,
+ mock.patch("webargs.core.Parser.load_json") as load_json,
+ ):
mock_loadfunc.return_value = {}
load_json.return_value = {}
p = Parser()
diff --git a/tox.ini b/tox.ini
index d76ff068c..96d1222b5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,9 @@
[tox]
envlist=
lint
- py{38,39,310,311,312}-marshmallow3
+ py{39,310,311,312}-marshmallow3
py312-marshmallowdev
- py38-lowest
+ py39-lowest
docs
[testenv]