Skip to content

Commit

Permalink
Add back Serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
slozier committed Dec 27, 2024
1 parent cdd8997 commit 9b2e812
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
40 changes: 39 additions & 1 deletion Src/IronPython/Runtime/CommonDictionaryStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Threading;

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

#if FEATURE_SERIALIZATION
private CommonDictionaryStorage(SerializationInfo info, StreamingContext context) {
// Remember the serialization info, we'll deserialize when we get the callback. This
// enables special types like DBNull.Value to successfully be deserialized inside of us. We
// store the serialization info in a special bucket so we don't have an extra field just for
// serialization.
_buckets = new List<Bucket> { new Bucket(null, info, 0) };
}
#endif

public override void Add(ref DictionaryStorage storage, object key, object value)
=> Add(key, value);

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

#endregion

#if FEATURE_SERIALIZATION
#region ISerializable Members

public void GetObjectData(SerializationInfo info, StreamingContext context) {
info.AddValue("buckets", GetItems());
}

void IDeserializationCallback.OnDeserialization(object sender) {
if (_indices is not null) {
// we've received multiple OnDeserialization callbacks, only
// deserialize after the 1st one
return;
}

var info = (SerializationInfo)_buckets[0].Value;
_buckets.Clear();

var buckets = (List<KeyValuePair<object, object>>)info.GetValue("buckets", typeof(List<KeyValuePair<object, object>>));
foreach (KeyValuePair<object, object> kvp in buckets) {
AddNoLock(kvp.Key, kvp.Value);
}
}

#endregion
#endif
}
}
1 change: 1 addition & 0 deletions Tests/test_ordered_dict_stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def load_tests(loader, standard_tests, pattern):
]

skip_tests = [
test.test_ordered_dict.CPythonBuiltinDictTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?
test.test_ordered_dict.CPythonOrderedDictSubclassTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?
test.test_ordered_dict.CPythonOrderedDictTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?
test.test_ordered_dict.PurePythonOrderedDictSubclassTests('test_highly_nested_subclass'), # intermittent AssertionError - GC related?
Expand Down

0 comments on commit 9b2e812

Please sign in to comment.