Coverage for pySDC/helpers/pysdc_helper.py: 94%

17 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 14:51 +0000

1import logging 

2 

3 

4class FrozenClass(object): 

5 """ 

6 Helper class to freeze a class, i.e. to avoid adding more attributes 

7 

8 Attributes: 

9 __isfrozen: Flag to freeze a class 

10 """ 

11 

12 attrs = [] 

13 

14 __isfrozen = False 

15 

16 def __setattr__(self, key, value): 

17 """ 

18 Function called when setting attributes 

19 

20 Args: 

21 key: the attribute 

22 value: the value 

23 """ 

24 

25 # check if attribute exists and if class is frozen 

26 if self.__isfrozen and not (key in self.attrs or hasattr(self, key)): 

27 raise TypeError(f'{type(self).__name__!r} is a frozen class, cannot add attribute {key!r}') 

28 

29 object.__setattr__(self, key, value) 

30 

31 def __getattr__(self, key): 

32 """ 

33 This is needed in case the variables have not been initialized after adding. 

34 """ 

35 if key in self.attrs: 

36 return None 

37 else: 

38 super().__getattribute__(key) 

39 

40 @classmethod 

41 def add_attr(cls, key, raise_error_if_exists=False): 

42 """ 

43 Add a key to the allowed attributes of this class. 

44 

45 Args: 

46 key (str): The key to add 

47 raise_error_if_exists (bool): Raise an error if the attribute already exists in the class 

48 """ 

49 logger = logging.getLogger(cls.__name__) 

50 if key in cls.attrs: 

51 if raise_error_if_exists: 

52 raise TypeError(f'Attribute {key!r} already exists in {cls.__name__}!') 

53 else: 

54 logger.debug(f'Skip adding attribute {key!r} because it already exists in {cls.__name__}!') 

55 else: 

56 cls.attrs += [key] 

57 logger.debug(f'Added attribute {key!r} to {cls.__name__}') 

58 

59 def _freeze(self): 

60 """ 

61 Function to freeze the class 

62 """ 

63 self.__isfrozen = True 

64 

65 def get(self, key, default=None): 

66 """ 

67 Wrapper for `__dict__.get` to use when reading variables that might not exist, depending on the configuration 

68 

69 Args: 

70 key (str): Name of the variable you wish to read 

71 default: Value to be returned if the variable does not exist 

72 

73 Returns: 

74 __dict__.get(key, default) 

75 """ 

76 return self.__dict__.get(key, default) 

77 

78 def __dir__(self): 

79 """ 

80 My hope is that some editors can use this for dynamic autocompletion. 

81 """ 

82 return super().__dir__() + self.attrs