Skip to content

Commit 871d8e2

Browse files
author
Sergey Vasilyev
committed
Refactor UUID & ArithUUID from inheritance into composition
1 parent 50c1595 commit 871d8e2

File tree

2 files changed

+62
-10
lines changed

2 files changed

+62
-10
lines changed

data_diff/databases/base.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from data_diff.abcs.compiler import AbstractCompiler, Compilable
2121
from data_diff.queries.extras import ApplyFuncAndNormalizeAsString, Checksum, NormalizeAsString
2222
from data_diff.schema import RawColumnInfo
23-
from data_diff.utils import ArithString, is_uuid, join_iter, safezip
23+
from data_diff.utils import ArithString, ArithUUID, is_uuid, join_iter, safezip
2424
from data_diff.queries.api import Expr, table, Select, SKIP, Explain, Code, this
2525
from data_diff.queries.ast_classes import (
2626
Alias,
@@ -248,6 +248,9 @@ def _compile(self, compiler: Compiler, elem) -> str:
248248
return self.timestamp_value(elem)
249249
elif isinstance(elem, bytes):
250250
return f"b'{elem.decode()}'"
251+
elif isinstance(elem, ArithUUID):
252+
s = f"'{elem.uuid}'"
253+
return s
251254
elif isinstance(elem, ArithString):
252255
return f"'{elem}'"
253256
assert False, elem
@@ -681,8 +684,10 @@ def _constant_value(self, v):
681684
return f"'{v}'"
682685
elif isinstance(v, datetime):
683686
return self.timestamp_value(v)
684-
elif isinstance(v, UUID):
687+
elif isinstance(v, UUID): # probably unused anymore in favour of ArithUUID
685688
return f"'{v}'"
689+
elif isinstance(v, ArithUUID):
690+
return f"'{v.uuid}'"
686691
elif isinstance(v, decimal.Decimal):
687692
return str(v)
688693
elif isinstance(v, bytearray):

data_diff/utils.py

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,23 +135,70 @@ def range(self, other: "ArithString", count: int) -> List[Self]:
135135
return [self.new(int=i) for i in checkpoints]
136136

137137

138-
# @attrs.define # not as long as it inherits from UUID
139-
class ArithUUID(UUID, ArithString):
138+
def _any_to_uuid(v: Union[str, int, UUID]) -> UUID:
139+
if isinstance(v, UUID):
140+
return v
141+
elif isinstance(v, str):
142+
return UUID(v)
143+
elif isinstance(v, int):
144+
return UUID(int=v)
145+
else:
146+
raise ValueError(f"Cannot convert a value to UUID: {v!r}")
147+
148+
149+
@attrs.define(frozen=True, eq=False, order=False)
150+
class ArithUUID(ArithString):
140151
"A UUID that supports basic arithmetic (add, sub)"
141152

153+
uuid: UUID = attrs.field(converter=_any_to_uuid)
154+
def range(self, other: "ArithUUID", count: int) -> List[Self]:
155+
assert isinstance(other, ArithUUID)
156+
checkpoints = split_space(self.uuid.int, other.uuid.int, count)
157+
return [attrs.evolve(self, uuid=i) for i in checkpoints]
158+
142159
def __int__(self):
143-
return self.int
160+
return self.uuid.int
144161

145162
def __add__(self, other: int) -> Self:
146163
if isinstance(other, int):
147-
return self.new(int=self.int + other)
164+
return attrs.evolve(self, uuid=self.uuid.int + other)
148165
return NotImplemented
149166

150-
def __sub__(self, other: Union[UUID, int]):
167+
def __sub__(self, other: Union["ArithUUID", int]):
151168
if isinstance(other, int):
152-
return self.new(int=self.int - other)
153-
elif isinstance(other, UUID):
154-
return self.int - other.int
169+
return attrs.evolve(self, uuid=self.uuid.int - other)
170+
elif isinstance(other, ArithUUID):
171+
return self.uuid.int - other.uuid.int
172+
return NotImplemented
173+
174+
def __eq__(self, other: object) -> bool:
175+
if isinstance(other, ArithUUID):
176+
return self.uuid == other.uuid
177+
return NotImplemented
178+
179+
def __ne__(self, other: object) -> bool:
180+
if isinstance(other, ArithUUID):
181+
return self.uuid != other.uuid
182+
return NotImplemented
183+
184+
def __gt__(self, other: object) -> bool:
185+
if isinstance(other, ArithUUID):
186+
return self.uuid > other.uuid
187+
return NotImplemented
188+
189+
def __lt__(self, other: object) -> bool:
190+
if isinstance(other, ArithUUID):
191+
return self.uuid < other.uuid
192+
return NotImplemented
193+
194+
def __ge__(self, other: object) -> bool:
195+
if isinstance(other, ArithUUID):
196+
return self.uuid >= other.uuid
197+
return NotImplemented
198+
199+
def __le__(self, other: object) -> bool:
200+
if isinstance(other, ArithUUID):
201+
return self.uuid <= other.uuid
155202
return NotImplemented
156203

157204

0 commit comments

Comments
 (0)