Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit946107f

Browse files
committed
Rework the serialization of reflected types
Serialization of System.Type, MemberInfo and MethodBase is now stringbased. At deserialization, use reflection to attempt to recreate theobject, which may fail safely instead of throwing aSerializaitonException during the deserialization of the whoie datastream. Appropriate Exceptions will now be raised when the Maybe*'sValue property.ClasseBase objects are now de-initialized and re-initialized in Reloadmode so that it's tp_dict picks up newly added members and removedmembers no longer linger.ModuleObject clears it's cache and remove cached members from it'stp_dict.Minor refactoring and modernization of MethodObject and MethodBinder
1 parent2253ef3 commit946107f

22 files changed

+681
-302
lines changed

‎src/domain_tests/test_domain_reload.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,47 +14,36 @@ def _run_test(testname):
1414

1515
assertproc.returncode==0
1616

17-
@pytest.mark.xfail(reason="Issue not yet fixed.")
1817
deftest_rename_class():
1918
_run_test('class_rename')
2019

21-
@pytest.mark.xfail(reason="Issue not yet fixed.")
2220
deftest_rename_class_member_static_function():
2321
_run_test('static_member_rename')
2422

25-
@pytest.mark.xfail(reason="Issue not yet fixed.")
2623
deftest_rename_class_member_function():
2724
_run_test('member_rename')
2825

29-
@pytest.mark.xfail(reason="Issue not yet fixed.")
3026
deftest_rename_class_member_field():
3127
_run_test('field_rename')
3228

33-
@pytest.mark.xfail(reason="Issue not yet fixed.")
3429
deftest_rename_class_member_property():
3530
_run_test('property_rename')
3631

37-
@pytest.mark.xfail(reason="Issue not yet fixed.")
3832
deftest_rename_namespace():
3933
_run_test('namespace_rename')
4034

41-
@pytest.mark.xfail(reason="Issue not yet fixed.")
4235
deftest_field_visibility_change():
4336
_run_test("field_visibility_change")
4437

45-
@pytest.mark.xfail(reason="Issue not yet fixed.")
4638
deftest_method_visibility_change():
4739
_run_test("method_visibility_change")
4840

49-
@pytest.mark.xfail(reason="Issue not yet fixed.")
5041
deftest_property_visibility_change():
5142
_run_test("property_visibility_change")
5243

53-
@pytest.mark.xfail(reason="Issue not yet fixed.")
5444
deftest_class_visibility_change():
5545
_run_test("class_visibility_change")
5646

57-
@pytest.mark.xfail(reason="Issue not yet fixed.")
5847
deftest_method_parameters_change():
5948
_run_test("method_parameters_change")
6049

‎src/runtime/Python.Runtime.csproj

Lines changed: 192 additions & 191 deletions
Large diffs are not rendered by default.

‎src/runtime/arrayobject.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,18 @@ internal override bool CanSubclass()
2323
publicstaticIntPtrtp_new(IntPtrtp,IntPtrargs,IntPtrkw)
2424
{
2525
varself=GetManagedObject(tp)asArrayObject;
26+
if(!self.type.Valid)
27+
{
28+
returnExceptions.RaiseTypeError(self.type.DeletedMessage);
29+
}
2630
if(Runtime.PyTuple_Size(args)!=1)
2731
{
2832
returnExceptions.RaiseTypeError("array expects 1 argument");
2933
}
3034
IntPtrop=Runtime.PyTuple_GetItem(args,0);
3135
objectresult;
3236

33-
if(!Converter.ToManaged(op,self.type,outresult,true))
37+
if(!Converter.ToManaged(op,self.type.Value,outresult,true))
3438
{
3539
returnIntPtr.Zero;
3640
}
@@ -45,8 +49,12 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
4549
{
4650
varobj=(CLRObject)GetManagedObject(ob);
4751
vararrObj=(ArrayObject)GetManagedObjectType(ob);
52+
if(!arrObj.type.Valid)
53+
{
54+
returnExceptions.RaiseTypeError(arrObj.type.DeletedMessage);
55+
}
4856
varitems=obj.instasArray;
49-
TypeitemType=arrObj.type.GetElementType();
57+
TypeitemType=arrObj.type.Value.GetElementType();
5058
intrank=items.Rank;
5159
intindex;
5260
objectvalue;

‎src/runtime/classbase.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,21 @@ namespace Python.Runtime
1818
[Serializable]
1919
internalclassClassBase:ManagedType
2020
{
21+
[NonSerialized]
22+
internalList<string>dotNetMembers;
2123
internalIndexerindexer;
22-
internalTypetype;
24+
internalMaybeTypetype;
2325

2426
internalClassBase(Typetp)
2527
{
28+
dotNetMembers=newList<string>();
2629
indexer=null;
2730
type=tp;
2831
}
2932

3033
internalvirtualboolCanSubclass()
3134
{
32-
return!type.IsEnum;
35+
return!type.Value.IsEnum;
3336
}
3437

3538

@@ -44,7 +47,12 @@ public virtual IntPtr type_subscript(IntPtr idx)
4447
returnExceptions.RaiseTypeError("type(s) expected");
4548
}
4649

47-
Typetarget=GenericUtil.GenericForType(type,types.Length);
50+
if(!type.Valid)
51+
{
52+
returnExceptions.RaiseTypeError(type.DeletedMessage);
53+
}
54+
55+
Typetarget=GenericUtil.GenericForType(type.Value,types.Length);
4856

4957
if(target!=null)
5058
{

‎src/runtime/classmanager.cs

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace Python.Runtime
1818
/// </summary>
1919
internalclassClassManager
2020
{
21-
privatestaticDictionary<Type,ClassBase>cache;
21+
privatestaticDictionary<MaybeType,ClassBase>cache;
2222
privatestaticreadonlyTypedtype;
2323

2424
privateClassManager()
@@ -36,7 +36,7 @@ static ClassManager()
3636

3737
publicstaticvoidReset()
3838
{
39-
cache=newDictionary<Type,ClassBase>(128);
39+
cache=newDictionary<MaybeType,ClassBase>(128);
4040
}
4141

4242
internalstaticvoidDisposePythonWrappersForClrTypes()
@@ -85,26 +85,56 @@ internal static void SaveRuntimeData(RuntimeDataStorage storage)
8585
varcontexts=storage.AddValue("contexts",
8686
newDictionary<IntPtr,InterDomainContext>());
8787
storage.AddValue("cache",cache);
88-
foreach(varclsincache.Values)
88+
foreach(varclsincache)
8989
{
90+
if(!cls.Key.Valid)
91+
{
92+
// Don't serialize an invalid class
93+
continue;
94+
}
9095
// This incref is for cache to hold the cls,
9196
// thus no need for decreasing it at RestoreRuntimeData.
92-
Runtime.XIncref(cls.pyHandle);
93-
varcontext=contexts[cls.pyHandle]=newInterDomainContext();
94-
cls.Save(context);
97+
Runtime.XIncref(cls.Value.pyHandle);
98+
varcontext=contexts[cls.Value.pyHandle]=newInterDomainContext();
99+
cls.Value.Save(context);
100+
101+
// Remove all members added in InitBaseClass.
102+
// this is done so that if domain reloads and a member of a
103+
// reflected dotnet class is removed, it is removed from the
104+
// Python object's dictionary tool; thus raising an AttributeError
105+
// instead of a TypeError.
106+
// Classes are re-initialized on in RestoreRuntimeData.
107+
IntPtrdict=Marshal.ReadIntPtr(cls.Value.tpHandle,TypeOffset.tp_dict);
108+
foreach(varmemberincls.Value.dotNetMembers)
109+
{
110+
// No need to decref the member, the ClassBase instance does
111+
// not own the reference.
112+
Runtime.PyDict_DelItemString(dict,member);
113+
}
114+
// Trying to remove a key that's not in the dictionary may
115+
// raise an error. We don't care about it.
116+
Runtime.PyErr_Clear();
95117
}
96118
}
97119

98120
internalstaticDictionary<ManagedType,InterDomainContext>RestoreRuntimeData(RuntimeDataStoragestorage)
99121
{
100-
cache=storage.GetValue<Dictionary<Type,ClassBase>>("cache");
122+
var_cache=storage.GetValue<Dictionary<MaybeType,ClassBase>>("cache");
101123
varcontexts=storage.GetValue<Dictionary<IntPtr,InterDomainContext>>("contexts");
102124
varloadedObjs=newDictionary<ManagedType,InterDomainContext>();
103-
foreach(varclsincache.Values)
125+
foreach(varpairin_cache)
104126
{
105-
varcontext=contexts[cls.pyHandle];
106-
cls.Load(context);
107-
loadedObjs.Add(cls,context);
127+
if(!pair.Key.Valid)
128+
{
129+
Runtime.XDecref(pair.Value.pyHandle);
130+
continue;
131+
}
132+
// re-init the class
133+
InitClassBase(pair.Key.Value,pair.Value);
134+
cache.Add(pair.Key,pair.Value);
135+
varcontext=contexts[pair.Value.pyHandle];
136+
pair.Value.Load(context);
137+
loadedObjs.Add(pair.Value,context);
108138
}
109139
returnloadedObjs;
110140
}
@@ -209,11 +239,16 @@ private static void InitClassBase(Type type, ClassBase impl)
209239
IntPtrdict=Marshal.ReadIntPtr(tp,TypeOffset.tp_dict);
210240

211241

242+
if(impl.dotNetMembers==null)
243+
{
244+
impl.dotNetMembers=newList<string>();
245+
}
212246
IDictionaryEnumeratoriter=info.members.GetEnumerator();
213247
while(iter.MoveNext())
214248
{
215249
varitem=(ManagedType)iter.Value;
216250
varname=(string)iter.Key;
251+
impl.dotNetMembers.Add(name);
217252
Runtime.PyDict_SetItemString(dict,name,item.pyHandle);
218253
// Decref the item now that it's been used.
219254
item.DecrRefCount();
@@ -241,7 +276,7 @@ private static void InitClassBase(Type type, ClassBase impl)
241276
// required that the ClassObject.ctors be changed to internal
242277
if(co!=null)
243278
{
244-
if(co.ctors.Length>0)
279+
if(co.NumCtors>0)
245280
{
246281
// Implement Overloads on the class object
247282
if(!CLRModule._SuppressOverloads)

‎src/runtime/classobject.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ namespace Python.Runtime
1313
internalclassClassObject:ClassBase
1414
{
1515
internalConstructorBinderbinder;
16-
internalConstructorInfo[]ctors;
16+
internalintNumCtors=0;
1717

1818
internalClassObject(Typetp):base(tp)
1919
{
20-
ctors=type.GetConstructors();
21-
binder=newConstructorBinder(type);
22-
23-
foreach(ConstructorInfotinctors)
20+
var_ctors=type.Value.GetConstructors();
21+
NumCtors=_ctors.Length;
22+
binder=newConstructorBinder(type.Value);
23+
foreach(ConstructorInfotin_ctors)
2424
{
2525
binder.AddMethod(t);
2626
}
@@ -61,7 +61,11 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
6161
returnExceptions.RaiseTypeError("invalid object");
6262
}
6363

64-
Typetype=self.type;
64+
if(!self.type.Valid)
65+
{
66+
returnExceptions.RaiseTypeError(self.type.DeletedMessage);
67+
}
68+
Typetype=self.type.Value;
6569

6670
// Primitive types do not have constructors, but they look like
6771
// they do from Python. If the ClassObject represents one of the
@@ -114,16 +118,21 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
114118
/// </summary>
115119
publicoverrideIntPtrtype_subscript(IntPtridx)
116120
{
121+
if(!type.Valid)
122+
{
123+
returnExceptions.RaiseTypeError(type.DeletedMessage);
124+
}
125+
117126
// If this type is the Array type, the [<type>] means we need to
118127
// construct and return an array type of the given element type.
119-
if(type==typeof(Array))
128+
if(type.Value==typeof(Array))
120129
{
121130
if(Runtime.PyTuple_Check(idx))
122131
{
123132
returnExceptions.RaiseTypeError("type expected");
124133
}
125134
varc=GetManagedObject(idx)asClassBase;
126-
Typet=c!=null?c.type:Converter.GetTypeByAlias(idx);
135+
Typet=c!=null?c.type.Value:Converter.GetTypeByAlias(idx);
127136
if(t==null)
128137
{
129138
returnExceptions.RaiseTypeError("type expected");
@@ -143,7 +152,7 @@ public override IntPtr type_subscript(IntPtr idx)
143152
returnExceptions.RaiseTypeError("type(s) expected");
144153
}
145154

146-
Typegtype=AssemblyManager.LookupType($"{type.FullName}`{types.Length}");
155+
Typegtype=AssemblyManager.LookupType($"{type.Value.FullName}`{types.Length}");
147156
if(gtype!=null)
148157
{
149158
varg=ClassManager.GetClass(gtype)asGenericType;

‎src/runtime/constructorbinder.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Python.Runtime
1414
[Serializable]
1515
internalclassConstructorBinder:MethodBinder
1616
{
17-
privateType_containingType;
17+
privateMaybeType_containingType;
1818

1919
internalConstructorBinder(TypecontainingType)
2020
{
@@ -51,10 +51,14 @@ internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw)
5151
/// </remarks>
5252
internalobjectInvokeRaw(IntPtrinst,IntPtrargs,IntPtrkw,MethodBaseinfo)
5353
{
54+
if(!_containingType.Valid)
55+
{
56+
returnExceptions.RaiseTypeError(_containingType.DeletedMessage);
57+
}
5458
objectresult;
5559

56-
if(_containingType.IsValueType&&!_containingType.IsPrimitive&&
57-
!_containingType.IsEnum&&_containingType!=typeof(decimal)&&
60+
if(_containingType.Value.IsValueType&&!_containingType.Value.IsPrimitive&&
61+
!_containingType.Value.IsEnum&&_containingType.Value!=typeof(decimal)&&
5862
Runtime.PyTuple_Size(args)==0)
5963
{
6064
// If you are trying to construct an instance of a struct by
@@ -64,7 +68,7 @@ internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info)
6468
// Activator.CreateInstance().
6569
try
6670
{
67-
result=Activator.CreateInstance(_containingType);
71+
result=Activator.CreateInstance(_containingType.Value);
6872
}
6973
catch(Exceptione)
7074
{

‎src/runtime/constructorbinding.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace Python.Runtime
2222
[Serializable]
2323
internalclassConstructorBinding:ExtensionType
2424
{
25-
privateTypetype;// The managed Type being wrapped in a ClassObject
25+
privateMaybeTypetype;// The managed Type being wrapped in a ClassObject
2626
privateIntPtrpyTypeHndl;// The python type tells GetInstHandle which Type to create.
2727
privateConstructorBinderctorBinder;
2828

@@ -92,6 +92,10 @@ public static IntPtr tp_descr_get(IntPtr op, IntPtr instance, IntPtr owner)
9292
publicstaticIntPtrmp_subscript(IntPtrop,IntPtrkey)
9393
{
9494
varself=(ConstructorBinding)GetManagedObject(op);
95+
if(!self.type.Valid)
96+
{
97+
returnExceptions.RaiseTypeError(self.type.DeletedMessage);
98+
}
9599

96100
Type[]types=Runtime.PythonArgsToTypeArray(key);
97101
if(types==null)
@@ -100,12 +104,12 @@ public static IntPtr mp_subscript(IntPtr op, IntPtr key)
100104
}
101105
//MethodBase[] methBaseArray = self.ctorBinder.GetMethods();
102106
//MethodBase ci = MatchSignature(methBaseArray, types);
103-
ConstructorInfoci=self.type.GetConstructor(types);
107+
ConstructorInfoci=self.type.Value.GetConstructor(types);
104108
if(ci==null)
105109
{
106110
returnExceptions.RaiseTypeError("No match found for constructor signature");
107111
}
108-
varboundCtor=newBoundContructor(self.type,self.pyTypeHndl,self.ctorBinder,ci);
112+
varboundCtor=newBoundContructor(self.type.Value,self.pyTypeHndl,self.ctorBinder,ci);
109113

110114
returnboundCtor.pyHandle;
111115
}
@@ -122,7 +126,7 @@ public static IntPtr tp_repr(IntPtr ob)
122126
returnself.repr;
123127
}
124128
MethodBase[]methods=self.ctorBinder.GetMethods();
125-
stringname=self.type.FullName;
129+
stringname=self.type.Value.FullName;
126130
vardoc="";
127131
foreach(MethodBasetinmethods)
128132
{

‎src/runtime/converter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
344344
}
345345
if(mtisClassBase)
346346
{
347-
result=((ClassBase)mt).type;
347+
result=((ClassBase)mt).type.Value;
348348
returntrue;
349349
}
350350
// shouldn't happen

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp