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
« 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.
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.
8The main classes are:
9- DefaultPreferences: Defines the default values for all preferences
10- ChebPreferences: The actual preferences object used throughout the package
12The module creates a singleton instance of ChebPreferences called _preferences,
13which is imported by other modules to access the current settings.
14"""
16from types import TracebackType
17from typing import Any, ClassVar
19import numpy as np
22class DefaultPreferences:
23 """Default preferences for chebpy."""
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
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] != "_"}
40class ChebPreferences(DefaultPreferences):
41 """Preferences object used in chebpy."""
43 def reset(self, *names: str) -> None:
44 """Reset default preferences.
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))
55 # Singleton
56 _instance: ClassVar["ChebPreferences | None"] = None # persistent reference for the singleton object
58 def __new__(cls) -> "ChebPreferences":
59 """Create or return the singleton instance of ChebPreferences.
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.
65 Args:
66 cls (type): The class being instantiated (ChebPreferences).
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
75 # Context manager
76 _stash: ClassVar[list[dict[str, Any]]] = [] # persistent stash for old prefs when entering context(s)
78 def __enter__(self) -> "ChebPreferences":
79 """Save current preferences when entering a context.
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.
85 Args:
86 self (ChebPreferences): The preferences object.
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]
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.
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.
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)
116# create the singleton object for easy import in sister modules
117_preferences = ChebPreferences()