-
Notifications
You must be signed in to change notification settings - Fork 752
[WIP] Add ability to create module from C# #1447
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
Conversation
We now have https://github.com/pythonnet/pythonnet/blob/master/src/runtime/pymodule.cs Also, you should probably use pythonnet/src/runtime/runtime.cs Line 1895 in 16f04e9
|
Cool, I didn't know about pymodule.cs, I'll definitely migrate there and use the PyModule_New |
src/embed_tests/TestPyModule.cs
Outdated
|
||
namespace Python.EmbeddingTest | ||
{ | ||
class TestPyModule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think test class must be public
.
src/runtime/pymodule.cs
Outdated
@@ -37,5 +40,40 @@ public static PyModule FromString(string name, string code) | |||
PythonException.ThrowIfIsNull(m); | |||
return new PyModule(ref m); | |||
} | |||
|
|||
public static PyModule Create(string name, string filename = "none") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method violates single responsibility principle.
First, Create
should never return an existing module. Instead, the caller should be able to check if module already exists by name by calling a separate function.
Second, I am uncertain about setting up __builtins__
by default. It would be great to know why Python does not do it before discarding that potentially good rationale. Users can always manually do newModule.Dict.Set("__builtins__", GetBuiltIns())
. If this is a common scenario in your product, just make a factory method combining the two.
Third, I don't think adding new module to sys.modules
right away is a good idea. Especially, overwriting the existing value. This might cause hard to debug surprise issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second, I am uncertain about setting up
__builtins__
by default. It would be great to know why Python does not do it before discarding that potentially good rationale. Users can always manually donewModule.Dict.Set("__builtins__", GetBuiltIns())
. If this is a common scenario in your product, just make a factory method combining the two.
I didn't see a public method that would allow access to the __builtins__. There is an internal method, on Runtime
, but not a public method that could be used outside.
src/runtime/pymodule.cs
Outdated
PythonException.ThrowIfIsNull(__builtins__); | ||
int rc = Runtime.PyDict_SetItemString(globals, "__builtins__", __builtins__); | ||
PythonException.ThrowIfIsNotZero(rc); | ||
rc = Runtime.PyDict_SetItemString(globals, "__file__", new BorrowedReference(filename.ToPython().Handle)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default value for filename
should be null
and when it is null __file__
should simply not be set.
This is a good add feature, is anyone working on it? I am migrating from C where I create a handful of accessible modules from C using Py_InitModule3() and passing in the methods (C function pointers) and vars. Is there an alternative method here or is this something that would pend this change being actioned? |
I need to get back to it and make the changes that were requested. I just have a local compiled version with my changes that I have been using, so I haven't had a huge push to get me back to fixing this up. I'll try and work on it soon. |
@lostmsu I think I addressed the feedback you provided, please let me know if there are more changes you would like me to make. If not, I will make this a normal PR and remove the WIP. |
Feedback hopefully addressed. Thanks for being patient. I still don't know the codebase very well. |
What does this implement/fix? Explain your changes.
This allows doing something like this, which I haven't found any other way to do:
This is very useful for providing objects to an embedded Python engine.
Does this close any currently open issues?
I could not find any specific issues that would be related.
Any other comments?
This is an initial PR to get feedback if this would be allowed, I have a build of the library locally with this change and use this in my code, but would like to have it upstream if possible. I will fill out the remaining details and add tests if folks think this would be ok.
Checklist
Check all those that are applicable and complete.
AUTHORS
CHANGELOG