Skip to content

Commit

Permalink
chore: drop python 3.7
Browse files Browse the repository at this point in the history
  • Loading branch information
efiop committed Apr 1, 2024
1 parent fd80ca7 commit 1b443d4
Show file tree
Hide file tree
Showing 20 changed files with 264 additions and 292 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

matrix:
os: [ubuntu-latest, macos-latest]
python: ["3.7", "3.8", "3.9", "3.10"]
python: ["3.8", "3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -52,7 +52,6 @@ jobs:
python -m pip install -e ".[build]"
- name: Install uv
if: ${{ matrix.python != '3.7' }}
run: |
python -m pip install uv
Expand Down
17 changes: 10 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ repos:
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
exclude: '^src/.*_pb2.py$'
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
- id: ruff-format
exclude: '^src/.*_pb2.py$'
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.20.1
hooks:
- id: setup-cfg-fmt
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.2.0
hooks:
Expand All @@ -19,13 +15,20 @@ repos:
- --disallow-incomplete-defs
- --ignore-missing-imports
- --no-warn-no-return
exclude: '^src/.*_pb2.py$'
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
additional_dependencies: [types-protobuf]
- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
hooks:
- id: codespell
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
- repo: https://github.com/python-poetry/poetry
rev: 1.8.2
hooks:
- id: poetry-check
- repo: https://github.com/asottile/pyupgrade
rev: v3.1.0
hooks:
- id: pyupgrade
args: ["--py38-plus"]
exclude: ".*(_pb2.py|_pb2.pyi|_pb2_grpc.py)$"
372 changes: 176 additions & 196 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ authors = ["Features & Labels <[email protected]>"]
repository = "https://github.com/fal-ai/isolate"

[tool.poetry.dependencies]
python = ">=3.7,<4.0"
python = ">=3.8,<4.0"
grpcio = ">=1.49"
protobuf = "*"

Expand Down
6 changes: 2 additions & 4 deletions src/isolate/backends/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
Any,
Callable,
ClassVar,
Dict,
Generic,
Iterator,
Optional,
TypeVar,
)

Expand Down Expand Up @@ -37,14 +35,14 @@ class BaseEnvironment(Generic[ConnectionKeyType]):
"""Represents a managed environment definition for an isolatation backend
that can be used to run Python code with different set of dependencies."""

BACKEND_NAME: ClassVar[Optional[str]] = None
BACKEND_NAME: ClassVar[str | None] = None

settings: IsolateSettings = DEFAULT_SETTINGS

@classmethod
def from_config(
cls,
config: Dict[str, Any],
config: dict[str, Any],
settings: IsolateSettings = DEFAULT_SETTINGS,
) -> BaseEnvironment:
"""Create a new environment from the given configuration."""
Expand Down
14 changes: 7 additions & 7 deletions src/isolate/backends/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from functools import lru_cache
from pathlib import Path
from types import ModuleType
from typing import Callable, Dict, Iterator, Optional, Tuple, Union
from typing import Callable, Iterator

# For ensuring that the lock is created and not forgotten
# (e.g. the process which acquires it crashes, so it is never
Expand Down Expand Up @@ -91,7 +91,7 @@ def get_executable_path(search_path: Path, executable_name: str) -> Path:


def _io_observer(
hooks: Dict[int, HookT],
hooks: dict[int, HookT],
termination_event: threading.Event,
) -> threading.Thread:
"""Starts a new thread that reads from the specified file descriptors
Expand Down Expand Up @@ -156,7 +156,7 @@ def _reader():
return observer_thread


def _unblocked_pipe() -> Tuple[int, int]:
def _unblocked_pipe() -> tuple[int, int]:
"""Create a pair of unblocked pipes. This is actually
the same as os.pipe2(os.O_NONBLOCK), but that is not
available in MacOS so we have to do it manually."""
Expand All @@ -170,8 +170,8 @@ def _unblocked_pipe() -> Tuple[int, int]:
@contextmanager
def logged_io(
stdout_hook: HookT,
stderr_hook: Optional[HookT] = None,
) -> Iterator[Tuple[int, int]]:
stderr_hook: HookT | None = None,
) -> Iterator[tuple[int, int]]:
"""Open two new streams (for stdout and stderr, respectively) and start relaying all
the output from them to the given hooks."""

Expand Down Expand Up @@ -201,11 +201,11 @@ def logged_io(


@lru_cache(maxsize=None)
def sha256_digest_of(*unique_fields: Union[str, bytes]) -> str:
def sha256_digest_of(*unique_fields: str | bytes) -> str:
"""Return the SHA256 digest that corresponds to the combined version
of 'unique_fields. The order is preserved."""

def _normalize(text: Union[str, bytes]) -> bytes:
def _normalize(text: str | bytes) -> bytes:
if isinstance(text, str):
return text.encode()
else:
Expand Down
16 changes: 8 additions & 8 deletions src/isolate/backends/conda.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from dataclasses import dataclass, field
from functools import partial
from pathlib import Path
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing import Any, ClassVar

from isolate.backends import BaseEnvironment, EnvironmentCreationError
from isolate.backends.common import (
Expand Down Expand Up @@ -41,16 +41,16 @@
class CondaEnvironment(BaseEnvironment[Path]):
BACKEND_NAME: ClassVar[str] = "conda"

environment_definition: Dict[str, Any] = field(default_factory=dict)
python_version: Optional[str] = None
tags: List[str] = field(default_factory=list)
_exec_home: Optional[str] = _ISOLATE_MAMBA_HOME
_exec_command: Optional[str] = _MAMBA_COMMAND
environment_definition: dict[str, Any] = field(default_factory=dict)
python_version: str | None = None
tags: list[str] = field(default_factory=list)
_exec_home: str | None = _ISOLATE_MAMBA_HOME
_exec_command: str | None = _MAMBA_COMMAND

@classmethod
def from_config(
cls,
config: Dict[str, Any],
config: dict[str, Any],
settings: IsolateSettings = DEFAULT_SETTINGS,
) -> BaseEnvironment:
processing_config = copy.deepcopy(config)
Expand Down Expand Up @@ -187,7 +187,7 @@ def open_connection(self, connection_key: Path) -> PythonIPC:


def _depends_on(
dependencies: List[Union[str, Dict[str, List[str]]]],
dependencies: list[str | dict[str, list[str]]],
package_name: str,
) -> bool:
for dependency in dependencies:
Expand Down
4 changes: 2 additions & 2 deletions src/isolate/backends/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import Any, ClassVar, Dict
from typing import Any, ClassVar

from isolate.backends import BaseEnvironment
from isolate.backends.common import sha256_digest_of
Expand All @@ -18,7 +18,7 @@ class LocalPythonEnvironment(BaseEnvironment[Path]):
@classmethod
def from_config(
cls,
config: Dict[str, Any],
config: dict[str, Any],
settings: IsolateSettings = DEFAULT_SETTINGS,
) -> BaseEnvironment:
environment = cls(**config)
Expand Down
6 changes: 3 additions & 3 deletions src/isolate/backends/pyenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from dataclasses import dataclass
from functools import partial
from pathlib import Path
from typing import Any, ClassVar, Dict, Optional
from typing import Any, ClassVar

from isolate.backends import BaseEnvironment, EnvironmentCreationError
from isolate.backends.common import logged_io
Expand All @@ -28,7 +28,7 @@ class PyenvEnvironment(BaseEnvironment[Path]):
@classmethod
def from_config(
cls,
config: Dict[str, Any],
config: dict[str, Any],
settings: IsolateSettings = DEFAULT_SETTINGS,
) -> BaseEnvironment:
environment = cls(**config)
Expand Down Expand Up @@ -60,7 +60,7 @@ def create(self, *, force: bool = False) -> Path:
assert prefix is not None
return prefix

def _try_get_prefix(self, pyenv: Path, root_path: Path) -> Optional[Path]:
def _try_get_prefix(self, pyenv: Path, root_path: Path) -> Path | None:
try:
prefix = subprocess.check_output(
[pyenv, "prefix", self.python_version],
Expand Down
14 changes: 7 additions & 7 deletions src/isolate/backends/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import copy
import json
from dataclasses import dataclass
from typing import Any, ClassVar, Dict, List, Optional
from typing import Any, ClassVar, List

import grpc

Expand All @@ -28,12 +28,12 @@ class IsolateServer(BaseEnvironment[List[EnvironmentDefinition]]):
BACKEND_NAME: ClassVar[str] = "isolate-server"

host: str
target_environments: List[Dict[str, Any]]
target_environments: list[dict[str, Any]]

@classmethod
def from_config(
cls,
config: Dict[str, Any],
config: dict[str, Any],
settings: IsolateSettings = DEFAULT_SETTINGS,
) -> BaseEnvironment:
environment = cls(**config)
Expand All @@ -48,7 +48,7 @@ def key(self) -> str:
json.dumps(self.target_environments),
)

def create(self, *, force: bool = False) -> List[EnvironmentDefinition]:
def create(self, *, force: bool = False) -> list[EnvironmentDefinition]:
if force is True:
raise NotImplementedError(
"Only individual environments can be forcibly created, please set them up"
Expand All @@ -75,16 +75,16 @@ def exists(self) -> bool:

def open_connection(
self,
connection_key: List[EnvironmentDefinition],
connection_key: list[EnvironmentDefinition],
) -> IsolateServerConnection:
return IsolateServerConnection(self, self.host, connection_key)


@dataclass
class IsolateServerConnection(EnvironmentConnection):
host: str
definitions: List[EnvironmentDefinition]
_channel: Optional[grpc.Channel] = None
definitions: list[EnvironmentDefinition]
_channel: grpc.Channel | None = None

def _acquire_channel(self) -> None:
self._channel = grpc.insecure_channel(self.host)
Expand Down
18 changes: 9 additions & 9 deletions src/isolate/backends/virtualenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from dataclasses import dataclass, field
from functools import partial
from pathlib import Path
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing import Any, ClassVar

from isolate.backends import BaseEnvironment, EnvironmentCreationError
from isolate.backends.common import (
Expand All @@ -29,17 +29,17 @@
class VirtualPythonEnvironment(BaseEnvironment[Path]):
BACKEND_NAME: ClassVar[str] = "virtualenv"

requirements: List[str] = field(default_factory=list)
constraints_file: Optional[os.PathLike] = None
python_version: Optional[str] = None
extra_index_urls: List[str] = field(default_factory=list)
tags: List[str] = field(default_factory=list)
resolver: Optional[str] = None
requirements: list[str] = field(default_factory=list)
constraints_file: os.PathLike | None = None
python_version: str | None = None
extra_index_urls: list[str] = field(default_factory=list)
tags: list[str] = field(default_factory=list)
resolver: str | None = None

@classmethod
def from_config(
cls,
config: Dict[str, Any],
config: dict[str, Any],
settings: IsolateSettings = DEFAULT_SETTINGS,
) -> BaseEnvironment:
environment = cls(**config)
Expand Down Expand Up @@ -99,7 +99,7 @@ def install_requirements(self, path: Path) -> None:
else:
base_pip_cmd = [get_executable_path(path, "pip")]

pip_cmd: List[Union[str, os.PathLike]] = [
pip_cmd: list[str | os.PathLike] = [
*base_pip_cmd, # type: ignore
"install",
*self.requirements,
Expand Down
9 changes: 3 additions & 6 deletions src/isolate/connections/_local/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@
from typing import (
TYPE_CHECKING,
Any,
Dict,
Generic,
Iterator,
List,
TypeVar,
Union,
)

from isolate.backends.common import get_executable_path, logged_io
Expand Down Expand Up @@ -102,7 +99,7 @@ class PythonExecutionBase(Generic[ConnectionType]):

environment: BaseEnvironment
environment_path: Path
extra_inheritance_paths: List[Path] = field(default_factory=list)
extra_inheritance_paths: list[Path] = field(default_factory=list)

@contextmanager
def start_process(
Expand All @@ -127,7 +124,7 @@ def start_process(
text=True,
)

def get_env_vars(self) -> Dict[str, str]:
def get_env_vars(self) -> dict[str, str]:
"""Return the environment variables to run the agent process with. By default
PYTHONUNBUFFERED is set to 1 to ensure the prints to stdout/stderr are reflect
immediately (so that we can seamlessly transfer logs)."""
Expand Down Expand Up @@ -161,7 +158,7 @@ def get_python_cmd(
self,
executable: Path,
connection: ConnectionType,
) -> List[Union[str, Path]]:
) -> list[str | Path]:
"""Return the command to run the agent process with."""
raise NotImplementedError

Expand Down
6 changes: 3 additions & 3 deletions src/isolate/connections/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
from contextlib import contextmanager
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Iterator, Optional, cast
from typing import TYPE_CHECKING, Any, Iterator, cast

from tblib import Traceback, TracebackParseError

Expand Down Expand Up @@ -59,7 +59,7 @@ def load_serialized_object(
raw_object: bytes,
*,
was_it_raised: bool = False,
stringized_traceback: Optional[str] = None,
stringized_traceback: str | None = None,
) -> Any:
"""Load the given serialized object using the given serialization method. If
anything fails, then a SerializationError will be raised. If the was_it_raised
Expand Down Expand Up @@ -101,7 +101,7 @@ def is_agent() -> bool:
def prepare_exc(
exc: BaseException,
*,
stringized_traceback: Optional[str] = None,
stringized_traceback: str | None = None,
) -> BaseException:
if stringized_traceback:
try:
Expand Down
Loading

0 comments on commit 1b443d4

Please sign in to comment.