Accessing a C# dictionary in Python.NET : TypeError: cannot convert dictionary update sequence element #0 to a sequence

Viewed 420

I'm stuck trying to access a C# Dictionary from some Python code using Python.NET.

Trying to explicitly create a Python dict from a C# Dictionary fails with a TypeError: cannot convert dictionary update sequence element #0 to a sequence error:

import clr

clr.AddReference('System')
clr.AddReference('System.Collections')

from System.Collections.Generic import Dictionary
from System import String
from System import Object

d = Dictionary[String, Object]()
d['Entry 1'] = 'test'
d['Entry 2'] = 12.3
print(f" d.Count : {d.Count}") # returns 2

py_dict = dict(d)
 d.Count : 2
Traceback (most recent call last):
  File "test_dict.py", line 21, in <module>
    py_dict = dict(d)
TypeError: cannot convert dictionary update sequence element #0 to a sequence

In my real code the c_sharp_obj Dictionary is being declared as:

Dictionary<DescriptorType, IDescriptor> Descriptors { get; }

IDescriptor is a custom C# class:

public interface IDescriptor : IDisposable

And DescriptorType is an enum:

public enum DescriptorType
{
  CharacteristicAggregateFormat   = 0x2905,
  CharacteristicExtendedProperties = 0x2900,
  CharacteristicPresentationFormat = 0x2904,
  CharacteristicUserDescription = 0x2901,
  ClientCharacteristicConfiguration = 0x2902,
}

On IronPython I could iterate over the key and values with

for k, v in  in dict(c_sharp_obj).iteritems():

If I try:

print(c_sharp_obj)
print(type(c_sharp_obj))

I get:

System.Collections.Generic.Dictionary`2[DescriptorType,IDescriptor]
<class 'System.Collections.Generic.313, Culture=neutral, PublicKeyToken=null]]'>

I can iterate over the Dictionary with:

for k in c_sharp_obj:
    print(k)
    print(type(k))

And I get:

[CharacteristicUserDescription, Type:CharacteristicUserDescription]
<class 'System.Collections.Generic.313, Culture=neutral, PublicKeyToken=null]]'>

Shouldn't I get DescriptorType as the type? If I try to index the Dictionary with the key:

print(c_sharp_obj[k])

I get a TypeError: No method matches given arguments: (<class 'System.Collections.Generic.313, Culture=neutral, PublicKeyToken=null]]'>).

I was able to access the enum value with:

enum_name = str(k).split(',')[0].replace('[', '')
enum_value = System.Enum.Parse(clr.GetClrType(Arendi.BleLibrary.Service.DescriptorType), enum_name);
print(hex(enum_name))
print(c_sharp_obj[enum_name])

But the line print(c_sharp_obj[enum_name]) gives me Type:CharacteristicUserDescription and not a IDescriptor object.

How can I iterate over the C# Dictionary accessing the original C# classes?

I'm using Python.NET 2.5.2. Thanks!!!

1 Answers

The generic type System.Collections.Generic.313 you are seeing when iterating over .NET dictionary using Python.NET is propbably an instantiation of KeyValuePair<TKey, TValue>. So in your loop you can access k.Key and k.Value. Which, BTW, you could have discovered by running dir(k).

Related