@@ -16,21 +16,23 @@ namespace Python.Runtime
1616public static class RuntimeData
1717{
1818
19- public readonly static Func < IFormatter > DefaultFormatterFactory = ( ) =>
19+ public readonly static Func < IFormatter ? > DefaultFormatterFactory = ( ) =>
2020{
2121try
2222{
23- return new BinaryFormatter ( ) ;
24- }
25- catch
26- {
27- return new NoopFormatter ( ) ;
23+ var fw = RuntimeInformation . FrameworkDescription ;
24+ if ( fw . StartsWith ( ".NET Framework" ) || fw . StartsWith ( "Mono" ) )
25+ {
26+ return new BinaryFormatter ( ) ;
27+ }
2828}
29+ catch { }
30+ return null ;
2931} ;
3032
31- private static Func < IFormatter > _formatterFactory { get ; set ; } = DefaultFormatterFactory ;
33+ private static Func < IFormatter ? > _formatterFactory { get ; set ; } = DefaultFormatterFactory ;
3234
33- public static Func < IFormatter > FormatterFactory
35+ public static Func < IFormatter ? > FormatterFactory
3436{
3537get => _formatterFactory ;
3638set
@@ -82,6 +84,14 @@ static void ClearCLRData ()
8284
8385internal static void Stash ( )
8486{
87+ ClearCLRData ( ) ;
88+
89+ IFormatter ? formatter = CreateFormatter ( ) ;
90+
91+ if ( formatter == null )
92+ // No formatter defined, exit early
93+ return ;
94+
8595var runtimeStorage = new PythonNetState
8696{
8797Metatype = MetaType . SaveRuntimeData ( ) ,
@@ -91,7 +101,6 @@ internal static void Stash()
91101SharedObjects = SaveRuntimeDataObjects ( ) ,
92102} ;
93103
94- IFormatter formatter = CreateFormatter ( ) ;
95104var ms = new MemoryStream ( ) ;
96105formatter . Serialize ( ms , runtimeStorage ) ;
97106
@@ -102,11 +111,10 @@ internal static void Stash()
102111Marshal . WriteIntPtr ( mem , ( IntPtr ) ms . Length ) ;
103112Marshal . Copy ( data , 0 , mem + IntPtr . Size , ( int ) ms . Length ) ;
104113
105- ClearCLRData ( ) ;
106-
107114using NewReference capsule = PyCapsule_New ( mem , IntPtr . Zero , IntPtr . Zero ) ;
108115int res = PySys_SetObject ( "clr_data" , capsule . BorrowOrThrow ( ) ) ;
109116PythonException . ThrowIfIsNotZero ( res ) ;
117+
110118PostStashHook ? . Invoke ( ) ;
111119}
112120
@@ -124,6 +132,12 @@ internal static void RestoreRuntimeData()
124132
125133private static void RestoreRuntimeDataImpl ( )
126134{
135+ IFormatter ? formatter = CreateFormatter ( ) ;
136+
137+ if ( formatter == null )
138+ // No formatter defined, exit early
139+ return ;
140+
127141PreRestoreHook ? . Invoke ( ) ;
128142BorrowedReference capsule = PySys_GetObject ( "clr_data" ) ;
129143if ( capsule . IsNull )
@@ -135,7 +149,6 @@ private static void RestoreRuntimeDataImpl()
135149byte [ ] data = new byte [ length ] ;
136150Marshal . Copy ( mem + IntPtr . Size , data , 0 , length ) ;
137151var ms = new MemoryStream ( data ) ;
138- var formatter = CreateFormatter ( ) ;
139152var storage = ( PythonNetState ) formatter . Deserialize ( ms ) ;
140153
141154PyCLRMetaType = MetaType . RestoreRuntimeData ( storage . Metatype ) ;
@@ -373,9 +386,8 @@ public static MemoryStream GetSerializationData(string key)
373386return new MemoryStream ( buffer , writable : false ) ;
374387}
375388
376- internal static IFormatter CreateFormatter ( )
389+ internal static IFormatter ? CreateFormatter ( )
377390{
378-
379391if ( FormatterType != null )
380392{
381393return ( IFormatter ) Activator . CreateInstance ( FormatterType ) ;