Repository: pyinstaller/pyinstaller

Issue:
'six' is required; worked fine with previous version of pyinstaller
I get this when I run the built executable. It worked fine when built with the previous version of `pyinstaller`.

```
Traceback (most recent call last):
  File "<string>", line 11, in <module>
  File "/usr/lib/python3.5/site-packages/PyInstaller/loader/pyimod03_importers.py", line 363, in load_module
    exec(bytecode, module.__dict__)
  File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 48, in <module>
    from pkg_resources.extern import six
  File "/usr/lib/python3.5/site-packages/pkg_resources/extern/__init__.py", line 60, in load_module
    "distribution.".format(**locals())
ImportError: The 'six' package is required; normally this is bundled with this package so if you get this warning, consult the packager of your distribution.
pyi_rth_pkgres returned -1
```

'six' is required; worked fine with previous version of pyinstaller
I get this when I run the built executable. It worked fine when built with the previous version of `pyinstaller`.

```
Traceback (most recent call last):
  File "<string>", line 11, in <module>
  File "/usr/lib/python3.5/site-packages/PyInstaller/loader/pyimod03_importers.py", line 363, in load_module
    exec(bytecode, module.__dict__)
  File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 48, in <module>
    from pkg_resources.extern import six
  File "/usr/lib/python3.5/site-packages/pkg_resources/extern/__init__.py", line 60, in load_module
    "distribution.".format(**locals())
ImportError: The 'six' package is required; normally this is bundled with this package so if you get this warning, consult the packager of your distribution.
pyi_rth_pkgres returned -1
```



Discussion:
To solve, in spec file, I hadd to add the followings in hidden imports:

hiddenimports=['six','packaging', 'packaging.version', 'packaging.specifiers'],

This seams to be an issue with setuptools 19.3, see https://github.com/pyinstaller/pyinstaller/issues/1772#issuecomment-172467268. Please try downgrading setuptools to 19.2 and report back if this solved the issue in your case, too.

Downgrading to setuptools==19.2 fixed this issue for me.

Same problem here, I fixed this with a new hook script for the vendor hack inside pkg_resources:

``` diff
(loco2-precise)torsten.landschoff@horatio:~/opensrc/pyinstaller$ git diff --cached
diff --git a/PyInstaller/hooks/hook-pkg_resources.py b/PyInstaller/hooks/hook-pkg_resources.py
new file mode 100644
index 0000000..cff9036
--- /dev/null
+++ b/PyInstaller/hooks/hook-pkg_resources.py
@@ -0,0 +1,6 @@
+def list_vendored_modules():
+    from pkgutil import walk_packages
+    import pkg_resources._vendor
+    return ["pkg_resources._vendor.{1}".format(*x) for x in walk_packages(pkg_resources._vendor.__path__)]
+
+hiddenimports = list_vendored_modules()
```

@Bluehorn Would you pleas be so kind submitting a pull-request, so you'll get the credits for this fix. (I'm going to prepare release 3.1.1 in the meanwhile).

@Bluehorn Just a quick question: This code basically collects `pkg_resources._vendor` and all sub-modules? Correct? So if you are going to issue a pull-request, please use 

```
from PyInstaller.utils.hooks import collect_submodules
hiddenimports = collect_submodules('pkg_resources._vendor')
```

@htgoebel Thanks, I did not know of `collect_submodules`.

To solve, in spec file, I hadd to add the followings in hidden imports:

hiddenimports=['six','packaging', 'packaging.version', 'packaging.specifiers'],

This seams to be an issue with setuptools 19.3, see https://github.com/pyinstaller/pyinstaller/issues/1772#issuecomment-172467268. Please try downgrading setuptools to 19.2 and report back if this solved the issue in your case, too.

Downgrading to setuptools==19.2 fixed this issue for me.

Same problem here, I fixed this with a new hook script for the vendor hack inside pkg_resources:

``` diff
(loco2-precise)torsten.landschoff@horatio:~/opensrc/pyinstaller$ git diff --cached
diff --git a/PyInstaller/hooks/hook-pkg_resources.py b/PyInstaller/hooks/hook-pkg_resources.py
new file mode 100644
index 0000000..cff9036
--- /dev/null
+++ b/PyInstaller/hooks/hook-pkg_resources.py
@@ -0,0 +1,6 @@
+def list_vendored_modules():
+    from pkgutil import walk_packages
+    import pkg_resources._vendor
+    return ["pkg_resources._vendor.{1}".format(*x) for x in walk_packages(pkg_resources._vendor.__path__)]
+
+hiddenimports = list_vendored_modules()
```

@Bluehorn Would you pleas be so kind submitting a pull-request, so you'll get the credits for this fix. (I'm going to prepare release 3.1.1 in the meanwhile).

@Bluehorn Just a quick question: This code basically collects `pkg_resources._vendor` and all sub-modules? Correct? So if you are going to issue a pull-request, please use 

```
from PyInstaller.utils.hooks import collect_submodules
hiddenimports = collect_submodules('pkg_resources._vendor')
```

@htgoebel Thanks, I did not know of `collect_submodules`.


Resolving patch:
diff --git a/PyInstaller/hooks/hook-pkg_resources.py b/PyInstaller/hooks/hook-pkg_resources.py
new file mode 100644
--- /dev/null
+++ b/PyInstaller/hooks/hook-pkg_resources.py
@@ -0,0 +1,5 @@
+from PyInstaller.utils.hooks import collect_submodules
+
+# pkg_resources keeps vendored modules in its _vendor subpackage, and does
+# sys.meta_path based import magic to expose them as pkg_resources.extern.*
+hiddenimports = collect_submodules('pkg_resources._vendor')


Test patch:
diff --git a/tests/functional/scripts/pyi_hooks/use_pkg_resources.py b/tests/functional/scripts/pyi_hooks/use_pkg_resources.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/scripts/pyi_hooks/use_pkg_resources.py
@@ -0,0 +1,3 @@
+import pkg_resources
+
+pkg_resources.working_set.require()
diff --git a/tests/functional/test_hooks/test_pkg_resources.py b/tests/functional/test_hooks/test_pkg_resources.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/test_hooks/test_pkg_resources.py
@@ -0,0 +1,8 @@
+from PyInstaller.utils.tests import importorskip
+
+@importorskip('pkg_resources')
+def test_pkg_resources_importable(pyi_builder):
+    """
+    Check that a trivial example using pkg_resources does build.
+    """
+    pyi_builder.test_script('pyi_hooks/use_pkg_resources.py')