Use Self for return instances of cls (#4116)

This commit is contained in:
codefiles 2026-01-11 17:06:19 -05:00 committed by GitHub
parent bde3b0ed6e
commit 3374b47d50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 39 additions and 38 deletions

View File

@ -7,7 +7,7 @@ from argparse import ArgumentParser, Namespace
from dataclasses import dataclass, field from dataclasses import dataclass, field
from importlib.metadata import version from importlib.metadata import version
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any, Self
from urllib.request import Request, urlopen from urllib.request import Request, urlopen
from pydantic.dataclasses import dataclass as p_dataclass from pydantic.dataclasses import dataclass as p_dataclass
@ -131,7 +131,7 @@ class ArchConfig:
return config return config
@classmethod @classmethod
def from_config(cls, args_config: dict[str, Any], args: Arguments) -> 'ArchConfig': def from_config(cls, args_config: dict[str, Any], args: Arguments) -> Self:
arch_config = cls() arch_config = cls()
arch_config.locale_config = LocaleConfiguration.parse_arg(args_config) arch_config.locale_config = LocaleConfiguration.parse_arg(args_config)

View File

@ -2,6 +2,7 @@ import os
from enum import Enum from enum import Enum
from functools import cached_property from functools import cached_property
from pathlib import Path from pathlib import Path
from typing import Self
from .exceptions import SysCallError from .exceptions import SysCallError
from .general import SysCommand from .general import SysCommand
@ -16,7 +17,7 @@ class CpuVendor(Enum):
_Unknown = 'unknown' _Unknown = 'unknown'
@classmethod @classmethod
def get_vendor(cls, name: str) -> 'CpuVendor': def get_vendor(cls, name: str) -> Self:
if vendor := getattr(cls, name, None): if vendor := getattr(cls, name, None):
return vendor return vendor
else: else:

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import sys import sys
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum from enum import Enum
from typing import Any from typing import Any, Self
from archinstall.lib.translationhandler import tr from archinstall.lib.translationhandler import tr
@ -33,7 +33,7 @@ class Bootloader(Enum):
return self.value return self.value
@classmethod @classmethod
def get_default(cls) -> Bootloader: def get_default(cls) -> Self:
from ..args import arch_config_handler from ..args import arch_config_handler
if arch_config_handler.args.skip_boot: if arch_config_handler.args.skip_boot:
@ -44,7 +44,7 @@ class Bootloader(Enum):
return cls.Grub return cls.Grub
@classmethod @classmethod
def from_arg(cls, bootloader: str, skip_boot: bool) -> Bootloader: def from_arg(cls, bootloader: str, skip_boot: bool) -> Self:
# to support old configuration files # to support old configuration files
bootloader = bootloader.capitalize() bootloader = bootloader.capitalize()
@ -68,14 +68,14 @@ class BootloaderConfiguration:
return {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable} return {'bootloader': self.bootloader.json(), 'uki': self.uki, 'removable': self.removable}
@classmethod @classmethod
def parse_arg(cls, config: dict[str, Any], skip_boot: bool) -> BootloaderConfiguration: def parse_arg(cls, config: dict[str, Any], skip_boot: bool) -> Self:
bootloader = Bootloader.from_arg(config.get('bootloader', ''), skip_boot) bootloader = Bootloader.from_arg(config.get('bootloader', ''), skip_boot)
uki = config.get('uki', False) uki = config.get('uki', False)
removable = config.get('removable', True) removable = config.get('removable', True)
return cls(bootloader=bootloader, uki=uki, removable=removable) return cls(bootloader=bootloader, uki=uki, removable=removable)
@classmethod @classmethod
def get_default(cls) -> BootloaderConfiguration: def get_default(cls) -> Self:
bootloader = Bootloader.get_default() bootloader = Bootloader.get_default()
removable = SysInfo.has_uefi() and bootloader.has_removable_support() removable = SysInfo.has_uefi() and bootloader.has_removable_support()
uki = SysInfo.has_uefi() and bootloader.has_uki_support() uki = SysInfo.has_uefi() and bootloader.has_uki_support()

View File

@ -86,7 +86,7 @@ class DiskLayoutConfiguration:
cls, cls,
disk_config: _DiskLayoutConfigurationSerialization, disk_config: _DiskLayoutConfigurationSerialization,
enc_password: Password | None = None, enc_password: Password | None = None,
) -> DiskLayoutConfiguration | None: ) -> Self | None:
from archinstall.lib.disk.device_handler import device_handler from archinstall.lib.disk.device_handler import device_handler
device_modifications: list[DeviceModification] = [] device_modifications: list[DeviceModification] = []
@ -223,7 +223,7 @@ class PartitionTable(Enum):
return self == PartitionTable.MBR return self == PartitionTable.MBR
@classmethod @classmethod
def default(cls) -> PartitionTable: def default(cls) -> Self:
return cls.GPT if SysInfo.has_uefi() else cls.MBR return cls.GPT if SysInfo.has_uefi() else cls.MBR
@ -293,7 +293,7 @@ class SectorSize:
} }
@classmethod @classmethod
def parse_args(cls, arg: _SectorSizeSerialization) -> SectorSize: def parse_args(cls, arg: _SectorSizeSerialization) -> Self:
return cls( return cls(
arg['value'], arg['value'],
Unit[arg['unit']], Unit[arg['unit']],
@ -330,7 +330,7 @@ class Size:
} }
@classmethod @classmethod
def parse_args(cls, size_arg: _SizeSerialization) -> Size: def parse_args(cls, size_arg: _SizeSerialization) -> Self:
sector_size = size_arg['sector_size'] sector_size = size_arg['sector_size']
return cls( return cls(
@ -537,7 +537,7 @@ class _PartitionInfo:
lsblk_info: LsblkInfo, lsblk_info: LsblkInfo,
fs_type: FilesystemType | None, fs_type: FilesystemType | None,
btrfs_subvol_infos: list[_BtrfsSubvolumeInfo] = [], btrfs_subvol_infos: list[_BtrfsSubvolumeInfo] = [],
) -> _PartitionInfo: ) -> Self:
partition_type = PartitionType.get_type_from_code(partition.type) partition_type = PartitionType.get_type_from_code(partition.type)
flags = [f for f in PartitionFlag if partition.getFlag(f.flag_id)] flags = [f for f in PartitionFlag if partition.getFlag(f.flag_id)]
@ -595,7 +595,7 @@ class _DeviceInfo:
} }
@classmethod @classmethod
def from_disk(cls, disk: Disk) -> _DeviceInfo: def from_disk(cls, disk: Disk) -> Self:
device = disk.device device = disk.device
if device.type == 18: if device.type == 18:
device_type = 'loop' device_type = 'loop'
@ -631,11 +631,11 @@ class SubvolumeModification:
mountpoint: Path | None = None mountpoint: Path | None = None
@classmethod @classmethod
def from_existing_subvol_info(cls, info: _BtrfsSubvolumeInfo) -> SubvolumeModification: def from_existing_subvol_info(cls, info: _BtrfsSubvolumeInfo) -> Self:
return cls(info.name, mountpoint=info.mountpoint) return cls(info.name, mountpoint=info.mountpoint)
@classmethod @classmethod
def parse_args(cls, subvol_args: list[_SubvolumeModificationSerialization]) -> list[SubvolumeModification]: def parse_args(cls, subvol_args: list[_SubvolumeModificationSerialization]) -> list[Self]:
mods = [] mods = []
for entry in subvol_args: for entry in subvol_args:
if not entry.get('name', None) or not entry.get('mountpoint', None): if not entry.get('name', None) or not entry.get('mountpoint', None):
@ -721,7 +721,7 @@ class PartitionType(Enum):
_Unknown = 'unknown' _Unknown = 'unknown'
@classmethod @classmethod
def get_type_from_code(cls, code: int) -> PartitionType: def get_type_from_code(cls, code: int) -> Self:
if code == parted.PARTITION_NORMAL: if code == parted.PARTITION_NORMAL:
return cls.Primary return cls.Primary
else: else:
@ -754,7 +754,7 @@ class PartitionFlag(PartitionFlagDataMixin, Enum):
return self.alias or self.name.lower() return self.alias or self.name.lower()
@classmethod @classmethod
def from_string(cls, s: str) -> PartitionFlag | None: def from_string(cls, s: str) -> Self | None:
s = s.lower() s = s.lower()
for partition_flag in cls: for partition_flag in cls:
@ -911,7 +911,7 @@ class PartitionModification:
return self.fs_type return self.fs_type
@classmethod @classmethod
def from_existing_partition(cls, partition_info: _PartitionInfo) -> PartitionModification: def from_existing_partition(cls, partition_info: _PartitionInfo) -> Self:
if partition_info.btrfs_subvol_infos: if partition_info.btrfs_subvol_infos:
mountpoint = None mountpoint = None
subvol_mods = [] subvol_mods = []
@ -1431,7 +1431,7 @@ class EncryptionType(Enum):
LuksOnLvm = 'luks_on_lvm' LuksOnLvm = 'luks_on_lvm'
@classmethod @classmethod
def _encryption_type_mapper(cls) -> dict[str, 'EncryptionType']: def _encryption_type_mapper(cls) -> dict[str, Self]:
return { return {
tr('No Encryption'): cls.NoEncryption, tr('No Encryption'): cls.NoEncryption,
tr('LUKS'): cls.Luks, tr('LUKS'): cls.Luks,
@ -1440,7 +1440,7 @@ class EncryptionType(Enum):
} }
@classmethod @classmethod
def text_to_type(cls, text: str) -> 'EncryptionType': def text_to_type(cls, text: str) -> Self:
mapping = cls._encryption_type_mapper() mapping = cls._encryption_type_mapper()
return mapping[text] return mapping[text]
@ -1518,7 +1518,7 @@ class DiskEncryption:
disk_config: DiskLayoutConfiguration, disk_config: DiskLayoutConfiguration,
disk_encryption: _DiskEncryptionSerialization, disk_encryption: _DiskEncryptionSerialization,
password: Password | None = None, password: Password | None = None,
) -> 'DiskEncryption | None': ) -> Self | None:
if not cls.validate_enc(disk_config.device_modifications, disk_config.lvm_config): if not cls.validate_enc(disk_config.device_modifications, disk_config.lvm_config):
return None return None
@ -1580,7 +1580,7 @@ class Fido2Device:
} }
@classmethod @classmethod
def parse_arg(cls, arg: _Fido2DeviceSerialization) -> 'Fido2Device': def parse_arg(cls, arg: _Fido2DeviceSerialization) -> Self:
return cls( return cls(
Path(arg['path']), Path(arg['path']),
arg['manufacturer'], arg['manufacturer'],

View File

@ -41,7 +41,7 @@ class LocaleConfiguration:
self.kb_layout = args['kb_layout'] self.kb_layout = args['kb_layout']
@classmethod @classmethod
def parse_arg(cls, args: dict[str, Any]) -> 'LocaleConfiguration': def parse_arg(cls, args: dict[str, Any]) -> Self:
default = cls.default() default = cls.default()
if 'locale_config' in args: if 'locale_config' in args:

View File

@ -5,7 +5,7 @@ import urllib.parse
import urllib.request import urllib.request
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
from typing import Any, TypedDict, override from typing import Any, Self, TypedDict, override
from pydantic import BaseModel, field_validator, model_validator from pydantic import BaseModel, field_validator, model_validator
@ -191,7 +191,7 @@ class CustomRepository:
} }
@classmethod @classmethod
def parse_args(cls, args: list[dict[str, str]]) -> list['CustomRepository']: def parse_args(cls, args: list[dict[str, str]]) -> list[Self]:
configs = [] configs = []
for arg in args: for arg in args:
configs.append( configs.append(
@ -217,7 +217,7 @@ class CustomServer:
return {'url': self.url} return {'url': self.url}
@classmethod @classmethod
def parse_args(cls, args: list[dict[str, str]]) -> list['CustomServer']: def parse_args(cls, args: list[dict[str, str]]) -> list[Self]:
configs = [] configs = []
for arg in args: for arg in args:
configs.append( configs.append(
@ -304,7 +304,7 @@ class MirrorConfiguration:
cls, cls,
args: dict[str, Any], args: dict[str, Any],
backwards_compatible_repo: list[Repository] = [], backwards_compatible_repo: list[Repository] = [],
) -> 'MirrorConfiguration': ) -> Self:
config = cls() config = cls()
mirror_regions = args.get('mirror_regions', []) mirror_regions = args.get('mirror_regions', [])

View File

@ -226,7 +226,7 @@ class WifiConfiguredNetwork:
flags: list[str] flags: list[str]
@classmethod @classmethod
def from_wpa_cli_output(cls, list_networks: str) -> list[WifiConfiguredNetwork]: def from_wpa_cli_output(cls, list_networks: str) -> list[Self]:
""" """
Example output from 'wpa_cli list_networks' Example output from 'wpa_cli list_networks'

View File

@ -152,8 +152,8 @@ class PackageGroup:
def from_available_packages( def from_available_packages(
cls, cls,
packages: dict[str, AvailablePackage], packages: dict[str, AvailablePackage],
) -> dict[str, 'PackageGroup']: ) -> dict[str, Self]:
pkg_groups: dict[str, 'PackageGroup'] = {} pkg_groups: dict[str, Self] = {}
for pkg in packages.values(): for pkg in packages.values():
if 'None' in pkg.groups: if 'None' in pkg.groups:

View File

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING, TypedDict from typing import TYPE_CHECKING, Self, TypedDict
from archinstall.default_profiles.profile import GreeterType, Profile from archinstall.default_profiles.profile import GreeterType, Profile
@ -33,7 +33,7 @@ class ProfileConfiguration:
} }
@classmethod @classmethod
def parse_arg(cls, arg: _ProfileConfigurationSerialization) -> 'ProfileConfiguration': def parse_arg(cls, arg: _ProfileConfigurationSerialization) -> Self:
from ..profile.profiles_handler import profile_handler from ..profile.profiles_handler import profile_handler
profile = profile_handler.parse_profile_config(arg['profile']) profile = profile_handler.parse_profile_config(arg['profile'])

View File

@ -1,6 +1,6 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
from typing import NotRequired, TypedDict, override from typing import NotRequired, Self, TypedDict, override
from archinstall.lib.translationhandler import tr from archinstall.lib.translationhandler import tr
@ -38,7 +38,7 @@ class PasswordStrength(Enum):
return 'green' return 'green'
@classmethod @classmethod
def strength(cls, password: str) -> 'PasswordStrength': def strength(cls, password: str) -> Self:
digit = any(character.isdigit() for character in password) digit = any(character.isdigit() for character in password)
upper = any(character.isupper() for character in password) upper = any(character.isupper() for character in password)
lower = any(character.islower() for character in password) lower = any(character.islower() for character in password)
@ -53,7 +53,7 @@ class PasswordStrength(Enum):
lower: bool, lower: bool,
symbol: bool, symbol: bool,
length: int, length: int,
) -> 'PasswordStrength': ) -> Self:
# suggested evaluation # suggested evaluation
# https://github.com/archlinux/archinstall/issues/1304#issuecomment-1146768163 # https://github.com/archlinux/archinstall/issues/1304#issuecomment-1146768163
if digit and upper and lower and symbol: if digit and upper and lower and symbol:
@ -185,8 +185,8 @@ class User:
def parse_arguments( def parse_arguments(
cls, cls,
args: list[UserSerialization], args: list[UserSerialization],
) -> list['User']: ) -> list[Self]:
users: list[User] = [] users = []
for entry in args: for entry in args:
username = entry.get('username') username = entry.get('username')