Skip to content
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

Add more import APIs #210

Merged
merged 1 commit into from
Feb 26, 2020
Merged

Add more import APIs #210

merged 1 commit into from
Feb 26, 2020

Conversation

indygreg
Copy link
Contributor

I need some of these APIs to support in-memory extension module
importing in PyOxidizer. While I was adding the ones I needed, I
figured I would include some other missing symbols from
import.h as well.


#[cfg(not(Py_3_7))]
pub fn _PyImport_FindBuiltin(name: *const c_char) -> *mut PyObject;
#[cfg(Py_3_6)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be Py_3_7, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I force pushed a fix.

I need some of these APIs to support in-memory extension module
importing in PyOxidizer. While I was adding the ones I needed, I
figured I would include some other missing symbols from
import.h as well.
@markbt markbt merged commit 76fbba6 into dgrunwald:master Feb 26, 2020
indygreg added a commit to indygreg/PyOxidizer that referenced this pull request Feb 28, 2020
There exists a dark arts mechanism for loading Windows PE files from
memory. A mechanism to facilitate this is implemented in the
MemoryModule library at https://github.com/fancycode/MemoryModule.

I have published a `memory-module-sys` Rust crate to expose
bindings to this library. This enables Rust to load DLLs from
memory.

Previously in PyOxidizer, we taught the embedded Python resources
data structure to define the contents of a shared library extension
module to be imported from memory.

This commit combines the two efforts and enables the `pyembed` crate
to import Python extension modules which reside in memory.

Getting this working took a fair amount of effort. There were
a handful of attempts that did not pan out. Some of the failed
attempts appeared to work. But they were subtly broken due to e.g.
the `LazyLoader` importer assuming that the `sys.modules()` entry
wouldn't be modified. In the end, the final implementation
emulates CPython's extension module loading mechanism as closely
as possible. This was the only way I was able to preserve compatibility
with `LazyLoader` (just implementing `exec_module()` without
`create_module()` appears impossible - at least without writing our
own lazy module implementation).

While this commit produces working results, it is far from feature
complete. We still do not handle library dependencies properly.
We will likely need to teach the embedded resources data structure
about the existence of shared library resources and dependencies
from extension modules so that shared libraries can be imported
from memory when an extension module is imported.

Because this commit utilizes some CPython APIs outside the paved
road of CPython APIs, we had to contribute support for these
symbols to python3-sys
(dgrunwald/rust-cpython#210). This is why
we now depend on a specific Git commit of python3-sys and the
cpython crates. This means we can't release pyembed to crates.io
until a new version of these crates is published... We're likely
a ways off from a new release, as I don't want to solidify the new
embedded resources format until it has more features. So hopefully
this isn't a problem...
indygreg added a commit to indygreg/PyOxidizer that referenced this pull request Feb 28, 2020
There exists a dark arts mechanism for loading Windows PE files from
memory. A mechanism to facilitate this is implemented in the
MemoryModule library at https://github.com/fancycode/MemoryModule.

I have published a `memory-module-sys` Rust crate to expose
bindings to this library. This enables Rust to load DLLs from
memory.

Previously in PyOxidizer, we taught the embedded Python resources
data structure to define the contents of a shared library extension
module to be imported from memory.

This commit combines the two efforts and enables the `pyembed` crate
to import Python extension modules which reside in memory.

Getting this working took a fair amount of effort. There were
a handful of attempts that did not pan out. Some of the failed
attempts appeared to work. But they were subtly broken due to e.g.
the `LazyLoader` importer assuming that the `sys.modules()` entry
wouldn't be modified. In the end, the final implementation
emulates CPython's extension module loading mechanism as closely
as possible. This was the only way I was able to preserve compatibility
with `LazyLoader` (just implementing `exec_module()` without
`create_module()` appears impossible - at least without writing our
own lazy module implementation).

While this commit produces working results, it is far from feature
complete. We still do not handle library dependencies properly.
We will likely need to teach the embedded resources data structure
about the existence of shared library resources and dependencies
from extension modules so that shared libraries can be imported
from memory when an extension module is imported.

Because this commit utilizes some CPython APIs outside the paved
road of CPython APIs, we had to contribute support for these
symbols to python3-sys
(dgrunwald/rust-cpython#210). This is why
we now depend on a specific Git commit of python3-sys and the
cpython crates. This means we can't release pyembed to crates.io
until a new version of these crates is published... We're likely
a ways off from a new release, as I don't want to solidify the new
embedded resources format until it has more features. So hopefully
this isn't a problem...
indygreg added a commit to indygreg/PyOxidizer that referenced this pull request Feb 28, 2020
There exists a dark arts mechanism for loading Windows PE files from
memory. A mechanism to facilitate this is implemented in the
MemoryModule library at https://github.com/fancycode/MemoryModule.

I have published a `memory-module-sys` Rust crate to expose
bindings to this library. This enables Rust to load DLLs from
memory.

Previously in PyOxidizer, we taught the embedded Python resources
data structure to define the contents of a shared library extension
module to be imported from memory.

This commit combines the two efforts and enables the `pyembed` crate
to import Python extension modules which reside in memory.

Getting this working took a fair amount of effort. There were
a handful of attempts that did not pan out. Some of the failed
attempts appeared to work. But they were subtly broken due to e.g.
the `LazyLoader` importer assuming that the `sys.modules()` entry
wouldn't be modified. In the end, the final implementation
emulates CPython's extension module loading mechanism as closely
as possible. This was the only way I was able to preserve compatibility
with `LazyLoader` (just implementing `exec_module()` without
`create_module()` appears impossible - at least without writing our
own lazy module implementation).

While this commit produces working results, it is far from feature
complete. We still do not handle library dependencies properly.
We will likely need to teach the embedded resources data structure
about the existence of shared library resources and dependencies
from extension modules so that shared libraries can be imported
from memory when an extension module is imported.

Because this commit utilizes some CPython APIs outside the paved
road of CPython APIs, we had to contribute support for these
symbols to python3-sys
(dgrunwald/rust-cpython#210). This is why
we now depend on a specific Git commit of python3-sys and the
cpython crates. This means we can't release pyembed to crates.io
until a new version of these crates is published... We're likely
a ways off from a new release, as I don't want to solidify the new
embedded resources format until it has more features. So hopefully
this isn't a problem...
indygreg added a commit to indygreg/PyOxidizer that referenced this pull request Feb 28, 2020
There exists a dark arts mechanism for loading Windows PE files from
memory. A mechanism to facilitate this is implemented in the
MemoryModule library at https://github.com/fancycode/MemoryModule.

I have published a `memory-module-sys` Rust crate to expose
bindings to this library. This enables Rust to load DLLs from
memory.

Previously in PyOxidizer, we taught the embedded Python resources
data structure to define the contents of a shared library extension
module to be imported from memory.

This commit combines the two efforts and enables the `pyembed` crate
to import Python extension modules which reside in memory.

Getting this working took a fair amount of effort. There were
a handful of attempts that did not pan out. Some of the failed
attempts appeared to work. But they were subtly broken due to e.g.
the `LazyLoader` importer assuming that the `sys.modules()` entry
wouldn't be modified. In the end, the final implementation
emulates CPython's extension module loading mechanism as closely
as possible. This was the only way I was able to preserve compatibility
with `LazyLoader` (just implementing `exec_module()` without
`create_module()` appears impossible - at least without writing our
own lazy module implementation).

While this commit produces working results, it is far from feature
complete. We still do not handle library dependencies properly.
We will likely need to teach the embedded resources data structure
about the existence of shared library resources and dependencies
from extension modules so that shared libraries can be imported
from memory when an extension module is imported.

Because this commit utilizes some CPython APIs outside the paved
road of CPython APIs, we had to contribute support for these
symbols to python3-sys
(dgrunwald/rust-cpython#210). This is why
we now depend on a specific Git commit of python3-sys and the
cpython crates. This means we can't release pyembed to crates.io
until a new version of these crates is published... We're likely
a ways off from a new release, as I don't want to solidify the new
embedded resources format until it has more features. So hopefully
this isn't a problem...
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 this pull request may close these issues.

2 participants