isolate 0.26.7__tar.gz → 0.26.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.
Files changed (96) hide show
  1. {isolate-0.26.7/src/isolate.egg-info → isolate-0.26.9}/PKG-INFO +1 -1
  2. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/_isolate_version.py +3 -3
  3. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/common.py +13 -0
  4. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/agent.py +7 -0
  5. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/common.proto +4 -0
  6. isolate-0.26.9/src/isolate/connections/grpc/definitions/common_pb2.py +35 -0
  7. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/common_pb2.pyi +15 -2
  8. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/interface.py +34 -1
  9. {isolate-0.26.7 → isolate-0.26.9/src/isolate.egg-info}/PKG-INFO +1 -1
  10. {isolate-0.26.7 → isolate-0.26.9}/tests/test_serialization.py +45 -0
  11. isolate-0.26.7/src/isolate/connections/grpc/definitions/common_pb2.py +0 -35
  12. {isolate-0.26.7 → isolate-0.26.9}/.github/workflows/claude-code-review.yml +0 -0
  13. {isolate-0.26.7 → isolate-0.26.9}/.github/workflows/claude.yml +0 -0
  14. {isolate-0.26.7 → isolate-0.26.9}/.github/workflows/lint.yml +0 -0
  15. {isolate-0.26.7 → isolate-0.26.9}/.github/workflows/release.yml +0 -0
  16. {isolate-0.26.7 → isolate-0.26.9}/.github/workflows/test.yml +0 -0
  17. {isolate-0.26.7 → isolate-0.26.9}/.gitignore +0 -0
  18. {isolate-0.26.7 → isolate-0.26.9}/.pre-commit-config.yaml +0 -0
  19. {isolate-0.26.7 → isolate-0.26.9}/LICENSE +0 -0
  20. {isolate-0.26.7 → isolate-0.26.9}/README.md +0 -0
  21. {isolate-0.26.7 → isolate-0.26.9}/pyproject.toml +0 -0
  22. {isolate-0.26.7 → isolate-0.26.9}/setup.cfg +0 -0
  23. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/__init__.py +0 -0
  24. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/_version.py +0 -0
  25. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/__init__.py +0 -0
  26. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/_base.py +0 -0
  27. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/common.py +0 -0
  28. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/conda.py +0 -0
  29. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/container.py +0 -0
  30. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/local.py +0 -0
  31. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/pyenv.py +0 -0
  32. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/remote.py +0 -0
  33. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/settings.py +0 -0
  34. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/backends/virtualenv.py +0 -0
  35. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/common/__init__.py +0 -0
  36. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/common/timestamp.py +0 -0
  37. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/__init__.py +0 -0
  38. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/_local/__init__.py +0 -0
  39. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/_local/_base.py +0 -0
  40. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/_local/agent_startup.py +0 -0
  41. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/__init__.py +0 -0
  42. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/_base.py +0 -0
  43. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/configuration.py +0 -0
  44. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/__init__.py +0 -0
  45. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/agent.proto +0 -0
  46. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/agent_pb2.py +0 -0
  47. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/agent_pb2.pyi +0 -0
  48. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/agent_pb2_grpc.py +0 -0
  49. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/grpc/definitions/common_pb2_grpc.py +0 -0
  50. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/ipc/__init__.py +0 -0
  51. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/ipc/_base.py +0 -0
  52. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/connections/ipc/agent.py +0 -0
  53. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/logger.py +0 -0
  54. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/logs.py +0 -0
  55. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/py.typed +0 -0
  56. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/registry.py +0 -0
  57. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/__init__.py +0 -0
  58. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/definitions/__init__.py +0 -0
  59. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/definitions/server.proto +0 -0
  60. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/definitions/server_pb2.py +0 -0
  61. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/definitions/server_pb2.pyi +0 -0
  62. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/definitions/server_pb2_grpc.py +0 -0
  63. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/health/__init__.py +0 -0
  64. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/health/health.proto +0 -0
  65. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/health/health_pb2.py +0 -0
  66. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/health/health_pb2.pyi +0 -0
  67. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/health/health_pb2_grpc.py +0 -0
  68. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/health_server.py +0 -0
  69. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/interface.py +0 -0
  70. {isolate-0.26.7 → isolate-0.26.9}/src/isolate/server/server.py +0 -0
  71. {isolate-0.26.7 → isolate-0.26.9}/src/isolate.egg-info/SOURCES.txt +0 -0
  72. {isolate-0.26.7 → isolate-0.26.9}/src/isolate.egg-info/dependency_links.txt +0 -0
  73. {isolate-0.26.7 → isolate-0.26.9}/src/isolate.egg-info/entry_points.txt +0 -0
  74. {isolate-0.26.7 → isolate-0.26.9}/src/isolate.egg-info/requires.txt +0 -0
  75. {isolate-0.26.7 → isolate-0.26.9}/src/isolate.egg-info/top_level.txt +0 -0
  76. {isolate-0.26.7 → isolate-0.26.9}/tests/__init__.py +0 -0
  77. {isolate-0.26.7 → isolate-0.26.9}/tests/conftest.py +0 -0
  78. {isolate-0.26.7 → isolate-0.26.9}/tests/test_agent_backward_compatibility.py +0 -0
  79. {isolate-0.26.7 → isolate-0.26.9}/tests/test_backends.py +0 -0
  80. {isolate-0.26.7 → isolate-0.26.9}/tests/test_concurrency.py +0 -0
  81. {isolate-0.26.7 → isolate-0.26.9}/tests/test_connections.py +0 -0
  82. {isolate-0.26.7 → isolate-0.26.9}/tests/test_connections_grpc_base.py +0 -0
  83. {isolate-0.26.7 → isolate-0.26.9}/tests/test_isolate.py +0 -0
  84. {isolate-0.26.7 → isolate-0.26.9}/tests/test_log.py +0 -0
  85. {isolate-0.26.7 → isolate-0.26.9}/tests/test_log_masking.py +0 -0
  86. {isolate-0.26.7 → isolate-0.26.9}/tests/test_logged_io_pipe.py +0 -0
  87. {isolate-0.26.7 → isolate-0.26.9}/tests/test_logger.py +0 -0
  88. {isolate-0.26.7 → isolate-0.26.9}/tests/test_server.py +0 -0
  89. {isolate-0.26.7 → isolate-0.26.9}/tests/test_shutdown.py +0 -0
  90. {isolate-0.26.7 → isolate-0.26.9}/tools/Dockerfile +0 -0
  91. {isolate-0.26.7 → isolate-0.26.9}/tools/agent_requirements.txt +0 -0
  92. {isolate-0.26.7 → isolate-0.26.9}/tools/isolate_client.py +0 -0
  93. {isolate-0.26.7 → isolate-0.26.9}/tools/protobuf-requirements.txt +0 -0
  94. {isolate-0.26.7 → isolate-0.26.9}/tools/regen_grpc.py +0 -0
  95. {isolate-0.26.7 → isolate-0.26.9}/tools/requirements.txt +0 -0
  96. {isolate-0.26.7 → isolate-0.26.9}/tools/test_agent_requirements.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isolate
3
- Version: 0.26.7
3
+ Version: 0.26.9
4
4
  Summary: Managed isolated environments for Python
5
5
  Author-email: Features & Labels <hello@fal.ai>
6
6
  Project-URL: Issues, https://github.com/fal-ai/isolate/issues
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.26.7'
32
- __version_tuple__ = version_tuple = (0, 26, 7)
31
+ __version__ = version = '0.26.9'
32
+ __version_tuple__ = version_tuple = (0, 26, 9)
33
33
 
34
- __commit_id__ = commit_id = 'g9b3604b86'
34
+ __commit_id__ = commit_id = 'g803409edf'
@@ -35,6 +35,12 @@ class ExceptionDeserializationError(SerializationError):
35
35
  module that defines its type isn't importable here)."""
36
36
 
37
37
  original_traceback: TracebackType | None
38
+ original_stringized_traceback: str | None
39
+ # Display-only simple type name, matching traceback text (for example,
40
+ # "RemoteOnlyError").
41
+ original_exception_type_name: str | None = None
42
+ # Display-only str() of the remote exception.
43
+ original_exception_message: str | None = None
38
44
 
39
45
 
40
46
  # NOTE: tblib's install() will search for BaseException subclasses,
@@ -75,6 +81,8 @@ def load_serialized_object(
75
81
  *,
76
82
  was_it_raised: bool = False,
77
83
  stringized_traceback: str | None = None,
84
+ exception_type_name: str | None = None,
85
+ exception_message: str | None = None,
78
86
  ) -> Any:
79
87
  """Load the given serialized object using the given serialization method. If
80
88
  anything fails, then a SerializationError will be raised. If the was_it_raised
@@ -94,9 +102,14 @@ def load_serialized_object(
94
102
  # We were trying to reconstruct a remote exception but its type
95
103
  # isn't importable here, so loads() failed. Surface the genuine
96
104
  # local cause along with the remote traceback.
105
+ # Keep both traceback forms: Traceback.from_string() preserves
106
+ # frames, while the string also includes the exception type/message.
97
107
  raise ExceptionDeserializationError(
98
108
  exc.message,
99
109
  original_traceback=_prepare_traceback(stringized_traceback),
110
+ original_stringized_traceback=stringized_traceback,
111
+ original_exception_type_name=exception_type_name,
112
+ original_exception_message=exception_message,
100
113
  ) from exc.__cause__
101
114
  raise
102
115
 
@@ -542,6 +542,13 @@ class AgentServicer(definitions.AgentServicer):
542
542
  was_it_raised=was_it_raised,
543
543
  stringized_traceback=stringized_tb,
544
544
  )
545
+ if was_it_raised:
546
+ # Current agent scripts can run against older installed isolate packages
547
+ # whose generated protobuf classes do not know about newly added fields.
548
+ if "exception_type_name" in serialized_obj.DESCRIPTOR.fields_by_name:
549
+ serialized_obj.exception_type_name = type(result).__name__
550
+ if "exception_message" in serialized_obj.DESCRIPTOR.fields_by_name:
551
+ serialized_obj.exception_message = str(result)
545
552
  return definitions.PartialRunResult(
546
553
  result=serialized_obj,
547
554
  is_complete=True,
@@ -13,6 +13,10 @@ message SerializedObject {
13
13
  bool was_it_raised = 3;
14
14
  // The stringized version of the traceback, if it was raised.
15
15
  optional string stringized_traceback = 4;
16
+ // The remote exception type name, if it was raised.
17
+ optional string exception_type_name = 5;
18
+ // The remote exception message, if it was raised.
19
+ optional string exception_message = 6;
16
20
  }
17
21
 
18
22
  message PartialRunResult {
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: common.proto
4
+ # Protobuf Python Version: 4.25.1
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
16
+
17
+
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0c\x63ommon.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf9\x01\n\x10SerializedObject\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\x12\n\ndefinition\x18\x02 \x01(\x0c\x12\x15\n\rwas_it_raised\x18\x03 \x01(\x08\x12!\n\x14stringized_traceback\x18\x04 \x01(\tH\x00\x88\x01\x01\x12 \n\x13\x65xception_type_name\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x1e\n\x11\x65xception_message\x18\x06 \x01(\tH\x02\x88\x01\x01\x42\x17\n\x15_stringized_tracebackB\x16\n\x14_exception_type_nameB\x14\n\x12_exception_message\"n\n\x10PartialRunResult\x12\x13\n\x0bis_complete\x18\x01 \x01(\x08\x12\x12\n\x04logs\x18\x02 \x03(\x0b\x32\x04.Log\x12&\n\x06result\x18\x03 \x01(\x0b\x32\x11.SerializedObjectH\x00\x88\x01\x01\x42\t\n\x07_result\"{\n\x03Log\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x1a\n\x06source\x18\x02 \x01(\x0e\x32\n.LogSource\x12\x18\n\x05level\x18\x03 \x01(\x0e\x32\t.LogLevel\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp*.\n\tLogSource\x12\x0b\n\x07\x42UILDER\x10\x00\x12\n\n\x06\x42RIDGE\x10\x01\x12\x08\n\x04USER\x10\x02*Z\n\x08LogLevel\x12\t\n\x05TRACE\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x0b\n\x07WARNING\x10\x03\x12\t\n\x05\x45RROR\x10\x04\x12\n\n\x06STDOUT\x10\x05\x12\n\n\x06STDERR\x10\x06\x62\x06proto3')
19
+
20
+ _globals = globals()
21
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
22
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'common_pb2', _globals)
23
+ if _descriptor._USE_C_DESCRIPTORS == False:
24
+ DESCRIPTOR._options = None
25
+ _globals['_LOGSOURCE']._serialized_start=538
26
+ _globals['_LOGSOURCE']._serialized_end=584
27
+ _globals['_LOGLEVEL']._serialized_start=586
28
+ _globals['_LOGLEVEL']._serialized_end=676
29
+ _globals['_SERIALIZEDOBJECT']._serialized_start=50
30
+ _globals['_SERIALIZEDOBJECT']._serialized_end=299
31
+ _globals['_PARTIALRUNRESULT']._serialized_start=301
32
+ _globals['_PARTIALRUNRESULT']._serialized_end=411
33
+ _globals['_LOG']._serialized_start=413
34
+ _globals['_LOG']._serialized_end=536
35
+ # @@protoc_insertion_point(module_scope)
@@ -69,6 +69,8 @@ class SerializedObject(google.protobuf.message.Message):
69
69
  DEFINITION_FIELD_NUMBER: builtins.int
70
70
  WAS_IT_RAISED_FIELD_NUMBER: builtins.int
71
71
  STRINGIZED_TRACEBACK_FIELD_NUMBER: builtins.int
72
+ EXCEPTION_TYPE_NAME_FIELD_NUMBER: builtins.int
73
+ EXCEPTION_MESSAGE_FIELD_NUMBER: builtins.int
72
74
  method: builtins.str
73
75
  """The serialization method used to serialize the the raw_object. Must be
74
76
  present in the environment that is running the agent itself.
@@ -81,6 +83,10 @@ class SerializedObject(google.protobuf.message.Message):
81
83
  """
82
84
  stringized_traceback: builtins.str
83
85
  """The stringized version of the traceback, if it was raised."""
86
+ exception_type_name: builtins.str
87
+ """The remote exception type name, if it was raised."""
88
+ exception_message: builtins.str
89
+ """The remote exception message, if it was raised."""
84
90
  def __init__(
85
91
  self,
86
92
  *,
@@ -88,9 +94,16 @@ class SerializedObject(google.protobuf.message.Message):
88
94
  definition: builtins.bytes = ...,
89
95
  was_it_raised: builtins.bool = ...,
90
96
  stringized_traceback: builtins.str | None = ...,
97
+ exception_type_name: builtins.str | None = ...,
98
+ exception_message: builtins.str | None = ...,
91
99
  ) -> None: ...
92
- def HasField(self, field_name: typing_extensions.Literal["_stringized_traceback", b"_stringized_traceback", "stringized_traceback", b"stringized_traceback"]) -> builtins.bool: ...
93
- def ClearField(self, field_name: typing_extensions.Literal["_stringized_traceback", b"_stringized_traceback", "definition", b"definition", "method", b"method", "stringized_traceback", b"stringized_traceback", "was_it_raised", b"was_it_raised"]) -> None: ...
100
+ def HasField(self, field_name: typing_extensions.Literal["_exception_message", b"_exception_message", "_exception_type_name", b"_exception_type_name", "_stringized_traceback", b"_stringized_traceback", "exception_message", b"exception_message", "exception_type_name", b"exception_type_name", "stringized_traceback", b"stringized_traceback"]) -> builtins.bool: ...
101
+ def ClearField(self, field_name: typing_extensions.Literal["_exception_message", b"_exception_message", "_exception_type_name", b"_exception_type_name", "_stringized_traceback", b"_stringized_traceback", "definition", b"definition", "exception_message", b"exception_message", "exception_type_name", b"exception_type_name", "method", b"method", "stringized_traceback", b"stringized_traceback", "was_it_raised", b"was_it_raised"]) -> None: ...
102
+ @typing.overload
103
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_exception_message", b"_exception_message"]) -> typing_extensions.Literal["exception_message"] | None: ...
104
+ @typing.overload
105
+ def WhichOneof(self, oneof_group: typing_extensions.Literal["_exception_type_name", b"_exception_type_name"]) -> typing_extensions.Literal["exception_type_name"] | None: ...
106
+ @typing.overload
94
107
  def WhichOneof(self, oneof_group: typing_extensions.Literal["_stringized_traceback", b"_stringized_traceback"]) -> typing_extensions.Literal["stringized_traceback"] | None: ...
95
108
 
96
109
  global___SerializedObject = SerializedObject
@@ -26,11 +26,23 @@ def to_grpc(obj: Any) -> definitions.Message:
26
26
 
27
27
  @from_grpc.register
28
28
  def _(message: definitions.SerializedObject) -> Any:
29
+ exception_type_name = None
30
+ if message.HasField("exception_type_name"):
31
+ exception_type_name = message.exception_type_name
32
+
33
+ exception_message = None
34
+ if message.HasField("exception_message"):
35
+ exception_message = message.exception_message
36
+
29
37
  return load_serialized_object(
30
38
  message.method,
31
39
  message.definition,
32
40
  was_it_raised=message.was_it_raised,
41
+ # This field predates optional exception metadata; absent values arrive
42
+ # as "", and _prepare_traceback treats that the same as None.
33
43
  stringized_traceback=message.stringized_traceback,
44
+ exception_type_name=exception_type_name,
45
+ exception_message=exception_message,
34
46
  )
35
47
 
36
48
 
@@ -61,11 +73,32 @@ def to_serialized_object(
61
73
  method: str,
62
74
  was_it_raised: bool = False,
63
75
  stringized_traceback: Optional[str] = None,
76
+ exception_type_name: Optional[str] = None,
77
+ exception_message: Optional[str] = None,
64
78
  ) -> definitions.SerializedObject:
65
79
  """Convert a Python object into a gRPC message."""
66
- return definitions.SerializedObject(
80
+ if was_it_raised:
81
+ if exception_type_name is None:
82
+ exception_type_name = type(obj).__name__
83
+ if exception_message is None:
84
+ exception_message = str(obj)
85
+
86
+ serialized_obj = definitions.SerializedObject(
67
87
  method=method,
68
88
  definition=serialize_object(method, obj),
69
89
  was_it_raised=was_it_raised,
70
90
  stringized_traceback=stringized_traceback,
71
91
  )
92
+ # Current code can run against older generated protobuf classes that do not
93
+ # know about newly added optional fields.
94
+ if (
95
+ exception_type_name is not None
96
+ and "exception_type_name" in serialized_obj.DESCRIPTOR.fields_by_name
97
+ ):
98
+ serialized_obj.exception_type_name = exception_type_name
99
+ if (
100
+ exception_message is not None
101
+ and "exception_message" in serialized_obj.DESCRIPTOR.fields_by_name
102
+ ):
103
+ serialized_obj.exception_message = exception_message
104
+ return serialized_obj
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isolate
3
- Version: 0.26.7
3
+ Version: 0.26.9
4
4
  Summary: Managed isolated environments for Python
5
5
  Author-email: Features & Labels <hello@fal.ai>
6
6
  Project-URL: Issues, https://github.com/fal-ai/isolate/issues
@@ -10,6 +10,7 @@ from isolate.connections.common import (
10
10
  load_serialized_object,
11
11
  serialize_object,
12
12
  )
13
+ from isolate.connections.grpc.interface import from_grpc, to_serialized_object
13
14
 
14
15
 
15
16
  @pytest.mark.parametrize(
@@ -66,13 +67,57 @@ def test_deserialize_raised_exception_with_unimportable_type_preserves_traceback
66
67
  serialized,
67
68
  was_it_raised=True,
68
69
  stringized_traceback=stringized_traceback,
70
+ exception_type_name="RemoteOnlyError",
71
+ exception_message="remote boom",
69
72
  )
70
73
 
71
74
  assert exc_info.value.message == "Error while deserializing the given object"
72
75
  assert exc_info.value.original_traceback is not None
76
+ assert exc_info.value.original_stringized_traceback == stringized_traceback
77
+ assert exc_info.value.original_exception_type_name == "RemoteOnlyError"
78
+ assert exc_info.value.original_exception_message == "remote boom"
73
79
  assert isinstance(exc_info.value.__cause__, ModuleNotFoundError)
74
80
 
75
81
 
82
+ def test_to_serialized_object_includes_raised_exception_metadata():
83
+ serialized = to_serialized_object(
84
+ ValueError("some error"),
85
+ method="pickle",
86
+ was_it_raised=True,
87
+ )
88
+
89
+ assert serialized.exception_type_name == "ValueError"
90
+ assert serialized.exception_message == "some error"
91
+
92
+
93
+ def test_from_grpc_preserves_empty_raised_exception_message_metadata(
94
+ tmp_path,
95
+ monkeypatch,
96
+ ):
97
+ module_name = "remote_only_empty_exc_for_isolate_test"
98
+ module_path = tmp_path / f"{module_name}.py"
99
+ module_path.write_text("class RemoteOnlyError(Exception):\n pass\n")
100
+ monkeypatch.syspath_prepend(str(tmp_path))
101
+ remote_module = importlib.import_module(module_name)
102
+
103
+ serialized = to_serialized_object(
104
+ remote_module.RemoteOnlyError(),
105
+ method="pickle",
106
+ was_it_raised=True,
107
+ )
108
+
109
+ sys.modules.pop(module_name, None)
110
+ # Keep the remote exception class unimportable while from_grpc reconstructs
111
+ # the result; monkeypatch teardown would happen too late for this assertion.
112
+ sys.path.remove(str(tmp_path))
113
+
114
+ with pytest.raises(ExceptionDeserializationError) as exc_info:
115
+ from_grpc(serialized)
116
+
117
+ assert exc_info.value.original_exception_type_name == "RemoteOnlyError"
118
+ assert exc_info.value.original_exception_message == ""
119
+
120
+
76
121
  def error_while_serializing():
77
122
  anon = lambda: 2 + 2 # anonymous functions are not # noqa: E731
78
123
  # serializable by pickle
@@ -1,35 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Generated by the protocol buffer compiler. DO NOT EDIT!
3
- # source: common.proto
4
- # Protobuf Python Version: 4.25.1
5
- """Generated protocol buffer code."""
6
- from google.protobuf import descriptor as _descriptor
7
- from google.protobuf import descriptor_pool as _descriptor_pool
8
- from google.protobuf import symbol_database as _symbol_database
9
- from google.protobuf.internal import builder as _builder
10
- # @@protoc_insertion_point(imports)
11
-
12
- _sym_db = _symbol_database.Default()
13
-
14
-
15
- from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
16
-
17
-
18
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0c\x63ommon.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x89\x01\n\x10SerializedObject\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\x12\n\ndefinition\x18\x02 \x01(\x0c\x12\x15\n\rwas_it_raised\x18\x03 \x01(\x08\x12!\n\x14stringized_traceback\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x17\n\x15_stringized_traceback\"n\n\x10PartialRunResult\x12\x13\n\x0bis_complete\x18\x01 \x01(\x08\x12\x12\n\x04logs\x18\x02 \x03(\x0b\x32\x04.Log\x12&\n\x06result\x18\x03 \x01(\x0b\x32\x11.SerializedObjectH\x00\x88\x01\x01\x42\t\n\x07_result\"{\n\x03Log\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x1a\n\x06source\x18\x02 \x01(\x0e\x32\n.LogSource\x12\x18\n\x05level\x18\x03 \x01(\x0e\x32\t.LogLevel\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp*.\n\tLogSource\x12\x0b\n\x07\x42UILDER\x10\x00\x12\n\n\x06\x42RIDGE\x10\x01\x12\x08\n\x04USER\x10\x02*Z\n\x08LogLevel\x12\t\n\x05TRACE\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x01\x12\x08\n\x04INFO\x10\x02\x12\x0b\n\x07WARNING\x10\x03\x12\t\n\x05\x45RROR\x10\x04\x12\n\n\x06STDOUT\x10\x05\x12\n\n\x06STDERR\x10\x06\x62\x06proto3')
19
-
20
- _globals = globals()
21
- _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
22
- _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'common_pb2', _globals)
23
- if _descriptor._USE_C_DESCRIPTORS == False:
24
- DESCRIPTOR._options = None
25
- _globals['_LOGSOURCE']._serialized_start=426
26
- _globals['_LOGSOURCE']._serialized_end=472
27
- _globals['_LOGLEVEL']._serialized_start=474
28
- _globals['_LOGLEVEL']._serialized_end=564
29
- _globals['_SERIALIZEDOBJECT']._serialized_start=50
30
- _globals['_SERIALIZEDOBJECT']._serialized_end=187
31
- _globals['_PARTIALRUNRESULT']._serialized_start=189
32
- _globals['_PARTIALRUNRESULT']._serialized_end=299
33
- _globals['_LOG']._serialized_start=301
34
- _globals['_LOG']._serialized_end=424
35
- # @@protoc_insertion_point(module_scope)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes