Re: [Pyobjc-dev] py2app release delayed

Barry Scott <[email protected]> Tue, 10 Jan 2017 16:00:17 +0000
Newsgroups gmane.comp.python.apple
Message-ID <[email protected]>
Ronald,

Attached is a patch that cleans up the false positives by allows the recipes to tell build_app what is expected to be missing.

I can turn into a pull request if you like the direction of this patch.

Oh and the syntax errors in PyQt5 have been fixes for the 5.7.1 version.

Barry

_______________________________________________
Pythonmac-SIG maillist  -  [email protected]
https://mail.python.org/mailman/listinfo/pythonmac-sig
unsubscribe: https://mail.python.org/mailman/options/Pythonmac-SIG
py2app_expected_missing_imports.patch (application/octet-stream, 7 KB)
diff -r d3f3d531abc1 py2app/build_app.py
--- a/py2app/build_app.py	Mon Dec 26 07:23:31 2016 -0800
+++ b/py2app/build_app.py	Tue Jan 10 15:56:23 2017 +0000
@@ -458,6 +458,8 @@
         self.no_report_missing_conditional_import = False
         self.redirect_stdout_to_asl = False
         self._python_app = None
+        self.expected_missing_imports = set( ['org', 'java'] )
+
 
     def finalize_options (self):
         if os.path.exists(os.path.join(sys.prefix, 'pyvenv.cfg')):
@@ -886,6 +888,9 @@
                 del rdict[name]
                 print('*** using recipe: %s ***' % (name,))
 
+                if 'expected_missing_imports' in rval:
+                    self.expected_missing_imports |= rval.get('expected_missing_imports')
+
                 if rval.get('packages'):
                     self.packages.update(rval['packages'])
                     find_needed_modules(mf, packages=rval['packages'])
@@ -998,6 +1003,15 @@
             for pkg in self.packages
         ]))
 
+    def may_log_missing(self, module_name):
+        module_parts = module_name.split('.')
+        for num_parts in range(1,len(module_parts)+1):
+            module_id = '.'.join(module_parts[0:num_parts])
+            if module_id in self.expected_missing_imports:
+                return False
+
+        return True
+
     def run_normal(self):
         mf = self.get_modulefinder()
         filters = self.collect_filters()
@@ -1040,7 +1054,7 @@
             missing_fromimport_conditional = collections.defaultdict(set)
             missing_conditional = collections.defaultdict(set)
 
-
+            log.info( 'QQQ finding missing' )
             for module in sorted(missing):
                 for m in mf.getReferers(module):
                     if m is None: continue # XXX
@@ -1076,7 +1090,8 @@
                             try:
                                 o = getattr(o, m2)
                             except AttributeError:
-                                log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_unconditional[m]))))
+                                if self.may_log_missing(m):
+                                    log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_unconditional[m]))))
                                 continue
 
 
@@ -1084,10 +1099,12 @@
                             o = __import__(m)
 
                         if isinstance(o, types.ModuleType):
-                            log.warn(" * %s (%s) [module alias]" % (m, ", ".join(sorted(missing_unconditional[m]))))
+                            if self.may_log_missing(m):
+                                log.warn(" * %s (%s) [module alias]" % (m, ", ".join(sorted(missing_unconditional[m]))))
 
                     except ImportError:
-                        log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_unconditional[m]))))
+                        if self.may_log_missing(m):
+                            log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_unconditional[m]))))
                 log.warn("")
 
 
@@ -1101,7 +1118,8 @@
                             try:
                                 o = getattr(o, m2)
                             except AttributeError:
-                                log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_unconditional[m]))))
+                                if self.may_log_missing(m):
+                                    log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_unconditional[m]))))
                                 continue
 
 
@@ -1111,7 +1129,8 @@
                         if isinstance(o, types.ModuleType):
                             log.warn(" * %s (%s) [module alias]" % (m, ", ".join(sorted(missing_unconditional[m]))))
                     except ImportError:
-                        log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_conditional[m]))))
+                        if self.may_log_missing(m):
+                            log.warn(" * %s (%s)" % (m, ", ".join(sorted(missing_conditional[m]))))
                 log.warn("")
 
             if self.report_missing_from_imports and (
diff -r d3f3d531abc1 py2app/recipes/__init__.py
--- a/py2app/recipes/__init__.py	Mon Dec 26 07:23:31 2016 -0800
+++ b/py2app/recipes/__init__.py	Tue Jan 10 15:56:23 2017 +0000
@@ -4,7 +4,9 @@
 from . import ftplib
 from . import lxml
 from . import matplotlib
+from . import mimetypes
 from . import numpy
+from . import os
 from . import pydoc
 from . import pyenchant
 from . import pygame
@@ -12,8 +14,10 @@
 from . import pyside
 from . import pyzmq
 from . import qt5
+from . import re
 from . import scipy
 from . import sip
+from . import subprocess
 from . import virtualenv
 from . import wx
 from . import xml
diff -r d3f3d531abc1 py2app/recipes/mimetypes.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/py2app/recipes/mimetypes.py	Tue Jan 10 15:56:23 2017 +0000
@@ -0,0 +1,4 @@
+def check(cmd, mf):
+    m = mf.findNode('mimetypes')
+    if m:
+        return dict(expected_missing_imports=set(['winreg']))
diff -r d3f3d531abc1 py2app/recipes/os.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/py2app/recipes/os.py	Tue Jan 10 15:56:23 2017 +0000
@@ -0,0 +1,4 @@
+def check(cmd, mf):
+    m = mf.findNode('os')
+    if m:
+        return dict(expected_missing_imports=set(['nt']))
diff -r d3f3d531abc1 py2app/recipes/pkg_resources.py
--- a/py2app/recipes/pkg_resources.py	Mon Dec 26 07:23:31 2016 -0800
+++ b/py2app/recipes/pkg_resources.py	Tue Jan 10 15:56:23 2017 +0000
@@ -5,4 +5,7 @@
     for pkg in [
             'packaging', 'pyparsing', 'six', 'appdirs' ]:
         mf.import_hook('pkg_resources._vendor.' + pkg, m, ['*'])
-    return dict()
+    return dict(expected_missing_imports=set(
+            ['pkg_resources.extern.pyparsing',
+             'pkg_resources.extern.six',
+             'pkg_resources._vendor.appdirs']))
diff -r d3f3d531abc1 py2app/recipes/qt5.py
--- a/py2app/recipes/qt5.py	Mon Dec 26 07:23:31 2016 -0800
+++ b/py2app/recipes/qt5.py	Tue Jan 10 15:56:23 2017 +0000
@@ -1,3 +1,5 @@
+import sys
+
 def check(cmd, mf):
     m = mf.findNode('PyQt5')
     if m:
@@ -16,6 +18,10 @@
         # 2. Use of other modules, datafiles and C libraries
         #    in the PyQt5 package.
         mf.import_hook('sip', m)
-        return dict(packages=['PyQt5'])
+        if sys.version[0] != 2:
+            return dict(packages=['PyQt5'],
+                        expected_missing_imports=set(['copy_reg', 'cStringIO', 'StringIO']))
+        else:
+            return dict(packages=['PyQt5'])
 
     return None
diff -r d3f3d531abc1 py2app/recipes/re.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/py2app/recipes/re.py	Tue Jan 10 15:56:23 2017 +0000
@@ -0,0 +1,4 @@
+def check(cmd, mf):
+    m = mf.findNode('re')
+    if m:
+        return dict(expected_missing_imports=set(['sys.getwindowsversion']))
diff -r d3f3d531abc1 py2app/recipes/subprocess.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/py2app/recipes/subprocess.py	Tue Jan 10 15:56:23 2017 +0000
@@ -0,0 +1,4 @@
+def check(cmd, mf):
+    m = mf.findNode('subprocess')
+    if m:
+        return dict(expected_missing_imports=set(['_winapi']))