GeneralManager 0.4.3__tar.gz → 0.4.5__tar.gz
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.
- {generalmanager-0.4.3 → generalmanager-0.4.5}/GeneralManager.egg-info/PKG-INFO +1 -1
- {generalmanager-0.4.3 → generalmanager-0.4.5}/PKG-INFO +1 -1
- {generalmanager-0.4.3 → generalmanager-0.4.5}/pyproject.toml +1 -1
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/measurement/measurement.py +49 -2
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_measurement.py +112 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/GeneralManager.egg-info/SOURCES.txt +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/LICENSE +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/README.md +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/setup.cfg +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/apps.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/auxiliary/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/auxiliary/argsToKwargs.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/auxiliary/filterParser.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/auxiliary/jsonEncoder.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/auxiliary/makeCacheKey.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/auxiliary/noneToZero.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/auxiliary/pathMapping.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/cache/cacheDecorator.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/cache/cacheTracker.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/cache/dependencyIndex.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/cache/modelDependencyCollector.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/cache/signals.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/factory/factoryMethods.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/interface/baseInterface.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/interface/calculationInterface.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/interface/databaseInterface.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/manager/generalManager.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/manager/groupManager.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/measurement/measurementField.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/basePermission.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/fileBasedPermission.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/managerBasedPermission.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/permissionChecks.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/permissionDataManager.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_argsToKwargs.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_basePermission.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_cacheDecorator.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_cacheTracker.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_dependencyIndex.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_factories.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_factoryMethods.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_filterParser.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_graph_ql.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_input.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_jsonEncoder.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_makeCacheKey.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_managerBasedPermission.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_measurement_field.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_modelDependencyCollector.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_noneToZero.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_rule_handler.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_rules.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_settings.py +0 -0
- {generalmanager-0.4.3 → generalmanager-0.4.5}/tests/test_signals.py +0 -0
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/measurement/measurement.py
RENAMED
@@ -56,7 +56,22 @@ class Measurement:
|
|
56
56
|
|
57
57
|
@classmethod
|
58
58
|
def from_string(cls, value: str) -> Measurement:
|
59
|
-
|
59
|
+
"""
|
60
|
+
Creates a Measurement instance from a string in the format 'value unit'.
|
61
|
+
|
62
|
+
Args:
|
63
|
+
value: A string containing a numeric value and a unit separated by a space (e.g., '10.5 kg').
|
64
|
+
|
65
|
+
Returns:
|
66
|
+
A Measurement instance representing the parsed value and unit.
|
67
|
+
|
68
|
+
Raises:
|
69
|
+
ValueError: If the input string does not contain exactly two parts separated by a space.
|
70
|
+
"""
|
71
|
+
splitted = value.split(" ")
|
72
|
+
if len(splitted) != 2:
|
73
|
+
raise ValueError("String must be in the format 'value unit'.")
|
74
|
+
value, unit = splitted
|
60
75
|
return cls(value, unit)
|
61
76
|
|
62
77
|
@staticmethod
|
@@ -202,12 +217,31 @@ class Measurement:
|
|
202
217
|
return f"Measurement({self.quantity.magnitude}, '{self.quantity.units}')"
|
203
218
|
|
204
219
|
def _compare(self, other: Any, operation: Callable[..., bool]) -> bool:
|
220
|
+
"""
|
221
|
+
Compares this Measurement with another using the specified comparison operation.
|
222
|
+
|
223
|
+
If `other` is a string, it is parsed into a Measurement. Raises a TypeError if
|
224
|
+
`other` is not a Measurement instance. Converts `other` to this instance's unit
|
225
|
+
before applying the comparison. Raises a ValueError if the measurements have
|
226
|
+
incompatible dimensions.
|
227
|
+
|
228
|
+
Args:
|
229
|
+
other: The object to compare with, either a Measurement or a string in the format "value unit".
|
230
|
+
operation: A callable that takes two magnitudes and returns a boolean result.
|
231
|
+
|
232
|
+
Returns:
|
233
|
+
The result of the comparison operation.
|
234
|
+
|
235
|
+
Raises:
|
236
|
+
TypeError: If `other` is not a Measurement instance or a valid string representation.
|
237
|
+
ValueError: If the measurements have different dimensions and cannot be compared.
|
238
|
+
"""
|
205
239
|
if isinstance(other, str):
|
206
240
|
other = Measurement.from_string(other)
|
207
241
|
|
208
242
|
# Überprüfen, ob `other` ein Measurement-Objekt ist
|
209
243
|
if not isinstance(other, Measurement):
|
210
|
-
|
244
|
+
raise TypeError("Comparison is only allowed between Measurement instances.")
|
211
245
|
try:
|
212
246
|
# Convert `other` to the same units as `self`
|
213
247
|
other_converted: pint.Quantity = other.quantity.to(self.quantity.units) # type: ignore
|
@@ -238,4 +272,17 @@ class Measurement:
|
|
238
272
|
return self._compare(other, gt)
|
239
273
|
|
240
274
|
def __ge__(self, other: Any) -> bool:
|
275
|
+
"""
|
276
|
+
Returns True if this measurement is greater than or equal to another measurement.
|
277
|
+
|
278
|
+
Comparison is performed after converting the other operand to the same unit. Raises a TypeError if the other object is not a Measurement instance or a compatible string, or a ValueError if the units are not compatible.
|
279
|
+
"""
|
241
280
|
return self._compare(other, ge)
|
281
|
+
|
282
|
+
def __hash__(self) -> int:
|
283
|
+
"""
|
284
|
+
Returns a hash value based on the magnitude and unit of the measurement.
|
285
|
+
|
286
|
+
This enables Measurement instances to be used in hash-based collections such as sets and dictionaries.
|
287
|
+
"""
|
288
|
+
return hash((self.quantity.magnitude, str(self.quantity.units)))
|
@@ -40,12 +40,29 @@ class MeasurementTestCase(TestCase):
|
|
40
40
|
self.assertEqual(str(result), "3 meter")
|
41
41
|
|
42
42
|
def test_addition_different_units_same_dimension(self):
|
43
|
+
"""
|
44
|
+
Tests addition of `Measurement` instances with different units of the same physical dimension.
|
45
|
+
|
46
|
+
Verifies correct unit conversion and commutativity when adding measurements with compatible units (e.g., kilometers and meters). Asserts that adding zero to a `Measurement` returns the measurement unchanged, and that adding a plain number raises a `TypeError`.
|
47
|
+
"""
|
43
48
|
m1 = Measurement(1, "kilometer") # 1000 meter
|
44
49
|
m2 = Measurement(500, "meter")
|
45
50
|
result = m1 + m2
|
46
51
|
self.assertEqual(str(result), "1.5 kilometer")
|
47
52
|
|
53
|
+
result = m2 + m1 # Commutative property
|
54
|
+
self.assertEqual(str(result), "1500 meter")
|
55
|
+
|
56
|
+
result = 0 + m1
|
57
|
+
self.assertEqual(str(result), "1 kilometer")
|
58
|
+
|
59
|
+
with self.assertRaises(TypeError):
|
60
|
+
_ = 10 + m1 # Adding a number to a Measurement should raise an error
|
61
|
+
|
48
62
|
def test_subtraction_different_units_same_dimension(self):
|
63
|
+
"""
|
64
|
+
Tests subtraction of two Measurement instances with different units but the same physical dimension, verifying correct unit conversion and result.
|
65
|
+
"""
|
49
66
|
m1 = Measurement(2, "kilometer") # 2000 meter
|
50
67
|
m2 = Measurement(500, "meter")
|
51
68
|
result = m1 - m2
|
@@ -104,6 +121,11 @@ class MeasurementTestCase(TestCase):
|
|
104
121
|
self.assertEqual(str(result), "1 meter")
|
105
122
|
|
106
123
|
def test_random_measurements(self):
|
124
|
+
"""
|
125
|
+
Tests addition and subtraction of randomly generated Measurement instances with various units.
|
126
|
+
|
127
|
+
Randomly generates pairs of Measurement objects with physical or currency units and verifies correct arithmetic behavior. Ensures that operations with matching units succeed, while operations between incompatible units or between currency and physical units raise appropriate exceptions.
|
128
|
+
"""
|
107
129
|
units = ["meter", "second", "kilogram", "liter", "EUR", "USD"]
|
108
130
|
for _ in range(100):
|
109
131
|
random_value_1 = Decimal(random.uniform(1, 1000))
|
@@ -138,3 +160,93 @@ class MeasurementTestCase(TestCase):
|
|
138
160
|
|
139
161
|
with self.assertRaises(ValueError):
|
140
162
|
result_sub = measurement_1 - measurement_2
|
163
|
+
|
164
|
+
def test_pickleable(self):
|
165
|
+
"""
|
166
|
+
Tests that a Measurement instance can be pickled and unpickled, preserving its value and units.
|
167
|
+
"""
|
168
|
+
import pickle
|
169
|
+
|
170
|
+
m = Measurement(10, "meter")
|
171
|
+
m_pickled = pickle.dumps(m)
|
172
|
+
m_unpickled = pickle.loads(m_pickled)
|
173
|
+
self.assertEqual(str(m), str(m_unpickled))
|
174
|
+
self.assertEqual(m.quantity.units, m_unpickled.quantity.units)
|
175
|
+
self.assertEqual(m.quantity.magnitude, m_unpickled.quantity.magnitude)
|
176
|
+
|
177
|
+
def test_equality(self):
|
178
|
+
"""
|
179
|
+
Tests equality comparisons between Measurement instances, including correct handling of value and unit differences and appropriate exception raising for invalid comparisons.
|
180
|
+
"""
|
181
|
+
m1 = Measurement(10, "meter")
|
182
|
+
m2 = Measurement(10, "meter")
|
183
|
+
m3 = Measurement(5, "meter")
|
184
|
+
|
185
|
+
self.assertEqual(m1, m2)
|
186
|
+
self.assertNotEqual(m1, m3)
|
187
|
+
with self.assertRaises(ValueError):
|
188
|
+
_ = m1 == "not a measurement"
|
189
|
+
with self.assertRaises(TypeError):
|
190
|
+
_ = m1 == 10
|
191
|
+
with self.assertRaises(ValueError):
|
192
|
+
_ = m1 == Measurement(10, "second")
|
193
|
+
|
194
|
+
def test_inequality(self):
|
195
|
+
"""
|
196
|
+
Tests inequality comparisons between Measurement instances.
|
197
|
+
|
198
|
+
Verifies that measurements with identical values and units are considered equal, while those with different values are not. Ensures that comparing a Measurement to an incompatible type or to a measurement with a different unit raises the appropriate exception.
|
199
|
+
"""
|
200
|
+
m1 = Measurement(10, "meter")
|
201
|
+
m2 = Measurement(10, "meter")
|
202
|
+
m3 = Measurement(5, "meter")
|
203
|
+
|
204
|
+
self.assertFalse(m1 != m2)
|
205
|
+
self.assertTrue(m1 != m3)
|
206
|
+
with self.assertRaises(ValueError):
|
207
|
+
_ = m1 != "not a measurement"
|
208
|
+
with self.assertRaises(TypeError):
|
209
|
+
_ = m1 != 10
|
210
|
+
with self.assertRaises(ValueError):
|
211
|
+
_ = m1 != Measurement(10, "second")
|
212
|
+
|
213
|
+
def test_comparison(self):
|
214
|
+
"""
|
215
|
+
Tests relational comparison operators for Measurement instances.
|
216
|
+
|
217
|
+
Verifies correct behavior of equality and ordering comparisons between Measurement objects with the same and different values and units. Ensures that comparing with incompatible types or units raises appropriate exceptions.
|
218
|
+
"""
|
219
|
+
m1 = Measurement(10, "meter")
|
220
|
+
m2 = Measurement(10, "meter")
|
221
|
+
m3 = Measurement(5, "meter")
|
222
|
+
|
223
|
+
self.assertTrue(m1 == m2)
|
224
|
+
self.assertFalse(m1 < m2)
|
225
|
+
self.assertFalse(m1 > m2)
|
226
|
+
self.assertTrue(m1 >= m2)
|
227
|
+
self.assertTrue(m1 <= m2)
|
228
|
+
|
229
|
+
self.assertTrue(m1 > m3)
|
230
|
+
self.assertFalse(m1 < m3)
|
231
|
+
self.assertTrue(m1 >= m3)
|
232
|
+
self.assertFalse(m1 <= m3)
|
233
|
+
|
234
|
+
with self.assertRaises(ValueError):
|
235
|
+
_ = m1 < "not a measurement"
|
236
|
+
with self.assertRaises(TypeError):
|
237
|
+
_ = m1 < 10
|
238
|
+
with self.assertRaises(ValueError):
|
239
|
+
_ = m1 < Measurement(10, "second")
|
240
|
+
|
241
|
+
def test_hash(self):
|
242
|
+
"""
|
243
|
+
Tests that Measurement instances with equal values and units have equal hashes, and that differing values, units, or types produce different hashes.
|
244
|
+
"""
|
245
|
+
m1 = Measurement(10, "meter")
|
246
|
+
m2 = Measurement(10, "meter")
|
247
|
+
m3 = Measurement(5, "meter")
|
248
|
+
|
249
|
+
self.assertEqual(hash(m1), hash(m2))
|
250
|
+
self.assertNotEqual(hash(m1), hash(m3))
|
251
|
+
self.assertNotEqual(hash(m1), hash(Measurement(10, "second")))
|
252
|
+
self.assertNotEqual(hash(m1), hash("not a measurement"))
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/cache/modelDependencyCollector.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/interface/baseInterface.py
RENAMED
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/interface/calculationInterface.py
RENAMED
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/interface/databaseInterface.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/measurement/measurementField.py
RENAMED
File without changes
|
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/basePermission.py
RENAMED
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/fileBasedPermission.py
RENAMED
File without changes
|
File without changes
|
{generalmanager-0.4.3 → generalmanager-0.4.5}/src/general_manager/permission/permissionChecks.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|