Skip to content

Commit

Permalink
Drop Python 3.8.
Browse files Browse the repository at this point in the history
It is EOL at the end of October.
  • Loading branch information
aaugustin committed Sep 21, 2024
1 parent 37c7f65 commit 44ccee1
Show file tree
Hide file tree
Showing 32 changed files with 76 additions and 129 deletions.
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ jobs:
strategy:
matrix:
python:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
Expand Down
3 changes: 1 addition & 2 deletions docs/howto/django.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ authentication fails, it closes the connection and exits.
When we call an API that makes a database query such as ``get_user()``, we
wrap the call in :func:`~asyncio.to_thread`. Indeed, the Django ORM doesn't
support asynchronous I/O. It would block the event loop if it didn't run in a
separate thread. :func:`~asyncio.to_thread` is available since Python 3.9. In
earlier versions, use :meth:`~asyncio.loop.run_in_executor` instead.
separate thread.

Finally, we start a server with :func:`~websockets.asyncio.server.serve`.

Expand Down
2 changes: 1 addition & 1 deletion docs/intro/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Getting started
Requirements
------------

websockets requires Python ≥ 3.8.
websockets requires Python ≥ 3.9.

.. admonition:: Use the most recent Python release
:class: tip
Expand Down
14 changes: 9 additions & 5 deletions docs/project/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ notice.

*In development*

Backwards-incompatible changes
..............................

.. admonition:: websockets 14.0 requires Python ≥ 3.9.
:class: tip

websockets 13.1 is the last version supporting Python 3.8.


.. _13.1:

13.1
Expand Down Expand Up @@ -106,11 +115,6 @@ Bug fixes
Backwards-incompatible changes
..............................

.. admonition:: websockets 13.0 requires Python ≥ 3.8.
:class: tip

websockets 12.0 is the last version supporting Python 3.7.

.. admonition:: Receiving the request path in the second parameter of connection
handlers is deprecated.
:class: note
Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "websockets"
description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
requires-python = ">=3.8"
requires-python = ">=3.9"
license = { text = "BSD-3-Clause" }
authors = [
{ name = "Aymeric Augustin", email = "aymeric.augustin@m4x.org" },
Expand All @@ -19,7 +19,6 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand Down
5 changes: 3 additions & 2 deletions src/websockets/asyncio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import logging
import os
import urllib.parse
from collections.abc import AsyncIterator, Generator, Sequence
from types import TracebackType
from typing import Any, AsyncIterator, Callable, Generator, Sequence
from typing import Any, Callable

from ..client import ClientProtocol, backoff
from ..datastructures import HeadersLike
Expand Down Expand Up @@ -492,7 +493,7 @@ async def __aexit__(
# async for ... in connect(...):

async def __aiter__(self) -> AsyncIterator[ClientConnection]:
delays: Generator[float, None, None] | None = None
delays: Generator[float] | None = None
while True:
try:
async with self as protocol:
Expand Down
11 changes: 2 additions & 9 deletions src/websockets/asyncio/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,9 @@
import struct
import sys
import uuid
from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Iterable, Mapping
from types import TracebackType
from typing import (
Any,
AsyncIterable,
AsyncIterator,
Awaitable,
Iterable,
Mapping,
cast,
)
from typing import Any, cast

from ..exceptions import (
ConcurrencyError,
Expand Down
10 changes: 2 additions & 8 deletions src/websockets/asyncio/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,8 @@
import asyncio
import codecs
import collections
from typing import (
Any,
AsyncIterator,
Callable,
Generic,
Iterable,
TypeVar,
)
from collections.abc import AsyncIterator, Iterable
from typing import Any, Callable, Generic, TypeVar

from ..exceptions import ConcurrencyError
from ..frames import OP_BINARY, OP_CONT, OP_TEXT, Frame
Expand Down
16 changes: 4 additions & 12 deletions src/websockets/asyncio/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,9 @@
import logging
import socket
import sys
from collections.abc import Awaitable, Generator, Iterable, Sequence
from types import TracebackType
from typing import (
Any,
Awaitable,
Callable,
Generator,
Iterable,
Sequence,
Tuple,
cast,
)
from typing import Any, Callable, cast

from ..exceptions import InvalidHeader
from ..extensions.base import ServerExtensionFactory
Expand Down Expand Up @@ -905,9 +897,9 @@ def basic_auth(

if credentials is not None:
if is_credentials(credentials):
credentials_list = [cast(Tuple[str, str], credentials)]
credentials_list = [cast(tuple[str, str], credentials)]
elif isinstance(credentials, Iterable):
credentials_list = list(cast(Iterable[Tuple[str, str]], credentials))
credentials_list = list(cast(Iterable[tuple[str, str]], credentials))
if not all(is_credentials(item) for item in credentials_list):
raise TypeError(f"invalid credentials argument: {credentials}")
else:
Expand Down
7 changes: 4 additions & 3 deletions src/websockets/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import os
import random
import warnings
from typing import Any, Generator, Sequence
from collections.abc import Generator, Sequence
from typing import Any

from .datastructures import Headers, MultipleValuesError
from .exceptions import (
Expand Down Expand Up @@ -313,7 +314,7 @@ def send_request(self, request: Request) -> None:

self.writes.append(request.serialize())

def parse(self) -> Generator[None, None, None]:
def parse(self) -> Generator[None]:
if self.state is CONNECTING:
try:
response = yield from Response.parse(
Expand Down Expand Up @@ -374,7 +375,7 @@ def backoff(
min_delay: float = BACKOFF_MIN_DELAY,
max_delay: float = BACKOFF_MAX_DELAY,
factor: float = BACKOFF_FACTOR,
) -> Generator[float, None, None]:
) -> Generator[float]:
"""
Generate a series of backoff delays between reconnection attempts.
Expand Down
15 changes: 3 additions & 12 deletions src/websockets/datastructures.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
from __future__ import annotations

from typing import (
Any,
Iterable,
Iterator,
Mapping,
MutableMapping,
Protocol,
Tuple,
Union,
)
from collections.abc import Iterable, Iterator, Mapping, MutableMapping
from typing import Any, Protocol, Union


__all__ = ["Headers", "HeadersLike", "MultipleValuesError"]
Expand Down Expand Up @@ -179,8 +171,7 @@ def __getitem__(self, key: str) -> str: ...
HeadersLike = Union[
Headers,
Mapping[str, str],
# Change to tuple[str, str] when dropping Python < 3.9.
Iterable[Tuple[str, str]],
Iterable[tuple[str, str]],
SupportsKeysAndGetItem,
]
"""
Expand Down
2 changes: 1 addition & 1 deletion src/websockets/extensions/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Sequence
from collections.abc import Sequence

from ..frames import Frame
from ..typing import ExtensionName, ExtensionParameter
Expand Down
3 changes: 2 additions & 1 deletion src/websockets/extensions/permessage_deflate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import dataclasses
import zlib
from typing import Any, Sequence
from collections.abc import Sequence
from typing import Any

from .. import frames
from ..exceptions import (
Expand Down
3 changes: 2 additions & 1 deletion src/websockets/frames.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import os
import secrets
import struct
from typing import Callable, Generator, Sequence
from collections.abc import Generator, Sequence
from typing import Callable

from .exceptions import PayloadTooBig, ProtocolError

Expand Down
3 changes: 2 additions & 1 deletion src/websockets/headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import binascii
import ipaddress
import re
from typing import Callable, Sequence, TypeVar, cast
from collections.abc import Sequence
from typing import Callable, TypeVar, cast

from .exceptions import InvalidHeaderFormat, InvalidHeaderValue
from .typing import (
Expand Down
3 changes: 2 additions & 1 deletion src/websockets/http11.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import re
import sys
import warnings
from typing import Callable, Generator
from collections.abc import Generator
from typing import Callable

from .datastructures import Headers
from .exceptions import SecurityError
Expand Down
3 changes: 2 additions & 1 deletion src/websockets/imports.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import warnings
from typing import Any, Iterable
from collections.abc import Iterable
from typing import Any


__all__ = ["lazy_import"]
Expand Down
6 changes: 3 additions & 3 deletions src/websockets/legacy/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import functools
import hmac
import http
from typing import Any, Awaitable, Callable, Iterable, Tuple, cast
from collections.abc import Awaitable, Iterable
from typing import Any, Callable, cast

from ..datastructures import Headers
from ..exceptions import InvalidHeader
Expand All @@ -13,8 +14,7 @@

__all__ = ["BasicAuthWebSocketServerProtocol", "basic_auth_protocol_factory"]

# Change to tuple[str, str] when dropping Python < 3.9.
Credentials = Tuple[str, str]
Credentials = tuple[str, str]


def is_credentials(value: Any) -> bool:
Expand Down
10 changes: 2 additions & 8 deletions src/websockets/legacy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,9 @@
import random
import urllib.parse
import warnings
from collections.abc import AsyncIterator, Generator, Sequence
from types import TracebackType
from typing import (
Any,
AsyncIterator,
Callable,
Generator,
Sequence,
cast,
)
from typing import Any, Callable, cast

from ..asyncio.compatibility import asyncio_timeout
from ..datastructures import Headers, HeadersLike
Expand Down
3 changes: 2 additions & 1 deletion src/websockets/legacy/framing.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import struct
from typing import Any, Awaitable, Callable, NamedTuple, Sequence
from collections.abc import Awaitable, Sequence
from typing import Any, Callable, NamedTuple

from .. import extensions, frames
from ..exceptions import PayloadTooBig, ProtocolError
Expand Down
13 changes: 2 additions & 11 deletions src/websockets/legacy/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,8 @@
import time
import uuid
import warnings
from typing import (
Any,
AsyncIterable,
AsyncIterator,
Awaitable,
Callable,
Deque,
Iterable,
Mapping,
cast,
)
from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Iterable, Mapping
from typing import Any, Callable, Deque, cast

from ..asyncio.compatibility import asyncio_timeout
from ..datastructures import Headers
Expand Down
16 changes: 3 additions & 13 deletions src/websockets/legacy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,9 @@
import logging
import socket
import warnings
from collections.abc import Awaitable, Generator, Iterable, Sequence
from types import TracebackType
from typing import (
Any,
Awaitable,
Callable,
Generator,
Iterable,
Sequence,
Tuple,
Union,
cast,
)
from typing import Any, Callable, Union, cast

from ..asyncio.compatibility import asyncio_timeout
from ..datastructures import Headers, HeadersLike, MultipleValuesError
Expand Down Expand Up @@ -59,8 +50,7 @@
# Change to HeadersLike | ... when dropping Python < 3.10.
HeadersLikeOrCallable = Union[HeadersLike, Callable[[str, Headers], HeadersLike]]

# Change to tuple[...] when dropping Python < 3.9.
HTTPResponse = Tuple[StatusLike, HeadersLike, bytes]
HTTPResponse = tuple[StatusLike, HeadersLike, bytes]


class WebSocketServerProtocol(WebSocketCommonProtocol):
Expand Down
Loading

0 comments on commit 44ccee1

Please sign in to comment.