guetzli-recursively-gui/.eggs/py2app-0.12-py3.6.egg/py2app/recipes/sip.py

149 lines
5.1 KiB
Python
Raw Normal View History

2017-04-20 00:57:59 +02:00
"""
Py2app support for project using sip, which basicly means PyQt and wrappers
for other Qt-based libraries.
This will include all C modules that might be used when you import a package
using sip because we have no way to fine-tune this.
The problem with SIP is that all inter-module depedencies (for example from
PyQt4.Qt to PyQt4.QtCore) are handled in C code and therefore cannot be
detected by the python code in py2app).
"""
# since pkg_resources.py lives next to this file, we need to disambiguate the import
from __future__ import absolute_import
import sys
import glob
import os
import pkg_resources
class Sip(object):
def __init__(self):
self.packages = None
self.plugin_dir = None
def config(self):
if self.packages is not None:
print("packages", self.packages)
return self.packages
import sipconfig, os
try:
from PyQt4 import pyqtconfig
cfg = pyqtconfig.Configuration()
qtdir = cfg.qt_lib_dir
sipdir = os.path.dirname(cfg.pyqt_mod_dir)
self.plugin_dir = os.path.join(cfg.qt_dir, 'plugins')
except ImportError:
from PyQt5.QtCore import QLibraryInfo
qtdir = QLibraryInfo.location(QLibraryInfo.LibrariesPath)
self.plugin_dir = QLibraryInfo.location(QLibraryInfo.PluginsPath)
sipdir = os.path.dirname(sipconfig.__file__)
if not os.path.exists(qtdir):
print("sip: Qtdir %r does not exist"%(qtdir))
# half-broken installation? ignore.
raise ImportError
# Qt is GHETTO!
dyld_library_path = os.environ.get('DYLD_LIBRARY_PATH', '').split(':')
if qtdir not in dyld_library_path:
dyld_library_path.insert(0, qtdir)
os.environ['DYLD_LIBRARY_PATH'] = ':'.join(dyld_library_path)
self.packages = set()
for fn in os.listdir(sipdir):
fullpath = os.path.join(sipdir, fn)
if os.path.isdir(fullpath):
self.packages.add(fn)
if fn in ('PyQt4', 'PyQt5'):
# PyQt4 and later has a nested structure, also import
# subpackage to ensure everything get seen.
for sub in os.listdir(fullpath):
if ".py" not in sub:
self.packages.add('%s.%s'%(fn, sub.replace(".so","")))
# Causes a python3-related syntax error (metaclass keyword),
# and you probably don't need it:
#if "PyQt4.uic" in self.packages and sys.version_info.major != 3:
# print("WARNING: PyQt uic module found.")
# print("avoid python3 metaclass syntax errors by adding 'PyQt4.uic' to your excludes option.")
print("sip: packages: %s"%(self.packages,))
return self.packages
def check(self, cmd, mf):
try:
packages = self.config()
except ImportError:
return None
if 'PyQt4.uic' in packages:
# PyQt4.uic contains subpackages with python 2 and python 3
# support. Exclude the variant that won't be ussed, this avoids
# compilation errors on Python 2 (because some of the Python 3
# code is not valid Python 2 code)
if sys.version_info[0] == 2:
ref = 'PyQt4.uic.port_v3'
else:
ref = 'PyQt4.uic.port_v2'
if 'PyQt5.uic' in packages:
# ditto
if sys.version_info[0] == 2:
ref = 'PyQt5.uic.port_v3'
else:
ref = 'PyQt5.uic.port_v2'
# Exclude...
mf.lazynodes[ref] = None
for pkg in packages:
m = mf.findNode(pkg)
if m is not None and m.filename is not None:
break
else:
print("sip: No sip package used in application")
return None
mf.import_hook('sip', m)
m = mf.findNode('sip')
# naive inclusion of ALL sip packages
# stupid C modules.. hate hate hate
for pkg in packages:
try:
mf.import_hook(pkg, m)
except ImportError as exc:
print("WARNING: ImportError in sip recipe ignored: %s"%(exc,))
print(mf.findNode("PyQt4"))
print(mf.findNode("PyQt5"))
if mf.findNode('PyQt4') is not None or mf.findNode('PyQt5') is not None:
resources = [pkg_resources.resource_filename('py2app', 'recipes/qt.conf')]
for item in cmd.qt_plugins:
if '/' not in item:
item = item + '/*'
if '*' in item:
for path in glob.glob(os.path.join(self.plugin_dir, item)):
resources.append((os.path.dirname('qt_plugins' + path[len(self.plugin_dir):]), [path]))
else:
resources.append((os.path.dirname(os.path.join('qt_plugins', item)), [os.path.join(self.plugin_dir, item)]))
print("PyQt resources", resources)
return dict(resources=resources)
print("Return {}")
return dict()
check = Sip().check