Skip to content

Commit 5150106

Browse files
committed
Merge branch 'master' of https://github.com/marcusva/py-sdl2
2 parents ff6c1f4 + b943313 commit 5150106

File tree

1 file changed

+52
-6
lines changed

1 file changed

+52
-6
lines changed

sdl2/dll.py

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@
77

88
# Prints warning without stack or line info
99
def prettywarn(msg, warntype):
10-
original = warnings.showwarning
11-
def _warning(message, category, filename, lineno, file=None, line=None):
12-
print(message)
13-
warnings.showwarning = _warning
10+
"""Prints a suppressable warning without stack or line info."""
11+
original = warnings.formatwarning
12+
def _pretty_fmt(message, category, filename, lineno, line=None):
13+
return "{0}: {1}\n".format(category.__name__, message)
14+
warnings.formatwarning = _pretty_fmt
1415
warnings.warn(msg, warntype)
15-
warnings.showwarning = original
16+
warnings.formatwarning = original
1617

1718
# Use DLLs from pysdl2-dll, if installed and DLL path not explicitly set
1819
try:
1920
prepath = os.getenv('PYSDL2_DLL_PATH')
2021
import sdl2dll
2122
postpath = os.getenv('PYSDL2_DLL_PATH')
2223
if prepath != postpath:
23-
msg = "UserWarning: Using SDL2 binaries from pysdl2-dll {0}"
24+
msg = "Using SDL2 binaries from pysdl2-dll {0}"
2425
prettywarn(msg.format(sdl2dll.__version__), UserWarning)
2526
except ImportError:
2627
pass
@@ -36,6 +37,48 @@ class SDL_version(Structure):
3637
]
3738

3839

40+
def _using_ms_store_python():
41+
"""Checks if the Python interpreter was installed from the Microsoft Store."""
42+
return 'WindowsApps\\PythonSoftwareFoundation.' in sys.executable
43+
44+
45+
def _preload_deps(libname, dllpath):
46+
"""Preloads all DLLs that SDL2 and its extensions link to (e.g. libFLAC).
47+
48+
This is required for Python installed from the Microsoft Store, which has
49+
strict DLL loading rules but will allow loading of DLLs that have already
50+
been loaded by the current process.
51+
"""
52+
deps = {
53+
"SDL2": [],
54+
"SDL2_ttf": ["freetype"],
55+
"SDL2_image": ["zlib", "jpeg", "png16", "tiff", "webp"],
56+
"SDL2_mixer": ["modplug", "mpg123", "ogg", "vorbis", "vorbisfile",
57+
"opus", "opusfile", "FLAC"],
58+
"SDL2_gfx": []
59+
}
60+
preloaded = {}
61+
dlldir = os.path.abspath(os.path.join(dllpath, os.pardir))
62+
all_dlls = [f for f in os.listdir(dlldir) if f.split(".")[-1] == "dll"]
63+
for name in deps[libname]:
64+
dllname = name if name == "zlib" else "lib{0}-".format(name)
65+
for dll in all_dlls:
66+
if dll.startswith(dllname):
67+
try:
68+
filepath = os.path.join(dlldir, dll)
69+
preloaded[name] = CDLL(filepath)
70+
except OSError:
71+
pass
72+
break
73+
74+
if len(preloaded) < len(deps[libname]):
75+
e = ("Unable to preload all dependencies for {0}. This module may not "
76+
"work correctly.")
77+
prettywarn(e.format(libname), RuntimeWarning)
78+
79+
return preloaded
80+
81+
3982
def _findlib(libnames, path=None):
4083
"""Finds SDL2 libraries and returns them in a list, with libraries found in the directory
4184
optionally specified by 'path' being first (taking precedence) and libraries found in system
@@ -98,6 +141,7 @@ class DLL(object):
98141
"""
99142
def __init__(self, libinfo, libnames, path=None):
100143
self._dll = None
144+
self._deps = None
101145
self._libname = libinfo
102146
self._version = None
103147
minversions = {
@@ -133,6 +177,8 @@ def __init__(self, libinfo, libnames, path=None):
133177
if self._dll is None:
134178
raise RuntimeError("found %s, but it's not usable for the library %s" %
135179
(foundlibs, libinfo))
180+
if _using_ms_store_python():
181+
self._deps = _preload_deps(libinfo, self._libfile)
136182
if path is not None and sys.platform in ("win32",) and \
137183
path in self._libfile:
138184
os.environ["PATH"] = "%s;%s" % (path, os.environ["PATH"])

0 commit comments

Comments
 (0)