-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
Python 3.11.0 -> 3.11.1 : ...\Python311\DLLs not added to sys.path in embedded startup on Windows #100320
Comments
An also: When I symlink or copy the Python3.12 or 3.11.1 A long error:
Interesting also here is the line
which is the only entry with non-absolute path, thus "double wrong" - which may point back to the initial error issue. |
Prior to 3.11, if Python's home directory can't be determined, then the default value of the "PythonPath" key in the registry gets added to
The value of If the platform library landmark isn't found, then both |
So I guess this needs to be re-established at priority due to a bug introduced from 3.11.0 to .1 : a)
This will solve both issues above (embedded.exe w dynamic loading of python DLL + linked/copied python.exe & .dll) at least as far as to regain the previous function and not break things. In addition, reading the description and the linked doc regarding sys.path initialization (on Windows), the following may be reasonable to add / change in the logic for making it more robust and smart: Regarding,
b) c) d) |
We're also running into this issue. Has anyone figured out a good workaround? Also, how come |
That also works only as far as it sits in the 'home' directory besides
.. and explanations from eryksun and in the linked document. Maybe @zooba @vstinner have an idea what caused the bug?
Like mmomtchev (linked issue/commit) I use 3.11.0 until the bug is hopefully fixed again in 3.11.2 . More are facing this bug. |
I came up with the following workaround for the time being:
|
By the way, Anaconda fork has a similar issue (ignoring |
Part of the change in 3.11.1 is that it no longer searches up from the executable directory to find In 3.10 on Windows, I don't understand the cited reason for not setting # Then add stdlib_dir and platstdlib_dir
if os_name == 'nt' and venv_prefix:
# QUIRK: Windows generates paths differently in a venv
if platstdlib_dir:
pythonpath.append(platstdlib_dir)
if stdlib_dir:
pythonpath.append(stdlib_dir)
if executable_dir not in pythonpath:
pythonpath.append(executable_dir)
else:
if stdlib_dir:
pythonpath.append(stdlib_dir)
if platstdlib_dir:
pythonpath.append(platstdlib_dir) On Windows, I think the above snippet should be modified to remove the # Then add stdlib_dir and platstdlib_dir
if os_name == 'nt':
# QUIRK: Windows uses a different ordering, and it includes the
# directory of the executable.
if platstdlib_dir:
pythonpath.append(platstdlib_dir)
if stdlib_dir:
pythonpath.append(stdlib_dir)
if executable_dir:
pythonpath.append(executable_dir)
else:
if stdlib_dir:
pythonpath.append(stdlib_dir)
if platstdlib_dir:
pythonpath.append(platstdlib_dir) I'd modify the code that sets # Detect exec_prefix by searching from executable for the platstdlib_dir
if PLATSTDLIB_LANDMARK and not exec_prefix:
if executable_dir:
if os_name == 'nt':
# QUIRK: For compatibility and security, do not search for the
# DLLs directory.
if isdir(joinpath(executable_dir, PLATSTDLIB_LANDMARK)):
exec_prefix = executable_dir
else:
exec_prefix = search_up(executable_dir, PLATSTDLIB_LANDMARK, test=isdir)
if not exec_prefix:
if EXEC_PREFIX:
exec_prefix = EXEC_PREFIX
# QUIRK: On Windows, if DLLs isn't found in the executable
# directory, don't warn. Just use the fallback that makes
# exec_prefix the same as prefix, and assume that DLLs exists
# there. If DLLs doesn't exist, an embedding application can place
# extension modules in the directory of the executable, which is
# always in sys.path ahead of site-packages.
elif os_name != 'nt':
warn('Could not find platform dependent libraries <exec_prefix>')
# Fallback: assume exec_prefix == prefix
if not exec_prefix:
exec_prefix = prefix |
There's a lot of discussion here, but fundamentally it seems like the bug is the registry code not loading properly. For the (IMHO, broken) scenario where you have a normal Python install but are trying to use it from a different executable, the registry key is how the stdlib should be found. The better layout is to not just copy the Python executable, but also the libraries that match it.1 We have preferred "adjacent to the executable" since 3.6-ish because it is necessary to be able to run a full copy of Python independent from a "real" install. Before that, you could have had a whole copy of 3.5.5 in one directory and an installed copy of 3.5.1 would break it because the registry key "won". But we shouldn't be breaking the registry here. I'll take a look. I've not been convinced of any of the other changes that are mentioned. Footnotes
|
Looks like I missed the case of reading directly from the Setting |
…utable is not in the expected location.
No, the problem is this change, which I discussed in my previous post and made suggestions to fix. Pythonwin works in 3.11.0 and earlier versions without using the fallback |
There was a lot going on in that post, I didn't come away feeling like I had a fix :) In the past, we never used the library path to find prefix except in the case where the zip file existed (or a [Many revisions later] Okay, I've convinced myself that Eryk's logic for setting With that change, Eryk's change for appending the two/three paths is also good, though we can't assume that |
That cannot happen, unless via the # Then add stdlib_dir and platstdlib_dir
if os_name == 'nt':
# QUIRK: Windows uses a different ordering, and it includes the
# directory of the executable.
if platstdlib_dir:
pythonpath.append(platstdlib_dir)
if stdlib_dir:
pythonpath.append(stdlib_dir)
if executable_dir:
pythonpath.append(executable_dir) |
I wonder what situation I ran into that convinced me otherwise? Hmm |
In any case, the change I just pushed should satisfy things. The only thing we're discussing now is whether |
The code in 3.10 is partly based on the Lines 877 to 910 in a3b6577
Thus it adds In a 3.10 virtual environment, In 3.10, |
Are there tests in CPython test suite which test embedded scenarios? If so, they should be extended with testing native module imports (like ctypes). It seems things got broken multiple times in the past because " |
Yes, but we don't test this scenario because it's not a supported one. If you want to embed Python, embed all of it, or else configure the paths properly when you initialise it. Taking the executable and hoping it will find an existing install isn't the way. |
assuming we want to rely on an existing full install, is there a howto/example of how to "configure the paths properly" which would not have been broken by this issue? |
The example at https://docs.python.org/3/c-api/init_config.html#initialization-with-pyconfig basically shows it, and the rest of that page covers things in more detail. For a full install though, your entry point is So the other way that wouldn't have been broken is to run |
Incidentally, I'd love to hear about these if you have them, because I haven't come across anything before that really needed it (without also needing to control the rest of the Python runtime, i.e. bring their own version). Not knowing makes it hard to factor in the scenarios when we're looking at what can/should/might change. |
…outside of the normal location (GH-100947)
…moved outside of the normal location (pythonGH-100947) (cherry picked from commit df10571) Co-authored-by: Steve Dower <steve.dower@python.org>
…moved outside of the normal location (pythonGH-100947)
Taking the fix as it stands, so we've at least got something. |
…outside of the normal location (GH-100947)
Igor spotted this issue in the context of IDAPython. |
I do this in my app as well. I don't see how I could possibly use the python executable, as I need the interpreter running inside the same address space as the rest of the code so I can have shared access to the same data. Using an existing python library means the user can install Python and their packages any numbers of ways, apt, dnf, pip, msys2, anaconda, homebrew, etc. Why would I want to get into the cross platform Python packaging and installation business?! That's crazy. And it's already been done. |
Bug report
When updating Python 3.11.0 -> 3.11.1 (or reverse to reverse the issue), the
...\Python311\DLLs
folder is suddenly not added anymore to sys.path in embedded startup due to somehow impaired search path algorithm. E.g. inPythonwin.exe
. And thus things like ctypes, socket, hashlib etc. cannot be imported. But...\Python311\Lib
and all the other paths are correctly there, just the DLLs path missing.The same was observed e.g. here:
mhammond/pywin32#1995
The issue is also in current Py 3.12.0a3 at least.
The issue seems not to be with
python.exe
startup.The issue also disappears when I monkey-copy the
Pythonwin.exe
next topython.exe
and use that copy.Note:
Pythonwin.exe
locates pythonNN.dll dynamically and does the usual Python init.And extra confusing: in the registry there is a
PythonPath
key likeC:\Python312\Lib\;C:\Python312\DLLs\
:I always thought that the DLLs path is taken from there. But when I edit-damage that like
C:\Python312\Lib\;C:\Python312\DLLsx\
e.g., it has no effect :-)The correct DLLs dir (only) is still in the sys.path in the above working cases, and
DLLsx
also does not appear on sys.path in the non-working cases.Reproduce:
import ctypes
and/or inspect sys.path after start.Linked PRs
The text was updated successfully, but these errors were encountered: