Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Python 3.6 #1261

Merged
merged 2 commits into from
Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: "${{ matrix.os }}"
strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
os: [windows-latest, ubuntu-latest]
steps:
- uses: "actions/checkout@v2"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

**Documentation**: [https://www.uvicorn.org](https://www.uvicorn.org)

**Requirements**: Python 3.6+ (For Python 3.5 support, install version 0.8.6.)
**Requirements**: Python 3.7+ (For Python 3.6 support, install version 0.15.0.)
euri10 marked this conversation as resolved.
Show resolved Hide resolved

Uvicorn is a lightning-fast ASGI server implementation, using [uvloop][uvloop] and [httptools][httptools].

Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ cryptography==3.4.8
coverage==5.5
httpx==1.0.0b0
pytest-asyncio==0.15.1
async_generator==1.10 ; python_version < '3.7'


# Documentation
Expand Down
7 changes: 1 addition & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ def get_packages(package):

env_marker_win = "sys_platform == 'win32'"
env_marker_below_38 = "python_version < '3.8'"
env_marker_below_37 = "python_version < '3.7'"
env_marker_gte_37 = "python_version >= '3.7'"

minimal_requirements = [
"asgiref>=3.4.0",
Expand All @@ -54,9 +52,7 @@ def get_packages(package):


extra_requirements = [
"websockets>=9.1; " + env_marker_below_37,
"websockets>=10.0; " + env_marker_gte_37,
"httptools>=0.2.0,<0.4.0",
"websockets>=1" "httptools>=0.2.0,<0.4.0",
"uvloop>=0.14.0,!=0.15.0,!=0.15.1; " + env_marker_cpython,
"colorama>=0.4;" + env_marker_win,
"watchgod>=0.6",
Expand Down Expand Up @@ -87,7 +83,6 @@ def get_packages(package):
"Operating System :: OS Independent",
"Topic :: Internet :: WWW/HTTP",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand Down
7 changes: 1 addition & 6 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import asyncio
import os
from contextlib import contextmanager
from contextlib import asynccontextmanager, contextmanager
from pathlib import Path

try:
from contextlib import asynccontextmanager
except ImportError: # pragma: no cover
from async_generator import asynccontextmanager

from uvicorn import Config, Server


Expand Down
15 changes: 2 additions & 13 deletions uvicorn/_handlers/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ async def handle_http(
# So we need to attach a callback to handle exceptions ourselves for that case.
# (It's not easy to know which loop we're effectively running on, so we attach the
# callback in all cases. In practice it won't be called on vanilla asyncio.)
task = _get_current_task()
task = asyncio.current_task()
assert task is not None

@task.add_done_callback
def retrieve_exception(task: asyncio.Task) -> None:
Expand Down Expand Up @@ -85,15 +86,3 @@ def retrieve_exception(task: asyncio.Task) -> None:
# Let the transport run in the background. When closed, this future will complete
# and we'll exit here.
await connection_lost


def _get_current_task() -> asyncio.Task:
try:
current_task = asyncio.current_task # type: ignore
except AttributeError: # pragma: no cover
# Python 3.6.
current_task = asyncio.Task.current_task # type: ignore

task = current_task()
assert task is not None
return task
18 changes: 1 addition & 17 deletions uvicorn/protocols/websockets/websockets_impl.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import asyncio
import http
import logging
import sys
from typing import Callable
from urllib.parse import unquote

Expand All @@ -25,22 +24,7 @@ def is_serving(self):
return not self.closing


# special case logger kwarg in websockets >=10
if sys.version_info >= (3, 7):

class _LoggerMixin:
pass


else:

class _LoggerMixin:
def __init__(self, *args, logger, **kwargs):
super().__init__(*args, **kwargs)
self.logger = logging.LoggerAdapter(logger, {"websocket": self})


class WebSocketProtocol(_LoggerMixin, websockets.WebSocketServerProtocol):
class WebSocketProtocol(websockets.WebSocketServerProtocol):
def __init__(
self, config, server_state, on_connection_lost: Callable = None, _loop=None
):
Expand Down
4 changes: 1 addition & 3 deletions uvicorn/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ def __init__(self, config: Config) -> None:

def run(self, sockets: Optional[List[socket.socket]] = None) -> None:
self.config.setup_event_loop()
if sys.version_info >= (3, 7):
return asyncio.run(self.serve(sockets=sockets))
return asyncio.get_event_loop().run_until_complete(self.serve(sockets=sockets))
return asyncio.run(self.serve(sockets=sockets))

async def serve(self, sockets: Optional[List[socket.socket]] = None) -> None:
process_id = os.getpid()
Expand Down
4 changes: 1 addition & 3 deletions uvicorn/workers.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,7 @@ async def _serve(self) -> None:
sys.exit(Arbiter.WORKER_BOOT_ERROR)

def run(self) -> None:
if sys.version_info >= (3, 7):
return asyncio.run(self._serve())
return asyncio.get_event_loop().run_until_complete(self._serve())
return asyncio.run(self._serve())

async def callback_notify(self) -> None:
self.notify()
Expand Down