8000 Domain reload test cases fixes by BadSingleton · Pull Request #1287 · pythonnet/pythonnet · GitHub
[go: up one dir, main page]

Skip to content

Domain reload test cases fixes #1287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
fc7da1d
Adds test cases for member changes during a domain reload
BadSingleton Nov 9, 2020
72fafdd
!fixup add the project to the solution files
BadSingleton Nov 9, 2020
20861b2
Add more test cases
BadSingleton Nov 18, 2020
2253ef3
Merge remote-tracking branch 'upstream/master' into domain-reload-tes…
BadSingleton Nov 18, 2020
635edac
Make the tests run as netcoreapp
BadSingleton Nov 19, 2020
0ee931e
Remove stray colon
BadSingleton Nov 19, 2020
3dad96e
Rework the serialization of reflected types
BadSingleton Nov 19, 2020
90a81f3
Call PyType_Modified after modifying the type
BadSingleton Nov 20, 2020
10276f1
Some code review changes
BadSingleton Nov 20, 2020
4d0e2ce
fixup! Some code review changes
BadSingleton Nov 23, 2020
02fa245
Remove hungarian notation from Maybe* types
BadSingleton Nov 23, 2020
91c881c
Check the type of the exception before ignoring it
BadSingleton Nov 23, 2020
284e8e1
Check for validity, don't throw
BadSingleton Nov 23, 2020
fe96781
Refactor the member binding logic of ClassManager
BadSingleton Nov 23, 2020
6ff9e0b
Include info about why deserialization failed in Maybe*
BadSingleton Nov 23, 2020
4d2d05b
improve deserialization resolution of ref, out and in parameters
BadSingleton Nov 24, 2020
5f061bc
Clean up the project and solution files
BadSingleton Nov 26, 2020
3adc559
Merge branch 'master' into domain-reload-test-cases
BadSingleton Nov 26, 2020
e8543cf
Rework the serialization of reflected types
BadSingleton Nov 19, 2020
61b0d8c
Call PyType_Modified after modifying the type
BadSingleton Nov 20, 2020
c8bacf3
Some code review changes
BadSingleton Nov 20, 2020
cde5c23
fixup! Some code review changes
BadSingleton Nov 23, 2020
a956773
Remove hungarian notation from Maybe* types
BadSingleton Nov 23, 2020
ee3b391
Check the type of the exception before ignoring it
BadSingleton Nov 23, 2020
9b4d5f9
Check for validity, don't throw
BadSingleton Nov 23, 2020
a2f3294
Refactor the member binding logic of ClassManager
BadSingleton Nov 23, 2020
46dcb9d
Include info about why deserialization failed in Maybe*
BadSingleton Nov 23, 2020
10116bb
improve deserialization resolution of ref, out and in parameters
BadSingleton Nov 24, 2020
102054e
!fixup leftover error from the rebase
BadSingleton Nov 26, 2020
329de5d
Add fixes and test for nested classes
BadSingleton Nov 27, 2020
f97262b
Code review fixes
BadSingleton Dec 2, 2020
ceb3fab
Merge branch 'master' into domain-reload-test-cases-fixes
BadSingleton Dec 2, 2020
2d6ae4c
fixup! Merge branch 'master' into domain-reload-test-cases-fixes
BadSingleton Dec 2, 2020
16a39a6
fixup! Code review fixes
BadSingleton Dec 2, 2020
ace340d
Fix build failures on non-windows
BadSingleton Dec 8, 2020
78a8088
fixup! Fix build failures on non-windows
BadSingleton Dec 8, 2020
3232f79
Merge remote-tracking branch 'origin/domain-reload-test-cases-fixes' …
BadSingleton Dec 8, 2020
87287a5
Merge branch 'master' into domain-reload-test-cases-fixes
BadSingleton Dec 8, 2020
44b4800
Merge branch 'master' into domain-reload-test-cases-fixes
BadSingleton Dec 10, 2020
79516f1
Code review fixes
BadSingleton Dec 10, 2020
421f665
Merge remote-tracking branch 'upstream/master' into domain-reload-tes…
BadSingleton Dec 10, 2020
5e4c976
(WIP) rework project structure
BadSingleton Dec 11, 2020
9d1991a
Merge remote-tracking branch 'upstream/master' into domain-reload-tes…
BadSingleton Dec 14, 2020
bcf0cd6
Rework the projects file structure
BadSingleton Dec 14, 2020
73e5a6b
Check teh return value of PyDict_DelItemString
BadSingleton Dec 14, 2020
510a7ae
netstandard.dll is a Facade Library
BadSingleton Dec 16, 2020
21eb14c
Remove TestClassReference
BadSingleton Dec 17, 2020
59e81e2
Test runner docs fixes
BadSingleton Dec 17, 2020
1383b5a
Skip the domain reload tests on macos
BadSingleton Dec 17, 2020
fbc06ef
fixup! Skip the domain reload tests on macos
BadSingleton Dec 17, 2020
b3e86da
Update ISSUE_TEMPLATE.md
filmor Dec 17, 2020
0b027c6
refactoring in CreateSubType
lostmsu Dec 17, 2020
b4533c4
allocate space for GCHandle in instances of CLR Metatype (which are t…
lostmsu Dec 18, 2020
0a3f044
classderived: handle tp_dealloc called after tp_clear
lostmsu Dec 18, 2020
639236a
a few extra assertions
lostmsu Dec 18, 2020
3069285
fixed crash in finalizer of CLR types defined in Python, that survive…
lostmsu Dec 18, 2020
5c14aad
Merge branch 'master' into domain-reload-test-cases-fixes
BadSingleton Dec 18, 2020
00c19d5
Merge branch 'master' into domain-reload-test-cases-fixes
BadSingleton Jan 4, 2021
833e836
Fix break introduced by merge
BadSingleton Jan 4, 2021
62ae107
Code review fixes
BadSingleton Jan 4, 2021
eedbae5
Merge remote-tracking branch 'upstream/master' into domain-reload-tes…
BadSingleton Jan 5, 2021
73f39bc
Add the PID of the test runner
BadSingleton Jan 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor the member binding logic of ClassManager
So that we can use that same logic when deserializing Maybe* types
  • Loading branch information
BadSingleton committed Nov 23, 2020
commit fe9678166f21019675cbc4ffb467c46267296688
34 changes: 28 additions & 6 deletions src/runtime/StateSerialization/MaybeMemberInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ internal struct MaybeMemberInfo<T> : ISerializable where T: MemberInfo

string name;
MemberInfo info;

// As seen in ClassManager.GetClassInfo
const BindingFlags k_flags = BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.Public ;

public string DeletedMessage
{
Expand Down Expand Up @@ -64,14 +59,41 @@ internal MaybeMemberInfo(SerializationInfo serializationInfo, StreamingContext c
if (tp != null)
{
var field_name = serializationInfo.GetString("f");
info = tp.GetField(field_name, k_flags);
MemberInfo mi = tp.GetField(field_name, ClassManager.BindingFlags);
if (mi != null && ShouldBindMember(mi))
{
info = mi;
}
}
}
catch
{
}
}

// This is complicated because we bind fields
// based on the visibility of the field, properties
// based on it's setter/getter (which is a method
// info) visibility and events based on their
// AddMethod visibility.
static bool ShouldBindMember(MemberInfo mi)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not totally satisfied with this solution, but it's the best I could find. If anyone has a better idea..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also leave this abstract and have class MaybePropertyInfo : MaybeMemberInfo<PropertyInfo> and so on, enforcing that if the type of member changed then it doesn't count as a match.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But maybe that's not critical.

{
if (mi is PropertyInfo pi)
{
return ClassManager.ShouldBindProperty(pi);
}
else if (mi is FieldInfo fi)
{
return ClassManager.ShouldBindField(fi);
}
else if (mi is EventInfo ei)
{
return ClassManager.ShouldBindEvent(ei);
}

return false;
}

public void GetObjectData(SerializationInfo serializationInfo, StreamingContext context)
{
serializationInfo.AddValue("s", name);
Expand Down
16 changes: 9 additions & 7 deletions src/runtime/StateSerialization/MaybeMethodBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ internal struct MaybeMethodBase<T> : ISerializable where T: MethodBase

string name;
MethodBase info;
// As seen in ClassManager.GetClassInfo
const BindingFlags k_flags = BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.Public ;

public T Value
{
Expand Down Expand Up @@ -62,11 +58,17 @@ internal MaybeMethodBase(SerializationInfo serializationInfo, StreamingContext c
types[i] = Type.GetType(param[i]);
}
// Try to get the method
info = tp.GetMethod(field_name, k_flags, binder:null, types:types, modifiers:null);
MethodBase mb = tp.GetMethod(field_name, ClassManager.BindingFlags, binder:null, types:types, modifiers:null);
// Try again, may be a constructor
if (info == null && name.Contains(".ctor"))
if (mb == null && name.Contains(".ctor"))
{
info = tp.GetConstructor(k_flags, binder:null, types:types, modifiers:null);
mb = tp.GetConstructor(ClassManager.BindingFlags, binder:null, types:types, modifiers:null);
}

// Do like in ClassManager.GetClassInfo
if(mb != null && ClassManager.ShouldBindMethod(mb))
{
info = mb;
}
}
catch
Expand Down
100 changes: 60 additions & 40 deletions src/runtime/classmanager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ namespace Python.Runtime
/// </summary>
internal class ClassManager
{

// Binding flags to determine which members to expose in Python.
// This is complicated because inheritance in Python is name
// based. We can't just find DeclaredOnly members, because we
// could have a base class A that defines two overloads of a
// method and a class B that defines two more. The name-based
// descriptor Python will find needs to know about inherited
// overloads as well as those declared on the sub class.
internal static readonly BindingFlags BindingFlags = BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic;

private static Dictionary<MaybeType, ClassBase> cache;
private static readonly Type dtype;

Expand Down Expand Up @@ -310,6 +323,47 @@ private static void InitClassBase(Type type, ClassBase impl)
Runtime.PyType_Modified(tp);
}

internal static bool ShouldBindMethod(MethodBase mb)
{
return (mb.IsPublic || mb.IsFamily || mb.IsFamilyOrAssembly);
}

internal static bool ShouldBindField(FieldInfo fi)
{
return (fi.IsPublic || fi.IsFamily || fi.IsFamilyOrAssembly);
}

internal static bool ShouldBindProperty(PropertyInfo pi)
{
MethodInfo mm = null;
try
{
mm = pi.GetGetMethod(true);
if (mm == null)
{
mm = pi.GetSetMethod(true);
}
}
catch (SecurityException)
{
// GetGetMethod may try to get a method protected by
// StrongNameIdentityPermission - effectively private.
return false;
}

if (mm == null)
{
return false;
}

return ShouldBindMethod(mm);
}

internal static bool ShouldBindEvent(EventInfo ei)
{
return ShouldBindMethod(ei.GetAddMethod(true));
}

private static ClassInfo GetClassInfo(Type type)
{
var ci = new ClassInfo();
Expand All @@ -322,18 +376,7 @@ private static ClassInfo GetClassInfo(Type type)
Type tp;
int i, n;

// This is complicated because inheritance in Python is name
// based. We can't just find DeclaredOnly members, because we
// could have a base class A that defines two overloads of a
// method and a class B that defines two more. The name-based
// descriptor Python will find needs to know about inherited
// overloads as well as those declared on the sub class.
BindingFlags flags = BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic;

MemberInfo[] info = type.GetMembers(flags);
MemberInfo[] info = type.GetMembers(BindingFlags);
var local = new Hashtable();
var items = new ArrayList();
MemberInfo m;
Expand Down Expand Up @@ -376,7 +419,7 @@ private static ClassInfo GetClassInfo(Type type)
for (i = 0; i < inheritedInterfaces.Length; ++i)
{
Type inheritedType = inheritedInterfaces[i];
F5DB MemberInfo[] imembers = inheritedType.GetMembers(flags);
MemberInfo[] imembers = inheritedType.GetMembers(BindingFlags);
for (n = 0; n < imembers.Length; n++)
{
m = imembers[n];
Expand Down Expand Up @@ -407,8 +450,7 @@ private static ClassInfo GetClassInfo(Type type)
{
case MemberTypes.Method:
meth = (MethodInfo)mi;
if (!(meth.IsPublic || meth.IsFamily ||
meth.IsFamilyOrAssembly))
if (!ShouldBindMethod(meth))
{
continue;
}
Expand All @@ -425,28 +467,7 @@ private static ClassInfo GetClassInfo(Type type)
case MemberTypes.Property:
var pi = (PropertyInfo)mi;

MethodInfo mm = null;
try
{
mm = pi.GetGetMethod(true);
if (mm == null)
{
mm = pi.GetSetMethod(true);
}
}
catch (SecurityException)
{
// GetGetMethod may try to get a method protected by
// StrongNameIdentityPermission - effectively private.
continue;
}

if (mm == null)
{
continue;
}

if (!(mm.IsPublic || mm.IsFamily || mm.IsFamilyOrAssembly))
if(!ShouldBindProperty(pi))
{
continue;
}
Expand All @@ -471,7 +492,7 @@ private static ClassInfo GetClassInfo(Type type)

case MemberTypes.Field:
var fi = (FieldInfo)mi;
if (!(fi.IsPublic || fi.IsFamily || fi.IsFamilyOrAssembly))
if (!ShouldBindField(fi))
{
continue;
}
Expand All @@ -481,8 +502,7 @@ private static ClassInfo GetClassInfo(Type type)

case MemberTypes.Event:
var ei = (EventInfo)mi;
MethodInfo me = ei.GetAddMethod(true);
if (!(me.IsPublic || me.IsFamily || me.IsFamilyOrAssembly))
if (!ShouldBindEvent(ei))
{
continue;
}
Expand Down
0