prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Nine: Lutris can't find Nine libraries
  A lot of changed before creating PR #2092 and merging it - biggest issue is commit 792c22176eff9e063b22d7b9700e2e9b79a11fae, which changes return val of iter_lib_folders() from lists to strings. I believe I used iter_lib_folders() in #2092 because I needed distinguish between lib32 and lib64 paths. I will take a look at this and try to fix it ASAP (this week).
  
  Original report:
  https://github.com/lutris/lutris/pull/2092#issuecomment-529362315
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `lutris/util/wine/nine.py`
  Content:
  ```
  1 """Gallium Nine helper module"""
  2 import os
  3 import shutil
  4 
  5 from lutris.util import system
  6 from lutris.runners.commands.wine import wineexec
  7 
  8 class NineUnavailable(RuntimeError):
  9     """Exception raised when Gallium Nine is not available"""
  10 
  11 class NineManager:
  12     """Utility class to install and manage Gallium Nine to a Wine prefix"""
  13 
  14     nine_files = ("d3d9-nine.dll", "ninewinecfg.exe")
  15     mesa_files = ("d3dadapter9.so.1",)
  16 
  17     def __init__(self, prefix, arch):
  18         self.prefix = prefix
  19         self.wine_arch = arch
  20 
  21     @staticmethod
  22     def nine_is_supported():
  23         """Check if MESA is built with Gallium Nine state tracker support
  24 
  25         basic check for presence of d3dadapter9 library in 'd3d' subdirectory
  26         of system library directory
  27         """
  28         for mesa_file in NineManager.mesa_files:
  29             if not any([os.path.exists(os.path.join(lib[0], "d3d", mesa_file))
  30             for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
  31                 return False
  32 
  33             if system.LINUX_SYSTEM.is_64_bit:
  34                 if not any([os.path.exists(os.path.join(lib[1], "d3d", mesa_file))
  35                 for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
  36                     return False
  37 
  38         return True
  39 
  40     @staticmethod
  41     def nine_is_installed():
  42         """Check if Gallium Nine standalone is installed on this system
  43 
  44         check 'wine/fakedlls' subdirectory of system library directory for Nine binaries
  45         """
  46         for nine_file in NineManager.nine_files:
  47             if not any([os.path.exists(os.path.join(lib[0], "wine/fakedlls", nine_file))
  48             for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
  49                 return False
  50 
  51             if system.LINUX_SYSTEM.is_64_bit:
  52                 if not any([os.path.exists(os.path.join(lib[1], "wine/fakedlls", nine_file))
  53                 for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
  54                     return False
  55 
  56         return True
  57 
  58     @staticmethod
  59     def is_available():
  60         """Check if Gallium Nine can be enabled on this system"""
  61         return NineManager.nine_is_supported() and NineManager.nine_is_installed()
  62 
  63     def get_system_path(self, arch):
  64         """Return path of Windows system directory with binaries of chosen architecture"""
  65         windows_path = os.path.join(self.prefix, "drive_c/windows")
  66 
  67         if self.wine_arch == "win32" and arch == "x32":
  68             return os.path.join(windows_path, "system32")
  69         if self.wine_arch == "win64" and arch == "x32":
  70             return os.path.join(windows_path, "syswow64")
  71         if self.wine_arch == "win64" and arch == "x64":
  72             return os.path.join(windows_path, "system32")
  73 
  74         return None
  75 
  76     def is_prefix_prepared(self):
  77         if not all(system.path_exists(os.path.join(self.get_system_path("x32"), nine_file))
  78         for nine_file in self.nine_files):
  79             return False
  80 
  81         if self.wine_arch == "win64":
  82             if not all(system.path_exists(os.path.join(self.get_system_path("x64"), nine_file))
  83             for nine_file in self.nine_files):
  84                 return False
  85 
  86         return True
  87 
  88     def prepare_prefix(self):
  89         for nine_file in NineManager.nine_files:
  90             for lib in system.LINUX_SYSTEM.iter_lib_folders():
  91                 nine_file_32 = os.path.join(lib[0], "wine/fakedlls", nine_file)
  92                 if os.path.exists(nine_file_32):
  93                     shutil.copy(nine_file_32, self.get_system_path("x32"))
  94 
  95                 if self.wine_arch == "win64":
  96                     nine_file_64 = os.path.join(lib[1], "wine/fakedlls", nine_file)
  97                     if os.path.exists(nine_file_64):
  98                         shutil.copy(nine_file_64, self.get_system_path("x64"))
  99 
  100     def enable(self):
  101         if not self.nine_is_supported():
  102             raise NineUnavailable("Nine is not supported on this system")
  103         if not self.nine_is_installed():
  104             raise NineUnavailable("Nine Standalone is not installed")
  105         if not self.is_prefix_prepared():
  106             self.prepare_prefix()
  107 
  108         wineexec(
  109             "ninewinecfg",
  110             args="-e",
  111             prefix=self.prefix,
  112             blocking=True,
  113         )
  114 
  115     def disable(self):
  116         if self.is_prefix_prepared():
  117             wineexec(
  118                 "ninewinecfg",
  119                 args="-d",
  120                 prefix=self.prefix,
  121                 blocking=True,
  122             )
  123
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/lutris/util/wine/nine.py b/lutris/util/wine/nine.py
  --- a/lutris/util/wine/nine.py
  +++ b/lutris/util/wine/nine.py
  @@ -4,6 +4,7 @@
   
   from lutris.util import system
   from lutris.runners.commands.wine import wineexec
  +from lutris.util.wine.cabinstall import CabInstaller
   
   class NineUnavailable(RuntimeError):
       """Exception raised when Gallium Nine is not available"""
  @@ -26,15 +27,10 @@
           of system library directory
           """
           for mesa_file in NineManager.mesa_files:
  -            if not any([os.path.exists(os.path.join(lib[0], "d3d", mesa_file))
  +            if not any([os.path.exists(os.path.join(lib, "d3d", mesa_file))
               for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
                   return False
   
  -            if system.LINUX_SYSTEM.is_64_bit:
  -                if not any([os.path.exists(os.path.join(lib[1], "d3d", mesa_file))
  -                for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
  -                    return False
  -
           return True
   
       @staticmethod
  @@ -44,15 +40,10 @@
           check 'wine/fakedlls' subdirectory of system library directory for Nine binaries
           """
           for nine_file in NineManager.nine_files:
  -            if not any([os.path.exists(os.path.join(lib[0], "wine/fakedlls", nine_file))
  +            if not any([os.path.exists(os.path.join(lib, "wine/fakedlls", nine_file))
               for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
                   return False
   
  -            if system.LINUX_SYSTEM.is_64_bit:
  -                if not any([os.path.exists(os.path.join(lib[1], "wine/fakedlls", nine_file))
  -                for lib in system.LINUX_SYSTEM.iter_lib_folders()]):
  -                    return False
  -
           return True
   
       @staticmethod
  @@ -88,15 +79,24 @@
       def prepare_prefix(self):
           for nine_file in NineManager.nine_files:
               for lib in system.LINUX_SYSTEM.iter_lib_folders():
  -                nine_file_32 = os.path.join(lib[0], "wine/fakedlls", nine_file)
  -                if os.path.exists(nine_file_32):
  -                    shutil.copy(nine_file_32, self.get_system_path("x32"))
  +                nine_file_path = os.path.join(lib, "wine/fakedlls", nine_file)
  +
  +                if (os.path.exists(nine_file_path) and
  +                CabInstaller.get_arch_from_dll(nine_file_path) == "win32"):
  +                    shutil.copy(nine_file_path, self.get_system_path("x32"))
   
                   if self.wine_arch == "win64":
  -                    nine_file_64 = os.path.join(lib[1], "wine/fakedlls", nine_file)
  -                    if os.path.exists(nine_file_64):
  +                    if (os.path.exists(nine_file_path) and
  +                    CabInstaller.get_arch_from_dll(nine_file_path) == "win64"):
                           shutil.copy(nine_file_64, self.get_system_path("x64"))
   
  +            if not os.path.exists(os.path.join(self.get_system_path("x32"), nine_file)):
  +                raise NineUnavailable("could not install " + nine_file + " (x32)")
  +
  +            if self.wine_arch == "win64":
  +                if not os.path.exists(os.path.join(self.get_system_path("x64"), nine_file)):
  +                    raise NineUnavailable("could not install " + nine_file + " (x64)")
  +
       def enable(self):
           if not self.nine_is_supported():
               raise NineUnavailable("Nine is not supported on this system")
  
verification_info: {"golden_diff": "diff --git a/lutris/util/wine/nine.py b/lutris/util/wine/nine.py\n--- a/lutris/util/wine/nine.py\n+++ b/lutris/util/wine/nine.py\n@@ -4,6 +4,7 @@\n \n from lutris.util import system\n from lutris.runners.commands.wine import wineexec\n+from lutris.util.wine.cabinstall import CabInstaller\n \n class NineUnavailable(RuntimeError):\n     \"\"\"Exception raised when Gallium Nine is not available\"\"\"\n@@ -26,15 +27,10 @@\n         of system library directory\n         \"\"\"\n         for mesa_file in NineManager.mesa_files:\n-            if not any([os.path.exists(os.path.join(lib[0], \"d3d\", mesa_file))\n+            if not any([os.path.exists(os.path.join(lib, \"d3d\", mesa_file))\n             for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                 return False\n \n-            if system.LINUX_SYSTEM.is_64_bit:\n-                if not any([os.path.exists(os.path.join(lib[1], \"d3d\", mesa_file))\n-                for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n-                    return False\n-\n         return True\n \n     @staticmethod\n@@ -44,15 +40,10 @@\n         check 'wine/fakedlls' subdirectory of system library directory for Nine binaries\n         \"\"\"\n         for nine_file in NineManager.nine_files:\n-            if not any([os.path.exists(os.path.join(lib[0], \"wine/fakedlls\", nine_file))\n+            if not any([os.path.exists(os.path.join(lib, \"wine/fakedlls\", nine_file))\n             for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                 return False\n \n-            if system.LINUX_SYSTEM.is_64_bit:\n-                if not any([os.path.exists(os.path.join(lib[1], \"wine/fakedlls\", nine_file))\n-                for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n-                    return False\n-\n         return True\n \n     @staticmethod\n@@ -88,15 +79,24 @@\n     def prepare_prefix(self):\n         for nine_file in NineManager.nine_files:\n             for lib in system.LINUX_SYSTEM.iter_lib_folders():\n-                nine_file_32 = os.path.join(lib[0], \"wine/fakedlls\", nine_file)\n-                if os.path.exists(nine_file_32):\n-                    shutil.copy(nine_file_32, self.get_system_path(\"x32\"))\n+                nine_file_path = os.path.join(lib, \"wine/fakedlls\", nine_file)\n+\n+                if (os.path.exists(nine_file_path) and\n+                CabInstaller.get_arch_from_dll(nine_file_path) == \"win32\"):\n+                    shutil.copy(nine_file_path, self.get_system_path(\"x32\"))\n \n                 if self.wine_arch == \"win64\":\n-                    nine_file_64 = os.path.join(lib[1], \"wine/fakedlls\", nine_file)\n-                    if os.path.exists(nine_file_64):\n+                    if (os.path.exists(nine_file_path) and\n+                    CabInstaller.get_arch_from_dll(nine_file_path) == \"win64\"):\n                         shutil.copy(nine_file_64, self.get_system_path(\"x64\"))\n \n+            if not os.path.exists(os.path.join(self.get_system_path(\"x32\"), nine_file)):\n+                raise NineUnavailable(\"could not install \" + nine_file + \" (x32)\")\n+\n+            if self.wine_arch == \"win64\":\n+                if not os.path.exists(os.path.join(self.get_system_path(\"x64\"), nine_file)):\n+                    raise NineUnavailable(\"could not install \" + nine_file + \" (x64)\")\n+\n     def enable(self):\n         if not self.nine_is_supported():\n             raise NineUnavailable(\"Nine is not supported on this system\")\n", "issue": "Nine: Lutris can't find Nine libraries\nA lot of changed before creating PR #2092 and merging it - biggest issue is commit 792c22176eff9e063b22d7b9700e2e9b79a11fae, which changes return val of iter_lib_folders() from lists to strings. I believe I used iter_lib_folders() in #2092 because I needed distinguish between lib32 and lib64 paths. I will take a look at this and try to fix it ASAP (this week).\r\n\r\nOriginal report:\r\nhttps://github.com/lutris/lutris/pull/2092#issuecomment-529362315\n", "before_files": [{"content": "\"\"\"Gallium Nine helper module\"\"\"\nimport os\nimport shutil\n\nfrom lutris.util import system\nfrom lutris.runners.commands.wine import wineexec\n\nclass NineUnavailable(RuntimeError):\n    \"\"\"Exception raised when Gallium Nine is not available\"\"\"\n\nclass NineManager:\n    \"\"\"Utility class to install and manage Gallium Nine to a Wine prefix\"\"\"\n\n    nine_files = (\"d3d9-nine.dll\", \"ninewinecfg.exe\")\n    mesa_files = (\"d3dadapter9.so.1\",)\n\n    def __init__(self, prefix, arch):\n        self.prefix = prefix\n        self.wine_arch = arch\n\n    @staticmethod\n    def nine_is_supported():\n        \"\"\"Check if MESA is built with Gallium Nine state tracker support\n\n        basic check for presence of d3dadapter9 library in 'd3d' subdirectory\n        of system library directory\n        \"\"\"\n        for mesa_file in NineManager.mesa_files:\n            if not any([os.path.exists(os.path.join(lib[0], \"d3d\", mesa_file))\n            for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                return False\n\n            if system.LINUX_SYSTEM.is_64_bit:\n                if not any([os.path.exists(os.path.join(lib[1], \"d3d\", mesa_file))\n                for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                    return False\n\n        return True\n\n    @staticmethod\n    def nine_is_installed():\n        \"\"\"Check if Gallium Nine standalone is installed on this system\n\n        check 'wine/fakedlls' subdirectory of system library directory for Nine binaries\n        \"\"\"\n        for nine_file in NineManager.nine_files:\n            if not any([os.path.exists(os.path.join(lib[0], \"wine/fakedlls\", nine_file))\n            for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                return False\n\n            if system.LINUX_SYSTEM.is_64_bit:\n                if not any([os.path.exists(os.path.join(lib[1], \"wine/fakedlls\", nine_file))\n                for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                    return False\n\n        return True\n\n    @staticmethod\n    def is_available():\n        \"\"\"Check if Gallium Nine can be enabled on this system\"\"\"\n        return NineManager.nine_is_supported() and NineManager.nine_is_installed()\n\n    def get_system_path(self, arch):\n        \"\"\"Return path of Windows system directory with binaries of chosen architecture\"\"\"\n        windows_path = os.path.join(self.prefix, \"drive_c/windows\")\n\n        if self.wine_arch == \"win32\" and arch == \"x32\":\n            return os.path.join(windows_path, \"system32\")\n        if self.wine_arch == \"win64\" and arch == \"x32\":\n            return os.path.join(windows_path, \"syswow64\")\n        if self.wine_arch == \"win64\" and arch == \"x64\":\n            return os.path.join(windows_path, \"system32\")\n\n        return None\n\n    def is_prefix_prepared(self):\n        if not all(system.path_exists(os.path.join(self.get_system_path(\"x32\"), nine_file))\n        for nine_file in self.nine_files):\n            return False\n\n        if self.wine_arch == \"win64\":\n            if not all(system.path_exists(os.path.join(self.get_system_path(\"x64\"), nine_file))\n            for nine_file in self.nine_files):\n                return False\n\n        return True\n\n    def prepare_prefix(self):\n        for nine_file in NineManager.nine_files:\n            for lib in system.LINUX_SYSTEM.iter_lib_folders():\n                nine_file_32 = os.path.join(lib[0], \"wine/fakedlls\", nine_file)\n                if os.path.exists(nine_file_32):\n                    shutil.copy(nine_file_32, self.get_system_path(\"x32\"))\n\n                if self.wine_arch == \"win64\":\n                    nine_file_64 = os.path.join(lib[1], \"wine/fakedlls\", nine_file)\n                    if os.path.exists(nine_file_64):\n                        shutil.copy(nine_file_64, self.get_system_path(\"x64\"))\n\n    def enable(self):\n        if not self.nine_is_supported():\n            raise NineUnavailable(\"Nine is not supported on this system\")\n        if not self.nine_is_installed():\n            raise NineUnavailable(\"Nine Standalone is not installed\")\n        if not self.is_prefix_prepared():\n            self.prepare_prefix()\n\n        wineexec(\n            \"ninewinecfg\",\n            args=\"-e\",\n            prefix=self.prefix,\n            blocking=True,\n        )\n\n    def disable(self):\n        if self.is_prefix_prepared():\n            wineexec(\n                \"ninewinecfg\",\n                args=\"-d\",\n                prefix=self.prefix,\n                blocking=True,\n            )\n", "path": "lutris/util/wine/nine.py"}], "after_files": [{"content": "\"\"\"Gallium Nine helper module\"\"\"\nimport os\nimport shutil\n\nfrom lutris.util import system\nfrom lutris.runners.commands.wine import wineexec\nfrom lutris.util.wine.cabinstall import CabInstaller\n\nclass NineUnavailable(RuntimeError):\n    \"\"\"Exception raised when Gallium Nine is not available\"\"\"\n\nclass NineManager:\n    \"\"\"Utility class to install and manage Gallium Nine to a Wine prefix\"\"\"\n\n    nine_files = (\"d3d9-nine.dll\", \"ninewinecfg.exe\")\n    mesa_files = (\"d3dadapter9.so.1\",)\n\n    def __init__(self, prefix, arch):\n        self.prefix = prefix\n        self.wine_arch = arch\n\n    @staticmethod\n    def nine_is_supported():\n        \"\"\"Check if MESA is built with Gallium Nine state tracker support\n\n        basic check for presence of d3dadapter9 library in 'd3d' subdirectory\n        of system library directory\n        \"\"\"\n        for mesa_file in NineManager.mesa_files:\n            if not any([os.path.exists(os.path.join(lib, \"d3d\", mesa_file))\n            for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                return False\n\n        return True\n\n    @staticmethod\n    def nine_is_installed():\n        \"\"\"Check if Gallium Nine standalone is installed on this system\n\n        check 'wine/fakedlls' subdirectory of system library directory for Nine binaries\n        \"\"\"\n        for nine_file in NineManager.nine_files:\n            if not any([os.path.exists(os.path.join(lib, \"wine/fakedlls\", nine_file))\n            for lib in system.LINUX_SYSTEM.iter_lib_folders()]):\n                return False\n\n        return True\n\n    @staticmethod\n    def is_available():\n        \"\"\"Check if Gallium Nine can be enabled on this system\"\"\"\n        return NineManager.nine_is_supported() and NineManager.nine_is_installed()\n\n    def get_system_path(self, arch):\n        \"\"\"Return path of Windows system directory with binaries of chosen architecture\"\"\"\n        windows_path = os.path.join(self.prefix, \"drive_c/windows\")\n\n        if self.wine_arch == \"win32\" and arch == \"x32\":\n            return os.path.join(windows_path, \"system32\")\n        if self.wine_arch == \"win64\" and arch == \"x32\":\n            return os.path.join(windows_path, \"syswow64\")\n        if self.wine_arch == \"win64\" and arch == \"x64\":\n            return os.path.join(windows_path, \"system32\")\n\n        return None\n\n    def is_prefix_prepared(self):\n        if not all(system.path_exists(os.path.join(self.get_system_path(\"x32\"), nine_file))\n        for nine_file in self.nine_files):\n            return False\n\n        if self.wine_arch == \"win64\":\n            if not all(system.path_exists(os.path.join(self.get_system_path(\"x64\"), nine_file))\n            for nine_file in self.nine_files):\n                return False\n\n        return True\n\n    def prepare_prefix(self):\n        for nine_file in NineManager.nine_files:\n            for lib in system.LINUX_SYSTEM.iter_lib_folders():\n                nine_file_path = os.path.join(lib, \"wine/fakedlls\", nine_file)\n\n                if (os.path.exists(nine_file_path) and\n                CabInstaller.get_arch_from_dll(nine_file_path) == \"win32\"):\n                    shutil.copy(nine_file_path, self.get_system_path(\"x32\"))\n\n                if self.wine_arch == \"win64\":\n                    if (os.path.exists(nine_file_path) and\n                    CabInstaller.get_arch_from_dll(nine_file_path) == \"win64\"):\n                        shutil.copy(nine_file_64, self.get_system_path(\"x64\"))\n\n            if not os.path.exists(os.path.join(self.get_system_path(\"x32\"), nine_file)):\n                raise NineUnavailable(\"could not install \" + nine_file + \" (x32)\")\n\n            if self.wine_arch == \"win64\":\n                if not os.path.exists(os.path.join(self.get_system_path(\"x64\"), nine_file)):\n                    raise NineUnavailable(\"could not install \" + nine_file + \" (x64)\")\n\n    def enable(self):\n        if not self.nine_is_supported():\n            raise NineUnavailable(\"Nine is not supported on this system\")\n        if not self.nine_is_installed():\n            raise NineUnavailable(\"Nine Standalone is not installed\")\n        if not self.is_prefix_prepared():\n            self.prepare_prefix()\n\n        wineexec(\n            \"ninewinecfg\",\n            args=\"-e\",\n            prefix=self.prefix,\n            blocking=True,\n        )\n\n    def disable(self):\n        if self.is_prefix_prepared():\n            wineexec(\n                \"ninewinecfg\",\n                args=\"-d\",\n                prefix=self.prefix,\n                blocking=True,\n            )\n", "path": "lutris/util/wine/nine.py"}]}