Typing and refactoring

This commit is contained in:
Mathieu Comandon 2023-09-13 18:59:28 -07:00
parent faccec5721
commit 7a3884f4a1
8 changed files with 50 additions and 54 deletions

View file

@ -11,12 +11,12 @@ from lutris.util.system import path_exists
from lutris.util.yaml import read_yaml_from_file, write_yaml_to_file
def make_game_config_id(game_slug):
def make_game_config_id(game_slug: str) -> str:
"""Return an unique config id to avoid clashes between multiple games"""
return "{}-{}".format(game_slug, int(time.time()))
def write_game_config(game_slug, config):
def write_game_config(game_slug: str, config: dict):
"""Writes a game config to disk"""
configpath = make_game_config_id(game_slug)
logger.debug("Writing game config to %s", configpath)
@ -25,7 +25,7 @@ def write_game_config(game_slug, config):
return configpath
def duplicate_game_config(game_slug, source_config_id):
def duplicate_game_config(game_slug: str, source_config_id: str):
"""Copies an existing configuration file, giving it a new id that this
function returns."""
new_config_id = make_game_config_id(game_slug)
@ -77,7 +77,7 @@ class LutrisConfig:
"""
def __init__(self, runner_slug=None, game_config_id=None, level=None):
def __init__(self, runner_slug: str = None, game_config_id: str = None, level: str = None):
self.game_config_id = game_config_id
if runner_slug:
self.runner_slug = str(runner_slug)

View file

@ -322,8 +322,8 @@ class LutrisInitDialog(Gtk.Dialog):
self.set_border_width(24)
self.set_decorated(False)
vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 12)
label = Gtk.Label(_("Checking for runtime updates, please wait…"))
vbox.add(label)
self.label = Gtk.Label(_("Checking for runtime updates, please wait…"))
vbox.add(self.label)
self.progress = Gtk.ProgressBar(visible=True)
self.progress.set_pulse_step(0.1)
vbox.add(self.progress)

View file

@ -306,9 +306,9 @@ class RunnerInstallDialog(ModelessDialog):
runner[self.COL_INSTALLED] = False
if self.runner_name == "wine":
logger.debug("Clearing wine version cache")
from lutris.util.wine.wine import get_wine_versions
from lutris.util.wine.wine import get_installed_wine_versions
get_wine_versions.cache_clear()
get_installed_wine_versions.cache_clear()
self.update_listboxrow(row)
def on_install_runner(self, _widget, row):
@ -405,8 +405,8 @@ class RunnerInstallDialog(ModelessDialog):
self.update_listboxrow(row)
if self.runner_name == "wine":
logger.debug("Clearing wine version cache")
from lutris.util.wine.wine import get_wine_versions
get_wine_versions.cache_clear()
from lutris.util.wine.wine import get_installed_wine_versions
get_installed_wine_versions.cache_clear()
def on_destroy(self, _dialog, _data=None):
"""Override delete handler to prevent closing while downloads are active"""

View file

@ -413,7 +413,7 @@ class Runner: # pylint: disable=too-many-public-methods
return True
return self.flatpak_id and flatpak.is_app_installed(self.flatpak_id)
def get_runner_version(self, version=None, lutris_only=False):
def get_runner_version(self, version=None) -> dict:
"""Get the appropriate version for a runner, as with get_default_runner_version(),
but this method allows the runner to apply its configuration."""
return get_default_runner_version(self.name, version)
@ -430,20 +430,20 @@ class Runner: # pylint: disable=too-many-public-methods
if self.download_url:
opts["dest"] = self.directory
return self.download_and_extract(self.download_url, **opts)
runner = self.get_runner_version(version, lutris_only=True)
if not runner:
runner_version = self.get_runner_version(version)
if not runner_version:
raise RunnerInstallationError(_("Failed to retrieve {} ({}) information").format(self.name, version))
if "wine" in self.name:
opts["merge_single"] = True
opts["dest"] = os.path.join(
self.directory, "{}-{}".format(runner["version"], runner["architecture"])
self.directory, "{}-{}".format(runner_version["version"], runner_version["architecture"])
)
if self.name == "libretro" and version:
opts["merge_single"] = False
opts["dest"] = os.path.join(settings.RUNNER_DIR, "retroarch/cores")
self.download_and_extract(runner["url"], **opts)
self.download_and_extract(runner_version["url"], **opts)
def download_and_extract(self, url, dest=None, **opts):
install_ui_delegate = opts["install_ui_delegate"]
@ -469,8 +469,8 @@ class Runner: # pylint: disable=too-many-public-methods
if self.name == "wine":
logger.debug("Clearing wine version cache")
from lutris.util.wine.wine import get_wine_versions
get_wine_versions.cache_clear()
from lutris.util.wine.wine import get_installed_wine_versions
get_installed_wine_versions.cache_clear()
if self.runner_executable:
runner_executable = os.path.join(settings.RUNNER_DIR, self.runner_executable)

View file

@ -27,9 +27,9 @@ from lutris.util.wine.extract_icon import PEFILE_AVAILABLE, ExtractIcon
from lutris.util.wine.prefix import DEFAULT_DLL_OVERRIDES, WinePrefixManager, find_prefix
from lutris.util.wine.vkd3d import VKD3DManager
from lutris.util.wine.wine import (
WINE_DEFAULT_ARCH, WINE_DIR, WINE_PATHS, detect_arch, get_default_version, get_overrides_env, get_proton_paths,
get_real_executable, get_system_wine_version, get_wine_versions, is_esync_limit_set, is_fsync_supported,
is_gstreamer_build, is_version_esync, is_version_fsync
WINE_DEFAULT_ARCH, WINE_DIR, WINE_PATHS, detect_arch, get_default_version, get_installed_wine_versions,
get_overrides_env, get_proton_paths, get_real_executable, get_system_wine_version, is_esync_limit_set,
is_fsync_supported, is_gstreamer_build, is_version_esync, is_version_fsync
)
@ -257,7 +257,7 @@ class wine(Runner):
"wine-development": _("Wine Development ({})"),
"system": _("System ({})"),
}
versions = get_wine_versions()
versions = get_installed_wine_versions()
for version in versions:
if version in labels:
version_number = get_system_wine_version(WINE_PATHS[version])
@ -675,23 +675,23 @@ class wine(Runner):
arch = WINE_DEFAULT_ARCH
return arch
def get_runner_version(self, version=None, lutris_only=False):
def get_runner_version(self, version=None):
if not version:
version = self.get_version(use_default=False)
version = self.read_version_from_config(use_default=False)
if version and not lutris_only and version in WINE_PATHS:
if version in WINE_PATHS:
return {"version": version}
return super().get_runner_version(version)
def get_version(self, use_default=True):
def read_version_from_config(self, use_default=True):
"""Return the Wine version to use. use_default can be set to false to
force the installation of a specific wine version"""
# We must use the config levels to avoid getting a default if the setting
# is not set; we'll fall back to get_default_version() or None rather.
for level in self.config.all_levels:
for level in [self.config.game_level, self.config.runner_level]:
if "wine" in level:
runner_version = level["wine"].get("version")
if runner_version:
@ -725,7 +725,7 @@ class wine(Runner):
A specific version can be specified if needed.
"""
if version is None:
version = self.get_version()
version = self.read_version_from_config()
if not version:
return
@ -754,7 +754,7 @@ class wine(Runner):
"""
if version:
return system.path_exists(self.get_executable(version, fallback))
return bool(get_wine_versions())
return bool(get_installed_wine_versions())
@classmethod
def msi_exec(
@ -989,11 +989,11 @@ class wine(Runner):
env["DXVK_LOG_LEVEL"] = "none"
env["WINEARCH"] = self.wine_arch
env["WINE"] = self.get_executable()
env["WINE_MONO_CACHE_DIR"] = os.path.join(WINE_DIR, self.get_version(), "mono")
env["WINE_GECKO_CACHE_DIR"] = os.path.join(WINE_DIR, self.get_version(), "gecko")
env["WINE_MONO_CACHE_DIR"] = os.path.join(WINE_DIR, self.read_version_from_config(), "mono")
env["WINE_GECKO_CACHE_DIR"] = os.path.join(WINE_DIR, self.read_version_from_config(), "gecko")
if is_gstreamer_build(self.get_executable()):
path_64 = os.path.join(WINE_DIR, self.get_version(), "lib64/gstreamer-1.0/")
path_32 = os.path.join(WINE_DIR, self.get_version(), "lib/gstreamer-1.0/")
path_64 = os.path.join(WINE_DIR, self.read_version_from_config(), "lib64/gstreamer-1.0/")
path_32 = os.path.join(WINE_DIR, self.read_version_from_config(), "lib/gstreamer-1.0/")
if os.path.exists(path_64) or os.path.exists(path_32):
env["GST_PLUGIN_SYSTEM_PATH_1_0"] = path_64 + ":" + path_32
if self.prefix_path:
@ -1028,7 +1028,7 @@ class wine(Runner):
env["WINEDLLOVERRIDES"] = get_overrides_env(self.dll_overrides)
# Proton support
if "Proton" in self.get_version():
if "Proton" in self.read_version_from_config():
steam_dir = get_steam_dir()
if steam_dir: # May be None for example if Proton-GE is used but Steam is not installed
env["STEAM_COMPAT_CLIENT_INSTALL_PATH"] = steam_dir

View file

@ -105,7 +105,7 @@ class Downloader:
return self.progress_fraction
def join(self, progress_callback=None):
"""Blocks waiting for the downlaod to complete.
"""Blocks waiting for the download to complete.
'progress_callback' is invoked repeatedly as the download
proceeds, if given, and is passed the downloader itself.

View file

@ -139,16 +139,16 @@ def is_installed_systemwide():
return False
def list_system_wine_versions():
def list_system_wine_versions() -> list:
"""Return the list of wine versions installed on the system"""
return [
build
for build, path in WINE_PATHS.items()
name
for name, path in WINE_PATHS.items()
if get_system_wine_version(path)
]
def get_lutris_wine_versions():
def list_lutris_wine_versions() -> list:
"""Return the list of wine versions installed by lutris"""
if not system.path_exists(WINE_DIR):
return []
@ -162,7 +162,7 @@ def get_lutris_wine_versions():
return versions
def get_proton_versions():
def list_proton_versions() -> list:
"""Return the list of Proton versions installed in Steam"""
versions = []
for proton_path in get_proton_paths():
@ -179,9 +179,9 @@ def get_proton_versions():
@lru_cache(maxsize=8)
def get_wine_versions():
def get_installed_wine_versions():
"""Return the list of Wine versions installed"""
return list_system_wine_versions() + get_lutris_wine_versions() + get_proton_versions()
return list_system_wine_versions() + list_lutris_wine_versions() + list_proton_versions()
def get_wine_version_exe(version):
@ -214,25 +214,25 @@ def version_sort(versions, reverse=False):
return sorted(versions, key=version_key, reverse=reverse)
def is_esync_limit_set():
def is_esync_limit_set()->bool:
"""Checks if the number of files open is acceptable for esync usage."""
return linux.LINUX_SYSTEM.has_enough_file_descriptors()
def is_fsync_supported():
def is_fsync_supported()->bool:
"""Checks if the running kernel has Valve's futex patch applied."""
return fsync.get_fsync_support()
def get_default_version():
def get_default_version()->str:
"""Return the default version of wine."""
installed_versions = get_wine_versions()
installed_versions = get_installed_wine_versions()
if installed_versions:
default_version = get_default_runner_version("wine")
if default_version:
vers = default_version["version"] + '-' + default_version["architecture"]
if vers in installed_versions:
return vers
version = default_version["version"] + '-' + default_version["architecture"]
if version in installed_versions:
return version
return installed_versions[0]
return None

View file

@ -1,29 +1,25 @@
"""Utility functions for YAML handling"""
# Third Party Libraries
# pylint: disable=no-member
import yaml
# Lutris Modules
from lutris.util.log import logger
from lutris.util.system import path_exists
def read_yaml_from_file(filename):
def read_yaml_from_file(filename: str):
"""Read filename and return parsed yaml"""
if not path_exists(filename):
return {}
with open(filename, "r", encoding='utf-8') as yaml_file:
try:
yaml_content = yaml.safe_load(yaml_file) or {}
except (yaml.scanner.ScannerError, yaml.parser.ParserError):
logger.error("error parsing file %s", filename)
yaml_content = {}
return yaml_content
def write_yaml_to_file(config, filepath):
def write_yaml_to_file(config: dict, filepath: str):
yaml_config = yaml.safe_dump(config, default_flow_style=False)
with open(filepath, "w", encoding='utf-8') as filehandler:
filehandler.write(yaml_config)