prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Python3.4 PyQt5 QML application requires environment variables
  With the PyQt5 fixes merged https://github.com/pyinstaller/pyinstaller/pull/3439 I decided to try creating an executable that I have been having trouble with. https://github.com/pyinstaller/pyinstaller/pull/3439#issuecomment-379064155
  
  This is the source code https://github.com/Siecje/qml-testing/tree/PyInstaller
  
  I'm using
  - Windows 7 32-bit
  - Qt 5.10.1
  - PyQt5 compiled from source
  - Python 3.4.4
  - pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
  When I run the .exe I get an error
  
  ```
  QWindowsEGLStaticContext::create: Failed to load and resolve libEGL function
  Failed to load opengl32sw.dll (The specified module could not be found.)
  Failed to load and resolve WGL/OpenGL functions
  Failed to create OpenGL context for format QsurfaceFormat(version 2.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize 24, ...<snip>
  This is most likely caused by not having the necessary graphics drivers installed.
  
  Install a driver providing OpenGL 2.0 or higher, or, if this is not possible, make sure the ANGLE Open GL ES 2.0 emulation libraries (libEGL.dll, libLESv2.dll and d3dcompiler_*.dll) are available in the application executabl's directory or in a location listed in PATH.
  ```
  
  To run the application I can copy these four .dlls into the `dist\main\` directory.
  
  - libEGL.dll
  - libGLESv2.dll
  - d3dcompiler_47.dll
  - opengl32sw.dll
  
  When I run it I get Command Prompt window with this output.
  ```
  QWindowsWGLStaticContext::create: Could not initialize EGL display: error 0x3001
  QWindowsWGLStaticContext::create: When using ANGLE, check if d3dcompiler_4x.dll is available.
  ```
  Instead of copying those .dll files I can add the Qt bin directory to my PATH.
  
  ```
  set PATH=%PATH%;C:\Qt\5.10.1\msvc2015\bin
  call main.exe
  QWindowsWGLStaticContext::create: Could not initialize EGL display: error 0x3001
  QWindowsWGLStaticContext::create: When using ANGLE, check if d3dcompiler_4x.dll is available.
  ```
  
  When I copy the `dist\main\` to another computer (Windows 10).
  
  I have to set two environment variables before the application will work.
  
  ```
  set QT_QPA_PLATFORM_PLUGIN_PATH=%exeDir%\PyQt5\Qt\plugins\platforms
  set QML2_IMPORT_PATH=%exeDir%\PyQt5\Qt\qml
  ```
  
  There are no error messages on the Windows 10 computer with these two environment variables set.
  
  </issue>
  <code>
  [start of PyInstaller/hooks/hook-PyQt5.py]
  1 #-----------------------------------------------------------------------------
  2 # Copyright (c) 2005-2018, PyInstaller Development Team.
  3 #
  4 # Distributed under the terms of the GNU General Public License with exception
  5 # for distributing bootloader.
  6 #
  7 # The full license is in the file COPYING.txt, distributed with this software.
  8 #-----------------------------------------------------------------------------
  9 import os
  10 
  11 from PyInstaller.utils.hooks import pyqt5_library_info, collect_system_data_files
  12 
  13 hiddenimports = ['sip']
  14 
  15 # Collect the ``qt.conf`` file.
  16 datas = [x for x in
  17          collect_system_data_files(pyqt5_library_info.location['PrefixPath'],
  18                                    'PyQt5')
  19          if os.path.basename(x[0]) == 'qt.conf']
  20 
  21 # Include ICU files, if they exist. See the "Deployment approach" section in
  22 # ``PyInstaller/utils/hooks/qt.py``.
  23 [(os.path.join(pyqt5_library_info.location['BinariesPath'], dll),
  24   os.path.join('PyQt5', 'Qt', 'bin', dll))
  25  for dll in ('icudt??.dll', 'icuin??.dll', 'icuuc??.dll')]
  26 
  27 # TODO: Include software rendering for OpenGL. See the "Deployment approach". However, because the standard PyQt5 wheel `doesn't include <https://www.riverbankcomputing.com/pipermail/pyqt/2018-June/040387.html>`_ ``d3dcompiler_XX.dll``, this produces failures. When the wheel is updated, this code can be uncommented.
  28 ##binaries = []
  29 ##for dll in ('libEGL.dll', 'libGLESv2.dll', 'd3dcompiler_??.dll', 'opengl32sw.dll'):
  30 ##    dll_path = os.path.join(pyqt5_library_info.location['BinariesPath'], dll)
  31 ##    # Only add files if they exist.
  32 ##    if glob(dll_path):
  33 ##        binaries += [(dll_path, os.path.join('PyQt5', 'Qt', 'bin', dll))]
  34
  [end of PyInstaller/hooks/hook-PyQt5.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/PyInstaller/hooks/hook-PyQt5.py b/PyInstaller/hooks/hook-PyQt5.py
  --- a/PyInstaller/hooks/hook-PyQt5.py
  +++ b/PyInstaller/hooks/hook-PyQt5.py
  @@ -6,6 +6,7 @@
   #
   # The full license is in the file COPYING.txt, distributed with this software.
   #-----------------------------------------------------------------------------
  +import glob
   import os
   
   from PyInstaller.utils.hooks import pyqt5_library_info, collect_system_data_files
  @@ -18,16 +19,42 @@
                                      'PyQt5')
            if os.path.basename(x[0]) == 'qt.conf']
   
  -# Include ICU files, if they exist. See the "Deployment approach" section in
  -# ``PyInstaller/utils/hooks/qt.py``.
  -[(os.path.join(pyqt5_library_info.location['BinariesPath'], dll),
  -  os.path.join('PyQt5', 'Qt', 'bin', dll))
  - for dll in ('icudt??.dll', 'icuin??.dll', 'icuuc??.dll')]
  -
  -# TODO: Include software rendering for OpenGL. See the "Deployment approach". However, because the standard PyQt5 wheel `doesn't include <https://www.riverbankcomputing.com/pipermail/pyqt/2018-June/040387.html>`_ ``d3dcompiler_XX.dll``, this produces failures. When the wheel is updated, this code can be uncommented.
  -##binaries = []
  -##for dll in ('libEGL.dll', 'libGLESv2.dll', 'd3dcompiler_??.dll', 'opengl32sw.dll'):
  -##    dll_path = os.path.join(pyqt5_library_info.location['BinariesPath'], dll)
  -##    # Only add files if they exist.
  -##    if glob(dll_path):
  -##        binaries += [(dll_path, os.path.join('PyQt5', 'Qt', 'bin', dll))]
  +
  +def find_all_or_none(globs_to_include, num_files):
  +    """
  +    globs_to_include is a list of file name globs
  +    If the number of found files does not match num_files
  +    then no files will be included.
  +    """
  +    # TODO: This function is required because CI is failing to include libEGL
  +    # The error in AppVeyor is:
  +    # [2312] LOADER: Running pyi_lib_PyQt5-uic.py
  +    # Failed to load libEGL (Access is denied.)
  +    # More info: https://github.com/pyinstaller/pyinstaller/pull/3568
  +    # Since the PyQt5 wheels do not include d3dcompiler_4?.dll, libEGL.dll and
  +    # libGLESv2.dll will not be included for PyQt5 builds during CI.
  +    to_include = []
  +    for dll in globs_to_include:
  +        dll_path = os.path.join(pyqt5_library_info.location['BinariesPath'],
  +                                dll)
  +        dll_file_paths = glob.glob(dll_path)
  +        for dll_file_path in dll_file_paths:
  +            file_name = os.path.basename(dll_file_path)
  +            dst_dll_path = os.path.join('PyQt5', 'Qt', 'bin', file_name)
  +            to_include.append((dll_file_path, dst_dll_path))
  +    if len(to_include) == num_files:
  +        return to_include
  +    return []
  +
  +
  +binaries = []
  +angle_files = ['libEGL.dll', 'libGLESv2.dll', 'd3dcompiler_??.dll']
  +binaries += find_all_or_none(angle_files, 3)
  +
  +opengl_software_renderer = ['opengl32sw.dll']
  +binaries += find_all_or_none(opengl_software_renderer, 1)
  +
  +# Include ICU files, if they exist.
  +# See the "Deployment approach" section in ``PyInstaller/utils/hooks/qt.py``.
  +icu_files = ['icudt??.dll', 'icuin??.dll', 'icuuc??.dll']
  +binaries += find_all_or_none(icu_files, 3)
  
verification_info: {"golden_diff": "diff --git a/PyInstaller/hooks/hook-PyQt5.py b/PyInstaller/hooks/hook-PyQt5.py\n--- a/PyInstaller/hooks/hook-PyQt5.py\n+++ b/PyInstaller/hooks/hook-PyQt5.py\n@@ -6,6 +6,7 @@\n #\n # The full license is in the file COPYING.txt, distributed with this software.\n #-----------------------------------------------------------------------------\n+import glob\n import os\n \n from PyInstaller.utils.hooks import pyqt5_library_info, collect_system_data_files\n@@ -18,16 +19,42 @@\n                                    'PyQt5')\n          if os.path.basename(x[0]) == 'qt.conf']\n \n-# Include ICU files, if they exist. See the \"Deployment approach\" section in\n-# ``PyInstaller/utils/hooks/qt.py``.\n-[(os.path.join(pyqt5_library_info.location['BinariesPath'], dll),\n-  os.path.join('PyQt5', 'Qt', 'bin', dll))\n- for dll in ('icudt??.dll', 'icuin??.dll', 'icuuc??.dll')]\n-\n-# TODO: Include software rendering for OpenGL. See the \"Deployment approach\". However, because the standard PyQt5 wheel `doesn't include <https://www.riverbankcomputing.com/pipermail/pyqt/2018-June/040387.html>`_ ``d3dcompiler_XX.dll``, this produces failures. When the wheel is updated, this code can be uncommented.\n-##binaries = []\n-##for dll in ('libEGL.dll', 'libGLESv2.dll', 'd3dcompiler_??.dll', 'opengl32sw.dll'):\n-##    dll_path = os.path.join(pyqt5_library_info.location['BinariesPath'], dll)\n-##    # Only add files if they exist.\n-##    if glob(dll_path):\n-##        binaries += [(dll_path, os.path.join('PyQt5', 'Qt', 'bin', dll))]\n+\n+def find_all_or_none(globs_to_include, num_files):\n+    \"\"\"\n+    globs_to_include is a list of file name globs\n+    If the number of found files does not match num_files\n+    then no files will be included.\n+    \"\"\"\n+    # TODO: This function is required because CI is failing to include libEGL\n+    # The error in AppVeyor is:\n+    # [2312] LOADER: Running pyi_lib_PyQt5-uic.py\n+    # Failed to load libEGL (Access is denied.)\n+    # More info: https://github.com/pyinstaller/pyinstaller/pull/3568\n+    # Since the PyQt5 wheels do not include d3dcompiler_4?.dll, libEGL.dll and\n+    # libGLESv2.dll will not be included for PyQt5 builds during CI.\n+    to_include = []\n+    for dll in globs_to_include:\n+        dll_path = os.path.join(pyqt5_library_info.location['BinariesPath'],\n+                                dll)\n+        dll_file_paths = glob.glob(dll_path)\n+        for dll_file_path in dll_file_paths:\n+            file_name = os.path.basename(dll_file_path)\n+            dst_dll_path = os.path.join('PyQt5', 'Qt', 'bin', file_name)\n+            to_include.append((dll_file_path, dst_dll_path))\n+    if len(to_include) == num_files:\n+        return to_include\n+    return []\n+\n+\n+binaries = []\n+angle_files = ['libEGL.dll', 'libGLESv2.dll', 'd3dcompiler_??.dll']\n+binaries += find_all_or_none(angle_files, 3)\n+\n+opengl_software_renderer = ['opengl32sw.dll']\n+binaries += find_all_or_none(opengl_software_renderer, 1)\n+\n+# Include ICU files, if they exist.\n+# See the \"Deployment approach\" section in ``PyInstaller/utils/hooks/qt.py``.\n+icu_files = ['icudt??.dll', 'icuin??.dll', 'icuuc??.dll']\n+binaries += find_all_or_none(icu_files, 3)\n", "issue": "Python3.4 PyQt5 QML application requires environment variables\nWith the PyQt5 fixes merged https://github.com/pyinstaller/pyinstaller/pull/3439 I decided to try creating an executable that I have been having trouble with. https://github.com/pyinstaller/pyinstaller/pull/3439#issuecomment-379064155\r\n\r\nThis is the source code https://github.com/Siecje/qml-testing/tree/PyInstaller\r\n\r\nI'm using\r\n- Windows 7 32-bit\r\n- Qt 5.10.1\r\n- PyQt5 compiled from source\r\n- Python 3.4.4\r\n- pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip\r\nWhen I run the .exe I get an error\r\n\r\n```\r\nQWindowsEGLStaticContext::create: Failed to load and resolve libEGL function\r\nFailed to load opengl32sw.dll (The specified module could not be found.)\r\nFailed to load and resolve WGL/OpenGL functions\r\nFailed to create OpenGL context for format QsurfaceFormat(version 2.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize 24, ...<snip>\r\nThis is most likely caused by not having the necessary graphics drivers installed.\r\n\r\nInstall a driver providing OpenGL 2.0 or higher, or, if this is not possible, make sure the ANGLE Open GL ES 2.0 emulation libraries (libEGL.dll, libLESv2.dll and d3dcompiler_*.dll) are available in the application executabl's directory or in a location listed in PATH.\r\n```\r\n\r\nTo run the application I can copy these four .dlls into the `dist\\main\\` directory.\r\n\r\n- libEGL.dll\r\n- libGLESv2.dll\r\n- d3dcompiler_47.dll\r\n- opengl32sw.dll\r\n\r\nWhen I run it I get Command Prompt window with this output.\r\n```\r\nQWindowsWGLStaticContext::create: Could not initialize EGL display: error 0x3001\r\nQWindowsWGLStaticContext::create: When using ANGLE, check if d3dcompiler_4x.dll is available.\r\n```\r\nInstead of copying those .dll files I can add the Qt bin directory to my PATH.\r\n\r\n```\r\nset PATH=%PATH%;C:\\Qt\\5.10.1\\msvc2015\\bin\r\ncall main.exe\r\nQWindowsWGLStaticContext::create: Could not initialize EGL display: error 0x3001\r\nQWindowsWGLStaticContext::create: When using ANGLE, check if d3dcompiler_4x.dll is available.\r\n```\r\n\r\nWhen I copy the `dist\\main\\` to another computer (Windows 10).\r\n\r\nI have to set two environment variables before the application will work.\r\n\r\n```\r\nset QT_QPA_PLATFORM_PLUGIN_PATH=%exeDir%\\PyQt5\\Qt\\plugins\\platforms\r\nset QML2_IMPORT_PATH=%exeDir%\\PyQt5\\Qt\\qml\r\n```\r\n\r\nThere are no error messages on the Windows 10 computer with these two environment variables set.\n", "before_files": [{"content": "#-----------------------------------------------------------------------------\n# Copyright (c) 2005-2018, PyInstaller Development Team.\n#\n# Distributed under the terms of the GNU General Public License with exception\n# for distributing bootloader.\n#\n# The full license is in the file COPYING.txt, distributed with this software.\n#-----------------------------------------------------------------------------\nimport os\n\nfrom PyInstaller.utils.hooks import pyqt5_library_info, collect_system_data_files\n\nhiddenimports = ['sip']\n\n# Collect the ``qt.conf`` file.\ndatas = [x for x in\n         collect_system_data_files(pyqt5_library_info.location['PrefixPath'],\n                                   'PyQt5')\n         if os.path.basename(x[0]) == 'qt.conf']\n\n# Include ICU files, if they exist. See the \"Deployment approach\" section in\n# ``PyInstaller/utils/hooks/qt.py``.\n[(os.path.join(pyqt5_library_info.location['BinariesPath'], dll),\n  os.path.join('PyQt5', 'Qt', 'bin', dll))\n for dll in ('icudt??.dll', 'icuin??.dll', 'icuuc??.dll')]\n\n# TODO: Include software rendering for OpenGL. See the \"Deployment approach\". However, because the standard PyQt5 wheel `doesn't include <https://www.riverbankcomputing.com/pipermail/pyqt/2018-June/040387.html>`_ ``d3dcompiler_XX.dll``, this produces failures. When the wheel is updated, this code can be uncommented.\n##binaries = []\n##for dll in ('libEGL.dll', 'libGLESv2.dll', 'd3dcompiler_??.dll', 'opengl32sw.dll'):\n##    dll_path = os.path.join(pyqt5_library_info.location['BinariesPath'], dll)\n##    # Only add files if they exist.\n##    if glob(dll_path):\n##        binaries += [(dll_path, os.path.join('PyQt5', 'Qt', 'bin', dll))]\n", "path": "PyInstaller/hooks/hook-PyQt5.py"}]}