Skip to content

PyObject.FromManagedObject(value); does not convert C# bool to Python bool #2415

Description

@Veselin-Stoilov

Environment

  • Pythonnet version: 3.0.3
  • Python version: 310
  • Operating System: Windows 11
  • .NET Runtime: 8.0.206

Details

  • I am trying to call a Python method from C# and pass a boolean value as a keyword argument. For this, I convert a C# dictionary (with string keys and object values) to a PyDict by iterating through each kvp in the C# dictionary and converting it to PyObject. Since there is no out-of-the-box PyBool(value) object, I used PyObject.FromManagedObject(value) to convert the C# boolean to a Python boolean. However, this approach didn't work as expected. The Python method expects a bool, which passed as a keyword argument is received as a Boolean with an uppercase "B", causing it to fail.
public static string PythonTestRunner(string pyDirPath, string pyModule, string pyMethod, Dictionary<string, object> argsDict)
{
    try
    {
        using (Py.GIL())
        {
            dynamic os = Py.Import("os");
            dynamic sys = Py.Import("sys");

            string currentPath = os.getcwd().ToString();
            string fullDirPath = os.path.join(currentPath, pyDirPath).ToString();
            sys.path.append(fullDirPath);

            dynamic module = Py.Import(pyModule);
            dynamic method = module.GetAttr(pyMethod);

            PyDict kwargs = new PyDict();
            foreach (var kvp in argsDict)
            {
                PyObject pyKey = new PyString(kvp.Key);
                PyObject pyValue = ConvertToPyObject(kvp.Value);
                kwargs[pyKey] = pyValue;
            }

            dynamic resultMessage = method.Invoke(new PyTuple(), kwargs);

            return (string)resultMessage;
        }
    }
    catch (Exception ex)
    {
        // Log the error and rethrow it
        throw;
    }
}
public static PyObject ConvertToPyObject(dynamic value)
{
    if (value == null)
        return PyObject.None;
    else if (value is string)
        return new PyString(value);
    else if (value is int)
        return new PyInt(value);
    else if (value is bool)
        return PyObject.FromManagedObject(value);
    else
        return PyObject.FromManagedObject(value);
}
# test_module.py
def test_method(param1: bool):
    error_messages = []   

    if not isinstance(param1, bool):
    error_messages.append(f"testBoolTrue is not a boolean, but {type(param1).__name__}")

    # Determine message
    result_message = "Invalid data types: " + ", ".join(error_messages)

return result_message
  • Message: Invalid data types: param1 is not a boolean, but Boolean

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions