Repository: miurahr/aqtinstall

Issue:
ERROR: Detected a package name collision
This bug happened to me when I added `qthttpserver` to an installation. Without `qthttpserver` everything installs fine.

List cmd:
`$ aqt list-qt linux desktop --modules 6.4.2 gcc_64`
debug_info qt3d qt5compat qtcharts qtconnectivity qtdatavis3d qthttpserver qtimageformats qtlanguageserver qtlottie qtmultimedia qtnetworkauth qtpdf qtpositioning qtquick3d qtquick3dphysics qtquicktimeline qtremoteobjects qtscxml qtsensors qtserialbus qtserialport qtshadertools qtspeech qtvirtualkeyboard qtwaylandcompositor qtwebchannel qtwebengine qtwebsockets qtwebview

Install cmd:
`$ aqt install-qt -O /opt/Qt linux desktop 6.4.2 gcc_64 --m qt5compat qtcharts qthttpserver qtimageformats qtlottie qtmultimedia qtquicktimeline qtspeech qtwebchannel qtwebsockets qthttpserver`

INFO    : aqtinstall(aqt) v3.1.0 on Python 3.10.6 [CPython GCC 11.3.0]
WARNING : Specified Qt version is unknown: 6.4.2.
ERROR   : Detected a package name collision
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/aqt/installer.py", line 177, in run
    args.func(args)
  File "/usr/local/lib/python3.10/dist-packages/aqt/installer.py", line 400, in run_install_qt
    qt_archives: QtArchives = retry_on_bad_connection(
  File "/usr/local/lib/python3.10/dist-packages/aqt/helper.py", line 165, in retry_on_bad_connection
    return function(base_url)
  File "/usr/local/lib/python3.10/dist-packages/aqt/installer.py", line 401, in <lambda>
    lambda base_url: QtArchives(
  File "/usr/local/lib/python3.10/dist-packages/aqt/archives.py", line 300, in __init__
    self._get_archives()
  File "/usr/local/lib/python3.10/dist-packages/aqt/archives.py", line 365, in _get_archives
    self._get_archives_base(f"qt{self.version.major}_{self._version_str()}{self._arch_ext()}", self._target_packages())
  File "/usr/local/lib/python3.10/dist-packages/aqt/archives.py", line 361, in _target_packages
    target_packages.add(module, package_names)
  File "/usr/local/lib/python3.10/dist-packages/aqt/archives.py", line 94, in add
    assert package_name not in self._packages_to_modules, "Detected a package name collision"
AssertionError: Detected a package name collision
ERROR   : aqtinstall(aqt) v3.1.0 on Python 3.10.6 [CPython GCC 11.3.0]
Working dir: `/`
Arguments: `['/usr/local/bin/aqt', 'install-qt', '-O', '/opt/Qt', 'linux', 'desktop', '6.4.2', 'gcc_64', '--m', 'qt5compat', 'qtcharts', 'qthttpserver', 'qtimageformats', 'qtlottie', 'qtmultimedia', 'qtquicktimeline', 'qtspeech', 'qtwebchannel', 'qtwebsockets', 'qthttpserver']` Host: `uname_result(system='Linux', node='4a4d7c6111e3', release='5.15.0-53-generic', version='#59-Ubuntu SMP Mon Oct 17 18:53:30 UTC 2022', machine='x86_64')`
===========================PLEASE FILE A BUG REPORT===========================
You have discovered a bug in aqt.
Please file a bug report at https://github.com/miurahr/aqtinstall/issues
Please remember to include a copy of this program's output in your report.

Discussion:

Patch:
diff --git a/aqt/archives.py b/aqt/archives.py
index 77eb5d7..214ca0e 100644
--- a/aqt/archives.py
+++ b/aqt/archives.py
@@ -22,7 +22,7 @@
 import posixpath
 from dataclasses import dataclass, field
 from logging import getLogger
-from typing import Dict, Iterable, List, Optional, Tuple
+from typing import Dict, Iterable, List, Optional, Set, Tuple
 from xml.etree.ElementTree import Element  # noqa
 
 from defusedxml import ElementTree
@@ -293,7 +293,7 @@ class QtArchives:
         self.logger = getLogger("aqt.archives")
         self.archives: List[QtPackage] = []
         self.subarchives: Optional[Iterable[str]] = subarchives
-        self.mod_list: Iterable[str] = modules or []
+        self.mod_list: Set[str] = set(modules or [])
         self.is_include_base_package: bool = is_include_base_package
         self.timeout = timeout
         try:


Test patch:
diff --git a/tests/test_install.py b/tests/test_install.py
index fc373ff..9cae23d 100644
--- a/tests/test_install.py
+++ b/tests/test_install.py
@@ -575,6 +575,30 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
                 r"INFO    : Time elapsed: .* second"
             ),
         ),
+        (  # Duplicates in the modules list
+            "install-qt windows desktop 6.1.0 win64_mingw81 -m qtcharts qtcharts qtcharts".split(),
+            "windows",
+            "desktop",
+            "6.1.0",
+            {"std": "win64_mingw81"},
+            {"std": "mingw81_64"},
+            {"std": "windows_x86/desktop/qt6_610/Updates.xml"},
+            {
+                "std": [
+                    plain_qtbase_archive("qt.qt6.610.win64_mingw81", "win64_mingw81"),
+                    qtcharts_module("6.1.0", "win64_mingw81"),
+                ]
+            },
+            re.compile(
+                r"^INFO    : aqtinstall\(aqt\) v.* on Python 3.*\n"
+                r"INFO    : Downloading qtbase...\n"
+                r"Finished installation of qtbase-windows-win64_mingw81.7z in .*\n"
+                r"INFO    : Downloading qtcharts...\n"
+                r"Finished installation of qtcharts-windows-win64_mingw81.7z in .*\n"
+                r"INFO    : Finished installation\n"
+                r"INFO    : Time elapsed: .* second"
+            ),
+        ),
         (
             "install-qt windows android 6.1.0 android_armv7".split(),
             "windows",