Coverage for adhoc-cicd-odoo-odoo / odoo / orm / identifiers.py: 59%
31 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 18:15 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-09 18:15 +0000
1import functools
2import typing
5@functools.total_ordering
6class NewId:
7 """ Pseudo-ids for new records, encapsulating an optional origin id (actual
8 record id) and an optional reference (any value).
9 """
10 __slots__ = ('origin', 'ref', '__hash') # noqa: RUF023
12 def __init__(self, origin=None, ref=None):
13 self.origin = origin
14 self.ref = ref
15 self.__hash = hash(origin or ref or id(self))
17 def __bool__(self):
18 return False
20 def __eq__(self, other):
21 return isinstance(other, NewId) and (
22 (self.origin and other.origin and self.origin == other.origin)
23 or (self.ref and other.ref and self.ref == other.ref)
24 )
26 def __hash__(self):
27 return self.__hash
29 def __lt__(self, other):
30 if isinstance(other, NewId):
31 other = other.origin
32 if other is None:
33 return other > self.origin if self.origin else False
34 if isinstance(other, int):
35 return bool(self.origin) and self.origin < other
36 return NotImplemented
38 def __repr__(self):
39 return (
40 "<NewId origin=%r>" % self.origin if self.origin else
41 "<NewId ref=%r>" % self.ref if self.ref else
42 "<NewId 0x%x>" % id(self)
43 )
45 def __str__(self):
46 if self.origin or self.ref: 46 ↛ 47line 46 didn't jump to line 47 because the condition on line 46 was never true
47 id_part = repr(self.origin or self.ref)
48 else:
49 id_part = hex(id(self))
50 return "NewId_%s" % id_part
53# By default, in the ORM we initialize it as an int, but any type should work.
54# However, and some parts of the ORM may assume it is an integer.
55# Non-exhaustive list: relational fields, references, hierarchies, etc.
56IdType: typing.TypeAlias = int | NewId | str