Repository: pyinstaller/pyinstaller

Issue:
'Qml2ImportsPath' KeyError with PySide6.4.0
## Description of the issue

PyInstaller does not work with PySide6 version 6.4.0.
Running PyInstaller aborts with a KeyError:

```
File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\utils\hooks\qt.py", line 730, in get_qt_qml_files
   qmldir = qt_library_info.location['Qml2ImportsPath']
KeyError: 'Qml2ImportsPath'
```
According to https://doc-snapshots.qt.io/qt6-6.4/qlibraryinfo.html, 'Qml2ImportsPath' is deprecated:
```
QLibraryInfo::QmlImportsPath | 7 | The path to installed QML extensions to import.
QLibraryInfo::Qml2ImportsPath | QmlImportsPath | This value is deprecated. Use QmlImportsPath instead.
```

The location dictionary looks like this:
```
{'ArchDataPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6', 'BinariesPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/bin', 'DataPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6', 'DocumentationPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/doc', 'ExamplesPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/examples', 'HeadersPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/include', 'LibrariesPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/lib', 'LibraryExecutablesPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/.', 'PluginsPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/plugins', 'PrefixPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/.', 'QmlImportsPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/qml', 'SettingsPath': '', 'TestsPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/tests', 'TranslationsPath': 'C:/Users/UserX/AppData/Local/Programs/Python/Python310/lib/site-packages/PySide6/translations'}
```
### Possible solution
Use 'QmlImportsPath' instead of 'Qml2ImportsPath' on line 730.
A change of this line allows the program to finish successfully on my setup. 
For the implementation of this fix you may need to consider backwards compatibility for older PySide/PyQt versions...

### System environment:
```
Python 3.10.6 on Win11

pyinstaller               5.5
pyinstaller-hooks-contrib 2022.10
PySide6                   6.4.0
PySide6-Addons            6.4.0
PySide6-Essentials        6.4.0
```


### Stacktrace / full error message


```
Traceback (most recent call last):

pyinstaller --noconfirm --clean MyApp.spec
...
39361 INFO: Loading module hook 'hook-PySide6.QtQml.py' from 'C:\\Users\\UserX\\AppData\\Roaming\\Python\\Python310\\site-packages\\PyInstaller\\hooks'...
Traceback (most recent call last):
  File "C:\Users\UserX\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\UserX\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\UserX\AppData\Local\Programs\Python\Python310\Scripts\pyinstaller.exe\__main__.py", line 7, in <module>
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\__main__.py", line 179, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\__main__.py", line 60, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\building\build_main.py", line 963, in main
    build(specfile, distpath, workpath, clean_build)
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\building\build_main.py", line 885, in build
    exec(code, spec_namespace)
  File "AS7505_GUI_EvalSW.spec", line 7, in <module>
    a = Analysis(
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\building\build_main.py", line 410, in __init__
    self.__postinit__()
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\building\datastruct.py", line 173, in __postinit__
    self.assemble()
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\building\build_main.py", line 579, in assemble
    self.graph.process_post_graph_hooks(self)
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\depend\analysis.py", line 329, in process_post_graph_hooks
    module_hook.post_graph(analysis)
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\depend\imphook.py", line 447, in post_graph
    self._load_hook_module(keep_module_ref=True)
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\depend\imphook.py", line 387, in _load_hook_module
    self._hook_module = importlib_load_source(self.hook_module_name, self.hook_filename)
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\compat.py", line 609, in importlib_load_source
    return mod_loader.load_module()
  File "<frozen importlib._bootstrap_external>", line 548, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 1063, in load_module
  File "<frozen importlib._bootstrap_external>", line 888, in load_module
  File "<frozen importlib._bootstrap>", line 290, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 719, in _load
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\hooks\hook-PySide6.QtQml.py", line 15, in <module>
    qml_binaries, qml_datas = get_qt_qml_files(pyside6_library_info)
  File "C:\Users\UserX\AppData\Roaming\Python\Python310\site-packages\PyInstaller\utils\hooks\qt.py", line 730, in get_qt_qml_files
    qmldir = qt_library_info.location['Qml2ImportsPath']
KeyError: 'Qml2ImportsPath'
```



Discussion:

Resolving patch:
diff --git a/PyInstaller/utils/hooks/qt.py b/PyInstaller/utils/hooks/qt.py
--- a/PyInstaller/utils/hooks/qt.py
+++ b/PyInstaller/utils/hooks/qt.py
@@ -727,7 +727,13 @@ def get_qt_qml_files(qt_library_info):
     #
     # https://github.com/pyinstaller/pyinstaller/pull/3229#issuecomment-359735031
     # https://github.com/pyinstaller/pyinstaller/issues/3864
-    qmldir = qt_library_info.location['Qml2ImportsPath']
+    #
+    # In Qt 6, Qml2ImportsPath was deprecated in favor of QmlImportsPath. The former is not available in PySide6
+    # 6.4.0 anymore (but is in PyQt6 6.4.
+    if 'QmlImportsPath' in qt_library_info.location:
+        qmldir = qt_library_info.location['QmlImportsPath']
+    else:
+        qmldir = qt_library_info.location['Qml2ImportsPath']
     if not qmldir or not os.path.exists(qmldir):
         logger.warning(
             'QML directory for %s, %r, does not exist. QML files not packaged.', qt_library_info.namespace, qmldir


Test patch:
diff --git a/tests/requirements-libraries.txt b/tests/requirements-libraries.txt
--- a/tests/requirements-libraries.txt
+++ b/tests/requirements-libraries.txt
@@ -37,18 +37,11 @@ pandas==1.5.0; python_version >= '3.8'
 pygments==2.13.0
 PyGObject==3.42.2; sys_platform == 'linux'
 pyside2==5.15.2.1
-# pyside6 6.2.2 wheel is incompatible with python < 3.8 on macOS
-# pyside6 6.3 wheels are incompatible with python < 3.8 on linux
-# see https://bugreports.qt.io/browse/PYSIDE-1797
-pyside6==6.2.1; sys_platform == 'darwin' and python_version < '3.8'  # pyup: ignore
-pyside6==6.2.4; sys_platform == 'linux' and python_version < '3.8'  # pyup: ignore
-pyside6==6.3.2; (sys_platform != 'darwin' and sys_platform != 'linux') or python_version >= '3.8'
-pyqt5==5.15.7; python_version < '3.10'
-pyqtwebengine==5.15.6; python_version < '3.10'
-pyqt6==6.4.0  # PyQt6 Qt6 bindings
-pyqt6-qt6==6.4.0  # Qt6 binaries (keep in sync with pyqt6 version!)
-pyqt6-webengine==6.4.0  # PyQt6 QtWebEngine bindings
-pyqt6-webengine-qt6==6.4.0  # Qt6 QtWebEngine binaries
+pyside6==6.4.0
+pyqt5==5.15.7
+pyqtwebengine==5.15.6
+pyqt6==6.4.0
+pyqt6-webengine==6.4.0
 python-dateutil==2.8.2
 pytz==2022.4
 requests==2.28.1