Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Allow setting typed objects via PyModule.Set #2311

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
dmitry-medvedev opened this issue Feb 1, 2024 · 3 comments · Fixed by #2330
Closed

Allow setting typed objects via PyModule.Set #2311

dmitry-medvedev opened this issue Feb 1, 2024 · 3 comments · Fixed by #2330

Comments

@dmitry-medvedev
Copy link

Environment

  • Pythonnet version: 3.0.1
  • Python version: 3.11
  • Operating System: Windows 11
  • .NET Runtime: .NET 4.8

Details

  • Right now, a .NET object can be passed to the Python scripting engine via PyModule.Set, which internally calls ToPythonDetectType(value)
    We'd like to pass a certain interface that the object supports, so only methods of this interface are available for Python scripting.

I suspect that adding the overloaded method PyModule.Set or ConverterExtension.ToPython that accepts the type of the object may resolve this issue.

@dmitry-medvedev
Copy link
Author

We were able to achieve the desired effect by using the following code:

 internal static class PythonModuleExtensions
 {
     public static void Set(this PyModule module, string name, object value, Type type)
     {
         using var pyValue = Converter.ToPython(value, type);
         SetPyValue(module, name, pyValue.Borrow());
     }

     private static void SetPyValue(PyModule module, string name, BorrowedReference value)
     {
         Check(module);
         if (name is null)
             throw new ArgumentNullException(nameof(name));

         using var pyKey = new PyString(name);

         var result = Runtime.PyObject_SetItem(module.variables, pyKey.obj, value);
         if (result < 0)
         {
             throw PythonException.ThrowLastAsClrException();
         }
     }

     private static void Check(PyModule module)
     {
         if (module.Reference.IsNull)
         {
             throw new ObjectDisposedException(nameof(PyModule));
         }
     }
 }

However, as some of these types/methods are internal, this is only possible if we use IgnoresAccessChecksToGenerator, which we would really like to avoid.

@lostmsu
Copy link
Member

lostmsu commented Feb 14, 2024

PyModule inherits from PyObject, and PyObject has a Set method that accepts PyObject value.

Sounds like we just need an overload for ToPython that takes type parameter. I think it would be better to have both generic and non-generic variants. PR would be welcome.

@dmitry-medvedev
Copy link
Author

We've sent PR via a separate ticket:
#2323

lostmsu added a commit to losttech/pythonnet that referenced this issue Feb 27, 2024
@lostmsu lostmsu mentioned this issue Feb 27, 2024
3 tasks
filmor pushed a commit that referenced this issue Feb 28, 2024
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

Successfully merging a pull request may close this issue.

2 participants