Skip to content

Commit 9ebfbde

Browse files
authored
Fix crash when event does not have Add method and improve message for some other internal errors (pythonnet#2409)
* not all events have Add method fixes pythonnet#2405 * give users some idea of why we might be unable to reflect .NET types to Python for them * mentioned event Add method crash fix in changelog
1 parent f82aeea commit 9ebfbde

File tree

4 files changed

+32
-13
lines changed

4 files changed

+32
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
2222
### Fixed
2323

2424
- Fixed RecursionError for reverse operators on C# operable types from python. See #2240
25+
- Fixed crash when .NET event has no `AddMethod`
2526
- Fixed probing for assemblies in `sys.path` failing when a path in `sys.path` has invalid characters. See #2376
2627

2728
## [3.0.3](https://github.com/pythonnet/pythonnet/releases/tag/v3.0.3) - 2023-10-11

src/runtime/ClassManager.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,13 @@ internal static void InitClassBase(Type type, ClassBase impl, ReflectedClrType p
290290

291291
internal static bool ShouldBindMethod(MethodBase mb)
292292
{
293+
if (mb is null) throw new ArgumentNullException(nameof(mb));
293294
return (mb.IsPublic || mb.IsFamily || mb.IsFamilyOrAssembly);
294295
}
295296

296297
internal static bool ShouldBindField(FieldInfo fi)
297298
{
299+
if (fi is null) throw new ArgumentNullException(nameof(fi));
298300
return (fi.IsPublic || fi.IsFamily || fi.IsFamilyOrAssembly);
299301
}
300302

@@ -326,7 +328,7 @@ internal static bool ShouldBindProperty(PropertyInfo pi)
326328

327329
internal static bool ShouldBindEvent(EventInfo ei)
328330
{
329-
return ShouldBindMethod(ei.GetAddMethod(true));
331+
return ei.GetAddMethod(true) is { } add && ShouldBindMethod(add);
330332
}
331333

332334
private static ClassInfo GetClassInfo(Type type, ClassBase impl)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System;
2+
3+
namespace Python.Runtime;
4+
5+
public class InternalPythonnetException : Exception
6+
{
7+
public InternalPythonnetException(string message, Exception innerException)
8+
: base(message, innerException) { }
9+
}

src/runtime/Types/ReflectedClrType.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,29 @@ public static ReflectedClrType GetOrCreate(Type type)
3030
return pyType;
3131
}
3232

33-
// Ensure, that matching Python type exists first.
34-
// It is required for self-referential classes
35-
// (e.g. with members, that refer to the same class)
36-
pyType = AllocateClass(type);
37-
ClassManager.cache.Add(type, pyType);
33+
try
34+
{
35+
// Ensure, that matching Python type exists first.
36+
// It is required for self-referential classes
37+
// (e.g. with members, that refer to the same class)
38+
pyType = AllocateClass(type);
39+
ClassManager.cache.Add(type, pyType);
3840

39-
var impl = ClassManager.CreateClass(type);
41+
var impl = ClassManager.CreateClass(type);
4042

41-
TypeManager.InitializeClassCore(type, pyType, impl);
43+
TypeManager.InitializeClassCore(type, pyType, impl);
4244

43-
ClassManager.InitClassBase(type, impl, pyType);
45+
ClassManager.InitClassBase(type, impl, pyType);
4446

45-
// Now we force initialize the Python type object to reflect the given
46-
// managed type, filling the Python type slots with thunks that
47-
// point to the managed methods providing the implementation.
48-
TypeManager.InitializeClass(pyType, impl, type);
47+
// Now we force initialize the Python type object to reflect the given
48+
// managed type, filling the Python type slots with thunks that
49+
// point to the managed methods providing the implementation.
50+
TypeManager.InitializeClass(pyType, impl, type);
51+
}
52+
catch (Exception e)
53+
{
54+
throw new InternalPythonnetException($"Failed to create Python type for {type.FullName}", e);
55+
}
4956

5057
return pyType;
5158
}

0 commit comments

Comments
 (0)