fixhunt

ruff ASYNC115

labelled unknown
Runs / 2026-10-17T20-10-23-330Z-90zl-ruff-ASYNC115ruff 0.17.12026-10-17 20:10 UTC8 programs × 2 round(s)16 programs, 12 fired, 11 fixed, 0 findings, 1 rejectedmodel cost $0.0046

Analysis Nemotron 3 Super

Flags calls to trio.sleep(0) or anyio.sleep(0) and suggests replacing them with explicit checkpoint functions.

Fix: Replace trio.sleep(0) with trio.lowlevel.checkpoint() and anyio.sleep(0) with anyio.checkpoint(), preserving the await keyword and surrounding expression structure.

12 hazards
  • If trio or anyio is imported as an alias (e.g., import trio as t), the fix may incorrectly reference trio.lowlevel.checkpoint instead of the aliased module, causing AttributeError.
  • If trio.sleep or anyio.sleep is shadowed by a local variable or function, the fix will replace the wrong symbol, leading to incorrect behavior or NameError.
  • If the call is part of a larger expression (e.g., f(trio.sleep(0))), replacing only the call may break argument ordering or introduce syntax errors if not handled contextually.
  • If the sleep call appears in a default argument or lambda, moving the checkpoint call may alter evaluation timing or scope, especially if closure variables are involved.
  • If the module trio.lowlevel or anyio is not imported, the fix may introduce a NameError unless the import is added, which the autofix may not do.
  • If there are comments inside the call parentheses (e.g., trio.sleep( # comment 0 )), the fix may drop them, violating user intent even if semantically equivalent.
  • If the code uses from trio import sleep, the fix cannot safely rewrite to trio.lowlevel.checkpoint without knowing the original import form, risking incorrect module references.
  • If the code is in a string or comment (e.g., docstring or # await trio.sleep(0)), the tool might incorrectly flag and modify it, breaking documentation or introducing invalid code.
  • If the sleep function is accessed via getattr or dynamic lookup (e.g., getattr(trio, 'sleep')(0)), the fix cannot apply safely as it assumes a direct attribute access.
  • If the code runs under a mock or test patch where trio.sleep is replaced, the fix may bypass the mock and call the real checkpoint, altering test behavior.
  • If the expression uses keyword arguments like trio.sleep(delay=0), the fix may fail to match or incorrectly rewrite, especially if mixed with positional args.
  • If the file has encoding issues or non-standard whitespace, the autofix may misidentify the boundaries of the expression, leading to malformed replacement.

Programs

idresulttitlehazard
r1-p001fix okEncoding and Whitespace Boundary MisidentificationIf the file has encoding issues or non-standard whitespace, the autofix may misidentify the boundaries of the expression, leading to malformed replacement.
r1-p002fix ok prediction offFile Modes and Truncation Partial Writesfile modes and truncation, partial writes, non-str data passed to write
r1-p003fix okImport Alias MisreferenceIf trio or anyio is imported as an alias (e.g., import trio as t), the fix may incorrectly reference trio.lowlevel.checkpoint instead of the aliased module, causing AttributeError.
r1-p004fix okMock Patch BypassIf the code runs under a mock or test patch where trio.sleep is replaced, the fix may bypass the mock and call the real checkpoint, altering test behavior.
r1-p005fix okEvaluation Order and Side Effectsevaluation order and side effects when expressions are merged, duplicated or deleted
r1-p006fix okString or Comment False PositiveIf the code is in a string or comment (e.g., docstring or # await trio.sleep(0)), the tool might incorrectly flag and modify it, breaking documentation or introducing invalid code.
r1-p007fix okMissing Module Import NameErrorIf the module trio.lowlevel or anyio is not imported, the fix may introduce a NameError unless the import is added, which the autofix may not do.
r1-p008silent prediction offInt/Float/Bool Coercion Edge Casesint/float/bool coercion, Decimal, division and rounding
r2-p001silent prediction offKeyword argument usageIf the expression uses keyword arguments like trio.sleep(delay=0), the fix may fail to match or incorrectly rewrite, especially if mixed with positional args.
r2-p002invalidParameter forwarding with defaultskeyword-only, positional-only, *args/**kwargs forwarding, defaults evaluated once
r2-p003fix okImport alias mismatchIf trio or anyio is imported as an alias (e.g., import trio as t), the fix may incorrectly reference trio.lowlevel.checkpoint instead of the aliased module, causing AttributeError.
r2-p004fix okFrom import prevents safe rewriteIf the code uses from trio import sleep, the fix cannot safely rewrite to trio.lowlevel.checkpoint without knowing the original import form, risking incorrect module references.
r2-p005fired, no fixComment inside parenthesesIf there are comments inside the call parentheses (e.g., trio.sleep( # comment\n 0 )), the fix may drop them, violating user intent even if semantically equivalent.
r2-p006silentDynamic attribute access via getattrIf the sleep function is accessed via getattr or dynamic lookup (e.g., getattr(trio, 'sleep')(0)), the fix cannot apply safely as it assumes a direct attribute access.
r2-p007fix okMissing lowlevel importIf the module trio.lowlevel or anyio is not imported, the fix may introduce a NameError unless the import is added, which the autofix may not do.
r2-p008fix okComments on removed/moved codecomments and docstrings attached to the removed or moved code

Sources

r1-p001 · Encoding and Whitespace Boundary Misidentification
1# -*- coding: utf-8 -*-
2import trio
3async def main():
4 x = 0
5 y = [
6 await trio.sleep( 0 ) # tab and space after comma
7 if False else None,
8 ]
9 print('y[0]:', y[0])
10try:
11 import asyncio
12 asyncio.run(main())
13except Exception as e:
14 print(f'{type(e).__name__}: {e}')
--- orig.py	2026-10-17 16:10:39.206082574 -0400
+++ fixed.py	2026-10-17 16:10:39.646069961 -0400
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
 import trio
+import trio.lowlevel
 async def main():
     x = 0
     y = [
-        await 	 trio.sleep( 0 )  # tab and space after comma
+        await 	 trio.lowlevel.checkpoint()  # tab and space after comma
         if False else None,
     ]
     print('y[0]:', y[0])
r1-p002 · File Modes and Truncation Partial Writes
1import trio
2async def main():
3 with open('test.bin', 'wb') as f:
4 try:
5 f.write(b'before')
6 await trio.sleep(0)
7 f.write(b'after')
8 except Exception as e:
9 print(f'{type(e).__name__}: {e}')
10 finally:
11 f.seek(0)
12 print('read:', f.read())
13import asyncio
14import os
15asyncio.run(main())
16os.remove('test.bin')
--- orig.py	2026-10-17 16:10:39.844064285 -0400
+++ fixed.py	2026-10-17 16:10:40.253052577 -0400
@@ -1,9 +1,10 @@
 import trio
+import trio.lowlevel
 async def main():
     with open('test.bin', 'wb') as f:
         try:
             f.write(b'before')
-            await trio.sleep(0)
+            await trio.lowlevel.checkpoint()
             f.write(b'after')
         except Exception as e:
             print(f'{type(e).__name__}: {e}')
r1-p003 · Import Alias Misreference
1import trio as t
2import anyio as a
3async def main():
4 await t.sleep(0)
5 await a.sleep(0)
6 print('both checkpoints passed')
7try:
8 import asyncio
9 asyncio.run(main())
10except Exception as e:
11 print(f'{type(e).__name__}: {e}')
--- orig.py	2026-10-17 16:10:40.468046427 -0400
+++ fixed.py	2026-10-17 16:10:40.844035672 -0400
@@ -1,8 +1,10 @@
 import trio as t
 import anyio as a
+import trio.lowlevel
+import anyio.lowlevel
 async def main():
-    await t.sleep(0)
-    await a.sleep(0)
+    await trio.lowlevel.checkpoint()
+    await anyio.lowlevel.checkpoint()
     print('both checkpoints passed')
 try:
     import asyncio
r1-p004 · Mock Patch Bypass
1import trio
2from unittest.mock import patch
3async def main():
4 with patch('trio.sleep', return_value='mocked'):
5 result = await trio.sleep(0)
6 print('result:', repr(result))
7try:
8 import asyncio
9 asyncio.run(main())
10except Exception as e:
11 print(f'{type(e).__name__}: {e}')
--- orig.py	2026-10-17 16:10:41.071029184 -0400
+++ fixed.py	2026-10-17 16:10:41.454018253 -0400
@@ -1,8 +1,9 @@
 import trio
 from unittest.mock import patch
+import trio.lowlevel
 async def main():
     with patch('trio.sleep', return_value='mocked'):
-        result = await trio.sleep(0)
+        result = await trio.lowlevel.checkpoint()
         print('result:', repr(result))
 try:
     import asyncio
r1-p005 · Evaluation Order and Side Effects
1import trio
2counter = 0
3async def inc():
4 global counter
5 counter += 1
6 return counter
7async def main():
8 global counter
9 counter = 0
10 results = []
11 for i in range(2):
12 val = inc()
13 await trio.sleep(0)
14 results.append((val, counter))
15 print('results:', results)
16try:
17 import asyncio
18 asyncio.run(main())
19except Exception as e:
20 print(f'{type(e).__name__}: {e}')
--- orig.py	2026-10-17 16:10:41.684011689 -0400
+++ fixed.py	2026-10-17 16:10:42.099999823 -0400
@@ -1,4 +1,5 @@
 import trio
+import trio.lowlevel
 counter = 0
 async def inc():
     global counter
@@ -10,7 +11,7 @@
     results = []
     for i in range(2):
         val = inc()
-        await trio.sleep(0)
+        await trio.lowlevel.checkpoint()
         results.append((val, counter))
     print('results:', results)
 try:
r1-p006 · String or Comment False Positive
1import trio
2async def main():
3 """This is a docstring with await trio.sleep(0) inside."""
4 s = 'not await trio.sleep(0)'
5 # await trio.sleep(0) # this is a comment
6 await trio.sleep(0) # real call
7 print('slept')
8try:
9 import asyncio
10 asyncio.run(main())
11except Exception as e:
12 print(f'{type(e).__name__}: {e}')
--- orig.py	2026-10-17 16:10:42.326993359 -0400
+++ fixed.py	2026-10-17 16:10:42.736981683 -0400
@@ -1,9 +1,10 @@
 import trio
+import trio.lowlevel
 async def main():
     """This is a docstring with await trio.sleep(0) inside."""
     s = 'not await trio.sleep(0)'
     # await trio.sleep(0)  # this is a comment
-    await trio.sleep(0)  # real call
+    await trio.lowlevel.checkpoint()  # real call
     print('slept')
 try:
     import asyncio
r1-p007 · Missing Module Import NameError
1import trio
2# trio.lowlevel not imported
3async def main():
4 await trio.sleep(0) # should become trio.lowlevel.checkpoint()
5 print('checkpoint passed')
6try:
7 import asyncio
8 asyncio.run(main())
9except Exception as e:
10 print(f'{type(e).__name__}: {e}')
--- orig.py	2026-10-17 16:10:42.955975447 -0400
+++ fixed.py	2026-10-17 16:10:43.341964477 -0400
@@ -1,7 +1,8 @@
 import trio
+import trio.lowlevel
 # trio.lowlevel not imported
 async def main():
-    await trio.sleep(0)  # should become trio.lowlevel.checkpoint()
+    await trio.lowlevel.checkpoint()  # should become trio.lowlevel.checkpoint()
     print('checkpoint passed')
 try:
     import asyncio
r1-p008 · Int/Float/Bool Coercion Edge Cases
1import trio
2from decimal import Decimal
3async def main():
4 vals = [0, 0.0, False, Decimal('0'), 0//1, (lambda: 0)()]
5 for v in vals:
6 try:
7 await trio.sleep(v)
8 print(f'{v!r}: slept')
9 except Exception as e:
10 print(f'{v!r}: {type(e).__name__}: {e}')
11try:
12 import asyncio
13 asyncio.run(main())
14except Exception as e:
15 print(f'{type(e).__name__}: {e}')
r2-p001 · Keyword argument usage
1import trio
2async def main():
3 delay_val = 0
4 await trio.sleep(delay=delay_val)
5 print('keyword ok')
6await trio.run(main())
r2-p002 · Parameter forwarding with defaults (generated program does not parse: Traceback (most recent call last):)
1import trio
2async def wrapper(*args, **kwargs):
3 return await trio.sleep(*args, **kwargs)
4async def main():
5 result = await wrapper(0)
6 print('forwarded:', result)
7async def posonly(/, delay):
8 return await trio.sleep(delay)
9async def main2():
10 r = await posonly(0)
11 print('posonly:', r)
12async def kwonly(*, delay):
13 return await trio.sleep(delay)
14async def main3():
15 r = await kwonly(delay=0)
16 print('kwonly:', r)
17asyncio.run(main())
18asyncio.run(main2())
19asyncio.run(main3())
r2-p003 · Import alias mismatch
1import trio as t
2async def main():
3 await t.sleep(0)
4 print('aliased ok')
5trio.run(main())
--- orig.py	2026-10-17 16:10:49.311795906 -0400
+++ fixed.py	2026-10-17 16:10:49.681785532 -0400
@@ -1,5 +1,6 @@
 import trio as t
+import trio.lowlevel
 async def main():
-    await t.sleep(0)
+    await trio.lowlevel.checkpoint()
     print('aliased ok')
 trio.run(main())
r2-p004 · From import prevents safe rewrite
1from trio import sleep
2async def main():
3 await sleep(0)
4 print('from import ok')
5trio.run(main())
--- orig.py	2026-10-17 16:10:49.878780008 -0400
+++ fixed.py	2026-10-17 16:10:50.261769286 -0400
@@ -1,5 +1,6 @@
 from trio import sleep
+import trio.lowlevel
 async def main():
-    await sleep(0)
+    await trio.lowlevel.checkpoint()
     print('from import ok')
 trio.run(main())
r2-p005 · Comment inside parentheses
1import trio
2async def main():
3 await trio.sleep(
4 0 # zero delay
5 )
6 print('comment preserved')
7trio.run(main())
r2-p006 · Dynamic attribute access via getattr
1import trio
2async def main():
3 sleep_fn = getattr(trio, 'sleep')
4 await sleep_fn(0)
5 print('getattr ok')
6trio.run(main())
r2-p007 · Missing lowlevel import
1import trio
2async def main():
3 await trio.sleep(0)
4 print('before checkpoint')
5 await trio.lowlevel.checkpoint() # This line will fail if not imported
6 print('after checkpoint')
7trio.run(main())
--- orig.py	2026-10-17 16:10:51.177743671 -0400
+++ fixed.py	2026-10-17 16:10:51.537733622 -0400
@@ -1,6 +1,7 @@
 import trio
+import trio.lowlevel
 async def main():
-    await trio.sleep(0)
+    await trio.lowlevel.checkpoint()
     print('before checkpoint')
     await trio.lowlevel.checkpoint()  # This line will fail if not imported
     print('after checkpoint')
r2-p008 · Comments on removed/moved code
1import trio
2# This is a comment before
3async def main():
4 # Comment before await
5 await trio.sleep(0) # Inline comment
6 # Comment after await
7 print('done')
8# Comment after function
9trio.run(main())
--- orig.py	2026-10-17 16:10:51.747727760 -0400
+++ fixed.py	2026-10-17 16:10:52.121717328 -0400
@@ -1,8 +1,9 @@
 import trio
+import trio.lowlevel
 # This is a comment before
 async def main():
     # Comment before await
-    await trio.sleep(0)  # Inline comment
+    await trio.lowlevel.checkpoint()  # Inline comment
     # Comment after await
     print('done')
 # Comment after function