mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-18 17:33:30 -05:00
fix: pass the installer's own lint gate
install.py held a local it never read and, since the registry path rules, a loop variable shadowing the platform module, so the py38 ruff gate the installer is held to failed. Both are fixed, and the suite reads the two rules from the syntax tree since CI has no ruff.
This commit is contained in:
1 parent
e04646d67a
commit
5a32a42d25
4 files changed
+51
-6
No files matched your search
+1
-1
@@ -8,7 +8,7 @@ param(
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$defaultInstallUrl = "https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
$defaultInstallSha256 = "dc6b428278a4352923c19ddcf055fd994aac1df77f35cb1d097e8f4c5d887ae1"
|
||||
$defaultInstallSha256 = "973e116ab59e233cd4fe5ebb77d4973bc06013b22b6388e80d12fa1d61fb0c73"
|
||||
$maximumInstallerBytes = 2MB
|
||||
$installerExit = 0
|
||||
$installer = if ($PSScriptRoot) { Join-Path $PSScriptRoot "install.py" } else { $null }
|
||||
|
||||
+3
-4
@@ -175,7 +175,6 @@ def _os_default_dests(os_type: str) -> dict[str, Path]:
|
||||
home = Path.home()
|
||||
if os_type == "windows":
|
||||
profile = Path(os.environ.get("USERPROFILE", str(home)))
|
||||
appdata = Path(os.environ.get("APPDATA", str(home / "AppData" / "Roaming")))
|
||||
return {
|
||||
# RetroArch's system directory defaults to <exe folder>\system
|
||||
# (platform_win32.c), and its installer to C:\RetroArch-Win64.
|
||||
@@ -904,11 +903,11 @@ def _rule_path(template: str) -> Path:
|
||||
def _detect_by_path(os_type: str, found: list[tuple[str, Path]]) -> None:
|
||||
"""Add what a registry path rule finds, for a platform not found yet."""
|
||||
systems = ("linux", "windows") if os_type == "wsl" else (os_type,)
|
||||
for rule_os, platform, path, bios in _PATH_RULES:
|
||||
if rule_os not in systems or any(name == platform for name, _ in found):
|
||||
for rule_os, platform_name, path, bios in _PATH_RULES:
|
||||
if rule_os not in systems or any(name == platform_name for name, _ in found):
|
||||
continue
|
||||
if _rule_path(path).exists():
|
||||
found.append((platform, _rule_path(bios or path)))
|
||||
found.append((platform_name, _rule_path(bios or path)))
|
||||
|
||||
|
||||
def detect_platforms(os_type: str) -> list[tuple[str, Path]]:
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ esac
|
||||
TEMP_INSTALLER=""
|
||||
TEMP_DIRECTORY=""
|
||||
DEFAULT_INSTALL_URL="https://raw.githubusercontent.com/Abdess/retrobios/main/install.py"
|
||||
DEFAULT_INSTALL_SHA256="dc6b428278a4352923c19ddcf055fd994aac1df77f35cb1d097e8f4c5d887ae1"
|
||||
DEFAULT_INSTALL_SHA256="973e116ab59e233cd4fe5ebb77d4973bc06013b22b6388e80d12fa1d61fb0c73"
|
||||
MAX_INSTALLER_BYTES=2097152
|
||||
|
||||
cleanup() {
|
||||
|
||||
@@ -1151,6 +1151,52 @@ class InstallerStaysOnPython38AndTheStdlib(unittest.TestCase):
|
||||
self.assertEqual(used, [])
|
||||
|
||||
|
||||
def test_no_local_is_assigned_and_never_read(self):
|
||||
"""ruff --select F in py38 mode is the installer's lint gate; an
|
||||
unread `appdata` in _os_default_dests made it exit 1. The suite has
|
||||
no ruff, so the rule is read from the syntax tree."""
|
||||
import ast # noqa: PLC0415
|
||||
|
||||
tree = ast.parse((Path(__file__).resolve().parents[1] / "install.py").read_text())
|
||||
unread = []
|
||||
for func in ast.walk(tree):
|
||||
if not isinstance(func, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
||||
continue
|
||||
stored, loaded = {}, set()
|
||||
for node in ast.walk(func):
|
||||
if isinstance(node, ast.Name):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
stored.setdefault(node.id, node.lineno)
|
||||
else:
|
||||
loaded.add(node.id)
|
||||
nested = {
|
||||
n.id for inner in ast.walk(func) if inner is not func
|
||||
and isinstance(inner, (ast.FunctionDef, ast.Lambda))
|
||||
for n in ast.walk(inner) if isinstance(n, ast.Name)
|
||||
}
|
||||
unread += [
|
||||
f"{func.name}:{line} {name}" for name, line in stored.items()
|
||||
if name not in loaded | nested and not name.startswith("_")
|
||||
and not any(
|
||||
isinstance(g, (ast.Global, ast.Nonlocal)) and name in g.names
|
||||
for g in ast.walk(func)
|
||||
)
|
||||
]
|
||||
self.assertEqual(unread, [])
|
||||
# Nor a module rebound: a loop variable named `platform` shadowed the
|
||||
# platform module in _detect_by_path (F402).
|
||||
modules = {
|
||||
alias.asname or alias.name.split(".")[0]
|
||||
for node in tree.body if isinstance(node, ast.Import)
|
||||
for alias in node.names
|
||||
}
|
||||
rebound = sorted(
|
||||
f"{node.id}:{node.lineno}" for node in ast.walk(tree)
|
||||
if isinstance(node, ast.Name) and isinstance(node.ctx, ast.Store)
|
||||
and node.id in modules
|
||||
)
|
||||
self.assertEqual(rebound, [])
|
||||
|
||||
class ARefusedCopyIsAnError(unittest.TestCase):
|
||||
"""A PermissionError on a standalone copy was counted as "dir not found"
|
||||
and the run ended on Done with exit code 0."""
|
||||
|
||||
Reference in new issue
Block a user