Coverage for src / chebpy / settings.py: 100%

34 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-22 21:33 +0000

1"""Configuration and preferences management for the ChebPy package. 

2 

3This module provides classes for managing preferences and settings in ChebPy. 

4It implements a singleton pattern for the preferences object, ensuring that 

5all parts of the package use the same settings. It also provides a context 

6manager interface for temporarily changing preferences. 

7 

8The main classes are: 

9- DefaultPreferences: Defines the default values for all preferences 

10- ChebPreferences: The actual preferences object used throughout the package 

11 

12The module creates a singleton instance of ChebPreferences called _preferences, 

13which is imported by other modules to access the current settings. 

14""" 

15 

16from types import TracebackType 

17from typing import Any, ClassVar 

18 

19import numpy as np 

20 

21 

22class DefaultPreferences: 

23 """Default preferences for chebpy.""" 

24 

25 eps = np.finfo(float).eps 

26 tech = "Chebtech" 

27 domain = np.array([-1.0, 1.0]) # TODO: should this be .utilities.Domain? 

28 N_plot = 2001 

29 maxpow2 = 16 

30 maxiter = 10 

31 sortroots = False 

32 mergeroots = True 

33 

34 @classmethod 

35 def _defaults(cls) -> dict[str, Any]: 

36 """Returns all defined class attributes.""" 

37 return {k: v for k, v in cls.__dict__.items() if k[0] != "_"} 

38 

39 

40class ChebPreferences(DefaultPreferences): 

41 """Preferences object used in chebpy.""" 

42 

43 def reset(self, *names: str) -> None: 

44 """Reset default preferences. 

45 

46 `.reset()` resets all preferences to the DefaultPrefs state 

47 `.reset(*names)` resets only the selected ones. 

48 This leaves additional user-added prefs untouched. 

49 """ 

50 reset_names: Any = names if len(names) > 0 else DefaultPreferences._defaults() 

51 for name in reset_names: 

52 if hasattr(DefaultPreferences, name): 

53 setattr(self, name, getattr(DefaultPreferences, name)) 

54 

55 # Singleton 

56 _instance: ClassVar["ChebPreferences | None"] = None # persistent reference for the singleton object 

57 

58 def __new__(cls) -> "ChebPreferences": 

59 """Create or return the singleton instance of ChebPreferences. 

60 

61 This method implements the singleton pattern, ensuring that only one 

62 instance of ChebPreferences exists. If an instance already exists, 

63 it returns that instance; otherwise, it creates a new one. 

64 

65 Args: 

66 cls (type): The class being instantiated (ChebPreferences). 

67 

68 Returns: 

69 ChebPreferences: The singleton instance of ChebPreferences. 

70 """ 

71 if cls._instance is None: 

72 cls._instance = super(DefaultPreferences, cls).__new__(cls) 

73 return cls._instance 

74 

75 # Context manager 

76 _stash: ClassVar[list[dict[str, Any]]] = [] # persistent stash for old prefs when entering context(s) 

77 

78 def __enter__(self) -> "ChebPreferences": 

79 """Save current preferences when entering a context. 

80 

81 This method is called when entering a context manager block. It saves 

82 the current preferences to a stack so they can be restored when exiting 

83 the context. 

84 

85 Args: 

86 self (ChebPreferences): The preferences object. 

87 

88 Returns: 

89 ChebPreferences: The preferences object (self._instance). 

90 """ 

91 self._stash.append({k: getattr(self, k) for k in DefaultPreferences._defaults()}) 

92 return self._instance # type: ignore[return-value] 

93 

94 def __exit__( 

95 self, 

96 exc_type: type[BaseException] | None, 

97 exc_value: BaseException | None, 

98 traceback: TracebackType | None, 

99 ) -> None: 

100 """Restore previous preferences when exiting a context. 

101 

102 This method is called when exiting a context manager block. It restores 

103 the preferences to their previous values by popping the stashed values 

104 from the stack and setting them back on the object. 

105 

106 Args: 

107 self (ChebPreferences): The preferences object. 

108 exc_type: The exception type, if an exception was raised in the context. 

109 exc_value: The exception value, if an exception was raised in the context. 

110 traceback: The traceback, if an exception was raised in the context. 

111 """ 

112 for k, v in self._stash.pop().items(): 

113 setattr(self, k, v) 

114 

115 

116# create the singleton object for easy import in sister modules 

117_preferences = ChebPreferences()