Skip to content

Commit 8dc1e91

Browse files
zzstoatzzCopilot
andauthored
Modernize codebase for Python 3.10+ (#1223)
* Modernize codebase for Python 3.10+ - Update type hints to use X | Y instead of Union[X, Y] - Replace Optional[T] with T | None throughout codebase - Fix forward reference type annotations to work with pipe operator - Keep Union for TypedDict fields with forward references (required) - All tests passing with modern syntax This prepares for Pydantic AI v1.0 which will require Python 3.10+ * Fix type annotation for _SessionLocal The sessionmaker itself can be None, not the sessions it creates. Changed from async_sessionmaker[AsyncSession | None] to async_sessionmaker[AsyncSession] | None Co-authored-by: Copilot <175728472+copilot-pull-request-reviewer[bot]@users.noreply.github.com> * Fix jsonschema test compatibility with Union type The test expects dataclass fields to use typing.Union which has __origin__ attribute. The new pipe syntax (field_type | None) creates types.UnionType which doesn't have __origin__. Keep using Union[field_type, None] for dynamically generated dataclass fields to maintain backward compatibility with existing tests and user code that may depend on the __origin__ attribute. * lil tweak --------- Co-authored-by: Copilot <175728472+copilot-pull-request-reviewer[bot]@users.noreply.github.com>
1 parent 94696e9 commit 8dc1e91

14 files changed

Lines changed: 49 additions & 42 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Marvin is a lightweight AI engineering toolkit for building natural language int
3939
### Finding Things
4040
- Use `rg` for searching, not grep
4141
- Use `ls` and `tree` for navigation
42-
- Check git context with `gh` and `git` commands
42+
- Check git context with using the GitHub MCP server
4343
- Think like a hacker with good intentions - search in site-packages when needed
4444

4545
### Linter Philosophy

docs/api-reference/marvin-agents-actor.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Actor(name: str, instructions: str | None = None, description: str | None
3535
```
3636
- **`get_current`**
3737
```python
38-
def get_current(cls) -> Optional[Actor]
38+
def get_current(cls) -> Actor | None
3939
```
4040
Get the current actor from context.
4141
- **`get_end_turn_tools`**

docs/api-reference/marvin-engine-orchestrator.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Orchestrator(tasks: list[Task[Any]], thread: Thread | str | None = None, h
3535
- ready: tasks that are ready to be run
3636
- **`get_current`**
3737
```python
38-
def get_current(cls) -> Optional[Orchestrator]
38+
def get_current(cls) -> Orchestrator | None
3939
```
4040
Get the current orchestrator from context.
4141
- **`handle_event`**

docs/api-reference/marvin-thread.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ Main runtime object for managing conversation context.
107107
Add a user message to the thread.
108108
- **`get_current`**
109109
```python
110-
def get_current(cls) -> Optional[Thread]
110+
def get_current(cls) -> Thread | None
111111
```
112112
Get the current thread from context.
113113
- **`get_llm_calls`**

docs/api-reference/marvin-utilities-jsonschema.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Create a field with simplified default handling.
7979

8080
### `create_numeric_type`
8181
```python
82-
def create_numeric_type(base: Type[Union[int, float]], schema: Mapping[str, Any]) -> type | Annotated[Any, ...]
82+
def create_numeric_type(base: Type[int | float], schema: Mapping[str, Any]) -> type | Annotated[Any, ...]
8383
```
8484
Create numeric type with optional constraints.
8585

docs/api-reference/marvin-utilities-types.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,12 @@ Attributes:
9696
function (Callable): The original function object.
9797
signature (inspect.Signature): The signature object of the function.
9898
name (str): The name of the function.
99-
docstring (Optional[str]): The docstring of the function.
99+
docstring (str | None): The docstring of the function.
100100
parameters (List[ParameterModel]): The parameters of the function.
101-
return_annotation (Optional[Any]): The return annotation of the function.
101+
return_annotation (Any | None): The return annotation of the function.
102102
source_code (str): The source code of the function.
103103
bound_parameters (dict[str, Any]): The parameters of the function bound with values.
104-
return_value (Optional[Any]): The return value of the function call.
104+
return_value (Any | None): The return value of the function call.
105105

106106
**Methods:**
107107

src/marvin/_internal/deprecation.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import functools
88
import warnings
99
from datetime import datetime, timedelta
10-
from typing import Any, Callable, Optional, TypeVar
10+
from typing import Any, Callable, TypeVar
1111

1212
from typing_extensions import ParamSpec
1313

@@ -22,8 +22,8 @@ class MarvinDeprecationWarning(DeprecationWarning):
2222

2323
def generate_deprecation_message(
2424
name: str,
25-
start_date: Optional[datetime] = None,
26-
end_date: Optional[datetime] = None,
25+
start_date: datetime | None = None,
26+
end_date: datetime | None = None,
2727
help: str = "",
2828
) -> str:
2929
"""Generate a deprecation warning message."""
@@ -45,8 +45,8 @@ def generate_deprecation_message(
4545

4646
def deprecated_class(
4747
*,
48-
start_date: Optional[datetime] = None,
49-
end_date: Optional[datetime] = None,
48+
start_date: datetime | None = None,
49+
end_date: datetime | None = None,
5050
stacklevel: int = 2,
5151
help: str = "",
5252
) -> Callable[[type[T]], type[T]]:
@@ -85,8 +85,8 @@ def new_init(self: T, *args: Any, **kwargs: Any) -> None:
8585

8686
def deprecated_callable(
8787
*,
88-
start_date: Optional[datetime] = None,
89-
end_date: Optional[datetime] = None,
88+
start_date: datetime | None = None,
89+
end_date: datetime | None = None,
9090
stacklevel: int = 2,
9191
help: str = "",
9292
) -> Callable[[Callable[P, R]], Callable[P, R]]:

src/marvin/agents/actor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from contextvars import ContextVar
55
from dataclasses import dataclass, field
66
from pathlib import Path
7-
from typing import TYPE_CHECKING, Any, Optional, Sequence, TypeVar
7+
from typing import TYPE_CHECKING, Any, Sequence, TypeVar
88

99
import pydantic_ai
1010
from pydantic_ai.agent import AgentRunResult
@@ -22,7 +22,7 @@
2222
from marvin.handlers.handlers import AsyncHandler, Handler
2323
T = TypeVar("T")
2424
# Global context var for current actor
25-
_current_actor: ContextVar[Optional["Actor"]] = ContextVar(
25+
_current_actor: ContextVar["Actor | None"] = ContextVar(
2626
"current_actor",
2727
default=None,
2828
)
@@ -79,7 +79,7 @@ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any):
7979
_current_actor.reset(self._tokens.pop())
8080

8181
@classmethod
82-
def get_current(cls) -> Optional["Actor"]:
82+
def get_current(cls) -> "Actor | None":
8383
"""Get the current actor from context."""
8484
return _current_actor.get()
8585

src/marvin/engine/orchestrator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from contextvars import ContextVar
55
from dataclasses import dataclass
66
from pathlib import Path
7-
from typing import Any, Literal, Optional, Sequence, TypeVar
7+
from typing import Any, Literal, Sequence, TypeVar
88

99
from pydantic_ai.agent import AgentRunResult
1010
from pydantic_ai.mcp import MCPServer
@@ -348,7 +348,7 @@ async def _get_messages(
348348
return user_prompt, [system_prompt] + message_history
349349

350350
@classmethod
351-
def get_current(cls) -> Optional["Orchestrator"]:
351+
def get_current(cls) -> "Orchestrator | None":
352352
"""Get the current orchestrator from context."""
353353
return _current_orchestrator.get()
354354

src/marvin/memory/providers/postgres.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import uuid
2-
from typing import Dict, Optional
2+
from typing import Dict
33

44
# async pg
55
import anyio
@@ -103,8 +103,8 @@ class PostgresMemory(MemoryProvider):
103103
)
104104

105105
# We'll store an async engine + session factory:
106-
_engine: Optional[AsyncEngine] = None
107-
_SessionLocal: Optional[async_sessionmaker[AsyncSession]] = None
106+
_engine: AsyncEngine | None = None
107+
_SessionLocal: async_sessionmaker[AsyncSession] | None = None
108108

109109
# Cache for dynamically generated table classes
110110
_table_class_cache: Dict[str, Base] = {}

0 commit comments

Comments
 (0)