drop support for python 3.7

This commit is contained in:
David Lord 2023-04-20 11:07:30 -07:00
parent 9659b11a45
commit 2e8fe7b2f2
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
14 changed files with 19 additions and 40 deletions

View file

@ -31,10 +31,9 @@ jobs:
- {name: '3.10', python: '3.10', os: ubuntu-latest, tox: py310} - {name: '3.10', python: '3.10', os: ubuntu-latest, tox: py310}
- {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39} - {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39}
- {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38} - {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38}
- {name: '3.7', python: '3.7', os: ubuntu-latest, tox: py37}
- {name: 'PyPy', python: 'pypy-3.9', os: ubuntu-latest, tox: pypy39} - {name: 'PyPy', python: 'pypy-3.9', os: ubuntu-latest, tox: pypy39}
- {name: 'Minimum Versions', python: '3.11', os: ubuntu-latest, tox: py311-min} - {name: 'Minimum Versions', python: '3.11', os: ubuntu-latest, tox: py311-min}
- {name: 'Development Versions', python: '3.7', os: ubuntu-latest, tox: py37-dev} - {name: 'Development Versions', python: '3.8', os: ubuntu-latest, tox: py38-dev}
- {name: Typing, python: '3.11', os: ubuntu-latest, tox: typing} - {name: Typing, python: '3.11', os: ubuntu-latest, tox: typing}
steps: steps:
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3

View file

@ -6,7 +6,7 @@ repos:
rev: v3.3.1 rev: v3.3.1
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: ["--py37-plus"] args: ["--py38-plus"]
- repo: https://github.com/asottile/reorder_python_imports - repo: https://github.com/asottile/reorder_python_imports
rev: v3.9.0 rev: v3.9.0
hooks: hooks:

View file

@ -3,6 +3,7 @@ Version 2.3.0
Unreleased Unreleased
- Drop support for Python 3.7. :pr:`5072`
- Remove previously deprecated code. :pr:`4995` - Remove previously deprecated code. :pr:`4995`
- The ``push`` and ``pop`` methods of the deprecated ``_app_ctx_stack`` and - The ``push`` and ``pop`` methods of the deprecated ``_app_ctx_stack`` and

View file

@ -293,9 +293,8 @@ ecosystem remain consistent and compatible.
any particular version scheme, but should use lower bounds to any particular version scheme, but should use lower bounds to
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 9. Indicate the versions of Python supported using ``python_requires=">=version"``.
``python_requires=">=version"``. Flask itself supports Python >=3.7 Flask itself supports Python >=3.8 as of April 2023, but this will update over time.
as of December 2021, 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

View file

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

View file

@ -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.7" requires-python = ">=3.8"
dependencies = ["flask>=2.2.2", "celery[redis]>=5.2.7"] dependencies = ["flask>=2.2.2", "celery[redis]>=5.2.7"]
[build-system] [build-system]

View file

@ -18,7 +18,7 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
"Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Application Frameworks",
] ]
requires-python = ">=3.7" requires-python = ">=3.8"
dependencies = [ dependencies = [
"Werkzeug>=2.2.2", "Werkzeug>=2.2.2",
"Jinja2>=3.0", "Jinja2>=3.0",
@ -67,7 +67,7 @@ source = ["flask", "tests"]
source = ["src", "*/site-packages"] source = ["src", "*/site-packages"]
[tool.mypy] [tool.mypy]
python_version = "3.7" python_version = "3.8"
files = ["src/flask"] files = ["src/flask"]
show_error_codes = true show_error_codes = true
pretty = true pretty = true

View file

@ -1,4 +1,4 @@
pytest pytest
asgiref asgiref
greenlet ; python_version < "3.11" greenlet ; python_version < "3.11"
python-dotenv>=1; python_version >= "3.8" python-dotenv

View file

@ -1,4 +1,4 @@
# SHA1:3c8dde35aba20388b22430b17974af8ef8205b4f # SHA1:42d37aff22e2f1fc447e20d483e13d6d4e066b10
# #
# This file is autogenerated by pip-compile-multi # This file is autogenerated by pip-compile-multi
# To update, run: # To update, run:
@ -15,5 +15,5 @@ pluggy==1.0.0
# via pytest # via pytest
pytest==7.3.1 pytest==7.3.1
# via -r requirements/tests.in # via -r requirements/tests.in
python-dotenv==1.0.0 ; python_version >= "3.8" python-dotenv==1.0.0
# via -r requirements/tests.in # via -r requirements/tests.in

View file

@ -1,7 +1,5 @@
from __future__ import annotations from __future__ import annotations
import functools
import inspect
import logging import logging
import os import os
import sys import sys
@ -9,6 +7,7 @@ import typing as t
import weakref import weakref
from collections.abc import Iterator as _abc_Iterator from collections.abc import Iterator as _abc_Iterator
from datetime import timedelta from datetime import timedelta
from inspect import iscoroutinefunction
from itertools import chain from itertools import chain
from types import TracebackType from types import TracebackType
from urllib.parse import quote as _url_quote from urllib.parse import quote as _url_quote
@ -70,7 +69,6 @@ from .wrappers import Request
from .wrappers import Response from .wrappers import Response
if t.TYPE_CHECKING: # pragma: no cover if t.TYPE_CHECKING: # pragma: no cover
import typing_extensions as te
from .blueprints import Blueprint from .blueprints import Blueprint
from .testing import FlaskClient from .testing import FlaskClient
from .testing import FlaskCliRunner from .testing import FlaskCliRunner
@ -83,19 +81,6 @@ T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallab
T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable)
T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable)
if sys.version_info >= (3, 8):
iscoroutinefunction = inspect.iscoroutinefunction
else:
def iscoroutinefunction(func: t.Any) -> bool:
while inspect.ismethod(func):
func = func.__func__
while isinstance(func, functools.partial):
func = func.func
return inspect.iscoroutinefunction(func)
def _make_timedelta(value: timedelta | int | None) -> timedelta | None: def _make_timedelta(value: timedelta | int | None) -> timedelta | None:
if value is None or isinstance(value, timedelta): if value is None or isinstance(value, timedelta):
@ -1430,7 +1415,7 @@ class Flask(Scaffold):
f"Exception on {request.path} [{request.method}]", exc_info=exc_info f"Exception on {request.path} [{request.method}]", exc_info=exc_info
) )
def raise_routing_exception(self, request: Request) -> te.NoReturn: def raise_routing_exception(self, request: Request) -> t.NoReturn:
"""Intercept routing exceptions and possibly do something else. """Intercept routing exceptions and possibly do something else.
In debug mode, intercept a routing redirect and replace it with In debug mode, intercept a routing redirect and replace it with

View file

@ -25,7 +25,6 @@ from .signals import message_flashed
if t.TYPE_CHECKING: # pragma: no cover if t.TYPE_CHECKING: # pragma: no cover
from werkzeug.wrappers import Response as BaseResponse from werkzeug.wrappers import Response as BaseResponse
from .wrappers import Response from .wrappers import Response
import typing_extensions as te
def get_debug_flag() -> bool: def get_debug_flag() -> bool:
@ -257,7 +256,7 @@ def redirect(
return _wz_redirect(location, code=code, Response=Response) return _wz_redirect(location, code=code, Response=Response)
def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> te.NoReturn: def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> t.NoReturn:
"""Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given """Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given
status code. status code.

View file

@ -13,7 +13,6 @@ from werkzeug.datastructures import CallbackDict
from .json.tag import TaggedJSONSerializer from .json.tag import TaggedJSONSerializer
if t.TYPE_CHECKING: # pragma: no cover if t.TYPE_CHECKING: # pragma: no cover
import typing_extensions as te
from .app import Flask from .app import Flask
from .wrappers import Request, Response from .wrappers import Request, Response
@ -94,7 +93,7 @@ class NullSession(SecureCookieSession):
but fail on setting. but fail on setting.
""" """
def _fail(self, *args: t.Any, **kwargs: t.Any) -> te.NoReturn: def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn:
raise RuntimeError( raise RuntimeError(
"The session is unavailable because no secret " "The session is unavailable because no secret "
"key was set. Set the secret_key on the " "key was set. Set the secret_key on the "

View file

@ -3,8 +3,6 @@ from __future__ import annotations
import typing as t import typing as t
from http import HTTPStatus from http import HTTPStatus
import typing_extensions as te
from flask import Flask from flask import Flask
from flask import jsonify from flask import jsonify
from flask import stream_template from flask import stream_template
@ -40,7 +38,7 @@ def hello_json_list() -> t.List[t.Any]:
return [{"message": "Hello"}, {"message": "World"}] return [{"message": "Hello"}, {"message": "World"}]
class StatusJSON(te.TypedDict): class StatusJSON(t.TypedDict):
status: str status: str

View file

@ -1,9 +1,9 @@
[tox] [tox]
envlist = envlist =
py3{12,11,10,9,8,7} py3{12,11,10,9,8}
pypy39 pypy39
py311-min py311-min
py37-dev py38-dev
style style
typing typing
docs docs