diff --git a/install.ps1 b/install.ps1 index b6ba50351..46ef83dfa 100644 --- a/install.ps1 +++ b/install.ps1 @@ -16,7 +16,7 @@ # and Invoke-WebRequest throws on a cut transfer before the hash is read: # the site's build rewrites this line there (scripts/sitebootstrap.py). $mismatchAdvice = "The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." - $defaultInstallSha256 = "25a88f9a078717afbe34419481d222d2f6f42c4bf24b4ec64bc3faa9561ea01c" + $defaultInstallSha256 = "ee24f4f154e68d7d503f12e4816e3f1ff38f80159432093e4c6ed86411783ed7" $maximumInstallerBytes = 2MB $installerExit = 0 $installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null } diff --git a/install.py b/install.py index 05d0bc9d7..6613a0554 100644 --- a/install.py +++ b/install.py @@ -1202,7 +1202,7 @@ def _parse_os_release() -> dict[str, str]: # path and nothing Windows-side was ever found from WSL. # unasked: why Windows could not be asked for its folders, said once by # detection. -_WSL = {"active": False, "root": "/mnt", "unasked": ""} +_WSL: dict[str, Any] = {"active": False, "root": "/mnt", "unasked": ""} _WINDOWS_VARIABLES = ("USERPROFILE", "APPDATA", "LOCALAPPDATA", "ProgramFiles", "ProgramFiles(x86)") diff --git a/install.sh b/install.sh index 5bbfc4ecd..d5ee07167 100755 --- a/install.sh +++ b/install.sh @@ -23,7 +23,7 @@ DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/ins # curl or wget stop on a cut transfer before the hash is read: the site's # build rewrites this line there (scripts/sitebootstrap.py). MISMATCH_ADVICE="The download was most likely cut short: try again. Within minutes of an update of this project the two files can come from caches of different ages. Waiting five minutes settles that." -DEFAULT_INSTALL_SHA256="25a88f9a078717afbe34419481d222d2f6f42c4bf24b4ec64bc3faa9561ea01c" +DEFAULT_INSTALL_SHA256="ee24f4f154e68d7d503f12e4816e3f1ff38f80159432093e4c6ed86411783ed7" MAX_INSTALLER_BYTES=2097152 cleanup() { diff --git a/install/launchers/index.json b/install/launchers/index.json index f40516460..44d04c39f 100644 --- a/install/launchers/index.json +++ b/install/launchers/index.json @@ -27,8 +27,8 @@ { "dest": "roms/ports/retrobios/install.py", "repo_path": "install.py", - "size": 1122406, - "sha256": "25a88f9a078717afbe34419481d222d2f6f42c4bf24b4ec64bc3faa9561ea01c", + "size": 1122422, + "sha256": "ee24f4f154e68d7d503f12e4816e3f1ff38f80159432093e4c6ed86411783ed7", "executable": false }, { @@ -71,8 +71,8 @@ "muos": { "archive": { "dest": "ARCHIVE/RetroBIOS.muxapp", - "size": 1176033, - "sha256": "05a543e24f2c996d79bea8c95d95789669b92574ad45ffe60df88eb4c80a553c" + "size": 1176049, + "sha256": "9ac4845d2a448ece2d421db3137c7aea6d636d0ecf6c92ed777630f47dd61021" }, "members": [ { @@ -92,8 +92,8 @@ { "name": "RetroBIOS/install.py", "repo_path": "install.py", - "size": 1122406, - "sha256": "25a88f9a078717afbe34419481d222d2f6f42c4bf24b4ec64bc3faa9561ea01c", + "size": 1122422, + "sha256": "ee24f4f154e68d7d503f12e4816e3f1ff38f80159432093e4c6ed86411783ed7", "executable": false }, { @@ -166,8 +166,8 @@ { "dest": ".config/modules/retrobios/install.py", "repo_path": "install.py", - "size": 1122406, - "sha256": "25a88f9a078717afbe34419481d222d2f6f42c4bf24b4ec64bc3faa9561ea01c", + "size": 1122422, + "sha256": "ee24f4f154e68d7d503f12e4816e3f1ff38f80159432093e4c6ed86411783ed7", "executable": false }, { diff --git a/mypy-baseline.txt b/mypy-baseline.txt index 6399b243c..6031a5fe0 100644 --- a/mypy-baseline.txt +++ b/mypy-baseline.txt @@ -6,13 +6,10 @@ install.py:0: error: "bool" has no attribute "name" [attr-defined] install.py:0: error: "bool" has no attribute "parent" [attr-defined] install.py:0: error: "object" has no attribute "get" [attr-defined] install.py:0: error: "object" has no attribute "get" [attr-defined] -install.py:0: error: "object" has no attribute "rstrip" [attr-defined] install.py:0: error: "object" object is not iterable [misc] install.py:0: error: "object" object is not iterable [misc] install.py:0: error: "str" has no attribute "append" [attr-defined] install.py:0: error: "str" has no attribute "append" [attr-defined] -install.py:0: error: Argument 1 to "Path" has incompatible type "object"; expected "Union[str, PathLike[str]]" [arg-type] -install.py:0: error: Argument 1 to "Path" has incompatible type "object"; expected "Union[str, PathLike[str]]" [arg-type] install.py:0: error: Argument 1 to "_ZippedLookup" has incompatible type "Optional[FolderIndex]"; expected "FolderIndex" [arg-type] install.py:0: error: Argument 1 to "__iadd__" of "list" has incompatible type "Invocation"; expected "Iterable[str]" [arg-type] install.py:0: error: Argument 1 to "_digest_file" has incompatible type "Optional[Path]"; expected "Path" [arg-type] @@ -228,17 +225,11 @@ scripts/check_platform_folder.py:0: error: Incompatible types in assignment (exp scripts/check_release_assets.py:0: error: Argument 1 to "get" of "dict" has incompatible type "Optional[str]"; expected "str" [arg-type] scripts/common.py:0: error: Argument "sha1_candidates" to "declared_hash_verdict" has incompatible type "list[str]"; expected "set[Any]" [arg-type] scripts/common.py:0: error: Argument "sha256_candidates" to "declared_hash_verdict" has incompatible type "list[str]"; expected "set[Any]" [arg-type] -scripts/common.py:0: error: Argument 1 to "append" of "list" has incompatible type "tuple[Any, Any, Any]"; expected "str" [arg-type] -scripts/common.py:0: error: Argument 2 to "name_match_size_ok" has incompatible type "str"; expected "Optional[int]" [arg-type] -scripts/common.py:0: error: Cannot determine type of "m" [has-type] -scripts/common.py:0: error: Cannot determine type of "size" [has-type] scripts/common.py:0: error: Incompatible return value type (got "str", expected "tuple[Optional[str], str]") [return-value] scripts/common.py:0: error: Incompatible return value type (got "str", expected "tuple[Optional[str], str]") [return-value] scripts/common.py:0: error: Incompatible types in assignment (expression has type "Optional[tuple[str, str]]", variable has type "Optional[str]") [assignment] scripts/common.py:0: error: Incompatible types in assignment (expression has type "Optional[tuple[str, str]]", variable has type "Optional[str]") [assignment] scripts/common.py:0: error: Name "folded" already defined on line 0 [no-redef] -scripts/common.py:0: error: Unpacking a string is disallowed [misc] -scripts/common.py:0: error: Unpacking a string is disallowed [misc] scripts/common.py:0: error: Unsupported left operand type for & ("None") [operator] scripts/core_probe.py:0: error: Incompatible types in assignment (expression has type "list[list[Any]]", target has type "Optional[str]") [assignment] scripts/core_probe.py:0: error: Incompatible types in assignment (expression has type "list[str]", target has type "Optional[str]") [assignment] @@ -956,7 +947,6 @@ scripts/validate_schemas.py:0: error: Argument 1 to "_semantic_database_checks" scripts/validate_schemas.py:0: error: Argument 3 to "_validate_json_files" has incompatible type "Callable[[Path, dict[Any, Any]], list[str]]"; expected "Optional[Callable[[Path, object], list[str]]]" [arg-type] scripts/validate_schemas.py:0: error: Argument 3 to "_validate_json_files" has incompatible type "Callable[[Path, dict[Any, Any]], list[str]]"; expected "Optional[Callable[[Path, object], list[str]]]" [arg-type] scripts/validate_schemas.py:0: error: Unpacked dict entry 0 has incompatible type "object"; expected "SupportsKeysAndGetItem[str, str]" [dict-item] -scripts/validation.py:0: error: "dict[str, str]" has no attribute "startswith" [attr-defined] scripts/validation.py:0: error: Argument 1 to "_merged_reason" has incompatible type "list[Optional[str]]"; expected "list[str]" [arg-type] scripts/validation.py:0: error: Argument 1 to "set" has incompatible type "Union[dict[Any, Any], list[str], Any, None]"; expected "Iterable[Any]" [arg-type] scripts/validation.py:0: error: Argument 1 to "setdefault" of "MutableMapping" has incompatible type "tuple[Optional[Any], Optional[Any]]"; expected "tuple[str, str]" [arg-type] diff --git a/scripts/common.py b/scripts/common.py index 777b6c745..b717ec9bb 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -1933,7 +1933,7 @@ def resolve_local_file( # 4. Name + alias fallback with md5_composite + direct MD5 per candidate md5_set = set(md5_list) - candidates = [] + named: list[tuple[str, str, int | None]] = [] seen_paths = set() for try_name in names_to_try: for match_sha1 in by_name.get(try_name, []): @@ -1942,28 +1942,28 @@ def resolve_local_file( path = entry["path"] if os.path.exists(path) and path not in seen_paths: seen_paths.add(path) - candidates.append( + named.append( (path, entry.get("md5", ""), entry.get("size")) ) if zipped_file: - candidates = [c for c in candidates if ".zip" in os.path.basename(c[0])] + named = [c for c in named if ".zip" in os.path.basename(c[0])] # Another maker's file is no mismatch of this one, it is another file. - candidates = [c for c in candidates if not other_maker(c[0], makers, db)] + named = [c for c in named if not other_maker(c[0], makers, db)] # A size the emulator itself verifies settles a name collision, so a # candidate that fits is preferred over one that does not: "ROM" answers # both an Apple IIgs image and a Macintosh one. It ranks rather than # excludes, because a present file of the wrong size is reported as # present and untested, and dropping it would report it as absent. - sized = [c for c in candidates if name_match_size_ok(file_entry, c[2])] + sized = [c for c in named if name_match_size_ok(file_entry, c[2])] if sized: - candidates = sized + named = sized - if candidates: + if named: if md5_set and not (sha1_candidates or sha256_candidates or crc_candidates): if composite_only: - candidates.sort(key=lambda c: "/.variants/" in c[0]) - for path, db_md5, _size in candidates: + named.sort(key=lambda c: "/.variants/" in c[0]) + for path, db_md5, _size in named: if ".zip" in os.path.basename(path): try: composite = md5_composite(path).lower() @@ -1982,7 +1982,7 @@ def resolve_local_file( # When zipped_file is set, only accept candidates that contain it if zipped_file: valid = [] - for path, m, size in candidates: + for path, m, size in named: try: with zipfile.ZipFile(path) as zf: inner_names = {n.casefold() for n in zf.namelist()} @@ -2001,7 +2001,7 @@ def resolve_local_file( return (primary[0] if primary else valid[0][0]), "hash_mismatch" # No candidate contains the zipped_file: fall through to step 5 elif not unsourceable: - ordered = _by_affinity([c[0] for c in candidates], file_entry, dest_hint) + ordered = _by_affinity([c[0] for c in named], file_entry, dest_hint) primary = [c for c in ordered if "/.variants/" not in c] return (primary[0] if primary else ordered[0]), "hash_mismatch" diff --git a/scripts/generate_pack.py b/scripts/generate_pack.py index 5a4c34f16..4b4c4f726 100644 --- a/scripts/generate_pack.py +++ b/scripts/generate_pack.py @@ -4065,16 +4065,16 @@ def _profile_copies( continue source = held[0] where = PurePosixPath(standalone) - targets: dict[str, list[str]] = {} + placed: dict[str, list[str]] = {} for system, root in roots.items(): sep = "\\" if system == "windows" else "/" target = root if str(where.parent) == "." else ( root + sep + str(where.parent).replace("/", sep)) if not covered(system, target, where.name): - targets[system] = [target] - if not targets: + placed[system] = [target] + if not placed: continue - copy = {"file": source, "targets": targets} + copy = {"file": source, "targets": placed} if where.name != PurePosixPath(source).name: copy["as"] = where.name copies.append(copy)