isolate 0.12.7__tar.gz → 0.12.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of isolate might be problematic. Click here for more details.

Files changed (60) hide show
  1. {isolate-0.12.7 → isolate-0.12.9}/PKG-INFO +4 -3
  2. {isolate-0.12.7 → isolate-0.12.9}/pyproject.toml +5 -8
  3. isolate-0.12.9/src/isolate/__init__.py +1 -0
  4. isolate-0.12.9/src/isolate/backends/__init__.py +2 -0
  5. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/_base.py +2 -4
  6. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/common.py +7 -7
  7. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/conda.py +9 -11
  8. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/local.py +2 -2
  9. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/pyenv.py +4 -4
  10. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/remote.py +8 -8
  11. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/settings.py +1 -1
  12. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/backends/virtualenv.py +9 -10
  13. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/__init__.py +1 -5
  14. isolate-0.12.9/src/isolate/connections/_local/__init__.py +2 -0
  15. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/_local/_base.py +3 -6
  16. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/common.py +5 -7
  17. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/__init__.py +1 -1
  18. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/_base.py +2 -2
  19. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/agent.py +3 -9
  20. isolate-0.12.9/src/isolate/connections/grpc/definitions/__init__.py +11 -0
  21. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/interface.py +1 -1
  22. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/ipc/__init__.py +1 -1
  23. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/ipc/_base.py +6 -13
  24. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/ipc/agent.py +4 -8
  25. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/logs.py +3 -6
  26. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/registry.py +3 -3
  27. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/__init__.py +1 -1
  28. isolate-0.12.9/src/isolate/server/definitions/__init__.py +13 -0
  29. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/health/__init__.py +3 -3
  30. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/server.py +6 -8
  31. isolate-0.12.7/src/isolate/__init__.py +0 -1
  32. isolate-0.12.7/src/isolate/backends/__init__.py +0 -2
  33. isolate-0.12.7/src/isolate/connections/_local/__init__.py +0 -2
  34. isolate-0.12.7/src/isolate/connections/grpc/definitions/__init__.py +0 -11
  35. isolate-0.12.7/src/isolate/server/definitions/__init__.py +0 -13
  36. {isolate-0.12.7 → isolate-0.12.9}/LICENSE +0 -0
  37. {isolate-0.12.7 → isolate-0.12.9}/README.md +0 -0
  38. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/common/__init__.py +0 -0
  39. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/common/timestamp.py +0 -0
  40. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/_local/agent_startup.py +0 -0
  41. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/configuration.py +0 -0
  42. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/agent.proto +0 -0
  43. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/agent_pb2.py +0 -0
  44. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/agent_pb2.pyi +0 -0
  45. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/agent_pb2_grpc.py +0 -0
  46. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/common.proto +0 -0
  47. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/common_pb2.py +0 -0
  48. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/common_pb2.pyi +0 -0
  49. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/connections/grpc/definitions/common_pb2_grpc.py +0 -0
  50. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/py.typed +0 -0
  51. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/definitions/server.proto +0 -0
  52. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/definitions/server_pb2.py +0 -0
  53. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/definitions/server_pb2.pyi +0 -0
  54. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/definitions/server_pb2_grpc.py +0 -0
  55. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/health/health.proto +0 -0
  56. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/health/health_pb2.py +0 -0
  57. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/health/health_pb2.pyi +0 -0
  58. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/health/health_pb2_grpc.py +0 -0
  59. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/health_server.py +0 -0
  60. {isolate-0.12.7 → isolate-0.12.9}/src/isolate/server/interface.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: isolate
3
- Version: 0.12.7
3
+ Version: 0.12.9
4
4
  Summary: Managed isolated environments for Python
5
+ Home-page: https://github.com/fal-ai/isolate
5
6
  Author: Features & Labels
6
7
  Author-email: hello@fal.ai
7
- Requires-Python: >=3.7,<4.0
8
+ Requires-Python: >=3.8,<4.0
8
9
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.7
10
10
  Classifier: Programming Language :: Python :: 3.8
11
11
  Classifier: Programming Language :: Python :: 3.9
12
12
  Classifier: Programming Language :: Python :: 3.10
@@ -21,6 +21,7 @@ Requires-Dist: platformdirs
21
21
  Requires-Dist: protobuf
22
22
  Requires-Dist: tblib (>=1.7.0)
23
23
  Requires-Dist: virtualenv (>=20.4) ; extra == "build"
24
+ Project-URL: Repository, https://github.com/fal-ai/isolate
24
25
  Description-Content-Type: text/markdown
25
26
 
26
27
  # Isolate
@@ -1,12 +1,13 @@
1
1
  [tool.poetry]
2
2
  name = "isolate"
3
- version = "0.12.7"
3
+ version = "0.12.9"
4
4
  readme = "README.md"
5
5
  description = "Managed isolated environments for Python"
6
6
  authors = ["Features & Labels <hello@fal.ai>"]
7
+ repository = "https://github.com/fal-ai/isolate"
7
8
 
8
9
  [tool.poetry.dependencies]
9
- python = ">=3.7,<4.0"
10
+ python = ">=3.8,<4.0"
10
11
  grpcio = ">=1.49"
11
12
  protobuf = "*"
12
13
 
@@ -39,9 +40,5 @@ build = ["virtualenv", "PyYAML"]
39
40
  requires = ["poetry-core>=1.1.0"]
40
41
  build-backend = "poetry.core.masonry.api"
41
42
 
42
- [tool.isort]
43
- atomic=true
44
- force_grid_wrap=0
45
- include_trailing_comma=true
46
- multi_line_output=3
47
- use_parentheses=true
43
+ [tool.ruff]
44
+ exclude = ["*_pb2.py", "*_pb2.pyi", "*_pb2_grpc.py"]
@@ -0,0 +1 @@
1
+ from isolate.registry import prepare_environment # noqa: F401
@@ -0,0 +1,2 @@
1
+ from isolate.backends._base import * # noqa: F403
2
+ from isolate.backends.settings import IsolateSettings # noqa: F401
@@ -6,10 +6,8 @@ from typing import (
6
6
  Any,
7
7
  Callable,
8
8
  ClassVar,
9
- Dict,
10
9
  Generic,
11
10
  Iterator,
12
- Optional,
13
11
  TypeVar,
14
12
  )
15
13
 
@@ -37,14 +35,14 @@ class BaseEnvironment(Generic[ConnectionKeyType]):
37
35
  """Represents a managed environment definition for an isolatation backend
38
36
  that can be used to run Python code with different set of dependencies."""
39
37
 
40
- BACKEND_NAME: ClassVar[Optional[str]] = None
38
+ BACKEND_NAME: ClassVar[str | None] = None
41
39
 
42
40
  settings: IsolateSettings = DEFAULT_SETTINGS
43
41
 
44
42
  @classmethod
45
43
  def from_config(
46
44
  cls,
47
- config: Dict[str, Any],
45
+ config: dict[str, Any],
48
46
  settings: IsolateSettings = DEFAULT_SETTINGS,
49
47
  ) -> BaseEnvironment:
50
48
  """Create a new environment from the given configuration."""
@@ -12,7 +12,7 @@ from contextlib import contextmanager, suppress
12
12
  from functools import lru_cache
13
13
  from pathlib import Path
14
14
  from types import ModuleType
15
- from typing import Callable, Dict, Iterator, Optional, Tuple, Union
15
+ from typing import Callable, Iterator
16
16
 
17
17
  # For ensuring that the lock is created and not forgotten
18
18
  # (e.g. the process which acquires it crashes, so it is never
@@ -91,7 +91,7 @@ HookT = Callable[[str], None]
91
91
 
92
92
 
93
93
  def _io_observer(
94
- hooks: Dict[int, HookT],
94
+ hooks: dict[int, HookT],
95
95
  termination_event: threading.Event,
96
96
  ) -> threading.Thread:
97
97
  """Starts a new thread that reads from the specified file descriptors
@@ -156,7 +156,7 @@ def _io_observer(
156
156
  return observer_thread
157
157
 
158
158
 
159
- def _unblocked_pipe() -> Tuple[int, int]:
159
+ def _unblocked_pipe() -> tuple[int, int]:
160
160
  """Create a pair of unblocked pipes. This is actually
161
161
  the same as os.pipe2(os.O_NONBLOCK), but that is not
162
162
  available in MacOS so we have to do it manually."""
@@ -170,8 +170,8 @@ def _unblocked_pipe() -> Tuple[int, int]:
170
170
  @contextmanager
171
171
  def logged_io(
172
172
  stdout_hook: HookT,
173
- stderr_hook: Optional[HookT] = None,
174
- ) -> Iterator[Tuple[int, int]]:
173
+ stderr_hook: HookT | None = None,
174
+ ) -> Iterator[tuple[int, int]]:
175
175
  """Open two new streams (for stdout and stderr, respectively) and start relaying all
176
176
  the output from them to the given hooks."""
177
177
 
@@ -201,11 +201,11 @@ def logged_io(
201
201
 
202
202
 
203
203
  @lru_cache(maxsize=None)
204
- def sha256_digest_of(*unique_fields: Union[str, bytes]) -> str:
204
+ def sha256_digest_of(*unique_fields: str | bytes) -> str:
205
205
  """Return the SHA256 digest that corresponds to the combined version
206
206
  of 'unique_fields. The order is preserved."""
207
207
 
208
- def _normalize(text: Union[str, bytes]) -> bytes:
208
+ def _normalize(text: str | bytes) -> bytes:
209
209
  if isinstance(text, str):
210
210
  return text.encode()
211
211
  else:
@@ -1,15 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import copy
4
- import functools
5
4
  import os
6
- import shutil
7
5
  import subprocess
8
6
  import tempfile
9
7
  from dataclasses import dataclass, field
10
8
  from functools import partial
11
9
  from pathlib import Path
12
- from typing import Any, ClassVar, Dict, List, Optional, Union
10
+ from typing import Any, ClassVar
13
11
 
14
12
  from isolate.backends import BaseEnvironment, EnvironmentCreationError
15
13
  from isolate.backends.common import (
@@ -43,16 +41,16 @@ _POSSIBLE_CONDA_VERSION_IDENTIFIERS = (
43
41
  class CondaEnvironment(BaseEnvironment[Path]):
44
42
  BACKEND_NAME: ClassVar[str] = "conda"
45
43
 
46
- environment_definition: Dict[str, Any] = field(default_factory=dict)
47
- python_version: Optional[str] = None
48
- tags: List[str] = field(default_factory=list)
49
- _exec_home: Optional[str] = _ISOLATE_MAMBA_HOME
50
- _exec_command: Optional[str] = _MAMBA_COMMAND
44
+ environment_definition: dict[str, Any] = field(default_factory=dict)
45
+ python_version: str | None = None
46
+ tags: list[str] = field(default_factory=list)
47
+ _exec_home: str | None = _ISOLATE_MAMBA_HOME
48
+ _exec_command: str | None = _MAMBA_COMMAND
51
49
 
52
50
  @classmethod
53
51
  def from_config(
54
52
  cls,
55
- config: Dict[str, Any],
53
+ config: dict[str, Any],
56
54
  settings: IsolateSettings = DEFAULT_SETTINGS,
57
55
  ) -> BaseEnvironment:
58
56
  processing_config = copy.deepcopy(config)
@@ -163,7 +161,7 @@ class CondaEnvironment(BaseEnvironment[Path]):
163
161
  def _run_create(self, env_path: str, env_name: str) -> None:
164
162
  if self._exec_command == "conda":
165
163
  self._run_conda(
166
- "env", "create", "--force", "--prefix", env_path, "-f", env_name
164
+ "env", "create", "--yes", "--prefix", env_path, "-f", env_name
167
165
  )
168
166
  else:
169
167
  self._run_conda("env", "create", "--prefix", env_path, "-f", env_name)
@@ -189,7 +187,7 @@ class CondaEnvironment(BaseEnvironment[Path]):
189
187
 
190
188
 
191
189
  def _depends_on(
192
- dependencies: List[Union[str, Dict[str, List[str]]]],
190
+ dependencies: list[str | dict[str, list[str]]],
193
191
  package_name: str,
194
192
  ) -> bool:
195
193
  for dependency in dependencies:
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import sys
4
4
  from dataclasses import dataclass
5
5
  from pathlib import Path
6
- from typing import Any, ClassVar, Dict
6
+ from typing import Any, ClassVar
7
7
 
8
8
  from isolate.backends import BaseEnvironment
9
9
  from isolate.backends.common import sha256_digest_of
@@ -18,7 +18,7 @@ class LocalPythonEnvironment(BaseEnvironment[Path]):
18
18
  @classmethod
19
19
  def from_config(
20
20
  cls,
21
- config: Dict[str, Any],
21
+ config: dict[str, Any],
22
22
  settings: IsolateSettings = DEFAULT_SETTINGS,
23
23
  ) -> BaseEnvironment:
24
24
  environment = cls(**config)
@@ -7,7 +7,7 @@ import subprocess
7
7
  from dataclasses import dataclass
8
8
  from functools import partial
9
9
  from pathlib import Path
10
- from typing import Any, ClassVar, Dict, Optional
10
+ from typing import Any, ClassVar
11
11
 
12
12
  from isolate.backends import BaseEnvironment, EnvironmentCreationError
13
13
  from isolate.backends.common import logged_io
@@ -28,7 +28,7 @@ class PyenvEnvironment(BaseEnvironment[Path]):
28
28
  @classmethod
29
29
  def from_config(
30
30
  cls,
31
- config: Dict[str, Any],
31
+ config: dict[str, Any],
32
32
  settings: IsolateSettings = DEFAULT_SETTINGS,
33
33
  ) -> BaseEnvironment:
34
34
  environment = cls(**config)
@@ -60,7 +60,7 @@ class PyenvEnvironment(BaseEnvironment[Path]):
60
60
  assert prefix is not None
61
61
  return prefix
62
62
 
63
- def _try_get_prefix(self, pyenv: Path, root_path: Path) -> Optional[Path]:
63
+ def _try_get_prefix(self, pyenv: Path, root_path: Path) -> Path | None:
64
64
  try:
65
65
  prefix = subprocess.check_output(
66
66
  [pyenv, "prefix", self.python_version],
@@ -87,7 +87,7 @@ class PyenvEnvironment(BaseEnvironment[Path]):
87
87
  stdout=stdout,
88
88
  stderr=stderr,
89
89
  )
90
- except subprocess.CalledProcessError as exc:
90
+ except subprocess.CalledProcessError:
91
91
  raise EnvironmentCreationError(
92
92
  f"Failed to install Python {self.python_version} via pyenv.\n"
93
93
  )
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import copy
4
4
  import json
5
5
  from dataclasses import dataclass
6
- from typing import Any, ClassVar, Dict, List, Optional
6
+ from typing import Any, ClassVar, List
7
7
 
8
8
  import grpc
9
9
 
@@ -28,12 +28,12 @@ class IsolateServer(BaseEnvironment[List[EnvironmentDefinition]]):
28
28
  BACKEND_NAME: ClassVar[str] = "isolate-server"
29
29
 
30
30
  host: str
31
- target_environments: List[Dict[str, Any]]
31
+ target_environments: list[dict[str, Any]]
32
32
 
33
33
  @classmethod
34
34
  def from_config(
35
35
  cls,
36
- config: Dict[str, Any],
36
+ config: dict[str, Any],
37
37
  settings: IsolateSettings = DEFAULT_SETTINGS,
38
38
  ) -> BaseEnvironment:
39
39
  environment = cls(**config)
@@ -48,7 +48,7 @@ class IsolateServer(BaseEnvironment[List[EnvironmentDefinition]]):
48
48
  json.dumps(self.target_environments),
49
49
  )
50
50
 
51
- def create(self, *, force: bool = False) -> List[EnvironmentDefinition]:
51
+ def create(self, *, force: bool = False) -> list[EnvironmentDefinition]:
52
52
  if force is True:
53
53
  raise NotImplementedError(
54
54
  "Only individual environments can be forcibly created, please set them up"
@@ -75,7 +75,7 @@ class IsolateServer(BaseEnvironment[List[EnvironmentDefinition]]):
75
75
 
76
76
  def open_connection(
77
77
  self,
78
- connection_key: List[EnvironmentDefinition],
78
+ connection_key: list[EnvironmentDefinition],
79
79
  ) -> IsolateServerConnection:
80
80
  return IsolateServerConnection(self, self.host, connection_key)
81
81
 
@@ -83,8 +83,8 @@ class IsolateServer(BaseEnvironment[List[EnvironmentDefinition]]):
83
83
  @dataclass
84
84
  class IsolateServerConnection(EnvironmentConnection):
85
85
  host: str
86
- definitions: List[EnvironmentDefinition]
87
- _channel: Optional[grpc.Channel] = None
86
+ definitions: list[EnvironmentDefinition]
87
+ _channel: grpc.Channel | None = None
88
88
 
89
89
  def _acquire_channel(self) -> None:
90
90
  self._channel = grpc.insecure_channel(self.host)
@@ -102,7 +102,7 @@ class IsolateServerConnection(EnvironmentConnection):
102
102
  executable: BasicCallable,
103
103
  *args: Any,
104
104
  **kwargs: Any,
105
- ) -> CallResultType:
105
+ ) -> CallResultType: # type: ignore[type-var]
106
106
  if self._channel is None:
107
107
  self._acquire_channel()
108
108
 
@@ -6,7 +6,7 @@ import tempfile
6
6
  from contextlib import contextmanager
7
7
  from dataclasses import dataclass, replace
8
8
  from pathlib import Path
9
- from typing import TYPE_CHECKING, Any, Callable, Iterator
9
+ from typing import TYPE_CHECKING, Callable, Iterator
10
10
 
11
11
  from platformdirs import user_cache_dir
12
12
 
@@ -1,13 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import os
4
- import shlex
5
4
  import shutil
6
5
  import subprocess
7
6
  from dataclasses import dataclass, field
8
7
  from functools import partial
9
8
  from pathlib import Path
10
- from typing import Any, ClassVar, Dict, List, Optional, Union
9
+ from typing import Any, ClassVar
11
10
 
12
11
  from isolate.backends import BaseEnvironment, EnvironmentCreationError
13
12
  from isolate.backends.common import (
@@ -30,17 +29,17 @@ _UV_RESOLVER_HOME = os.getenv("ISOLATE_UV_HOME")
30
29
  class VirtualPythonEnvironment(BaseEnvironment[Path]):
31
30
  BACKEND_NAME: ClassVar[str] = "virtualenv"
32
31
 
33
- requirements: List[str] = field(default_factory=list)
34
- constraints_file: Optional[os.PathLike] = None
35
- python_version: Optional[str] = None
36
- extra_index_urls: List[str] = field(default_factory=list)
37
- tags: List[str] = field(default_factory=list)
38
- resolver: Optional[str] = None
32
+ requirements: list[str] = field(default_factory=list)
33
+ constraints_file: os.PathLike | None = None
34
+ python_version: str | None = None
35
+ extra_index_urls: list[str] = field(default_factory=list)
36
+ tags: list[str] = field(default_factory=list)
37
+ resolver: str | None = None
39
38
 
40
39
  @classmethod
41
40
  def from_config(
42
41
  cls,
43
- config: Dict[str, Any],
42
+ config: dict[str, Any],
44
43
  settings: IsolateSettings = DEFAULT_SETTINGS,
45
44
  ) -> BaseEnvironment:
46
45
  environment = cls(**config)
@@ -100,7 +99,7 @@ class VirtualPythonEnvironment(BaseEnvironment[Path]):
100
99
  else:
101
100
  base_pip_cmd = [get_executable_path(path, "pip")]
102
101
 
103
- pip_cmd: List[Union[str, os.PathLike]] = [
102
+ pip_cmd: list[str | os.PathLike] = [
104
103
  *base_pip_cmd, # type: ignore
105
104
  "install",
106
105
  *self.requirements,
@@ -1,10 +1,6 @@
1
1
  import importlib
2
- from typing import TYPE_CHECKING
3
2
 
4
- from isolate.connections.ipc import IsolatedProcessConnection, PythonIPC
5
-
6
- if TYPE_CHECKING:
7
- from isolate.connections.grpc import LocalPythonGRPC
3
+ from isolate.connections.ipc import IsolatedProcessConnection, PythonIPC # noqa: F401
8
4
 
9
5
 
10
6
  def __getattr__(name):
@@ -0,0 +1,2 @@
1
+ from isolate.connections._local import agent_startup # noqa: F401
2
+ from isolate.connections._local._base import PythonExecutionBase # noqa: F401
@@ -10,12 +10,9 @@ from pathlib import Path
10
10
  from typing import (
11
11
  TYPE_CHECKING,
12
12
  Any,
13
- Dict,
14
13
  Generic,
15
14
  Iterator,
16
- List,
17
15
  TypeVar,
18
- Union,
19
16
  )
20
17
 
21
18
  from isolate.backends.common import get_executable_path, logged_io
@@ -102,7 +99,7 @@ class PythonExecutionBase(Generic[ConnectionType]):
102
99
 
103
100
  environment: BaseEnvironment
104
101
  environment_path: Path
105
- extra_inheritance_paths: List[Path] = field(default_factory=list)
102
+ extra_inheritance_paths: list[Path] = field(default_factory=list)
106
103
 
107
104
  @contextmanager
108
105
  def start_process(
@@ -127,7 +124,7 @@ class PythonExecutionBase(Generic[ConnectionType]):
127
124
  text=True,
128
125
  )
129
126
 
130
- def get_env_vars(self) -> Dict[str, str]:
127
+ def get_env_vars(self) -> dict[str, str]:
131
128
  """Return the environment variables to run the agent process with. By default
132
129
  PYTHONUNBUFFERED is set to 1 to ensure the prints to stdout/stderr are reflect
133
130
  immediately (so that we can seamlessly transfer logs)."""
@@ -161,7 +158,7 @@ class PythonExecutionBase(Generic[ConnectionType]):
161
158
  self,
162
159
  executable: Path,
163
160
  connection: ConnectionType,
164
- ) -> List[Union[str, Path]]:
161
+ ) -> list[str | Path]:
165
162
  """Return the command to run the agent process with."""
166
163
  raise NotImplementedError
167
164
 
@@ -4,7 +4,7 @@ import importlib
4
4
  import os
5
5
  from contextlib import contextmanager
6
6
  from dataclasses import dataclass
7
- from typing import TYPE_CHECKING, Any, Iterator, Optional, cast
7
+ from typing import TYPE_CHECKING, Any, Iterator, cast
8
8
 
9
9
  from tblib import Traceback, TracebackParseError
10
10
 
@@ -12,11 +12,9 @@ if TYPE_CHECKING:
12
12
  from typing import Protocol
13
13
 
14
14
  class SerializationBackend(Protocol):
15
- def loads(self, data: bytes) -> Any:
16
- ...
15
+ def loads(self, data: bytes) -> Any: ...
17
16
 
18
- def dumps(self, obj: Any) -> bytes:
19
- ...
17
+ def dumps(self, obj: Any) -> bytes: ...
20
18
 
21
19
 
22
20
  AGENT_SIGNATURE = "IS_ISOLATE_AGENT"
@@ -61,7 +59,7 @@ def load_serialized_object(
61
59
  raw_object: bytes,
62
60
  *,
63
61
  was_it_raised: bool = False,
64
- stringized_traceback: Optional[str] = None,
62
+ stringized_traceback: str | None = None,
65
63
  ) -> Any:
66
64
  """Load the given serialized object using the given serialization method. If
67
65
  anything fails, then a SerializationError will be raised. If the was_it_raised
@@ -103,7 +101,7 @@ def is_agent() -> bool:
103
101
  def prepare_exc(
104
102
  exc: BaseException,
105
103
  *,
106
- stringized_traceback: Optional[str] = None,
104
+ stringized_traceback: str | None = None,
107
105
  ) -> BaseException:
108
106
  if stringized_traceback:
109
107
  try:
@@ -1 +1 @@
1
- from isolate.connections.grpc._base import AgentError, LocalPythonGRPC
1
+ from isolate.connections.grpc._base import AgentError, LocalPythonGRPC # noqa: F401
@@ -15,8 +15,8 @@ from isolate.connections._local import PythonExecutionBase, agent_startup
15
15
  from isolate.connections.common import serialize_object
16
16
  from isolate.connections.grpc import agent, definitions
17
17
  from isolate.connections.grpc.configuration import get_default_options
18
- from isolate.connections.grpc.interface import from_grpc, to_grpc
19
- from isolate.logs import Log, LogLevel, LogSource
18
+ from isolate.connections.grpc.interface import from_grpc
19
+ from isolate.logs import LogLevel, LogSource
20
20
 
21
21
 
22
22
  class AgentError(Exception):
@@ -8,12 +8,9 @@ from concurrent import futures
8
8
  from dataclasses import dataclass, field
9
9
  from typing import (
10
10
  Any,
11
- Dict,
12
11
  Generator,
13
12
  Iterable,
14
13
  Iterator,
15
- List,
16
- Optional,
17
14
  cast,
18
15
  )
19
16
 
@@ -35,7 +32,7 @@ class AbortException(Exception):
35
32
 
36
33
  @dataclass
37
34
  class AgentServicer(definitions.AgentServicer):
38
- _run_cache: Dict[str, Any] = field(default_factory=dict)
35
+ _run_cache: dict[str, Any] = field(default_factory=dict)
39
36
 
40
37
  def Run(
41
38
  self,
@@ -111,11 +108,8 @@ class AgentServicer(definitions.AgentServicer):
111
108
  # TODO: technically any sort of exception could be raised here, since
112
109
  # depickling is basically involves code execution from the *user*.
113
110
  function = from_grpc(function)
114
- except SerializationError:
115
- yield from self.log(traceback.format_exc(), level=LogLevel.ERROR)
116
- raise AbortException(
117
- f"The {function_kind} function could not be deserialized."
118
- )
111
+ except SerializationError as exc:
112
+ return exc, True, traceback.format_exc()
119
113
 
120
114
  if not callable(function):
121
115
  raise AbortException(
@@ -0,0 +1,11 @@
1
+ from google.protobuf.message import Message # noqa: F401
2
+
3
+ from isolate.connections.grpc.definitions.agent_pb2 import * # noqa: F403
4
+ from isolate.connections.grpc.definitions.agent_pb2_grpc import ( # noqa: F401
5
+ AgentServicer,
6
+ AgentStub,
7
+ )
8
+ from isolate.connections.grpc.definitions.agent_pb2_grpc import ( # noqa: F401
9
+ add_AgentServicer_to_server as register_agent,
10
+ )
11
+ from isolate.connections.grpc.definitions.common_pb2 import * # noqa: F403
@@ -2,7 +2,7 @@
2
2
  and the Isolate Server to share."""
3
3
 
4
4
  import functools
5
- from typing import TYPE_CHECKING, Any, Optional
5
+ from typing import Any, Optional
6
6
 
7
7
  from isolate.common import timestamp
8
8
  from isolate.connections.common import load_serialized_object, serialize_object
@@ -1,4 +1,4 @@
1
- from isolate.connections.ipc._base import (
1
+ from isolate.connections.ipc._base import ( # noqa: F401
2
2
  IsolatedProcessConnection,
3
3
  PythonExecutionBase,
4
4
  PythonIPC,
@@ -13,9 +13,6 @@ from typing import (
13
13
  Any,
14
14
  Callable,
15
15
  ContextManager,
16
- List,
17
- Tuple,
18
- Union,
19
16
  )
20
17
 
21
18
  from isolate.backends import (
@@ -37,17 +34,13 @@ if TYPE_CHECKING:
37
34
  connection: Any,
38
35
  loads: Callable[[bytes], Any],
39
36
  dumps: Callable[[Any], bytes],
40
- ) -> None:
41
- ...
37
+ ) -> None: ...
42
38
 
43
- def recv(self) -> Any:
44
- ...
39
+ def recv(self) -> Any: ...
45
40
 
46
- def send(self, value: Any) -> None:
47
- ...
41
+ def send(self, value: Any) -> None: ...
48
42
 
49
- def close(self) -> None:
50
- ...
43
+ def close(self) -> None: ...
51
44
 
52
45
  else:
53
46
  from multiprocessing.connection import ConnectionWrapper
@@ -75,7 +68,7 @@ def loadserialization_method(backend_name: str) -> Any:
75
68
  return importlib.import_module(backend_name)
76
69
 
77
70
 
78
- def encode_service_address(address: Tuple[str, int]) -> str:
71
+ def encode_service_address(address: tuple[str, int]) -> str:
79
72
  host, port = address
80
73
  return base64.b64encode(f"{host}:{port}".encode()).decode("utf-8")
81
74
 
@@ -207,7 +200,7 @@ class PythonIPC(PythonExecutionBase[AgentListener], IsolatedProcessConnection):
207
200
  self,
208
201
  executable: Path,
209
202
  connection: AgentListener,
210
- ) -> List[Union[str, Path]]:
203
+ ) -> list[str | Path]:
211
204
  assert isinstance(connection.address, tuple)
212
205
  return [
213
206
  executable,
@@ -35,17 +35,13 @@ if TYPE_CHECKING:
35
35
  connection: Any,
36
36
  loads: Callable[[bytes], Any],
37
37
  dumps: Callable[[Any], bytes],
38
- ) -> None:
39
- ...
38
+ ) -> None: ...
40
39
 
41
- def recv(self) -> Any:
42
- ...
40
+ def recv(self) -> Any: ...
43
41
 
44
- def send(self, value: Any) -> None:
45
- ...
42
+ def send(self, value: Any) -> None: ...
46
43
 
47
- def close(self) -> None:
48
- ...
44
+ def close(self) -> None: ...
49
45
 
50
46
  else:
51
47
  from multiprocessing.connection import ConnectionWrapper
@@ -1,16 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- import shutil
4
3
  import tempfile
5
- from contextlib import contextmanager
6
- from dataclasses import dataclass, field, replace
4
+ from dataclasses import dataclass, field
7
5
  from datetime import datetime, timezone
8
6
  from enum import Enum
9
7
  from functools import total_ordering
10
8
  from pathlib import Path
11
- from typing import TYPE_CHECKING, Callable, Dict, Iterator, NewType, Optional
9
+ from typing import TYPE_CHECKING
12
10
 
13
- from platformdirs import user_cache_dir
14
11
 
15
12
  if TYPE_CHECKING:
16
13
  from isolate.backends import BaseEnvironment
@@ -65,7 +62,7 @@ class Log:
65
62
  message: str
66
63
  source: LogSource
67
64
  level: LogLevel = LogLevel.INFO
68
- bound_env: Optional[BaseEnvironment] = field(default=None, repr=False)
65
+ bound_env: BaseEnvironment | None = field(default=None, repr=False)
69
66
  timestamp: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
70
67
 
71
68
  def __str__(self) -> str:
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import sys
4
- from typing import TYPE_CHECKING, Any, Dict, Type, Union
4
+ from typing import TYPE_CHECKING, Any
5
5
 
6
6
  if sys.version_info >= (3, 10):
7
7
  import importlib.metadata as importlib_metadata
@@ -15,8 +15,8 @@ if TYPE_CHECKING:
15
15
  # time by simply adding an entry point to the `isolate.environment` group.
16
16
  _ENTRY_POINT = "isolate.backends"
17
17
 
18
- _ENTRY_POINTS: Dict[str, importlib_metadata.EntryPoint] = {}
19
- _ENVIRONMENTS: Dict[str, Type["BaseEnvironment"]] = {}
18
+ _ENTRY_POINTS: dict[str, importlib_metadata.EntryPoint] = {}
19
+ _ENVIRONMENTS: dict[str, type[BaseEnvironment]] = {}
20
20
 
21
21
 
22
22
  def _reload_registry() -> None:
@@ -1 +1 @@
1
- from isolate.server.server import BridgeManager, IsolateServicer
1
+ from isolate.server.server import BridgeManager, IsolateServicer # noqa: F401
@@ -0,0 +1,13 @@
1
+ from google.protobuf.json_format import MessageToDict as struct_to_dict # noqa: F401
2
+ from google.protobuf.struct_pb2 import Struct # noqa: F401
3
+
4
+ # Inherit everything from the gRPC connection handler.
5
+ from isolate.connections.grpc.definitions import * # noqa: F403
6
+ from isolate.server.definitions.server_pb2 import * # noqa: F403
7
+ from isolate.server.definitions.server_pb2_grpc import ( # noqa: F401
8
+ IsolateServicer,
9
+ IsolateStub,
10
+ )
11
+ from isolate.server.definitions.server_pb2_grpc import ( # noqa: F401
12
+ add_IsolateServicer_to_server as register_isolate,
13
+ )
@@ -1,8 +1,8 @@
1
- from isolate.server.health.health_pb2 import (
1
+ from isolate.server.health.health_pb2 import ( # noqa: F401
2
2
  HealthCheckRequest,
3
3
  HealthCheckResponse,
4
4
  )
5
- from isolate.server.health.health_pb2_grpc import HealthServicer, HealthStub
6
- from isolate.server.health.health_pb2_grpc import (
5
+ from isolate.server.health.health_pb2_grpc import HealthServicer, HealthStub # noqa: F401
6
+ from isolate.server.health.health_pb2_grpc import ( # noqa: F401
7
7
  add_HealthServicer_to_server as register_health,
8
8
  )
@@ -10,16 +10,14 @@ from concurrent.futures import ThreadPoolExecutor
10
10
  from contextlib import ExitStack, contextmanager
11
11
  from dataclasses import dataclass, field, replace
12
12
  from functools import partial
13
- from pathlib import Path
14
13
  from queue import Empty as QueueEmpty
15
14
  from queue import Queue
16
- from typing import Any, Callable, Dict, Iterator, List, Tuple, cast
15
+ from typing import Any, Callable, Iterator, cast
17
16
 
18
17
  import grpc
19
18
  from grpc import ServicerContext, StatusCode
20
19
 
21
20
  from isolate.backends import (
22
- BaseEnvironment,
23
21
  EnvironmentCreationError,
24
22
  IsolateSettings,
25
23
  )
@@ -95,7 +93,7 @@ class RunnerAgent:
95
93
  @dataclass
96
94
  class BridgeManager:
97
95
  _agent_access_lock: threading.Lock = field(default_factory=threading.Lock)
98
- _agents: Dict[Tuple[Any, ...], List[RunnerAgent]] = field(
96
+ _agents: dict[tuple[Any, ...], list[RunnerAgent]] = field(
99
97
  default_factory=lambda: defaultdict(list)
100
98
  )
101
99
  _stack: ExitStack = field(default_factory=ExitStack)
@@ -105,7 +103,7 @@ class BridgeManager:
105
103
  self,
106
104
  connection: LocalPythonGRPC,
107
105
  queue: Queue,
108
- ) -> Iterator[Tuple[definitions.AgentStub, Queue]]:
106
+ ) -> Iterator[tuple[definitions.AgentStub, Queue]]:
109
107
  agent = self._allocate_new_agent(connection, queue)
110
108
 
111
109
  try:
@@ -141,7 +139,7 @@ class BridgeManager:
141
139
  )
142
140
  return RunnerAgent(stub, queue, bound_context)
143
141
 
144
- def _identify(self, connection: LocalPythonGRPC) -> Tuple[Any, ...]:
142
+ def _identify(self, connection: LocalPythonGRPC) -> tuple[Any, ...]:
145
143
  return (
146
144
  connection.environment_path,
147
145
  *connection.extra_inheritance_paths,
@@ -184,7 +182,7 @@ class IsolateServicer(definitions.IsolateServicer):
184
182
 
185
183
  if not environments:
186
184
  return self.abort_with_msg(
187
- f"At least one environment must be specified for a run!",
185
+ "At least one environment must be specified for a run!",
188
186
  context,
189
187
  )
190
188
 
@@ -374,7 +372,7 @@ def main() -> None:
374
372
  definitions.register_isolate(IsolateServicer(bridge_manager), server)
375
373
  health.register_health(HealthServicer(), server)
376
374
 
377
- server.add_insecure_port(f"[::]:50001")
375
+ server.add_insecure_port("[::]:50001")
378
376
  print("Started listening at localhost:50001")
379
377
 
380
378
  server.start()
@@ -1 +0,0 @@
1
- from isolate.registry import prepare_environment
@@ -1,2 +0,0 @@
1
- from isolate.backends._base import *
2
- from isolate.backends.settings import IsolateSettings
@@ -1,2 +0,0 @@
1
- from isolate.connections._local import agent_startup
2
- from isolate.connections._local._base import PythonExecutionBase
@@ -1,11 +0,0 @@
1
- from google.protobuf.message import Message
2
-
3
- from isolate.connections.grpc.definitions.agent_pb2 import *
4
- from isolate.connections.grpc.definitions.agent_pb2_grpc import (
5
- AgentServicer,
6
- AgentStub,
7
- )
8
- from isolate.connections.grpc.definitions.agent_pb2_grpc import (
9
- add_AgentServicer_to_server as register_agent,
10
- )
11
- from isolate.connections.grpc.definitions.common_pb2 import *
@@ -1,13 +0,0 @@
1
- from google.protobuf.json_format import MessageToDict as struct_to_dict
2
- from google.protobuf.struct_pb2 import Struct
3
-
4
- # Inherit everything from the gRPC connection handler.
5
- from isolate.connections.grpc.definitions import *
6
- from isolate.server.definitions.server_pb2 import *
7
- from isolate.server.definitions.server_pb2_grpc import (
8
- IsolateServicer,
9
- IsolateStub,
10
- )
11
- from isolate.server.definitions.server_pb2_grpc import (
12
- add_IsolateServicer_to_server as register_isolate,
13
- )
File without changes
File without changes
File without changes