-
Notifications
You must be signed in to change notification settings - Fork 45
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
REPL cannot load libpython
when built and run under Python environment
#432
Comments
When the repl is built, it looks like we can point pyo3 at the python version we want to use. https://pyo3.rs/v0.19.2/building_and_distribution.html#configuring-the-python-version So I'll see what's involved in querying Conda, and potentially overriding pyo3's defaults if Conda is installed. The other option (which we might want to do regardless) is to document the |
I didn't mention it in an issue description, but in fact PyO3 compile against and uses absolutely correct version of the library. So I don't see any inconsistency. The issue is that this shared Python library from Conda is not found by OS when program is executed under the same environment. It sounds more like a Conda issue btw. |
This is how Conda manages it for its packages:
|
I would say the proper way to fix is to have two different dynamic links for two different cases:
|
I see. It seems like installing the REPL as part of a package under Conda's control would be the "right" fix from Conda's point of view. I don't know anything about how Conda and pip interact, but would installing the REPL as part of the current Python package accomplish this? |
I guess it is not a common use-case to share native executable as a part of a Python package. Thus I don't think it will work actually. At the link above I believe they are talking about a situation when a Conda package is being built. And to me it is an open question how to distribute the app which depends on Python. Probably like any other binary app. For distribution purposes we should use the version without specific path to the Python library. Two cases above which are proposed in #432 (comment) are for the local builds only. Btw it makes sense to switch between Python and non-Python in runtime instead of build time. Thus user can install MeTTa and use it with Python only when it is required. |
If you run
This is actually how I had it originally, but it was a lot of complexity and I didn't see the benefit so I removed it. There are two issues to doing this the "clean" way. |
A related but different issue is here: PyO3/pyo3#1554 It's useful to gain additional background to the python init under Conda. |
Yes, sure,
I am not sure what is an issue with that. We load MeTTa libraries on the start anyway. Looks like we can choose one set or another depending on whether
Yes, it is more serious. If PyO3 cannot load
Interesting.
Looks like it was came up with conclusion it is a Windows Conda's version issue. Anyway not only Conda is under the trouble, we should also test Python virtualenv (another popular Python env isolation framework). |
Just to update the ticket with my current thinking / findings: 1.) pyo3's build.rs script successfully locates the Conda python and libpython. (I think @vsbogd already mentioned this, but I've confirmed it using the 2.) It appears that the python interpreter binary statically links libpython, when running under Conda. So by extension, I would guess this is what the Conda designers intended for other apps that need access to libpython. 3.) So I tried switching to static linking of libpython, but I hit an issue with LTO (link-time-optimization) because of compiler mismatch. I spent way more time than I'd like to admit trying to get rustc not to attempt to LTO libpython, and I eventually found this comment in the pyo3 source. 4.) So static linking of libpython is going to be fraught with problems. (They practically beg you not to do it here: https://pyo3.rs/main/building_and_distribution#statically-embedding-the-python-interpreter) And Conda doesn't like its libraries to be in a system-wide search path for dynamic linking. (Which seems silly to me because that seems like one of the basic properties of having an environment activated... But here we are.) 5.) As @vsbogd suggested, we could detect conda / pyenv in a build script somehow, and then update the binary to link libpython by absolute path. That would fix the issue, but would break if the user switched conda environments. (Which if I understand, is a common thing for Conda users to do) 6.) Apparently the idea of springboarding isn't so crazy in this case. I found this line in the pyo3 docs (https://pyo3.rs/main/building_and_distribution#dynamically-embedding-the-python-interpreter)
So in conclusion: Therefore, it seems to me that the right solution is to write a wrapper / springboard that uses the python location logic from pyo3 to find the correct libpython for the current environment, and the execs the real binary. |
Well I would not bother about it. In fact Conda users should be aware that each environment is separated and if you built some app under environment
I would not complicate things here to that degree. First just be aware that updating Second, when we are distributing binaries it is natural to expect the library is installed in the system and can be loaded by OS loader. If we want to distribute binaries for the Conda users we need to prepare and publish Conda package (they have separate package management system) which is separate issue. Anyway I would not distribute Rust app through PyPi/Conda packages. I would use OS specific or universal Unix packages (like Snap or similar). Third if user is brave enough to build an application I would simplify the task to him by ensuring the app can be used in environment it was built for out of the box but not further. For example if it is built under specific Conda or virtualenv it should be usable from this env but not necessary with a system Python. If it is built for a system Python it should be usable with system Python even after library update. But if user switches the environments it is his responsibility to understand what he does. I am writing this I am trying to encourage you to do a simpler solution and save the time because experimenting with a big number of complex setups is time consuming. I would vote for making a trampoline layer for the loading |
Do you mean we should not set But I think setting |
Yes, sure, locally it should work as far as I see. |
According to #748 PyEnv is also affected. |
Yes. It's fundamentally a Python issue, not specific to PyEnv or Conda. It's not even really Pyo3's fault as it's doing what any other application is supposed to do to load a library. The fact that Python's compatibility solution requires multiple entire separate virtual environments is the source of the issue. If we want to fix this we have to "enter through the door" provided by the environment manager. ie. probably by locating the |
Re-reading the issue: I think we had it right last year: #432 (comment)
This should be robust against all python environments and environment switching after build, etc. I wonder if somebody else has already made a nice wrapper to handle this... I didn't see one when I looked last year, but maybe something exists now. UPDATE: Doesn't look like it... My thread PyO3/pyo3#3454 is still the top Google hit for me although I may not be searching with the right terms. |
First thing which comes into my mind is to split REPL on Python extension library and springboard executable and run |
Adding a separate shell script which find correct Python version and runs the binary has many problems. It means user should be aware that |
Either would solve the problem, and you are right that a single binary avoids many of the issues of a trampoline script. A tool If you think it's a high priority, I may be able to try to make something to do this soon (maybe this weekend). *I mean Conda and PyEnv are both essentially crazy hacks to get around the idea that Python is not designed to be self-contained, but real-world uses require multiple versions of Python to be installed. |
Thanks Luke, yes, I think we need to fix it after all. Looks like we found all information we need here. |
I use Conda environment to manage Python versions and dependencies. When I build MeTTa REPL under Conda and try to run it after the build I see the following error:
PyO3 compile against and uses absolutely correct version of the Python library. I don't see any inconsistency here.
According to PyO3/pyo3#1576 when using PyO3 app under Python env one need to add the path to the Python library into
LD_LIBRARY_PATH
. This kind of works but breaks other executables becauselib
directory in Conda env contains other libraries which overrides system library loading paths.Steps to reproduce (Conda is expected to be installed):
The text was updated successfully, but these errors were encountered: