Skip to content

Commit f4b9191

Browse files
committed
refactor: tighten lints
1 parent e6d3b0a commit f4b9191

25 files changed

Lines changed: 439 additions & 390 deletions

examples/__init__.py

Whitespace-only changes.

examples/agent.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@
44
import asyncio
55
from pathlib import Path
66
from typing import TYPE_CHECKING, cast
7+
from typing_extensions import override
78

89
from openai import AsyncOpenAI
9-
from openai.lib.streaming.chat import (
10-
ChatCompletionStreamState,
11-
)
12-
from openai.types.chat import (
13-
ChatCompletionChunk,
14-
)
10+
from openai.lib.streaming.chat import ChatCompletionStreamState
11+
from openai.types.chat import ChatCompletionChunk
1512
from pydantic import TypeAdapter
16-
from typing_extensions import override
1713

1814
import duron
1915
from duron import RunOptions, op
@@ -22,12 +18,12 @@
2218

2319
if TYPE_CHECKING:
2420
from collections.abc import AsyncGenerator
21+
from typing import Any
2522

2623
from openai.types.chat import (
2724
ChatCompletionMessageParam,
2825
ParsedChatCompletionMessage,
2926
)
30-
from typing_extensions import Any
3127

3228
from duron.codec import JSONValue
3329
from duron.typing import TypeHint
@@ -43,7 +39,9 @@ def encode_json(self, result: object) -> JSONValue:
4339
return cast(
4440
"JSONValue",
4541
TypeAdapter(type(result)).dump_python(
46-
result, mode="json", exclude_none=True
42+
result,
43+
mode="json",
44+
exclude_none=True,
4745
),
4846
)
4947

@@ -53,8 +51,8 @@ def decode_json(self, encoded: JSONValue, expected_type: TypeHint[Any]) -> objec
5351

5452

5553
@duron.fn(codec=PydanticCodec())
56-
async def agent_fn(ctx: duron.Context):
57-
completion_result = await completion(
54+
async def agent_fn(ctx: duron.Context) -> None:
55+
_ = await completion(
5856
ctx,
5957
messages=[
6058
{
@@ -67,13 +65,15 @@ async def agent_fn(ctx: duron.Context):
6765
},
6866
],
6967
)
70-
print(completion_result.content)
7168

7269

73-
async def main():
70+
async def main() -> None:
7471
parser = argparse.ArgumentParser(description="Duron Agent Example")
7572
_ = parser.add_argument(
76-
"--session-id", type=str, required=True, help="Session ID for log storage"
73+
"--session-id",
74+
type=str,
75+
required=True,
76+
help="Session ID for log storage",
7777
)
7878
args = parser.parse_args()
7979

@@ -84,7 +84,8 @@ async def main():
8484

8585

8686
async def completion(
87-
ctx: duron.Context, messages: list[ChatCompletionMessageParam]
87+
ctx: duron.Context,
88+
messages: list[ChatCompletionMessageParam],
8889
) -> ParsedChatCompletionMessage[None]:
8990
@op(
9091
checkpoint=True,
@@ -103,7 +104,8 @@ async def _completion_stream(
103104
) -> AsyncGenerator[ChatCompletionChunk, ChatCompletionStreamState | None]:
104105
if prev:
105106
msg = prev.current_completion_snapshot.choices[0].message
106-
messages = messages + [
107+
messages = [
108+
*messages,
107109
{
108110
"role": "assistant",
109111
"content": msg.content,
@@ -120,7 +122,7 @@ async def _completion_stream(
120122
)
121123
if msg.tool_calls
122124
else (),
123-
}
125+
},
124126
]
125127
async for chunk in await client.chat.completions.create(
126128
messages=messages,

noxfile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# type: ignore
1+
# type: ignore # noqa: PGH003
22
# pyright: basic, reportMissingImports=false
33

44
from __future__ import annotations
@@ -10,7 +10,7 @@
1010
ALL_PYTHON = ["3.14", "3.13", "3.12", "3.11", "3.10"]
1111

1212

13-
def install_deps(s: nox.Session, groups: list[str]):
13+
def install_deps(s: nox.Session, groups: list[str]) -> None:
1414
s.env["UV_PROJECT_ENVIRONMENT"] = s.virtualenv.location
1515
cmd = ["uv", "sync", "--frozen"]
1616
for g in groups:

pyproject.toml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,20 @@ examples = [
3838
]
3939

4040
[tool.ruff.lint]
41-
select = [
42-
"E",
43-
"F",
44-
"UP",
45-
"B",
46-
"SIM",
47-
"I",
48-
"TC",
41+
select = ["ALL"]
42+
ignore = [
43+
"COM812",
44+
"CPY", "D",
45+
"S101", "S311",
46+
"PLR0", "PLR1", "PLR2", "C901",
4947
]
5048
extend-safe-fixes = ["TC"]
5149
preview = true
5250
future-annotations = true
5351

52+
[tool.ruff.lint.isort]
53+
extra-standard-library = ["typing_extensions"]
54+
5455
[tool.ruff.lint.flake8-type-checking]
5556
runtime-evaluated-base-classes = ["typing_extensions.TypedDict"]
5657
runtime-evaluated-decorators = ["duron.fn"]
@@ -60,6 +61,7 @@ runtime-evaluated-decorators = ["duron.fn"]
6061

6162
[tool.ruff.format]
6263
preview = true
64+
docstring-code-format = true
6365

6466
[tool.mypy]
6567
disable_error_code = [

src/duron/_core/context.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from collections.abc import Callable, Coroutine
2424
from contextvars import Token
2525
from types import TracebackType
26-
2726
from typing_extensions import AsyncContextManager
2827

2928
from duron._core.options import RunOptions
@@ -60,15 +59,16 @@ def __exit__(
6059
exc_type: type[BaseException] | None,
6160
exc_val: BaseException | None,
6261
exc_tb: TracebackType | None,
63-
):
62+
) -> None:
6463
if self._token:
6564
_context.reset(self._token)
6665

6766
@staticmethod
6867
def current() -> Context:
6968
ctx = _context.get()
7069
if ctx is None:
71-
raise RuntimeError("No duron context is active")
70+
msg = "No duron context is active"
71+
raise RuntimeError(msg)
7272
return ctx
7373

7474
@overload
@@ -100,7 +100,8 @@ async def run(
100100
**kwargs: _P.kwargs,
101101
) -> _T:
102102
if asyncio.get_running_loop() is not self._loop:
103-
raise RuntimeError("Context time can only be used in the context loop")
103+
msg = "Context time can only be used in the context loop"
104+
raise RuntimeError(msg)
104105

105106
if isinstance(fn, CheckpointOp):
106107
async with self.run_stream(fn, options, *args, **kwargs) as stream:
@@ -111,7 +112,7 @@ async def run(
111112
fn.return_type
112113
if isinstance(fn, Op) and fn.return_type
113114
else self._task.codec.inspect_function(
114-
cast("Callable[..., object]", fn)
115+
cast("Callable[..., object]", fn),
115116
).return_type
116117
)
117118

@@ -138,8 +139,9 @@ def run_stream(
138139
) -> AsyncContextManager[Stream[_S, _T]]:
139140
_ = options
140141
if asyncio.get_running_loop() is not self._loop:
141-
raise RuntimeError("Context time can only be used in the context loop")
142-
r = run_stream(
142+
msg = "Context time can only be used in the context loop"
143+
raise RuntimeError(msg)
144+
return run_stream(
143145
self._loop,
144146
fn.action_type,
145147
fn.initial(),
@@ -148,7 +150,6 @@ def run_stream(
148150
*args,
149151
**kwargs,
150152
)
151-
return r
152153

153154
async def create_stream(
154155
self,
@@ -158,9 +159,13 @@ async def create_stream(
158159
metadata: dict[str, JSONValue] | None = None,
159160
) -> tuple[Stream[_T, None], StreamWriter[_T]]:
160161
if asyncio.get_running_loop() is not self._loop:
161-
raise RuntimeError("Context time can only be used in the context loop")
162+
msg = "Context time can only be used in the context loop"
163+
raise RuntimeError(msg)
162164
return await create_stream(
163-
self._loop, dtype, external=external, metadata=metadata
165+
self._loop,
166+
dtype,
167+
external=external,
168+
metadata=metadata,
164169
)
165170

166171
async def create_signal(
@@ -170,7 +175,8 @@ async def create_signal(
170175
metadata: dict[str, JSONValue] | None = None,
171176
) -> tuple[Signal[_T], SignalWriter[_T]]:
172177
if asyncio.get_running_loop() is not self._loop:
173-
raise RuntimeError("Context time can only be used in the context loop")
178+
msg = "Context time can only be used in the context loop"
179+
raise RuntimeError(msg)
174180
return await create_signal(self._loop, dtype, metadata=metadata)
175181

176182
async def create_promise(
@@ -180,28 +186,34 @@ async def create_promise(
180186
metadata: dict[str, JSONValue] | None = None,
181187
) -> tuple[str, asyncio.Future[_T]]:
182188
if asyncio.get_running_loop() is not self._loop:
183-
raise RuntimeError("Context time can only be used in the context loop")
189+
msg = "Context time can only be used in the context loop"
190+
raise RuntimeError(msg)
184191
fut = create_op(
185-
self._loop, ExternalPromiseCreate(metadata=metadata, return_type=dtype)
192+
self._loop,
193+
ExternalPromiseCreate(metadata=metadata, return_type=dtype),
186194
)
187195
return (base64.b64encode(fut.id).decode(), cast("asyncio.Future[_T]", fut))
188196

189197
async def barrier(self) -> int:
190198
if asyncio.get_running_loop() is not self._loop:
191-
raise RuntimeError("Context time can only be used in the context loop")
199+
msg = "Context time can only be used in the context loop"
200+
raise RuntimeError(msg)
192201
return await create_op(self._loop, Barrier())
193202

194203
def time(self) -> float:
195204
if asyncio.get_running_loop() is not self._loop:
196-
raise RuntimeError("Context time can only be used in the context loop")
205+
msg = "Context time can only be used in the context loop"
206+
raise RuntimeError(msg)
197207
return self._loop.time()
198208

199209
def time_ns(self) -> int:
200210
if asyncio.get_running_loop() is not self._loop:
201-
raise RuntimeError("Context time can only be used in the context loop")
211+
msg = "Context time can only be used in the context loop"
212+
raise RuntimeError(msg)
202213
return self._loop.time_us() * 1_000
203214

204215
def random(self) -> Random:
205216
if asyncio.get_running_loop() is not self._loop:
206-
raise RuntimeError("Context random can only be used in the context loop")
217+
msg = "Context random can only be used in the context loop"
218+
raise RuntimeError(msg)
207219
return Random(self._loop.generate_op_id())

0 commit comments

Comments
 (0)