8000 Completely disable stashing/unstashing logic if BinaryFormatter is no… · pythonnet/pythonnet@4ccde5b · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 4ccde5b

Browse files
committed
Completely disable stashing/unstashing logic if BinaryFormatter is not available
1 parent 907011e commit 4ccde5b

File tree

3 files changed

+59
-61
lines changed

3 files changed

+59
-61
lines changed

src/embed_tests/StateSerialization/MethodSerialization.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ static T SerializationRoundtrip<T>(T item)
3333
{
3434
using var buf = new MemoryStream();
3535
var formatter = RuntimeData.CreateFormatter();
36+
37+
if (formatter == null)
38+
Assert.Inconclusive("Failed to create formatter for state serialization");
39+
3640
formatter.Serialize(buf, item);
3741
buf.Position = 0;
3842
return (T)formatter.Deserialize(buf);

src/runtime/StateSerialization/NoopFormatter.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/runtime/StateSerialization/RuntimeData.cs

Lines changed: 55 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Python.Runtime
1616
public static class RuntimeData
1717
{
1818

19-
public readonly static Func<IFormatter> DefaultFormatterFactory = () =>
19+
public readonly static Func<IFormatter?> DefaultFormatterFactory = () =>
2020
{
2121
try
2222
{
@@ -27,12 +27,12 @@ public static class RuntimeData
2727
}
2828
}
2929
catch {}
30-
return new NoopFormatter();
30+
return null;
3131
};
3232

33-
private static Func<IFormatter> _formatterFactory { get; set; } = DefaultFormatterFactory;
33+
private static Func<IFormatter?> _formatterFactory { get; set; } = DefaultFormatterFactory;
3434

35-
public static Func<IFormatter> FormatterFactory
35+
public static Func<IFormatter?> FormatterFactory
3636
{
3737
get => _formatterFactory;
3838
set
@@ -84,32 +84,37 @@ static void ClearCLRData ()
8484

8585
internal static void Stash()
8686
{
87-
var runtimeStorage = new PythonNetState
88-
{
89-
Metatype = MetaType.SaveRuntimeData(),
90-
ImportHookState = ImportHook.SaveRuntimeData(),
91-
Types = TypeManager.SaveRuntimeData(),
92-
Classes = ClassManager.SaveRuntimeData(),
93-
SharedObjects = SaveRuntimeDataObjects(),
94-
};
95-
96-
IFormatter formatter = CreateFormatter();
97-
var ms = new MemoryStream();
98-
formatter.Serialize(ms, runtimeStorage);
99-
100-
Debug.Assert(ms.Length <= int.MaxValue);
101-
byte[] data = ms.GetBuffer();
102-
// TODO: use buffer api instead
103-
IntPtr mem = PyMem_Malloc(ms.Length + IntPtr.Size);
104-
Marshal.WriteIntPtr(mem, (IntPtr)ms.Length);
105-
Marshal.Copy(data, 0, mem + IntPtr.Size, (int)ms.Length);
106-
10787
ClearCLRData();
10888

109-
using NewReference capsule = PyCapsule_New(mem, IntPtr.Zero, IntPtr.Zero);
110-
int res = PySys_SetObject("clr_data", capsule.BorrowOrThrow());
111-
PythonException.ThrowIfIsNotZero(res);
112-
PostStashHook?.Invoke();
89+
IFormatter? formatter = CreateFormatter();
90+
91+
if (formatter != null)
92+
{
93+
var runtimeStorage = new PythonNetState
94+
{
95+
Metatype = MetaType.SaveRuntimeData(),
96+
ImportHookState = ImportHook.SaveRuntimeData(),
97+
Types = TypeManager.SaveRuntimeData(),
98+
Classes = ClassManager.SaveRuntimeData(),
99+
SharedObjects = SaveRuntimeDataObjects(),
100+
};
101+
102+
var ms = new MemoryStream();
103+
formatter.Serialize(ms, runtimeStorage);
104+
105+
Debug.Assert(ms.Length <= int.MaxValue);
106+
byte[] data = ms.GetBuffer();
107+
// TODO: use buffer api instead
108+
IntPtr mem = PyMem_Malloc(ms.Length + IntPtr.Size);
109+
Marshal.WriteIntPtr(mem, (IntPtr)ms.Length);
110+
Marshal.Copy(data, 0, mem + IntPtr.Size, (int)ms.Length);
111+
112+
using NewReference capsule = PyCapsule_New(mem, IntPtr.Zero, IntPtr.Zero);
113+
int res = PySys_SetObject("clr_data", capsule.BorrowOrThrow());
114+
PythonException.ThrowIfIsNotZero(res);
115+
116+
PostStashHook?.Invoke();
117+
}
113118
}
114119

115120
internal static void RestoreRuntimeData()
@@ -126,28 +131,32 @@ internal static void RestoreRuntimeData()
126131

127132
private static void RestoreRuntimeDataImpl()
128133
{
129-
PreRestoreHook?.Invoke();
130-
BorrowedReference capsule = PySys_GetObject("clr_data");
131-
if (capsule.IsNull)
134+
IFormatter? formatter = CreateFormatter();
135+
136+
if (formatter != null)
132137
{
133-
return;
134-
}
135-
IntPtr mem = PyCapsule_GetPointer(capsule, IntPtr.Zero);
136-
int length = (int)Marshal.ReadIntPtr(mem);
137-
byte[] data = new byte[length];
138-
Marshal.Copy(mem + IntPtr.Size, data, 0, length);
139-
var ms = new MemoryStream(data);
140-
var formatter = CreateFormatter();
141-
var storage = (PythonNetState)formatter.Deserialize(ms);
138+
PreRestoreHook?.Invoke();
139+
BorrowedReference capsule = PySys_GetObject("clr_data");
140+
if (capsule.IsNull)
141+
{
142+
return;
143+
}
144+
IntPtr mem = PyCapsule_GetPointer(capsule, IntPtr.Zero);
145+
int length = (int)Marshal.ReadIntPtr(mem);
146+
byte[] data = new byte[length];
147+
Marshal.Copy(mem + IntPtr.Size, data, 0, length);
148+
var ms = new MemoryStream(data);
149+
var storage = (PythonNetState)formatter.Deserialize(ms);
142150

143-
PyCLRMetaType = MetaType.RestoreRuntimeData(storage.Metatype);
151+
PyCLRMetaType = MetaType.RestoreRuntimeData(storage.Metatype);
144152

145-
TypeManager.RestoreRuntimeData(storage.Types);
146-
ClassManager.RestoreRuntimeData(storage.Classes);
153+
TypeManager.RestoreRuntimeData(storage.Types);
154+
ClassManager.RestoreRuntimeData(storage.Classes);
147155

148-
RestoreRuntimeDataObjects(storage.SharedObjects);
156+
RestoreRuntimeDataObjects(storage.SharedObjects);
149157

150-
ImportHook.RestoreRuntimeData(storage.ImportHookState);
158+
ImportHook.RestoreRuntimeData(storage.ImportHookState);
159+
}
151160
}
152161

153162
public static bool HasStashData()
@@ -375,9 +384,8 @@ public static MemoryStream GetSerializationData(string key)
375384
return new MemoryStream(buffer, writable:false);
376385
}
377386

378-
internal static IFormatter CreateFormatter()
387+
internal static IFormatter? CreateFormatter()
379388
{
380-
381389
if (FormatterType != null)
382390
{
383391
return (IFormatter)Activator.CreateInstance(FormatterType);

0 commit comments

Comments
 (0)
0