Coverage for src/seqrule/analysis/base.py: 61%

72 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-27 10:56 -0600

1""" 

2Base classes and enums for the analysis module. 

3 

4This module provides the fundamental types used throughout the analysis system: 

5- Complexity classes for time/space analysis 

6- Property access types for tracking how properties are used 

7- Base exceptions and utility types 

8""" 

9 

10from dataclasses import dataclass, field 

11from enum import Enum, auto 

12from typing import Set 

13 

14 

15class ComplexityClass(Enum): 

16 """Complexity classes for time and space analysis.""" 

17 

18 CONSTANT = 1 # O(1) 

19 LOGARITHMIC = 2 # O(log n) 

20 LINEAR = 3 # O(n) 

21 LINEARITHMIC = 4 # O(n log n) 

22 QUADRATIC = 5 # O(n²) 

23 CUBIC = 6 # O(n³) 

24 EXPONENTIAL = 7 # O(2ⁿ) 

25 FACTORIAL = 8 # O(n!) 

26 

27 def __lt__(self, other): 

28 if not isinstance(other, ComplexityClass): 

29 return NotImplemented 

30 return self.value < other.value 

31 

32 def __le__(self, other): 

33 if not isinstance(other, ComplexityClass): 

34 return NotImplemented 

35 return self.value <= other.value 

36 

37 def __gt__(self, other): 

38 if not isinstance(other, ComplexityClass): 

39 return NotImplemented 

40 return self.value > other.value 

41 

42 def __ge__(self, other): 

43 if not isinstance(other, ComplexityClass): 

44 return NotImplemented 

45 return self.value >= other.value 

46 

47 def __str__(self) -> str: 

48 """Return the big-O notation for this complexity class.""" 

49 return { 

50 ComplexityClass.CONSTANT: "O(1)", 

51 ComplexityClass.LOGARITHMIC: "O(log n)", 

52 ComplexityClass.LINEAR: "O(n)", 

53 ComplexityClass.LINEARITHMIC: "O(n log n)", 

54 ComplexityClass.QUADRATIC: "O(n²)", 

55 ComplexityClass.CUBIC: "O(n³)", 

56 ComplexityClass.EXPONENTIAL: "O(2ⁿ)", 

57 ComplexityClass.FACTORIAL: "O(n!)", 

58 }[self] 

59 

60 

61class PropertyAccessType(Enum): 

62 """Types of property access patterns.""" 

63 

64 READ = auto() # Direct read access 

65 CONDITIONAL = auto() # Used in conditional 

66 COMPARISON = auto() # Used in comparison 

67 METHOD = auto() # Method call 

68 NESTED = auto() # Nested property access 

69 

70 

71class ValidatedAccessTypeSet(set): 

72 """A set that only accepts PropertyAccessType values.""" 

73 

74 def add(self, item): 

75 if not isinstance(item, PropertyAccessType): 

76 raise ValueError( 

77 f"Invalid access type: {item}. Must be a PropertyAccessType." 

78 ) 

79 super().add(item) 

80 

81 

82@dataclass 

83class PropertyAccess: 

84 """Details about how a property is accessed.""" 

85 

86 name: str 

87 access_types: Set[PropertyAccessType] = field( 

88 default_factory=ValidatedAccessTypeSet 

89 ) 

90 access_count: int = 0 

91 nested_properties: Set[str] = field(default_factory=set) 

92 

93 

94class ComplexityScore(Enum): 

95 """Complexity score levels.""" 

96 

97 TRIVIAL = 1 

98 SIMPLE = 2 

99 MODERATE = 3 

100 COMPLEX = 4 

101 VERY_COMPLEX = 5 

102 EXTREME = 6 

103 

104 def __lt__(self, other): 

105 if not isinstance(other, ComplexityScore): 

106 return NotImplemented 

107 return self.value < other.value 

108 

109 def __le__(self, other): 

110 if not isinstance(other, ComplexityScore): 

111 return NotImplemented 

112 return self.value <= other.value 

113 

114 def __gt__(self, other): 

115 if not isinstance(other, ComplexityScore): 

116 return NotImplemented 

117 return self.value > other.value 

118 

119 def __ge__(self, other): 

120 if not isinstance(other, ComplexityScore): 

121 return NotImplemented 

122 return self.value >= other.value 

123 

124 

125class AnalysisError(Exception): 

126 """Error raised during rule analysis.""" 

127 

128 pass