Skip to content
Closed
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: 3 additions & 3 deletions sdk/python/cubesandbox/_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import json
import logging
import struct
from typing import TYPE_CHECKING, Any, Iterator
from typing import Any, Iterator, List, TYPE_CHECKING

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -122,7 +122,7 @@ def write(self, path: str, data: str | bytes, *, user: str | None = None) -> Non

def write_files(
self,
files: list[tuple[str, str | bytes]],
files: List[tuple[str, str | bytes]],
*,
user: str | None = None,
) -> int:
Expand All @@ -140,7 +140,7 @@ def write_files(
) from e
return len(files)

def list(self, path: str) -> list[dict[str, Any]]:
def list(self, path: str) -> List[dict[str, Any]]:
"""List entries in a directory."""
result = self._filesystem_rpc("ListDir", {"path": path})
return result.get("entries", [])
Expand Down
24 changes: 12 additions & 12 deletions sdk/python/cubesandbox/_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict
from typing import Any, Dict, List

import requests

Expand Down Expand Up @@ -41,7 +41,7 @@ class TemplateBuild:
message: str = ""
created_at: str = ""
finished_at: str = ""
logs: list[str] = field(default_factory=list)
logs: List[str] = field(default_factory=list)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rewrite isn't needed: TemplateBuild (like TemplateInfo) doesn't define a list method, so list[str] here already resolves to the builtin for both mypy and runtime. Only annotations lexically inside Template (which defines list) were affected by the shadowing — the same applies to replicas (line 83) and builds (line 87), which could stay list[...].

Reverting these three keeps the diff focused on the actual defect and consistent with the PEP-585 list[...] style used elsewhere in the same files (_models.py, _commands.py). It also avoids introducing typing.List in scopes where the builtin isn't shadowed, which ruff's UP006 (enabled via select = ["E", "F", "I", "UP"] in sdk/python/pyproject.toml) would flag if a full ruff check is ever run. (Not blocking — the changes are harmless.)


@classmethod
def from_dict(cls, data: dict) -> "TemplateBuild":
Expand Down Expand Up @@ -80,11 +80,11 @@ class TemplateInfo:
public: bool = False
cpu_count: int = 0
memory_mb: int = 0
replicas: list[dict] = field(default_factory=list)
replicas: List[dict] = field(default_factory=list)
create_request: dict | None = None
network_type: str | None = None
allow_internet_access: bool | None = None
builds: list[TemplateBuild] = field(default_factory=list)
builds: List[TemplateBuild] = field(default_factory=list)

@classmethod
def from_dict(cls, data: dict) -> "TemplateInfo":
Expand Down Expand Up @@ -146,7 +146,7 @@ class Template:


@classmethod
def list(cls, *, config: Config | None = None) -> list[TemplateInfo]:
def list(cls, *, config: Config | None = None) -> List[TemplateInfo]:
"""GET /templates — List all templates.

Args:
Expand Down Expand Up @@ -217,22 +217,22 @@ def build(
start_cmd: str | None = None,
instance_type: str | None = None,
writable_layer_size: str | None = None,
exposed_ports: list[int] | None = None,
exposed_ports: List[int] | None = None,
probe_port: int | None = None,
probe_path: str | None = None,
cpu_count: int | None = None,
memory_mb: int | None = None,
envs: Dict[str, str] | None = None,
allow_internet_access: bool | None = None,
network_type: str | None = None,
nodes: list[str] | None = None,
nodes: List[str] | None = None,
registry_username: str | None = None,
registry_password: str | None = None,
command: list[str] | None = None,
args: list[str] | None = None,
dns: list[str] | None = None,
allow_out: list[str] | None = None,
deny_out: list[str] | None = None,
command: List[str] | None = None,
args: List[str] | None = None,
dns: List[str] | None = None,
allow_out: List[str] | None = None,
deny_out: List[str] | None = None,
enable_ivshmem: bool | None = None,
config: Config | None = None,
**kwargs: Any,
Expand Down
10 changes: 5 additions & 5 deletions sdk/python/cubesandbox/_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import re
import threading
from dataclasses import dataclass
from typing import Dict, Union
from typing import Dict, List, Union

import requests

Expand Down Expand Up @@ -198,9 +198,9 @@ def _validate_mount_path(path: str) -> str:
return path


def _serialize_volume_mounts(mounts: VolumeMountsArg) -> list[dict[str, object]]:
def _serialize_volume_mounts(mounts: VolumeMountsArg) -> List[dict[str, object]]:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_serialize_volume_mounts is a module-level function, so list[dict[str, object]] here (and the serialized local on line 203) was never affected by the Volume.list shadowing — mypy resolves list to the builtin at module scope. The only annotation in this file that actually needed the fix is the return type of Volume.list (line 379). Consider reverting lines 201 and 203 to list[...] to keep the diff minimal and consistent with the surrounding PEP-585 style.

"""Serialize the e2b-style ``{path: volume}`` mapping into the wire format."""
serialized: list[dict[str, object]] = []
serialized: List[dict[str, object]] = []
for path, value in mounts.items():
if isinstance(value, VolumeMount):
volume = value.volume
Expand Down Expand Up @@ -244,7 +244,7 @@ class Volume:
sb.files.write("/workspace/note.txt", "persisted!")

# List / get_info / connect / destroy
for v in Volume.list(): # list[VolumeInfo]
for v in Volume.list(): # List[VolumeInfo]
print(v.volume_id, v.name)
Volume.get_info(vol.volume_id) # VolumeInfo
vol = Volume.connect("my-data") # Volume instance (== e2b)
Expand Down Expand Up @@ -376,7 +376,7 @@ def create(
return cls._from_info(VolumeInfo.from_dict(resp.json()), cfg)

@classmethod
def list(cls, *, config: Config | None = None) -> list[VolumeInfo]:
def list(cls, *, config: Config | None = None) -> List[VolumeInfo]:
"""GET /volumes — List all volumes.

The returned entries never carry a ``token`` (it is only surfaced on
Expand Down
14 changes: 7 additions & 7 deletions sdk/python/cubesandbox/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from __future__ import annotations

import threading
from typing import Any, Callable, Dict
from typing import Any, Callable, Dict, List

import httpx
import requests
Expand Down Expand Up @@ -190,7 +190,7 @@ def create(
env_vars: Dict[str, str] | None = None,
envs: Dict[str, str] | None = None,
metadata: Dict[str, str] | None = None,
distribution_scope: list[str] | None = None,
distribution_scope: List[str] | None = None,
allow_internet_access: bool = True,
network: Dict[str, Any] | None = None,
lifecycle: Dict[str, Any] | None = None,
Expand Down Expand Up @@ -354,7 +354,7 @@ def connect(cls, sandbox_id: str, *, config: Config | None = None) -> "Sandbox":


@classmethod
def list(cls, config: Config | None = None) -> list[dict]:
def list(cls, config: Config | None = None) -> List[dict]:
"""GET /sandboxes - List all running sandboxes (v1).

Args:
Expand All @@ -371,7 +371,7 @@ def list(cls, config: Config | None = None) -> list[dict]:
return resp.json()

@classmethod
def list_v2(cls, config: Config | None = None) -> list[dict]:
def list_v2(cls, config: Config | None = None) -> List[dict]:
"""GET /v2/sandboxes - List all running sandboxes (v2).

Supports state / metadata filtering on the server side.
Expand Down Expand Up @@ -644,7 +644,7 @@ def list_snapshots(
limit: int | None = None,
next_token: str | None = None,
config: Config | None = None,
) -> tuple[list[SnapshotInfo], str | None]:
) -> tuple[List[SnapshotInfo], str | None]:
"""GET /snapshots — List snapshots (1.2).

Args:
Expand Down Expand Up @@ -758,7 +758,7 @@ def _reset_connections(self) -> None:
pass
self._session = self._build_session()

def clone(self, n: int = 1, *, concurrency: int = 1) -> list["Sandbox"]:
def clone(self, n: int = 1, *, concurrency: int = 1) -> List["Sandbox"]:
"""Clone this sandbox *n* times (1.6).

Internally this executes three steps:
Expand Down Expand Up @@ -807,7 +807,7 @@ def clone(self, n: int = 1, *, concurrency: int = 1) -> list["Sandbox"]:
def _create_one() -> Sandbox:
return Sandbox.create(template=snap_id, config=cfg)

sandboxes: list[Sandbox] = []
sandboxes: List[Sandbox] = []
first_error: BaseException | None = None
if concurrency <= 1 or n <= 1:
# Sequential: short-circuit on first failure to preserve the
Expand Down
Loading