Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
88e9872
Apply ruff/flake8-bugbear rule B009
DimitriPapadopoulos Oct 13, 2025
4d920a8
Apply ruff/flake8-executable rule EXE001
DimitriPapadopoulos Oct 13, 2025
cd24a4b
Apply ruff/flake8-pie rule PIE808
DimitriPapadopoulos May 4, 2026
d926bce
Apply ruff/flake8-pie rule PIE810
DimitriPapadopoulos Oct 13, 2025
e9aa850
Apply ruff/flake8-slots rule SLOT000
DimitriPapadopoulos Oct 13, 2025
1cc7f88
Apply ruff/Pyflakes rule F401
DimitriPapadopoulos Oct 13, 2025
2d078e1
Apply ruff/Pylint rule PLC0208
DimitriPapadopoulos Oct 13, 2025
83de3e2
Apply ruff/Pylint rule PLR1722
DimitriPapadopoulos Oct 13, 2025
8a2aeb3
Apply ruff/Pylint rule PLR5501
DimitriPapadopoulos Oct 13, 2025
8d1445d
Apply ruff/Pylint rule PLR6201
DimitriPapadopoulos Oct 13, 2025
274be65
Apply ruff/pyupgrade rule UP006
DimitriPapadopoulos Oct 13, 2025
5c7295d
Apply ruff/pyupgrade rule UP007
DimitriPapadopoulos Oct 13, 2025
2d3bf82
Apply ruff/pyupgrade rule UP015
DimitriPapadopoulos May 4, 2026
5877e32
Apply ruff/pyupgrade rule UP020
DimitriPapadopoulos Oct 13, 2025
a9751e4
Apply ruff/pyupgrade rule UP022
DimitriPapadopoulos Oct 13, 2025
bcd1ae0
Apply ruff/pyupgrade rule UP024
DimitriPapadopoulos Oct 13, 2025
2c3ec4c
Apply ruff/pyupgrade rule UP031
DimitriPapadopoulos Oct 13, 2025
e293aa0
Apply ruff/pyupgrade rule UP032
DimitriPapadopoulos Oct 13, 2025
4761080
Apply ruff/pyupgrade rule UP045
DimitriPapadopoulos Oct 13, 2025
0496574
Apply ruff/refurb rule FURB167
DimitriPapadopoulos May 4, 2026
d80f363
Apply ruff rule RUF036
DimitriPapadopoulos Oct 13, 2025
06cd021
Apply ruff rule RUF046
DimitriPapadopoulos Oct 13, 2025
3264406
Enforce ruff rules
DimitriPapadopoulos May 4, 2026
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
Empty file modified .github/release_log.py
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion docs/conf.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
version_file = os.path.join(os.path.dirname(os.path.dirname(__file__)),
'uvloop', '_version.py')

with open(version_file, 'r') as f:
with open(version_file) as f:
for line in f:
if line.startswith('__version__ ='):
_, _, version = line.partition('=')
Expand Down
2 changes: 1 addition & 1 deletion examples/bench/echoclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
addr = args.addr.split(':')
addr[1] = int(addr[1])
addr = tuple(addr)
print('will connect to: {}'.format(addr))
print(f'will connect to: {addr}')

MSGSIZE = args.msize
REQSIZE = MSGSIZE * args.mpr
Expand Down
11 changes: 6 additions & 5 deletions examples/bench/echoserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pathlib
import socket
import ssl
import sys


PRINT = 0
Expand Down Expand Up @@ -138,7 +139,7 @@ async def print_debug(loop):
addr[1] = int(addr[1])
addr = tuple(addr)

print('serving on: {}'.format(addr))
print(f'serving on: {addr}')

server_context = None
if args.ssl:
Expand All @@ -159,11 +160,11 @@ async def print_debug(loop):
if args.streams:
if args.proto:
print('cannot use --stream and --proto simultaneously')
exit(1)
sys.exit(1)

if args.buffered:
print('cannot use --stream and --buffered simultaneously')
exit(1)
sys.exit(1)

print('using asyncio/streams')
if unix:
Expand All @@ -178,7 +179,7 @@ async def print_debug(loop):
elif args.proto:
if args.streams:
print('cannot use --stream and --proto simultaneously')
exit(1)
sys.exit(1)

if args.buffered:
print('using buffered protocol')
Expand All @@ -197,7 +198,7 @@ async def print_debug(loop):
else:
if args.ssl:
print('cannot use SSL for loop.sock_* methods')
exit(1)
sys.exit(1)

print('using sock_recv/sock_sendall')
loop.create_task(echo_server(loop, addr, unix))
Expand Down
2 changes: 1 addition & 1 deletion examples/bench/rlserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ async def print_debug(loop):
addr = tuple(addr)

print('readline performance test')
print('serving on: {}'.format(addr))
print(f'serving on: {addr}')

print('using asyncio/streams')
if unix:
Expand Down
55 changes: 55 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,58 @@ test-command = "python -m unittest discover -v {project}/tests"
addopts = "--capture=no --assert=plain --strict-markers --tb=native --import-mode=importlib"
testpaths = "tests"
filterwarnings = "default"

[tool.ruff.lint]
extend-select = [
"B",
"C4",
"EXE",
"ISC",
"PIE",
"PYI",
"SLOT",
"PERF",
"SIM",
"FLY",
"PERF",
"W",
"PLC",
"PLE",
"PLR",
"UP",
"FURB",
"RUF",
]
ignore = [
"B007", # Loop control variable not used within loop body
"B011", # Do not `assert False` (`python -O` removes these calls), raise `AssertionError()`
"PYI026", # Use `typing_extensions.TypeAlias` for type alias
"SIM105", # Use `contextlib.suppress(OSError)` instead of `try`-`except`-`pass`
"SIM108", # Use ternary operator instead of `if`-`else`-block
"PLC0415", # `import` should be at the top-level of a file
"PLE0605", # Invalid format for `__all__`, must be `tuple` or `list`
"PLR09", # Too many [...]
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable*
"RUF005", # Consider using unpacking operator instead of concatenation
"RUF006", # Store a reference to the return value
"RUF059", # Unpacked variable is never used
"RUF100", # Unused blanket `noqa` directive
]

[tool.ruff.lint.extend-per-file-ignores]
"setup.py" = [
"B904", # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
"C408", # Unnecessary `dict()` call (rewrite as a literal)
"E402", # Module level import not at top of file
]
"tests/**" = [
"B018", # Found useless expression. Either assign it to a variable or remove it.
"B904", # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling
"B023", # Function definition does not bind loop variable
"C408", # Unnecessary `dict()` call (rewrite as a literal)
"E731", # Do not assign a `lambda` expression, use a `def`
"PERF203", # `try`-`except` within a loop incurs performance overhead
"SIM115", # Use a context manager for opening files
"SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements
"RUF012", # Mutable default value for class attribute
]
17 changes: 9 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
if vi < (3, 8):
raise RuntimeError('uvloop requires Python 3.8 or greater')

if sys.platform in ('win32', 'cygwin', 'cli'):
if sys.platform in {'win32', 'cygwin', 'cli'}:
raise RuntimeError('uvloop does not support Windows at the moment')

import os
Expand All @@ -27,7 +27,7 @@
MODULES_CFLAGS = shlex.split(os.getenv('UVLOOP_OPT_CFLAGS', '-O2'))
_ROOT = pathlib.Path(__file__).parent
LIBUV_DIR = str(_ROOT / 'vendor' / 'libuv')
LIBUV_BUILD_DIR = str(_ROOT / 'build' / 'libuv-{}'.format(MACHINE))
LIBUV_BUILD_DIR = str(_ROOT / 'build' / f'libuv-{MACHINE}')


def _libuv_build_env():
Expand Down Expand Up @@ -119,15 +119,16 @@ def finalize_options(self):
import Cython
except ImportError:
raise RuntimeError(
'please install {} to compile uvloop from source'.format(
CYTHON_DEPENDENCY))
f'please install {CYTHON_DEPENDENCY} to compile uvloop '
'from source'
)

cython_dep = Requirement(CYTHON_DEPENDENCY)
if not cython_dep.specifier.contains(Cython.__version__):
raise RuntimeError(
'uvloop requires {}, got Cython=={}'.format(
CYTHON_DEPENDENCY, Cython.__version__
))
f'uvloop requires {CYTHON_DEPENDENCY}, '
f'got Cython=={Cython.__version__}'
)

from Cython.Build import cythonize

Expand Down Expand Up @@ -184,7 +185,7 @@ def build_libuv(self):
njobs = len(os.sched_getaffinity(0))
except AttributeError:
njobs = os.cpu_count()
j_flag = '-j{}'.format(njobs or 1)
j_flag = f'-j{njobs or 1}'
c_flag = "CFLAGS={}".format(env['CFLAGS'])
subprocess.run(
['make', j_flag, c_flag],
Expand Down
2 changes: 1 addition & 1 deletion tests/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ async def on_shutdown(app):
async def client():
async with aiohttp.ClientSession() as client:
async with client.ws_connect(
'http://127.0.0.1:{}'.format(port)) as ws:
f'http://127.0.0.1:{port}') as ws:
await ws.send_str("hello")
async for msg in ws:
assert msg.data == "hello"
Expand Down
6 changes: 3 additions & 3 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ def cb():

for i in range(8):
self.loop.call_later(0.06 + 0.01, cb) # 0.06999999999999999
started = int(round(self.loop.time() * 1000))
started = round(self.loop.time() * 1000)
self.loop.run_forever()
finished = int(round(self.loop.time() * 1000))
finished = round(self.loop.time() * 1000)
self.assertGreaterEqual(finished - started, 69)

def test_call_at(self):
Expand Down Expand Up @@ -854,7 +854,7 @@ def test_loop_call_later_handle_cancelled(self):

def test_loop_std_files_cloexec(self):
# See https://github.com/MagicStack/uvloop/issues/40 for details.
for fd in {0, 1, 2}:
for fd in (0, 1, 2):
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
self.assertFalse(flags & fcntl.FD_CLOEXEC)

Expand Down
18 changes: 8 additions & 10 deletions tests/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ def get_buffer(self, sizehint):
if self.buffered_ctx is None:
self.buffered_ctx = self.cvar.get()
elif self.cvar.get() != self.buffered_ctx:
self.data_received_fut.set_exception(ValueError("{} != {}".format(
self.buffered_ctx, self.cvar.get(),
)))
self.data_received_fut.set_exception(
ValueError(f"{self.buffered_ctx} != {self.cvar.get()}")
)
return bytearray(65536)

def buffer_updated(self, nbytes):
Expand All @@ -72,9 +72,7 @@ def buffer_updated(self, nbytes):
self.data_received_fut.set_result(self.cvar.get())
else:
self.data_received_fut.set_exception(
ValueError("{} != {}".format(
self.buffered_ctx, self.cvar.get(),
))
ValueError(f"{self.buffered_ctx} != {self.cvar.get()}")
)


Expand Down Expand Up @@ -202,16 +200,16 @@ def fut_on_done(fut):
for j in range(2):
fut = self.loop.create_future()
fut.add_done_callback(fut_on_done)
cvar.set('yes{}'.format(j))
cvar.set(f'yes{j}')
self.loop.call_soon(fut.set_result, None)
await fut
self.assertEqual(cvar.get(), 'yes{}'.format(j))
self.assertEqual(cvar.get(), f'yes{j}')

for i in range(3):
# Test that task passed its context to add_done_callback:
cvar.set('yes{}-{}'.format(i, j))
cvar.set(f'yes{i}-{j}')
await asyncio.sleep(0.001)
self.assertEqual(cvar.get(), 'yes{}-{}'.format(i, j))
self.assertEqual(cvar.get(), f'yes{i}-{j}')

task = self.loop.create_task(main())
self.loop.run_until_complete(task)
Expand Down
5 changes: 3 additions & 2 deletions tests/test_cython.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ def test_cython_coro_is_coroutine(self):

coro_fmt = _format_coroutine(coro)
self.assertTrue(
coro_fmt.startswith('_test_coroutine_1() done')
or coro_fmt.startswith('_test_coroutine_1() running')
coro_fmt.startswith(
('_test_coroutine_1() done', '_test_coroutine_1() running')
)
)
self.assertEqual(_test_coroutine_1.__qualname__, '_test_coroutine_1')
self.assertEqual(_test_coroutine_1.__name__, '_test_coroutine_1')
Expand Down
2 changes: 1 addition & 1 deletion tests/test_dns.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def test_getaddrinfo_close_loop(self):
try:
# Check that we have internet connection
socket.getaddrinfo('example.com', 80)
except socket.error:
except OSError:
raise unittest.SkipTest

async def run():
Expand Down
7 changes: 4 additions & 3 deletions tests/test_executors.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ def run_pool_test(self, pool_factory):
async def run():
pool = pool_factory()
with pool:
coros = []
for i in range(0, 10):
coros.append(self.loop.run_in_executor(pool, fib, i))
coros = [
self.loop.run_in_executor(pool, fib, i)
for i in range(10)
]
res = await asyncio.gather(*coros)
self.assertEqual(res, fib10)
await asyncio.sleep(0.01)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_fs_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def test_fs_event_change(self):
path = os.path.join(self.tmp_dir, filename)
q = asyncio.Queue()

with open(path, 'wt') as f:
with open(path, "w") as f:
async def file_writer():
while True:
f.write('hello uvloop\n')
Expand Down Expand Up @@ -74,7 +74,7 @@ def event_cb(ev_fname: bytes, evt: FileSystemEvent):
if len(changed_set) == 0:
event.set()

with open(os.path.join(self.tmp_dir, orig_name), 'wt') as f:
with open(os.path.join(self.tmp_dir, orig_name), "w") as f:
f.write('hello!')
h = self.loop._monitor_fs(self.tmp_dir, event_cb)
self.loop.run_until_complete(asyncio.sleep(0.5)) # let monitor start
Expand Down
13 changes: 6 additions & 7 deletions tests/test_pipes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import asyncio
import io
import os
import socket

Expand Down Expand Up @@ -74,7 +73,7 @@ def test_read_pipe(self):
proto = MyReadPipeProto(loop=self.loop)

rpipe, wpipe = os.pipe()
pipeobj = io.open(rpipe, 'rb', 1024)
pipeobj = open(rpipe, 'rb', 1024)

async def connect():
t, p = await self.loop.connect_read_pipe(
Expand Down Expand Up @@ -106,7 +105,7 @@ def test_read_pty_output(self):
proto = MyReadPipeProto(loop=self.loop)

master, slave = os.openpty()
master_read_obj = io.open(master, 'rb', 0)
master_read_obj = open(master, 'rb', 0)

async def connect():
t, p = await self.loop.connect_read_pipe(
Expand Down Expand Up @@ -142,7 +141,7 @@ async def connect():
def test_write_pipe(self):
rpipe, wpipe = os.pipe()
os.set_blocking(rpipe, False)
pipeobj = io.open(wpipe, 'wb', 1024)
pipeobj = open(wpipe, 'wb', 1024)

proto = MyWritePipeProto(loop=self.loop)
connect = self.loop.connect_write_pipe(lambda: proto, pipeobj)
Expand Down Expand Up @@ -185,7 +184,7 @@ def test_write_pipe_disconnect_on_close(self):
rsock, wsock = socket.socketpair()
rsock.setblocking(False)

pipeobj = io.open(wsock.detach(), 'wb', 1024)
pipeobj = open(wsock.detach(), 'wb', 1024)

proto = MyWritePipeProto(loop=self.loop)
connect = self.loop.connect_write_pipe(lambda: proto, pipeobj)
Expand All @@ -207,7 +206,7 @@ def test_write_pty(self):
master, slave = os.openpty()
os.set_blocking(master, False)

slave_write_obj = io.open(slave, 'wb', 0)
slave_write_obj = open(slave, 'wb', 0)

proto = MyWritePipeProto(loop=self.loop)
connect = self.loop.connect_write_pipe(lambda: proto, slave_write_obj)
Expand Down Expand Up @@ -250,7 +249,7 @@ def reader(data):

def test_write_buffer_full(self):
rpipe, wpipe = os.pipe()
pipeobj = io.open(wpipe, 'wb', 1024)
pipeobj = open(wpipe, 'wb', 1024)

proto = MyWritePipeProto(loop=self.loop)
connect = self.loop.connect_write_pipe(lambda: proto, pipeobj)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ async def test():
stdout=subprocess.PIPE)

pid = proc.pid
expected_result = '{}\n'.format(pid).encode()
expected_result = f'{pid}\n'.encode()

out, err = await proc.communicate()
self.assertEqual(out, expected_result)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_process_spawning.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ def spawn_process():
t.start()
t.join(timeout=10.0)
if t.is_alive():
raise Exception('process freeze detected at {}'
.format(iteration))
raise Exception(f'process freeze detected at {iteration}'
)

return True

Expand Down
Loading
Loading