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:
parent
dffe303482
commit
5796f50315
9 changed files with 22 additions and 29 deletions
3
.github/workflows/tests.yaml
vendored
3
.github/workflows/tests.yaml
vendored
|
|
@ -28,10 +28,9 @@ jobs:
|
||||||
- {python: '3.11'}
|
- {python: '3.11'}
|
||||||
- {python: '3.10'}
|
- {python: '3.10'}
|
||||||
- {python: '3.9'}
|
- {python: '3.9'}
|
||||||
- {python: '3.8'}
|
|
||||||
- {name: PyPy, python: 'pypy-3.10', tox: pypy310}
|
- {name: PyPy, python: 'pypy-3.10', tox: pypy310}
|
||||||
- {name: Minimum Versions, python: '3.12', tox: py-min}
|
- {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:
|
steps:
|
||||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||||
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
|
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
|
||||||
|
|
|
||||||
|
|
@ -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
|
well as all the HTTP method handlers in views that inherit from the
|
||||||
:class:`flask.views.MethodView` class.
|
: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
|
.. admonition:: Using ``async`` with greenlet
|
||||||
|
|
||||||
When using gevent or eventlet to serve an application or patch the
|
When using gevent or eventlet to serve an application or patch the
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,7 @@ ecosystem remain consistent and compatible.
|
||||||
indicate minimum compatibility support. For example,
|
indicate minimum compatibility support. For example,
|
||||||
``sqlalchemy>=1.4``.
|
``sqlalchemy>=1.4``.
|
||||||
9. Indicate the versions of Python supported using ``python_requires=">=version"``.
|
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
|
.. _PyPI: https://pypi.org/search/?c=Framework+%3A%3A+Flask
|
||||||
.. _Discord Chat: https://discord.gg/pallets
|
.. _Discord Chat: https://discord.gg/pallets
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ Installation
|
||||||
Python Version
|
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
|
Dependencies
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ name = "flask-example-celery"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
description = "Example Flask application with Celery background tasks."
|
description = "Example Flask application with Celery background tasks."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.9"
|
||||||
dependencies = ["flask>=2.2.2", "celery[redis]>=5.2.7"]
|
dependencies = ["flask>=2.2.2", "celery[redis]>=5.2.7"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ classifiers = [
|
||||||
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
||||||
"Typing :: Typed",
|
"Typing :: Typed",
|
||||||
]
|
]
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Werkzeug>=3.0.0",
|
"Werkzeug>=3.0.0",
|
||||||
"Jinja2>=3.1.2",
|
"Jinja2>=3.1.2",
|
||||||
|
|
@ -78,7 +78,7 @@ source = ["flask", "tests"]
|
||||||
source = ["src", "*/site-packages"]
|
source = ["src", "*/site-packages"]
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
python_version = "3.8"
|
python_version = "3.9"
|
||||||
files = ["src/flask", "tests/typing"]
|
files = ["src/flask", "tests/typing"]
|
||||||
show_error_codes = true
|
show_error_codes = true
|
||||||
pretty = true
|
pretty = true
|
||||||
|
|
@ -94,7 +94,7 @@ module = [
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
|
|
||||||
[tool.pyright]
|
[tool.pyright]
|
||||||
pythonVersion = "3.8"
|
pythonVersion = "3.9"
|
||||||
include = ["src/flask", "tests"]
|
include = ["src/flask", "tests"]
|
||||||
typeCheckingMode = "basic"
|
typeCheckingMode = "basic"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import typing as t
|
import typing as t
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import lru_cache
|
from functools import cache
|
||||||
from functools import update_wrapper
|
from functools import update_wrapper
|
||||||
|
|
||||||
import werkzeug.utils
|
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]
|
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]:
|
def _split_blueprint_path(name: str) -> list[str]:
|
||||||
out: list[str] = [name]
|
out: list[str] = [name]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ ResponseValue = t.Union[
|
||||||
"Response",
|
"Response",
|
||||||
str,
|
str,
|
||||||
bytes,
|
bytes,
|
||||||
t.List[t.Any],
|
list[t.Any],
|
||||||
# Only dict is actually accepted, but Mapping allows for TypedDict.
|
# Only dict is actually accepted, but Mapping allows for TypedDict.
|
||||||
t.Mapping[str, t.Any],
|
t.Mapping[str, t.Any],
|
||||||
t.Iterator[str],
|
t.Iterator[str],
|
||||||
|
|
@ -21,21 +21,21 @@ ResponseValue = t.Union[
|
||||||
|
|
||||||
# the possible types for an individual HTTP header
|
# the possible types for an individual HTTP header
|
||||||
# This should be a Union, but mypy doesn't pass unless it's a TypeVar.
|
# 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
|
# the possible types for HTTP headers
|
||||||
HeadersValue = t.Union[
|
HeadersValue = t.Union[
|
||||||
"Headers",
|
"Headers",
|
||||||
t.Mapping[str, HeaderValue],
|
t.Mapping[str, HeaderValue],
|
||||||
t.Sequence[t.Tuple[str, HeaderValue]],
|
t.Sequence[tuple[str, HeaderValue]],
|
||||||
]
|
]
|
||||||
|
|
||||||
# The possible types returned by a route function.
|
# The possible types returned by a route function.
|
||||||
ResponseReturnValue = t.Union[
|
ResponseReturnValue = t.Union[
|
||||||
ResponseValue,
|
ResponseValue,
|
||||||
t.Tuple[ResponseValue, HeadersValue],
|
tuple[ResponseValue, HeadersValue],
|
||||||
t.Tuple[ResponseValue, int],
|
tuple[ResponseValue, int],
|
||||||
t.Tuple[ResponseValue, int, HeadersValue],
|
tuple[ResponseValue, int, HeadersValue],
|
||||||
"WSGIApplication",
|
"WSGIApplication",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -56,21 +56,21 @@ BeforeRequestCallable = t.Union[
|
||||||
t.Callable[[], t.Optional[ResponseReturnValue]],
|
t.Callable[[], t.Optional[ResponseReturnValue]],
|
||||||
t.Callable[[], t.Awaitable[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[
|
TeardownCallable = t.Union[
|
||||||
t.Callable[[t.Optional[BaseException]], None],
|
t.Callable[[t.Optional[BaseException]], None],
|
||||||
t.Callable[[t.Optional[BaseException]], t.Awaitable[None]],
|
t.Callable[[t.Optional[BaseException]], t.Awaitable[None]],
|
||||||
]
|
]
|
||||||
TemplateContextProcessorCallable = t.Union[
|
TemplateContextProcessorCallable = t.Union[
|
||||||
t.Callable[[], t.Dict[str, t.Any]],
|
t.Callable[[], dict[str, t.Any]],
|
||||||
t.Callable[[], t.Awaitable[t.Dict[str, t.Any]]],
|
t.Callable[[], t.Awaitable[dict[str, t.Any]]],
|
||||||
]
|
]
|
||||||
TemplateFilterCallable = t.Callable[..., t.Any]
|
TemplateFilterCallable = t.Callable[..., t.Any]
|
||||||
TemplateGlobalCallable = t.Callable[..., t.Any]
|
TemplateGlobalCallable = t.Callable[..., t.Any]
|
||||||
TemplateTestCallable = t.Callable[..., bool]
|
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[
|
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
|
# This should take Exception, but that either breaks typing the argument
|
||||||
|
|
|
||||||
4
tox.ini
4
tox.ini
|
|
@ -1,9 +1,9 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist =
|
envlist =
|
||||||
py3{13,12,11,10,9,8}
|
py3{13,12,11,10,9}
|
||||||
pypy310
|
pypy310
|
||||||
py312-min
|
py312-min
|
||||||
py38-dev
|
py39-dev
|
||||||
style
|
style
|
||||||
typing
|
typing
|
||||||
docs
|
docs
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue