Skip to content

.NET OBject type error "value cannot be converted to Object" #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andygraham opened this issue Sep 1, 2015 · 6 comments
Closed

.NET OBject type error "value cannot be converted to Object" #94

andygraham opened this issue Sep 1, 2015 · 6 comments

Comments

@andygraham
Copy link

andygraham commented Sep 1, 2015

Using Cpython 2.7.10 and pythonnet-2.1.0.dev1

I may be missing something as I am an IronPython user just playing to see if my Windows Forms code can run on CPython and PythonNet.

To fully use Windows Forms with PythonNet it is convenient, even necessary at times, to treat any Python object as a .NET Object so that it can be passed as a parameter to a delegate. For example to invoke a Python function to run on a WinForms GUI thread from a different thread you need to use Control.BeginInvoke which takes an Object array for the method parameters. There is no need to access these objects from .NET code, merely to package and unpackage them as .NET Object types which IronPython has no trouble doing. An example of this failure

import clr, sys
from System import Object, Array
a = Array[Object]([sys]) ; print a[0]
TypeError: cannot convert value to Object

I was actually interested in passing frame objects which have the same problem.

@den-run-ai
Copy link
Contributor

can you treat sys as Dynamic object?

@andygraham
Copy link
Author

I don't understand the question! This is all in Python code, not C#.

@tonyroberts
Copy link
Contributor

tonyroberts commented Sep 2, 2015

@denfromufa I think you've missed the point somewhat. When passing a Python object to a managed call it is converted to a managed object (eg a python float is converted to a managed Double). If you were writing managed code you could use a dynamic type to refer to the instance of the converted object, but that doesn't help in this case as there is no conversion available from the python object to a managed object in the first place.

A possible solution would be to change Converter::ToManagedValue (in converter.cs) to fallback to convert all Python objects without a reasonable conversion to a native managed type to a PyObject managed type. This looks simple enough, but there are a couple of issues that would need to be considered:

  • If the PyObject instance is cleaned up by the garbage collector it may block on acquiring the GIL and that may cause a deadlock as all other threads will be suspended (and one of those threads may have the GIL acquired).
  • The Python object may end up being deleted by the Python garbage collector while the managed instance still exists if there are no other Python references left to the object. This would result in the object being dereferenced by the PyObject destructor after the CPython object had already been deallocated.

Both of these problems can be resolved, but I just wanted to point them out as it's not a simple as going in and fixing ToManagedValue.

@den-run-ai
Copy link
Contributor

@tonyroberts, @andygraham good point on Dynamic.

Regarding keeping PyObject in .NET, would that require pinning unmanaged Python object and later manually releasing the handle?
Not sure about similar mechanism on Python side.

@den-run-ai
Copy link
Contributor

Another thing I don't understand is why the following mechanism cannot be
reused when converting to managed - Python module can be imported in C#
side with Py.Import(), and its members dynamically accessed.

On Wed, Sep 2, 2015, 3:33 AM Tony Roberts notifications@github.com wrote:

@denfromufa https://github.com/denfromufa I think you've missed the
point somewhat. When passing a Python object to a managed call it is
converted to a managed object (eg a python float is converted to a managed
Double). If you were writing managed code you could use a dynamic type to
refer to the instance of the converted object, but that doesn't help in
this case as there is no conversion available from the python object to a
managed object in the first place.

A possible solution would be to change Converter::ToManagedValue (in
converter.cs) to fallback to convert all Python objects without a
reasonable conversion to a native managed type to a PyObject managed type.
This looks simple enough, but there are a couple of issues that would raise
that would need to be considered:

  • If the PyObject instance is cleaned up by the garbage collector it
    may block on acquiring the GIL and that may cause a deadlock as all other
    threads will be suspended (and one of those threads may have the GIL
    acquired).
  • The Python object may end up being deleted by the Python garbage
    collector while the managed instance still exists if there are no other
    Python references left to the object. This would result in the object being
    dereferenced by the PyObject destructor after the CPython object had
    already been deallocated.

Both of these problems can be resolved, but I just wanted to point them
out as it's not a simple as going in and fixing ToManagedValue.


Reply to this email directly or view it on GitHub
#94 (comment).

@filmor
Copy link
Member

filmor commented Aug 6, 2021

This is fixed.

@filmor filmor closed this as completed Aug 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants