Skip to content

Commit 0101b6c

Browse files
committed
Add back Serialization
1 parent 914b9bb commit 0101b6c

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

Src/IronPython/Runtime/CommonDictionaryStorage.cs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.Generic;
88
using System.Diagnostics;
99
using System.Runtime.CompilerServices;
10+
using System.Runtime.Serialization;
1011
using System.Threading;
1112

1213
using IronPython.Runtime.Operations;
@@ -33,7 +34,8 @@ namespace IronPython.Runtime {
3334
/// the buckets and then calls a static helper function to do the read from the bucket
3435
/// array to ensure that readers are not seeing multiple bucket arrays.
3536
/// </summary>
36-
internal sealed class CommonDictionaryStorage : DictionaryStorage {
37+
[Serializable]
38+
internal sealed class CommonDictionaryStorage : DictionaryStorage, ISerializable, IDeserializationCallback {
3739
private int[] _indices;
3840
private List<Bucket> _buckets;
3941
private int _count;
@@ -117,6 +119,16 @@ private CommonDictionaryStorage(int[] indices, List<Bucket> buckets, int count,
117119
_eqFunc = eqFunc;
118120
}
119121

122+
#if FEATURE_SERIALIZATION
123+
private CommonDictionaryStorage(SerializationInfo info, StreamingContext context) {
124+
// Remember the serialization info, we'll deserialize when we get the callback. This
125+
// enables special types like DBNull.Value to successfully be deserialized inside of us. We
126+
// store the serialization info in a special bucket so we don't have an extra field just for
127+
// serialization.
128+
_buckets = new List<Bucket> { new Bucket(null, info, 0) };
129+
}
130+
#endif
131+
120132
public override void Add(ref DictionaryStorage storage, object key, object value)
121133
=> Add(key, value);
122134

@@ -651,5 +663,31 @@ private static bool TupleEquals(object o1, object o2)
651663
private static bool GenericEquals(object o1, object o2) => PythonOps.EqualRetBool(o1, o2);
652664

653665
#endregion
666+
667+
#if FEATURE_SERIALIZATION
668+
#region ISerializable Members
669+
670+
public void GetObjectData(SerializationInfo info, StreamingContext context) {
671+
info.AddValue("buckets", GetItems());
672+
}
673+
674+
void IDeserializationCallback.OnDeserialization(object sender) {
675+
if (_indices is not null) {
676+
// we've received multiple OnDeserialization callbacks, only
677+
// deserialize after the 1st one
678+
return;
679+
}
680+
681+
var info = (SerializationInfo)_buckets[0].Value;
682+
_buckets.Clear();
683+
684+
var buckets = (List<KeyValuePair<object, object>>)info.GetValue("buckets", typeof(List<KeyValuePair<object, object>>));
685+
foreach (KeyValuePair<object, object> kvp in buckets) {
686+
AddNoLock(kvp.Key, kvp.Value);
687+
}
688+
}
689+
690+
#endregion
691+
#endif
654692
}
655693
}

Tests/test_ordered_dict_stdlib.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def load_tests(loader, standard_tests, pattern):
3030
]
3131

3232
skip_tests = [
33+
test.test_ordered_dict.CPythonBuiltinDictTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?
3334
test.test_ordered_dict.CPythonOrderedDictSubclassTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?
3435
test.test_ordered_dict.CPythonOrderedDictTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?
3536
test.test_ordered_dict.PurePythonOrderedDictSubclassTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?

0 commit comments

Comments
 (0)