Skip to content

c# <-> python dictionary converter #623

Closed

Activity

  1. yagweb commented on Feb 11, 2018

    @yagweb
    Contributor

    This function is similar to the function I proposed here #484. These two functions can be integrated into single one,“How to convert between python objects and CLR objects dynamically?”

    Based on my code before, I just wrote a new PyConverter here. I can make a PR if this design is accepted.

    It can be used in these ways,

    1. Convert between Python list and Clr List<T> dynamically;
    2. Convert between Python dict and Clr Dictionary<K, V> dynamically;
    3. Convert between Python object and Clr object, looks like Serialize and Deserialize.
    4. Convert any complex objects, such as nested dictionaries, lists and objects etc.
    5. It's extensible. Users can define his own PyClrType.

    For this issue from stackoverflow, we can use the PyConverter in this way,

    First define a PyConverter according to needs,

    public PyConverter NewMyDictConverter()
    {
        using (Py.GIL())
        {
            var converter = new PyConverter(); 
            converter.AddListType();
            converter.Add(new StringType());
            converter.Add(new Int64Type());
            converter.Add(new Int32Type());
            converter.Add(new FloatType());
            converter.Add(new DoubleType());
            converter.AddDictType<string, object>();
            return converter;
        }
    }
    
    

    Then, we can use this converter to convert a Clr Dictionary into a Python Dictionary, and vice versa.

    
    using (Py.GIL())
    {  
        //create a instance of PyConverter                
        var converter = NewMyDictConverter();
    
        var scope = Py.CreateScope();
        scope.Exec(
             "a={'0': 1, '1': [1, \"2\"]}"
        );
        dynamic a = scope.Get("a");  // mock a python dictionary
    
        var b = converter.ToClr(a);   //Convert python dict to Clr Dictionary<string, object>
    
        var c = converter.ToPython(b);  // Convert Clr Dictionary to python dict
        object c0 = c["0"];
        object c1 = c["1"];
    
        var d = converter.ToClr(c);
        object d0 = d["0"];
        object d1 = d["1"];
    
        scope.Dispose();
    }
    
  2. den-run-ai commented on Feb 12, 2018

    @den-run-ai
    ContributorAuthor

    @yagweb when you mention conversion happens "dynamically", do you mean the conversion happens at runtime or even later when the corresponding value/field is accessed?

  3. yagweb commented on Feb 12, 2018

    @yagweb
    Contributor

    @denfromufa "dynamically" here means the conversion happens at runtime.

    It‘s opposite to "static": we know the type of the value/field in coding phase, so we directly use the PyInt etc. in the code.

    There are three drawbacks of this hard coding method,

    1. We need to define lots of transformation codes which have similar structure.
    2. These codes are completely dependent on the specific data structure, so it's hard to maintenance.
    3. Sometimes we don’t know the type in coding phase, for example, for a list of type List<object>, we don't know the types of its element until runtime.

    The work steps of PyConverter are,

    1. Recognize the type of the object at runtime, or accept a given type for ‘static’ use
    2. Use the type to find a proper converter, e.g. Python int can be converted into Clr Int32/Int64 etc.
    3. Call the method and obtain the return value.
  4. den-run-ai commented on Feb 13, 2018

    @den-run-ai
    ContributorAuthor

    @yagweb i have not tested your converter API yet, but this looks promising. regarding preparing a PR, there is too much activity currently. i would wait until we stabilize .net core support in few weeks.

  5. kostjaaa commented on Nov 6, 2018

    @kostjaaa

    Have you tested this yet? It looks quite promising and I would like to use it.
    Would this be licensed under any terms?

  6. den-run-ai commented on Dec 19, 2018

    @den-run-ai
    ContributorAuthor

    @kostjaaa feel free to submit a PR, but make a summary of what you would like to achieve first.

  7. sschukat commented on Dec 21, 2018

    @sschukat

    I had a similar problem but solved it using Python code, which works with the current release
    See the netdict example.

  8. added this to the 3.0.0 milestone on Sep 23, 2021
  9. lostmsu commented on Sep 23, 2021

    @lostmsu
    Member

    This should now be fixed in 3.0

  10. siegfriedpammer commented on Feb 16, 2024

    @siegfriedpammer
    Contributor

    This should now be fixed in 3.0

    When working with a typing.Dict[str, str] and Dictionary<string, string> I still get

    TypeError: 'dict' value cannot be converted to System.Collections.Generic.Dictionary`2[System.String,System.String]

    on Python.NET 3.0.3

    Looking at the source code it seems there is a PyDict wrapper, but it is not used in any of the Converter logic. Are there any plans to add built-in conversion support for dictionaries?

    If it is supposed to work, an example show-casing the correct way to assign a python dictionary to an managed property accepting Dictionary<TKey, TValue> or IDictionary<TKey, TValue> or IReadOnlyDictionary<TKey, TValue> would be highly appreciated.

    If only Python.NET was more "user-friendly"... don't get me wrong, it is doing an awesome job with most things, there are just some rough edges and unfortunately I already spent countless hours figuring out these things without much success...

    Thanks!

  11. theGEBIRGE commented on Feb 26, 2024

    @theGEBIRGE

    I would also be interested in an example.

  12. nwoolls commented on Oct 21, 2024

    @nwoolls

    This should now be fixed in 3.0

    Any details on how this was fixed in 3.0? How are we meant to take a dictionary from python and convert it into a C# Dictionary<T,T>?

  13. iFreilicht commented on May 28, 2025

    @iFreilicht

    @lostmsu please reopen this issue, it is not fixed in Python.Net 3.0.5, the error message by @siegfriedpammer is still accurate.

  14. lostmsu commented on May 28, 2025

    @lostmsu
    Member

    @iFreilicht it is fixed one way where you can pass Dictionary<K,V> where Python expects dict. I am unsure, but it might be fixed for the scenario where you pass Python dict to IDictionary<K,V>. But it won't be fixed for dict -> Dictionary<K, V> because it might have surprising behavior: in both C# and Python you can modify a dictionary passed that way, but the above mentioned conversion would not modify the original dict.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions