-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
Make python slightly more relocatable #62509
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
Comments
Hi all, I want to move python a bit closer to be relocatable. The proposal is to add an additional attempt to find the python modules For architectures where we cannot determine the path of the shared I have attached a patch that tries to implement this. thanks in advance Mathias |
Hi Mathias. There is a current proposal (http://www.python.org/dev/peps/pep-0432/) for improving interpreter startup. So changes in this area are subject to extra caution. The changes you are talking about are at least indirectly impacted by the proposal, though I expect they are more directly tied to what happens in site.py. As to your proposal, aren't the embedding needs already addressed? See http://docs.python.org/2/c-api/intro.html#embedding-python. Is there some convention for keeping the site files adjacent to the SO/DLL that would warrant your proposed code? p.s. this would be a new feature so it only applies to Python 3.4. |
Hi Eric, Thanks for looking at that ticket so fast! Reassigning this to 3.4 is great. In general, yes I can already do what I need more or less. This is the reason why I can be fine with about every python version. The point I bring up this change that I believe I am doing this at an unappropriate place as I need to know some internals of python when I do so and that I think that other can probably also benefit from this idea/change. Why are we doing this? So, put that in short: I try to get all of the PEP you pointed me to. sys.prefix (?) if this is not already provided from the embedding application. And yes I am perfectly fine with a different or more general approach. Greetings Mathias |
The way we figure out where to find the standard library is crazy, and creating the infrastructure to start making it less crazy is actually one of the prime motivations for PEP-432 :) |
Note that the OSX port already does this for framework builds. I don't know why we don't use the same code for shared library builds. Issue bpo-15498 contains a patch that switches this code from a deprecated nextstep-era API to dladdr. Two comments on the patch attached to this issue:
|
Hi Ronald, Eric, Nick, Looking up the symbol name of the current function should work also. Attached is version 2 of the patch with the suggested changes. It would be interesting to know if this kind of lookup scheme can be included into PEP-432. Greetings Mathias |
The PEP-587 "Python Initialization Configuration" has been implemented in Python 3.8. It provides fine control on the "Path Configuration": |
Hi, Nice to see some progress. May be to rephrase that. The basic idea behind that request was to make best Mathias |
Hum, I am confused. I understood that this issue is able customizing sys.path when Python is embedded. But it seems like the feature request is more about the *default* implementation, not how to reimplement it outside Python (with custm code). |
Yes. msg191944 from Nick Coghlan, made me think that with all the initialization rework that appeared to be underway you want to incorporate that presented idea of basing the default onto the location of the libpython.so or the pythonX.X.dll instead of the location of python/python.exe. And this does not even change the default for the common case where the default is plain useful. It is just changing the way how the default is determined so that the default for the case of an embedded interpreter is more meaningful. As stated somewhere above. The you can do that with application code when setting up the embedded interpreter, but it would be nice if that just works out of the box and by that helps applications not thinking of that solution. best Mathias |
My plan is not to change the default implementation to calculate the path configuration, but make it easier to customize the path configuration. One idea is to rewrite Modules/getpath.c and PC/getpathp.c in Python and convert it to a frozen module. It is easier to modify Python code than C code. In the past, we already did such change for importlib (which also has a frozen part, importlib._bootstrap and importlib._bootstrap_external). The PEP-587 implementation moves towards that with the "Multi-Phase Initialization Private Provisional API": |
Ok, so far. |
I have exactly the same need and use-case as Mathias in my project which includes a requirement to embed python3 in a relocatable folder structure w which serves as an application package (https://github.com/shakfu/py-js). This can be done using the Framework structure, thanks to Greg Neagle's solution referenced in (https://bugs.python.org/issue42514), but not for any python builds with --enabled-shared. In any case, providing options (at the c-level or otherwise, for embedded applications as described by Mathias would be ideal: "I can imagine to provide several functions to build up the pythonpath starting from something. |
In Python 3.11, Modules/getpath.c has been rewritten in Python: Modules/getpath.py. Maybe it's now simpler to hack this file. But you must rebuild Python to take changes in account. |
Thanks, Victor. I can imagine getpath.py will be more hackable (even if it is frozen). Still, it replicates the old algorithm: # Before any searches are done, the location of the executable is In my case (and I think for Mathias), the executable is a non python application and what is actually dynamically linking to libpythonX.Y.dylib (built via --enable-shared) is a c-based plugin (which calls PyInitialize()), and these two are only aware of their relative locations via the @rpath, @loader_path mechanism. Currently, in this scenario, libpythonX.Y.dylib doesn't know here pythonhome is unless explicitly told via PySetPath() or it defaults to the hardcoded sys.prefix . If this is to be relocatable, then PySetPath() should be able to handle relative paths. |
Hey, Shakeeb Alireza is right, the original problem was an application that links and embeds against libpython*{so,dll,dynlib} and should more easily find components like //lib/python*.*/site.py and most probably now it needs to find getpath.py as well. While I am no longer working on that application where I wanted to have that feature, I still believe it would be worthwhile to find the *.py files in the file system relative to the location of the libpython*{so,dll,dynlib} file. Thanks for taking care. Mathias |
Thanks, Mathias. This is all about improving python's 'relocatability'. Just to expand on my prior point: the scenario we are talking about is where one embeds python in a host application's plugin system rather than in the host application itself. In this case, sys.executable is the host application and a relocatable plugin embeds a 'python client'. If a full python distribution is not bundled within this client[*], it needs to (1) link to libpythonX.Y.dylib and (2) get the location of the standard library. There are standard cross-platform methods for (1) to be achieved by way of symmetrical @rpath lookups on the client and libpythonX.Y.dylib sides. So this resolvable even in the case when python is compiled with --enabled-shared. However, even if (1) is achieved, the client cannot get, programmatically via the python c-api, the location of libpythonX.Y.dylib (even if it is properly dynamically linking to it), because it cannot rely on sys.executable. I think this is crux of Mathias' argument. Of course there are workarounds, but they are (at least to me) all platform specific. The first and easiest is to just build using the Framework structure and don't ever use --enable-shared, provided you find Greg Neagle's solution (https://bugs.python.org/issue42514) Another workaround which is specific to my context (which I have attached), is to use Apple's CoreFoundation library to get the path to the plugin bundle and from there find our way to the python distribution in the containing folder structure (package). [*] It is possible to insert a full python distribution into a bundle (in the osx meaning), but then it becomes necessarily frozen or 'sealed' due to Apple's codesigning and notarization requirements, and it basically means that the user cannot extend it with further installations of python packages which contain c-extensions unless they jump through some additional codesigning and notarization hoops. |
Hmm.. I did submit this issue with regards to windows (https://bugs.python.org/issue35173) a super long time ago (as I used to maintain a windbg extension where I encountered problems with regards to relocatability) which seemed to be just a super old regression due to a misplaced condition (from back when python used to have Py_ENABLE_SHARED of which I'm pretty sure that it's been refactored out by now). I was shocked because when I wrote the original patch, it seemed that Python actually used to do this, because all the logic to do it was already there for Windows. Hence my patch turned out to be only a 13 line fix. However, I didn't think there anybody still cared about this since all of the work from the PEP proposal that supposedly refactored this issue out of Python. To be clear (since I quit maintaining the windbg extension I mentioned since it required x86 and x64 support), the latest windbg extension to support Python is Pykd and the developer of pykd includes a completely separate extension to specifically to deal with the issue of windbg.exe controlling the path to python and its modules. IDA Pro (a disassembler used for reverse engineering) also includes a separate program called idapyswitch to deal with this situation. So although it's nice to have module support for hooking the interpreter to recommend to it on how to find its paths, it does mean you can't just bundle the shared object with its libraries and you absolutely need a whole other installer or distinctly separate loader for dealing with multiple instances of python that have separate packages, etc. Maybe these people that I mentioned are doing it wrong, though. (edited) |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: