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:05 +0000

1import functools 

2import typing 

3 

4 

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 

11 

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)) 

16 

17 def __bool__(self): 

18 return False 

19 

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 ) 

25 

26 def __hash__(self): 

27 return self.__hash 

28 

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 

37 

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 ) 

44 

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 

51 

52 

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