Drop Python 3.8 support

This addresses a failure in the `py38-dev` tests
caused by markupsafe recently dropping Python 3.8 support.

Changed in this commit:

* Drop Python 3.8 support
* Update CI and tox testing
* Update docs references to Python 3.8
* Remove a Windows / Python 3.8 admonition in the docs
* Address type annotations
* Incorporate style fixes

Still to do:

* `src/flask/sessions.py` contains these comments:

  > TODO generic when Python > 3.8

  This TODO should now be unblocked.
This commit is contained in:
Kurt McKee 2024-10-16 18:12:00 -05:00
parent dffe303482
commit 5796f50315
No known key found for this signature in database
GPG key ID: 64713C0B5BA8E1C2
9 changed files with 22 additions and 29 deletions

View file

@ -28,10 +28,9 @@ jobs:
- {python: '3.11'}
- {python: '3.10'}
- {python: '3.9'}
- {python: '3.8'}
- {name: PyPy, python: 'pypy-3.10', tox: pypy310}
- {name: Minimum Versions, python: '3.12', tox: py-min}
- {name: Development Versions, python: '3.8', tox: py-dev}
- {name: Development Versions, python: '3.9', tox: py-dev}
steps:
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0

View file

@ -23,12 +23,6 @@ method in views that inherit from the :class:`flask.views.View` class, as
well as all the HTTP method handlers in views that inherit from the
:class:`flask.views.MethodView` class.
.. admonition:: Using ``async`` on Windows on Python 3.8
Python 3.8 has a bug related to asyncio on Windows. If you encounter
something like ``ValueError: set_wakeup_fd only works in main thread``,
please upgrade to Python 3.9.
.. admonition:: Using ``async`` with greenlet
When using gevent or eventlet to serve an application or patch the

View file

@ -294,7 +294,7 @@ ecosystem remain consistent and compatible.
indicate minimum compatibility support. For example,
``sqlalchemy>=1.4``.
9. Indicate the versions of Python supported using ``python_requires=">=version"``.
Flask itself supports Python >=3.8 as of April 2023, but this will update over time.
Flask itself supports Python >=3.9 as of October 2024, but this will update over time.
.. _PyPI: https://pypi.org/search/?c=Framework+%3A%3A+Flask
.. _Discord Chat: https://discord.gg/pallets

View file

@ -5,7 +5,7 @@ Installation
Python Version
--------------
We recommend using the latest version of Python. Flask supports Python 3.8 and newer.
We recommend using the latest version of Python. Flask supports Python 3.9 and newer.
Dependencies

View file

@ -3,7 +3,7 @@ name = "flask-example-celery"
version = "1.0.0"
description = "Example Flask application with Celery background tasks."
readme = "README.md"
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = ["flask>=2.2.2", "celery[redis]>=5.2.7"]
[build-system]

View file

@ -19,7 +19,7 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Application Frameworks",
"Typing :: Typed",
]
requires-python = ">=3.8"
requires-python = ">=3.9"
dependencies = [
"Werkzeug>=3.0.0",
"Jinja2>=3.1.2",
@ -78,7 +78,7 @@ source = ["flask", "tests"]
source = ["src", "*/site-packages"]
[tool.mypy]
python_version = "3.8"
python_version = "3.9"
files = ["src/flask", "tests/typing"]
show_error_codes = true
pretty = true
@ -94,7 +94,7 @@ module = [
ignore_missing_imports = true
[tool.pyright]
pythonVersion = "3.8"
pythonVersion = "3.9"
include = ["src/flask", "tests"]
typeCheckingMode = "basic"

View file

@ -5,7 +5,7 @@ import os
import sys
import typing as t
from datetime import datetime
from functools import lru_cache
from functools import cache
from functools import update_wrapper
import werkzeug.utils
@ -623,7 +623,7 @@ def get_root_path(import_name: str) -> str:
return os.path.dirname(os.path.abspath(filepath)) # type: ignore[no-any-return]
@lru_cache(maxsize=None)
@cache
def _split_blueprint_path(name: str) -> list[str]:
out: list[str] = [name]

View file

@ -12,7 +12,7 @@ ResponseValue = t.Union[
"Response",
str,
bytes,
t.List[t.Any],
list[t.Any],
# Only dict is actually accepted, but Mapping allows for TypedDict.
t.Mapping[str, t.Any],
t.Iterator[str],
@ -21,21 +21,21 @@ ResponseValue = t.Union[
# the possible types for an individual HTTP header
# This should be a Union, but mypy doesn't pass unless it's a TypeVar.
HeaderValue = t.Union[str, t.List[str], t.Tuple[str, ...]]
HeaderValue = t.Union[str, list[str], tuple[str, ...]]
# the possible types for HTTP headers
HeadersValue = t.Union[
"Headers",
t.Mapping[str, HeaderValue],
t.Sequence[t.Tuple[str, HeaderValue]],
t.Sequence[tuple[str, HeaderValue]],
]
# The possible types returned by a route function.
ResponseReturnValue = t.Union[
ResponseValue,
t.Tuple[ResponseValue, HeadersValue],
t.Tuple[ResponseValue, int],
t.Tuple[ResponseValue, int, HeadersValue],
tuple[ResponseValue, HeadersValue],
tuple[ResponseValue, int],
tuple[ResponseValue, int, HeadersValue],
"WSGIApplication",
]
@ -56,21 +56,21 @@ BeforeRequestCallable = t.Union[
t.Callable[[], t.Optional[ResponseReturnValue]],
t.Callable[[], t.Awaitable[t.Optional[ResponseReturnValue]]],
]
ShellContextProcessorCallable = t.Callable[[], t.Dict[str, t.Any]]
ShellContextProcessorCallable = t.Callable[[], dict[str, t.Any]]
TeardownCallable = t.Union[
t.Callable[[t.Optional[BaseException]], None],
t.Callable[[t.Optional[BaseException]], t.Awaitable[None]],
]
TemplateContextProcessorCallable = t.Union[
t.Callable[[], t.Dict[str, t.Any]],
t.Callable[[], t.Awaitable[t.Dict[str, t.Any]]],
t.Callable[[], dict[str, t.Any]],
t.Callable[[], t.Awaitable[dict[str, t.Any]]],
]
TemplateFilterCallable = t.Callable[..., t.Any]
TemplateGlobalCallable = t.Callable[..., t.Any]
TemplateTestCallable = t.Callable[..., bool]
URLDefaultCallable = t.Callable[[str, t.Dict[str, t.Any]], None]
URLDefaultCallable = t.Callable[[str, dict[str, t.Any]], None]
URLValuePreprocessorCallable = t.Callable[
[t.Optional[str], t.Optional[t.Dict[str, t.Any]]], None
[t.Optional[str], t.Optional[dict[str, t.Any]]], None
]
# This should take Exception, but that either breaks typing the argument

View file

@ -1,9 +1,9 @@
[tox]
envlist =
py3{13,12,11,10,9,8}
py3{13,12,11,10,9}
pypy310
py312-min
py38-dev
py39-dev
style
typing
docs