Merge remote-tracking branch 'origin/2.1.x'

This commit is contained in:
David Lord 2022-05-23 10:08:52 -07:00
commit 1888df3440
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
8 changed files with 53 additions and 48 deletions

View file

@ -3,7 +3,7 @@ ci:
autoupdate_schedule: monthly autoupdate_schedule: monthly
repos: repos:
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v2.32.0 rev: v2.32.1
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: ["--py36-plus"] args: ["--py36-plus"]

View file

@ -10,19 +10,19 @@
-r typing.txt -r typing.txt
cfgv==3.3.1 cfgv==3.3.1
# via pre-commit # via pre-commit
click==8.1.2 click==8.1.3
# via # via
# pip-compile-multi # pip-compile-multi
# pip-tools # pip-tools
distlib==0.3.4 distlib==0.3.4
# via virtualenv # via virtualenv
filelock==3.6.0 filelock==3.7.0
# via # via
# tox # tox
# virtualenv # virtualenv
greenlet==1.1.2 ; python_version < "3.11" greenlet==1.1.2 ; python_version < "3.11"
# via -r requirements/tests.in # via -r requirements/tests.in
identify==2.5.0 identify==2.5.1
# via pre-commit # via pre-commit
nodeenv==1.6.0 nodeenv==1.6.0
# via pre-commit # via pre-commit
@ -30,11 +30,11 @@ pep517==0.12.0
# via pip-tools # via pip-tools
pip-compile-multi==2.4.5 pip-compile-multi==2.4.5
# via -r requirements/dev.in # via -r requirements/dev.in
pip-tools==6.6.0 pip-tools==6.6.1
# via pip-compile-multi # via pip-compile-multi
platformdirs==2.5.2 platformdirs==2.5.2
# via virtualenv # via virtualenv
pre-commit==2.18.1 pre-commit==2.19.0
# via -r requirements/dev.in # via -r requirements/dev.in
pyyaml==6.0 pyyaml==6.0
# via pre-commit # via pre-commit

View file

@ -9,7 +9,7 @@ alabaster==0.7.12
# via sphinx # via sphinx
babel==2.10.1 babel==2.10.1
# via sphinx # via sphinx
certifi==2021.10.8 certifi==2022.5.18.1
# via requests # via requests
charset-normalizer==2.0.12 charset-normalizer==2.0.12
# via requests # via requests
@ -21,7 +21,7 @@ idna==3.3
# via requests # via requests
imagesize==1.3.0 imagesize==1.3.0
# via sphinx # via sphinx
jinja2==3.1.1 jinja2==3.1.2
# via sphinx # via sphinx
markupsafe==2.1.1 markupsafe==2.1.1
# via jinja2 # via jinja2
@ -35,7 +35,7 @@ pygments==2.12.0
# via # via
# sphinx # sphinx
# sphinx-tabs # sphinx-tabs
pyparsing==3.0.8 pyparsing==3.0.9
# via packaging # via packaging
pytz==2022.1 pytz==2022.1
# via babel # via babel

View file

@ -5,7 +5,7 @@
# #
# pip-compile-multi # pip-compile-multi
# #
asgiref==3.5.0 asgiref==3.5.2
# via -r requirements/tests.in # via -r requirements/tests.in
attrs==21.4.0 attrs==21.4.0
# via pytest # via pytest
@ -21,7 +21,7 @@ pluggy==1.0.0
# via pytest # via pytest
py==1.11.0 py==1.11.0
# via pytest # via pytest
pyparsing==3.0.8 pyparsing==3.0.9
# via packaging # via packaging
pytest==7.1.2 pytest==7.1.2
# via -r requirements/tests.in # via -r requirements/tests.in

View file

@ -7,7 +7,7 @@
# #
cffi==1.15.0 cffi==1.15.0
# via cryptography # via cryptography
cryptography==37.0.1 cryptography==37.0.2
# via -r requirements/typing.in # via -r requirements/typing.in
mypy==0.950 mypy==0.950
# via -r requirements/typing.in # via -r requirements/typing.in
@ -21,7 +21,7 @@ types-contextvars==2.4.5
# via -r requirements/typing.in # via -r requirements/typing.in
types-dataclasses==0.6.5 types-dataclasses==0.6.5
# via -r requirements/typing.in # via -r requirements/typing.in
types-setuptools==57.4.14 types-setuptools==57.4.15
# via -r requirements/typing.in # via -r requirements/typing.in
typing-extensions==4.2.0 typing-extensions==4.2.0
# via mypy # via mypy

View file

@ -116,3 +116,6 @@ ignore_missing_imports = True
[mypy-cryptography.*] [mypy-cryptography.*]
ignore_missing_imports = True ignore_missing_imports = True
[mypy-importlib_metadata]
ignore_missing_imports = True

View file

@ -9,8 +9,6 @@ from functools import update_wrapper
from operator import attrgetter from operator import attrgetter
from threading import Lock from threading import Lock
from threading import Thread from threading import Thread
from typing import Any
from typing import TYPE_CHECKING
import click import click
from werkzeug.utils import import_string from werkzeug.utils import import_string
@ -20,31 +18,6 @@ from .helpers import get_debug_flag
from .helpers import get_env from .helpers import get_env
from .helpers import get_load_dotenv from .helpers import get_load_dotenv
try:
import dotenv
except ImportError:
dotenv = None
try:
import ssl
except ImportError:
ssl = None # type: ignore
if sys.version_info >= (3, 10):
from importlib import metadata
else:
# Use a backport on Python < 3.10.
#
# We technically have importlib.metadata on 3.8+,
# but the API changed in 3.10, so use the backport
# for consistency.
if TYPE_CHECKING:
metadata: Any
else:
# we do this to avoid a version dependent mypy error
# because importlib_metadata is not installed in python3.10+
import importlib_metadata as metadata
class NoAppException(click.UsageError): class NoAppException(click.UsageError):
"""Raised if an application cannot be found or loaded.""" """Raised if an application cannot be found or loaded."""
@ -520,6 +493,14 @@ class FlaskGroup(AppGroup):
if self._loaded_plugin_commands: if self._loaded_plugin_commands:
return return
if sys.version_info >= (3, 10):
from importlib import metadata
else:
# Use a backport on Python < 3.10. We technically have
# importlib.metadata on 3.8+, but the API changed in 3.10,
# so use the backport for consistency.
import importlib_metadata as metadata
for ep in metadata.entry_points(group="flask.commands"): for ep in metadata.entry_points(group="flask.commands"):
self.add_command(ep.load(), ep.name) self.add_command(ep.load(), ep.name)
@ -615,7 +596,9 @@ def load_dotenv(path=None):
.. versionadded:: 1.0 .. versionadded:: 1.0
""" """
if dotenv is None: try:
import dotenv
except ImportError:
if path or os.path.isfile(".env") or os.path.isfile(".flaskenv"): if path or os.path.isfile(".env") or os.path.isfile(".flaskenv"):
click.secho( click.secho(
" * Tip: There are .env or .flaskenv files present." " * Tip: There are .env or .flaskenv files present."
@ -691,12 +674,14 @@ class CertParamType(click.ParamType):
self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True)
def convert(self, value, param, ctx): def convert(self, value, param, ctx):
if ssl is None: try:
import ssl
except ImportError:
raise click.BadParameter( raise click.BadParameter(
'Using "--cert" requires Python to be compiled with SSL support.', 'Using "--cert" requires Python to be compiled with SSL support.',
ctx, ctx,
param, param,
) ) from None
try: try:
return self.path_type(value, param, ctx) return self.path_type(value, param, ctx)
@ -729,7 +714,13 @@ def _validate_key(ctx, param, value):
""" """
cert = ctx.params.get("cert") cert = ctx.params.get("cert")
is_adhoc = cert == "adhoc" is_adhoc = cert == "adhoc"
is_context = ssl and isinstance(cert, ssl.SSLContext)
try:
import ssl
except ImportError:
is_context = False
else:
is_context = isinstance(cert, ssl.SSLContext)
if value is not None: if value is not None:
if is_adhoc: if is_adhoc:

View file

@ -18,7 +18,6 @@ from flask import current_app
from flask import Flask from flask import Flask
from flask.cli import AppGroup from flask.cli import AppGroup
from flask.cli import DispatchingApp from flask.cli import DispatchingApp
from flask.cli import dotenv
from flask.cli import find_best_app from flask.cli import find_best_app
from flask.cli import FlaskGroup from flask.cli import FlaskGroup
from flask.cli import get_version from flask.cli import get_version
@ -492,7 +491,18 @@ class TestRoutes:
assert "No routes were registered." in result.output assert "No routes were registered." in result.output
need_dotenv = pytest.mark.skipif(dotenv is None, reason="dotenv is not installed") def dotenv_not_available():
try:
import dotenv # noqa: F401
except ImportError:
return True
return False
need_dotenv = pytest.mark.skipif(
dotenv_not_available(), reason="dotenv is not installed"
)
@need_dotenv @need_dotenv
@ -530,7 +540,7 @@ def test_dotenv_path(monkeypatch):
def test_dotenv_optional(monkeypatch): def test_dotenv_optional(monkeypatch):
monkeypatch.setattr("flask.cli.dotenv", None) monkeypatch.setitem(sys.modules, "dotenv", None)
monkeypatch.chdir(test_path) monkeypatch.chdir(test_path)
load_dotenv() load_dotenv()
assert "FOO" not in os.environ assert "FOO" not in os.environ
@ -602,7 +612,8 @@ def test_run_cert_import(monkeypatch):
def test_run_cert_no_ssl(monkeypatch): def test_run_cert_no_ssl(monkeypatch):
monkeypatch.setattr("flask.cli.ssl", None) monkeypatch.setitem(sys.modules, "ssl", None)
with pytest.raises(click.BadParameter): with pytest.raises(click.BadParameter):
run_command.make_context("run", ["--cert", "not_here"]) run_command.make_context("run", ["--cert", "not_here"])