From ffa5b1ac96b10976ed0e092a0bc1dd5526101356 Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Mon, 19 Jun 2023 08:36:24 +0200 Subject: [PATCH] Drop support for Python 3.7 (#1996) --- .github/workflows/publish.yml | 2 +- .github/workflows/test-suite.yml | 2 +- README.md | 2 +- pyproject.toml | 4 +--- tests/test_config.py | 7 +------ uvicorn/config.py | 9 ++------- uvicorn/logging.py | 7 +------ uvicorn/loops/asyncio.py | 2 +- uvicorn/protocols/http/h11_impl.py | 8 +------- uvicorn/protocols/http/httptools_impl.py | 8 +------- uvicorn/protocols/websockets/websockets_impl.py | 7 +------ uvicorn/protocols/websockets/wsproto_impl.py | 7 +------ 12 files changed, 13 insertions(+), 52 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d87dd2d36..f77310089 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,7 +17,7 @@ jobs: - uses: "actions/checkout@v3" - uses: "actions/setup-python@v4" with: - python-version: 3.7 + python-version: "3.8" - name: "Install dependencies" run: "scripts/install" - name: "Build package & docs" diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index ff82ebdfb..e1346b11a 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -13,7 +13,7 @@ jobs: runs-on: "${{ matrix.os }}" strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8", "3.9", "3.10", "3.11"] os: [windows-latest, ubuntu-latest, macos-latest] steps: - uses: "actions/checkout@v3" diff --git a/README.md b/README.md index 7cd56398b..82bc37379 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ **Documentation**: [https://www.uvicorn.org](https://www.uvicorn.org) -**Requirements**: Python 3.7+ (For Python 3.6 support, install version 0.16.0.) +**Requirements**: Python 3.8+ Uvicorn is an ASGI web server implementation for Python. diff --git a/pyproject.toml b/pyproject.toml index c7d6ad9ad..9e1626565 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ dynamic = ["version"] description = "The lightning-fast ASGI server." readme = "README.md" license = "BSD-3-Clause" -requires-python = ">=3.7" +requires-python = ">=3.8" authors = [ { name = "Tom Christie", email = "tom@tomchristie.com" }, ] @@ -19,7 +19,6 @@ classifiers = [ "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", @@ -31,7 +30,6 @@ classifiers = [ dependencies = [ "click>=7.0", "h11>=0.8", - "typing-extensions;python_version < '3.8'", ] [project.optional-dependencies] diff --git a/tests/test_config.py b/tests/test_config.py index 9be19207e..9413fed80 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -5,7 +5,7 @@ import sys import typing from pathlib import Path -from typing import Optional +from typing import Literal, Optional from unittest.mock import MagicMock import pytest @@ -26,11 +26,6 @@ from uvicorn.middleware.wsgi import WSGIMiddleware from uvicorn.protocols.http.h11_impl import H11Protocol -if sys.version_info < (3, 8): # pragma: py-gte-38 - from typing_extensions import Literal -else: # pragma: py-lt-38 - from typing import Literal - @pytest.fixture def mocked_logging_config_module(mocker: MockerFixture) -> MagicMock: diff --git a/uvicorn/config.py b/uvicorn/config.py index 2e52fd277..f9850a8a8 100644 --- a/uvicorn/config.py +++ b/uvicorn/config.py @@ -14,23 +14,18 @@ Callable, Dict, List, + Literal, Optional, Tuple, Type, Union, ) -from uvicorn.logging import TRACE_LOG_LEVEL - -if sys.version_info < (3, 8): # pragma: py-gte-38 - from typing_extensions import Literal -else: # pragma: py-lt-38 - from typing import Literal - import click from uvicorn._types import ASGIApplication from uvicorn.importer import ImportFromStringError, import_from_string +from uvicorn.logging import TRACE_LOG_LEVEL from uvicorn.middleware.asgi2 import ASGI2Middleware from uvicorn.middleware.message_logger import MessageLoggerMiddleware from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware diff --git a/uvicorn/logging.py b/uvicorn/logging.py index b12a710d0..c88d5fe55 100644 --- a/uvicorn/logging.py +++ b/uvicorn/logging.py @@ -2,15 +2,10 @@ import logging import sys from copy import copy -from typing import Optional +from typing import Literal, Optional import click -if sys.version_info < (3, 8): # pragma: py-gte-38 - from typing_extensions import Literal -else: # pragma: py-lt-38 - from typing import Literal - TRACE_LOG_LEVEL = 5 diff --git a/uvicorn/loops/asyncio.py b/uvicorn/loops/asyncio.py index 867545f2a..959cfc7fe 100644 --- a/uvicorn/loops/asyncio.py +++ b/uvicorn/loops/asyncio.py @@ -6,5 +6,5 @@ def asyncio_setup(use_subprocess: bool = False) -> None: # pragma: no cover - if sys.version_info >= (3, 8) and sys.platform == "win32" and use_subprocess: + if sys.platform == "win32" and use_subprocess: asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) diff --git a/uvicorn/protocols/http/h11_impl.py b/uvicorn/protocols/http/h11_impl.py index e9a68fe86..652cf9bfd 100644 --- a/uvicorn/protocols/http/h11_impl.py +++ b/uvicorn/protocols/http/h11_impl.py @@ -1,12 +1,12 @@ import asyncio import http import logging -import sys from typing import ( Any, Callable, Dict, List, + Literal, Optional, Tuple, Union, @@ -44,12 +44,6 @@ ) from uvicorn.server import ServerState -if sys.version_info < (3, 8): # pragma: py-gte-38 - from typing_extensions import Literal -else: # pragma: py-lt-38 - from typing import Literal - - H11Event = Union[ h11.Request, h11.InformationalResponse, diff --git a/uvicorn/protocols/http/httptools_impl.py b/uvicorn/protocols/http/httptools_impl.py index a1000fb08..8d1a0543c 100644 --- a/uvicorn/protocols/http/httptools_impl.py +++ b/uvicorn/protocols/http/httptools_impl.py @@ -2,7 +2,6 @@ import http import logging import re -import sys import urllib from asyncio.events import TimerHandle from collections import deque @@ -12,6 +11,7 @@ Deque, Dict, List, + Literal, Optional, Tuple, Union, @@ -47,12 +47,6 @@ ) from uvicorn.server import ServerState -if sys.version_info < (3, 8): # pragma: py-gte-38 - from typing_extensions import Literal -else: # pragma: py-lt-38 - from typing import Literal - - HEADER_RE = re.compile(b'[\x00-\x1F\x7F()<>@,;:[]={} \t\\"]') HEADER_VALUE_RE = re.compile(b"[\x00-\x1F\x7F]") diff --git a/uvicorn/protocols/websockets/websockets_impl.py b/uvicorn/protocols/websockets/websockets_impl.py index 19f4f326f..2cc9ebc13 100644 --- a/uvicorn/protocols/websockets/websockets_impl.py +++ b/uvicorn/protocols/websockets/websockets_impl.py @@ -1,11 +1,11 @@ import asyncio import http import logging -import sys from typing import ( Any, Dict, List, + Literal, Optional, Sequence, Tuple, @@ -42,11 +42,6 @@ ) from uvicorn.server import ServerState -if sys.version_info < (3, 8): # pragma: py-gte-38 - from typing_extensions import Literal -else: # pragma: py-lt-38 - from typing import Literal - class Server: closing = False diff --git a/uvicorn/protocols/websockets/wsproto_impl.py b/uvicorn/protocols/websockets/wsproto_impl.py index 90aaf9fd0..aa4bec8f2 100644 --- a/uvicorn/protocols/websockets/wsproto_impl.py +++ b/uvicorn/protocols/websockets/wsproto_impl.py @@ -1,7 +1,7 @@ import asyncio import logging -import sys import typing +from typing import Literal from urllib.parse import unquote import wsproto @@ -29,11 +29,6 @@ ) from uvicorn.server import ServerState -if sys.version_info < (3, 8): # pragma: py-gte-38 - from typing_extensions import Literal -else: # pragma: py-lt-38 - from typing import Literal - class WSProtocol(asyncio.Protocol): def __init__(