Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 0 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ jobs:
- macos-15-intel
- macos-latest
python:
- "cp38"
- "cp39"
- "cp310"
- "cp311"
Expand Down Expand Up @@ -128,12 +127,7 @@ jobs:
brew install gnu-sed libtool autoconf automake openssl@3
echo "OPENSSL_DIR=$(brew --prefix openssl@3)" >> "$GITHUB_ENV"

# cibuildwheel 4 added Python 3.15 but removed Python 3.8.
- uses: pypa/cibuildwheel@7c619efba910c04005a835b110b057fc28fd6e93 # v3.2.0
if: matrix.python == 'cp38'

- uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
if: matrix.python != 'cp38'
env:
CIBW_BEFORE_ALL_LINUX: >-
${{ matrix.python == 'cp315t' && 'bash {project}/.github/workflows/install-linux-test-deps.sh' || '' }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ jobs:
fail-fast: false
matrix:
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ about it.
Installation
------------

uvloop requires Python 3.8 or greater and is available on PyPI.
uvloop requires Python 3.9 or greater and is available on PyPI.
Use pip to install it::

$ pip install uvloop
Expand Down Expand Up @@ -96,7 +96,7 @@ snippet can be used:
Building From Source
--------------------

To build uvloop, you'll need Python 3.8 or greater:
To build uvloop, you'll need Python 3.9 or greater:

1. Clone the repository:

Expand Down
2 changes: 1 addition & 1 deletion docs/dev/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ from the `libuv` Github repository.
Build
-----

To build `uvloop`, you'll need ``Cython`` and Python 3.8.
To build `uvloop`, you'll need ``Cython`` and Python 3.9 or greater.

.. note::

Expand Down
2 changes: 1 addition & 1 deletion docs/user/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ uvloop.
Installation
------------

`uvloop` is available from PyPI. It requires Python 3.8.
`uvloop` is available from PyPI. It requires Python 3.9 or greater.

Use pip to install it.

Expand Down
7 changes: 2 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "uvloop"
description = "Fast implementation of asyncio event loop on top of libuv"
authors = [{name = "Yury Selivanov", email = "yury@magic.io"}]
requires-python = '>=3.8.1'
requires-python = '>=3.9'
readme = "README.rst"
license = {text = "MIT License"}
dynamic = ["version"]
Expand All @@ -19,7 +19,6 @@ classifiers = [
"Operating System :: POSIX",
"Operating System :: MacOS :: MacOS X",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand All @@ -41,9 +40,7 @@ test = [
'flake8~=6.1',
'psutil',
'pycodestyle~=2.11.0',
# pyOpenSSL 26.4 requires Python 3.9 or later.
'pyOpenSSL~=25.3.0; python_version < "3.9"',
'pyOpenSSL~=26.4.0; python_version >= "3.9"',
'pyOpenSSL~=26.4.0',
'mypy>=0.800',
]
dev = [
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import sys

vi = sys.version_info
if vi < (3, 8):
raise RuntimeError('uvloop requires Python 3.8 or greater')
if vi < (3, 9):
raise RuntimeError('uvloop requires Python 3.9 or greater')

if sys.platform in ('win32', 'cygwin', 'cli'):
raise RuntimeError('uvloop does not support Windows at the moment')
Expand Down
5 changes: 0 additions & 5 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,11 +837,6 @@ async def main():
self.fail(result.stdout.strip())

def test_thread_name_prefix_in_default_executor(self):
if self.implementation == "asyncio" and sys.version_info < (3, 9):
raise unittest.SkipTest(
"thread_name_prefix was added in CPython 3.9"
)

called = []

def cb():
Expand Down
11 changes: 0 additions & 11 deletions tests/test_sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import pickle
import select
import socket
import sys
import time
import unittest

Expand Down Expand Up @@ -161,11 +160,6 @@ def test_socket_sync_remove_and_immediately_close(self):
self.loop.run_until_complete(asyncio.sleep(0.01))

def test_sock_cancel_add_reader_race(self):
if self.is_asyncio_loop() and sys.version_info[:2] == (3, 8):
# asyncio 3.8.x has a regression; fixed in 3.9.0
# tracked in https://bugs.python.org/issue30064
raise unittest.SkipTest()

srv_sock_conn = None

async def server():
Expand Down Expand Up @@ -217,11 +211,6 @@ async def send_server_data():
self.loop.run_until_complete(server())

def test_sock_send_before_cancel(self):
if self.is_asyncio_loop() and sys.version_info[:2] == (3, 8):
# asyncio 3.8.x has a regression; fixed in 3.9.0
# tracked in https://bugs.python.org/issue30064
raise unittest.SkipTest()

srv_sock_conn = None

async def server():
Expand Down
6 changes: 1 addition & 5 deletions tests/test_tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2525,7 +2525,7 @@ def prog(sock):

async def start_server():
extras = {'ssl_handshake_timeout': SSL_HANDSHAKE_TIMEOUT}
if self.implementation != 'asyncio': # or self.PY38
if self.implementation != 'asyncio':
extras['ssl_shutdown_timeout'] = 0.5

srv = await asyncio.start_server(
Expand Down Expand Up @@ -2647,10 +2647,6 @@ def unwrap_server(sock):
except ssl.SSLError as ex:
# Since OpenSSL 1.1.1, it raises "application data after
# close notify"
# Python < 3.8:
if ex.reason == 'KRB5_S_INIT':
break
# Python >= 3.8:
if ex.reason == 'APPLICATION_DATA_AFTER_CLOSE_NOTIFY':
break
raise ex
Expand Down
2 changes: 0 additions & 2 deletions tests/test_udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,6 @@ def _skip_create_datagram_endpoint_reuse_addr(self):
if self.implementation == 'asyncio':
if sys.version_info[:2] >= (3, 11):
raise unittest.SkipTest()
if (3, 8, 0) <= sys.version_info < (3, 8, 1):
raise unittest.SkipTest()

def test_create_datagram_endpoint_reuse_address_error(self):
# bpo-37228: Ensure that explicit passing of `reuse_address=True`
Expand Down
5 changes: 1 addition & 4 deletions uvloop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,7 @@ async def wrapper():
try:
_cancel_all_tasks(loop)
loop.run_until_complete(loop.shutdown_asyncgens())
if hasattr(loop, 'shutdown_default_executor'):
loop.run_until_complete(
loop.shutdown_default_executor()
)
loop.run_until_complete(loop.shutdown_default_executor())
finally:
__asyncio.set_event_loop(None)
loop.close()
Expand Down
25 changes: 6 additions & 19 deletions uvloop/loop.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ include "includes/stdlib.pxi"
include "errors.pyx"

cdef:
int PY39 = PY_VERSION_HEX >= 0x03090000
int PY311 = PY_VERSION_HEX >= 0x030b0000
int PY313 = PY_VERSION_HEX >= 0x030d0000
uint64_t MAX_SLEEP = 3600 * 24 * 365 * 100
Expand Down Expand Up @@ -3315,15 +3314,9 @@ class _SyncSocketReaderFuture(aio_Future):
self.__loop.remove_reader(self.__sock)
self.__sock = None

if PY39:
def cancel(self, msg=None):
self.__remove_reader()
aio_Future.cancel(self, msg=msg)

else:
def cancel(self):
self.__remove_reader()
aio_Future.cancel(self)
def cancel(self, msg=None):
self.__remove_reader()
aio_Future.cancel(self, msg=msg)


class _SyncSocketWriterFuture(aio_Future):
Expand All @@ -3338,15 +3331,9 @@ class _SyncSocketWriterFuture(aio_Future):
self.__loop.remove_writer(self.__sock)
self.__sock = None

if PY39:
def cancel(self, msg=None):
self.__remove_writer()
aio_Future.cancel(self, msg=msg)

else:
def cancel(self):
self.__remove_writer()
aio_Future.cancel(self)
def cancel(self, msg=None):
self.__remove_writer()
aio_Future.cancel(self, msg=msg)


include "cbhandles.pyx"
Expand Down
Loading