Skip to content

Commit

Permalink
_win32sysloader now uses the same LoadLibrary flags as Python itself (f…
Browse files Browse the repository at this point in the history
…ixes #1787) (#1794)
  • Loading branch information
mhammond authored Dec 19, 2021
1 parent 15ab409 commit 0a1d405
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Note that build 228 was the last version supporting Python 2.

Since build 302:
----------------
* Tweaks to how DLLs are loaded and our installation found, which should
improve virtualenv support and version mismatch issues (#1787, #1794)

* Binary installers for 32-bit 3.10+ are no longer released (#1805)

Since build 301:
Expand Down
24 changes: 18 additions & 6 deletions win32/Lib/pywintypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,32 @@ def __import_pywin32_system_module__(modname, globs):
# easy_install...
if os.path.isfile(os.path.join(os.path.dirname(__file__), filename)):
found = os.path.join(os.path.dirname(__file__), filename)

# There are 2 site-packages directories - one "global" and one "user".
# We could be in either, or both (but with different versions!). Factors include
# virtualenvs, post-install script being run or not, `setup.py install` flags, etc.

# In a worst-case, it means, say 'python -c "import win32api"'
# will not work but 'python -c "import pywintypes, win32api"' will,
# but it's better than nothing.
# We prefer the "user" site-packages if it exists...
if found is None:
import site

maybe = os.path.join(site.USER_SITE, "pywin32_system32", filename)
if os.path.isfile(maybe):
found = maybe

# Or the "global" site-packages.
if found is None:
# We might have been installed via PIP and without the post-install
# script having been run, so they might be in the
# lib/site-packages/pywin32_system32 directory.
# This isn't ideal as it means, say 'python -c "import win32api"'
# will not work but 'python -c "import pywintypes, win32api"' will,
# but it's better than nothing...
import sysconfig

maybe = os.path.join(
sysconfig.get_paths()["platlib"], "pywin32_system32", filename
)
if os.path.isfile(maybe):
found = maybe

if found is None:
# give up in disgust.
raise ImportError("No system module '%s' (%s)" % (modname, filename))
Expand Down
11 changes: 10 additions & 1 deletion win32/src/_win32sysloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,17 @@ static PyObject *PyLoadModule(PyObject *self, PyObject *args)
TCHAR *modName = NULL;
if (!PyArg_ParseTuple(args, fmt, &modName))
return NULL;
HINSTANCE hinst = LoadLibrary(modName);

// Python 3.7 vs 3.8 use different flags for LoadLibraryEx and we match them.
// See github issue 1787.
#if (PY_VERSION_HEX < 0x03080000)
HINSTANCE hinst = LoadLibraryEx(modName, NULL,
LOAD_WITH_ALTERED_SEARCH_PATH);
#else
HINSTANCE hinst = LoadLibraryEx(modName, NULL,
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
#endif
if (hinst == NULL) {
Py_INCREF(Py_None);
return Py_None;
Expand Down

0 comments on commit 0a1d405

Please sign in to comment.