mirror of
https://github.com/openSUSE/osc.git
synced 2024-12-29 11:16:14 +01:00
Implement total ordering on BaseModel
This commit is contained in:
parent
747eb0ec52
commit
cd95478ac8
@ -7,6 +7,7 @@ This module IS NOT a supported API, it is meant for osc internal use only.
|
||||
"""
|
||||
|
||||
import copy
|
||||
import functools
|
||||
import inspect
|
||||
import sys
|
||||
import tempfile
|
||||
@ -368,6 +369,7 @@ class ModelMeta(type):
|
||||
return new_cls
|
||||
|
||||
|
||||
@functools.total_ordering
|
||||
class BaseModel(metaclass=ModelMeta):
|
||||
__fields__: Dict[str, Field]
|
||||
|
||||
@ -412,10 +414,28 @@ class BaseModel(metaclass=ModelMeta):
|
||||
|
||||
self._allow_new_attributes = False
|
||||
|
||||
def _get_cmp_data(self):
|
||||
result = []
|
||||
for name, field in self.__fields__.items():
|
||||
if field.exclude:
|
||||
continue
|
||||
value = getattr(self, name)
|
||||
if isinstance(value, dict):
|
||||
value = sorted(list(value.items()))
|
||||
result.append((name, value))
|
||||
return result
|
||||
|
||||
def __eq__(self, other):
|
||||
if type(self) != type(other):
|
||||
return False
|
||||
return self.dict() == other.dict()
|
||||
if self._get_cmp_data() != other._get_cmp_data():
|
||||
print(self._get_cmp_data(), other._get_cmp_data())
|
||||
return self._get_cmp_data() == other._get_cmp_data()
|
||||
|
||||
def __lt__(self, other):
|
||||
if type(self) != type(other):
|
||||
return False
|
||||
return self._get_cmp_data() < other._get_cmp_data()
|
||||
|
||||
def dict(self):
|
||||
result = {}
|
||||
|
@ -395,6 +395,57 @@ class Test(unittest.TestCase):
|
||||
self.assertIsInstance(m.field[0], BaseModel)
|
||||
self.assertEqual(m.field[0].text, "value")
|
||||
|
||||
def test_ordering(self):
|
||||
class TestSubmodel(BaseModel):
|
||||
txt: Optional[str] = Field()
|
||||
|
||||
class TestModel(BaseModel):
|
||||
num: Optional[int] = Field()
|
||||
txt: Optional[str] = Field()
|
||||
sub: Optional[TestSubmodel] = Field()
|
||||
dct: Optional[Dict[str, TestSubmodel]] = Field()
|
||||
|
||||
m1 = TestModel()
|
||||
m2 = TestModel()
|
||||
self.assertEqual(m1, m2)
|
||||
|
||||
m1 = TestModel(num=1)
|
||||
m2 = TestModel(num=2)
|
||||
self.assertNotEqual(m1, m2)
|
||||
self.assertLess(m1, m2)
|
||||
self.assertGreater(m2, m1)
|
||||
|
||||
m1 = TestModel(txt="a")
|
||||
m2 = TestModel(txt="b")
|
||||
self.assertNotEqual(m1, m2)
|
||||
self.assertLess(m1, m2)
|
||||
self.assertGreater(m2, m1)
|
||||
|
||||
m1 = TestModel(sub={})
|
||||
m2 = TestModel(sub={})
|
||||
self.assertEqual(m1, m2)
|
||||
|
||||
m1 = TestModel(sub={"txt": "a"})
|
||||
m2 = TestModel(sub={"txt": "b"})
|
||||
self.assertNotEqual(m1, m2)
|
||||
self.assertLess(m1, m2)
|
||||
self.assertGreater(m2, m1)
|
||||
|
||||
m1 = TestModel(dct={})
|
||||
m2 = TestModel(dct={})
|
||||
self.assertEqual(m1, m2)
|
||||
|
||||
m1 = TestModel(dct={"a": TestSubmodel()})
|
||||
m2 = TestModel(dct={"b": TestSubmodel()})
|
||||
self.assertNotEqual(m1, m2)
|
||||
self.assertLess(m1, m2)
|
||||
self.assertGreater(m2, m1)
|
||||
|
||||
# dict ordering doesn't matter
|
||||
m1 = TestModel(dct={"a": TestSubmodel(), "b": TestSubmodel()})
|
||||
m2 = TestModel(dct={"b": TestSubmodel(), "a": TestSubmodel()})
|
||||
self.assertEqual(m1, m2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user