Coverage for src / klipper_utils / klipper_choice.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-11 21:45 +0000

1"""Klipper config file object helpers.""" 

2 

3from __future__ import annotations 

4 

5import re 

6from abc import abstractmethod 

7from enum import Enum 

8 

9from klipper_utils.klipper_utils import ConfigWrapper 

10 

11 

12class KlipperChoice(Enum): 

13 """Base class for Klipper configuration that has a predetermined list of choices. 

14 

15 This base class is used to create a list of choices for Klipper's config.getchoice() function. 

16 The extending class name determines the configuration name in snake_case format. 

17 The enum values define the available choices for the configuration. 

18 

19 Example of Klipper's configuration file:: 

20 

21 [some section name] 

22 class_name: enum_name 

23 """ 

24 

25 @classmethod 

26 def get_klipper_choices(cls) -> list[str]: 

27 """Get all values choices as string, i.e. the enum names. 

28 

29 :return: List of enum names in lower case. 

30 """ 

31 return [e.name.lower() for e in cls] 

32 

33 @classmethod 

34 def get_value[T: KlipperChoice](cls: type[T], config: ConfigWrapper) -> T: 

35 """Get the config value for the Klipper config. 

36 

37 .. py:attribute:: T 

38 :type: ~typing.TypeVar 

39 

40 The generic type parameter for this function, bound to :class:`~klipper_utils.klipper_choice.KlipperChoice`. 

41 

42 :param config: Klipper config object. 

43 :return: The value. 

44 """ 

45 # Convert extending class name to snake_case 

46 conf_name = re.sub(r'(?<!^)(?=[A-Z])', '_', cls.__name__).lower() 

47 

48 choices = cls.get_klipper_choices() 

49 # klipper 11f04ba config.getchoice(): just a dict is accepted 

50 dict_choices = dict(zip(choices, choices, strict=True)) 

51 

52 return cls[config.getchoice(conf_name, dict_choices, default=cls.get_default().name.lower()).upper()] 

53 

54 # noinspection PyAbstractClass 

55 @classmethod 

56 @abstractmethod 

57 def get_default[T: KlipperChoice](cls: type[T]) -> T: 

58 """Get the default value for the Klipper config. 

59 

60 :return: The default choice. 

61 """