Hard crash when deleting from Dictionary

Environment

  • Pythonnet version: 3.0.5
  • Python version: both 3.12 and 3.13
  • Operating System: MacOS Sequoia 15.1.1
  • .NET Runtime: both 7.0.410 and 8.0.403

Details

  • Describe what you were trying to get done.

Remove an element from a .NET Dictionary using the del operator (__delitem__).

I reduced the problem to the following example, simply run from the command line:

import pythonnet
pythonnet.load('coreclr')
print(pythonnet.get_runtime_info(), end='\n\n')

import clr

from System.Collections.Generic import Dictionary
from System import Int32, String

DT = Dictionary[Int32, String]
d = DT()
d[10] = '10'
d[20] = '20'
print('__delitem__ is implemented by {}'.format(
    next(iter(cls for cls in DT.mro() if hasattr(cls, '__delitem__')))
))
del d[20]  # crash
  • If there was a crash, please include the traceback here.

The program crashed with the following output:

Runtime: CoreCLR
=============
  Version:      <undefined>
  Initialized:  True
  Shut down:    False
  Properties:
    HOST_RUNTIME_CONTRACT = 0x600003a840c8
    PROBING_DIRECTORIES =
    RUNTIME_IDENTIFIER = osx-arm64
    FX_DEPS_FILE = /usr/local/share/dotnet/shared/Microsoft.NETCore.App…
    APP_CONTEXT_DEPS_FILES = /usr/local/share/dotnet/shared/Microsoft.N…
    APP_CONTEXT_BASE_DIRECTORY =
    PLATFORM_RESOURCE_ROOTS = :
    NATIVE_DLL_SEARCH_DIRECTORIES = :/usr/local/share/dotnet/shared/Mic…
    TRUSTED_PLATFORM_ASSEMBLIES = /usr/local/share/dotnet/shared/Micros…

__delitem__ is implemented by <class 'System.Collections.Generic.Dictionary[Int32,String]'>
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at Python.Runtime.BorrowedReference.DangerousGetAddress() in /home/benedikt/.cache/uv/sdists-v6/.tmpkW03e6/pythonnet-3.0.5/src/runtime/Native/BorrowedReference.cs:line 18
   at Python.Runtime.NewReference..ctor(BorrowedReference reference, Boolean canBeNull) in /home/benedikt/.cache/uv/sdists-v6/.tmpkW03e6/pythonnet-3.0.5/src/runtime/Native/NewReference.cs:line 20
   at Python.Runtime.Runtime.PyTuple_SetItem(BorrowedReference pointer, IntPtr index, BorrowedReference value) in /home/benedikt/.cache/uv/sdists-v6/.tmpkW03e6/pythonnet-3.0.5/src/runtime/Runtime.cs:line 1482
   at Python.Runtime.ClassBase.mp_ass_subscript_impl(BorrowedReference ob, BorrowedReference idx, BorrowedReference v) in /home/benedikt/.cache/uv/sdists-v6/.tmpkW03e6/pythonnet-3.0.5/src/runtime/Types/ClassBase.cs:line 498
[1]    56976 abort      python3.12 /tmp/ramdisk/delme_test_pythonnet.py

Notice that __delitem__ is also implemented by the MutableMappingMixin class here, which simply calls the Remove() method, but Dictionary has its own implementation (that I can't find), which takes precedence.
The former would have worked correctly (tested), as Remove() works as usual.