syd 0.1.6__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
syd/support.py ADDED
@@ -0,0 +1,168 @@
1
+ from abc import ABCMeta
2
+ from typing import Any, List
3
+
4
+
5
+ class NoUpdate:
6
+ """Singleton class to represent a non-update in parameter operations."""
7
+
8
+ _instance = None
9
+ _noupdate_identifier = "NO_UPDATE"
10
+
11
+ def __new__(cls):
12
+ if cls._instance is None:
13
+ cls._instance = super().__new__(cls)
14
+ return cls._instance
15
+
16
+ def __eq__(self, other: Any):
17
+ """This makes sure all comparisons of NoUpdate objects return True"""
18
+ return isinstance(other, NoUpdate) or (
19
+ hasattr(other, "_noupdate_identifier")
20
+ and other._noupdate_identifier == self._noupdate_identifier
21
+ )
22
+
23
+
24
+ class NoInitialValue:
25
+ """Singleton class to represent a non-initial value in parameter operations."""
26
+
27
+ _instance = None
28
+ _noinitialvalue_identifier = "NO_INITIAL_VALUE"
29
+
30
+ def __new__(cls):
31
+ if cls._instance is None:
32
+ cls._instance = super().__new__(cls)
33
+ return cls._instance
34
+
35
+ def __eq__(self, other: Any):
36
+ """This makes sure all comparisons of NoInitialValue objects return True"""
37
+ return isinstance(other, NoInitialValue) or (
38
+ hasattr(other, "_noinitialvalue_identifier")
39
+ and other._noinitialvalue_identifier == self._noinitialvalue_identifier
40
+ )
41
+
42
+
43
+ # Keep original Parameter class and exceptions unchanged
44
+ class ParameterAddError(Exception):
45
+ """
46
+ Exception raised when there is an error creating a new parameter.
47
+
48
+ Parameters
49
+ ----------
50
+ parameter_name : str
51
+ Name of the parameter that failed to be created
52
+ parameter_type : str
53
+ Type of the parameter that failed to be created
54
+ message : str, optional
55
+ Additional error details
56
+ """
57
+
58
+ def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
59
+ self.parameter_name = parameter_name
60
+ self.parameter_type = parameter_type
61
+ super().__init__(
62
+ f"Failed to create {parameter_type} parameter '{parameter_name}'"
63
+ + (f": {message}" if message else "")
64
+ )
65
+
66
+
67
+ class ParameterUpdateError(Exception):
68
+ """
69
+ Exception raised when there is an error updating an existing parameter.
70
+
71
+ Parameters
72
+ ----------
73
+ parameter_name : str
74
+ Name of the parameter that failed to update
75
+ parameter_type : str
76
+ Type of the parameter that failed to update
77
+ message : str, optional
78
+ Additional error details
79
+ """
80
+
81
+ def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
82
+ self.parameter_name = parameter_name
83
+ self.parameter_type = parameter_type
84
+ super().__init__(
85
+ f"Failed to update {parameter_type} parameter '{parameter_name}'"
86
+ + (f": {message}" if message else "")
87
+ )
88
+
89
+
90
+ class ParameterUpdateWarning(Warning):
91
+ """
92
+ Warning raised when there is a non-critical issue updating a parameter.
93
+
94
+ Parameters
95
+ ----------
96
+ parameter_name : str
97
+ Name of the parameter that had the warning
98
+ parameter_type : str
99
+ Type of the parameter
100
+ message : str, optional
101
+ Additional warning details
102
+ """
103
+
104
+ def __init__(self, parameter_name: str, parameter_type: str, message: str = None):
105
+ self.parameter_name = parameter_name
106
+ self.parameter_type = parameter_type
107
+ super().__init__(
108
+ f"Warning updating {parameter_type} parameter '{parameter_name}'"
109
+ + (f": {message}" if message else "")
110
+ )
111
+
112
+
113
+ def get_parameter_attributes(param_class) -> List[str]:
114
+ """
115
+ Get all valid attributes for a parameter class.
116
+
117
+ Parameters
118
+ ----------
119
+ param_class : class
120
+ The parameter class to inspect
121
+
122
+ Returns
123
+ -------
124
+ list of str
125
+ Names of all valid attributes for the parameter class
126
+ """
127
+ attributes = []
128
+
129
+ # Walk through class hierarchy in reverse (most specific to most general)
130
+ for cls in reversed(param_class.__mro__):
131
+ if hasattr(cls, "__annotations__"):
132
+ # Only add annotations that haven't been specified by a more specific class
133
+ for name in cls.__annotations__:
134
+ if not name.startswith("_"):
135
+ attributes.append(name)
136
+
137
+ return attributes
138
+
139
+
140
+ class ParameterMeta(ABCMeta):
141
+ _parameter_types = {}
142
+ _parameter_ids = {} # Store unique identifiers for our parameter types
143
+
144
+ def __new__(cls, name, bases, namespace):
145
+ parameter_class = super().__new__(cls, name, bases, namespace)
146
+ if name != "Parameter":
147
+ # Generate a unique ID for this parameter type
148
+ type_id = f"syd.parameters.{name}" # Using fully qualified name
149
+ cls._parameter_ids[name] = type_id
150
+
151
+ # Add ID to the class
152
+ if not hasattr(parameter_class, "_parameter_type_id"):
153
+ setattr(parameter_class, "_parameter_type_id", type_id)
154
+ else:
155
+ if getattr(parameter_class, "_parameter_type_id") != type_id:
156
+ raise ValueError(
157
+ f"Parameter type {name} has multiple IDs: {type_id} and {getattr(parameter_class, '_parameter_type_id')}"
158
+ )
159
+ cls._parameter_types[name] = parameter_class
160
+ return parameter_class
161
+
162
+ def __instancecheck__(cls, instance):
163
+ type_id = cls._parameter_ids.get(cls.__name__)
164
+ if not type_id:
165
+ return False
166
+
167
+ # Check if instance has our type ID
168
+ return getattr(instance.__class__, "_parameter_type_id", None) == type_id