diff --git a/PyInstaller/building/api.py b/PyInstaller/building/api.py index 02d5c30a9fe..60e81be2d1e 100644 --- a/PyInstaller/building/api.py +++ b/PyInstaller/building/api.py @@ -42,6 +42,16 @@ from PyInstaller.utils.win32 import winmanifest, icon, versioninfo, winresource +def _is_libdynload_extension(typ, dst, src): + """ + Determines if the given TOC entry is an EXTENSION coming from + python's lib-dynload directory. + """ + return typ == 'EXTENSION' \ + and not os.path.dirname(os.path.normpath(dst)) \ + and os.path.basename(os.path.dirname(src)) == 'lib-dynload' + + class PYZ(Target): """ Creates a ZlibArchive that contains all pure Python modules. @@ -233,6 +243,11 @@ def assemble(self): # file is contained within python egg, it is added with the egg continue if typ in ('BINARY', 'EXTENSION', 'DEPENDENCY'): + if _is_libdynload_extension(typ, inm, fnm): + # Place extensions that originate from python's + # lib-dynload directory into _MEIPASS/lib-dynload + # instead of directly into _MEIPASS + inm = os.path.join('lib-dynload', inm) if self.exclude_binaries and typ == 'EXTENSION': self.dependencies.append((inm, fnm, typ)) elif not self.exclude_binaries or typ == 'DEPENDENCY': @@ -734,7 +749,13 @@ def assemble(self): or os.path.isabs(inm): raise SystemExit('Security-Alert: try to store file outside ' 'of dist-directory. Aborting. %r' % inm) - tofnm = os.path.join(self.name, inm) + if _is_libdynload_extension(typ, inm, fnm): + # Place extensions that originate from python's + # lib-dynload directory into _MEIPASS/lib-dynload + # instead of directly into _MEIPASS + tofnm = os.path.join(self.name, 'lib-dynload', inm) + else: + tofnm = os.path.join(self.name, inm) todir = os.path.dirname(tofnm) if not os.path.exists(todir): os.makedirs(todir)