Coverage for src/gitlabracadabra/gitlab/user_cache.py: 79%

34 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-14 23:10 +0200

1# 

2# Copyright (C) 2019-2025 Mathieu Parent <math.parent@gmail.com> 

3# 

4# This program is free software: you can redistribute it and/or modify 

5# it under the terms of the GNU Lesser General Public License as published by 

6# the Free Software Foundation, either version 3 of the License, or 

7# (at your option) any later version. 

8# 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU Lesser General Public License for more details. 

13# 

14# You should have received a copy of the GNU Lesser General Public License 

15# along with this program. If not, see <http://www.gnu.org/licenses/>. 

16 

17 

18from __future__ import annotations 

19 

20from typing import TYPE_CHECKING 

21 

22from gitlab.exceptions import GitlabGetError 

23from requests import codes 

24 

25if TYPE_CHECKING: 25 ↛ 26line 25 didn't jump to line 26 because the condition on line 25 was never true

26 from gitlabracadabra.gitlab.pygitlab import PyGitlab 

27 

28 

29class UserCache: 

30 """Users mapping cache. 

31 

32 indexed by id and username. 

33 """ 

34 

35 def __init__(self, connection: PyGitlab) -> None: 

36 """Initialize a Python-Gitlab wrapper. 

37 

38 Args: 

39 connection: A GitlabConnection/PyGitlab. 

40 """ 

41 self._connection = connection 

42 self._username2id: dict[str, int | None] = {} 

43 self._id2username: dict[int, str | None] = {} 

44 

45 def map_user(self, user_id: int, user_username: str) -> None: 

46 """Map user id and username. 

47 

48 Args: 

49 user_id: User id. 

50 user_username: User username. 

51 """ 

52 self._id2username[user_id] = user_username 

53 self._username2id[user_username] = user_id 

54 

55 def username_from_id(self, user_id: int) -> str | None: 

56 """Get user username from id. 

57 

58 Args: 

59 user_id: User id. 

60 

61 Returns: 

62 User username. 

63 

64 Raises: 

65 GitlabGetError: Any HTTP error other than 404. 

66 """ 

67 if user_id not in self._id2username: 67 ↛ 76line 67 didn't jump to line 76 because the condition on line 67 was always true

68 obj_manager = self._connection.pygitlab.users 

69 try: 

70 user = obj_manager.get(user_id) 

71 self.map_user(user.id, user.username) 

72 except GitlabGetError as err: 

73 if err.response_code != codes["not_found"]: 

74 raise 

75 self._id2username[user_id] = None 

76 return self._id2username[user_id] 

77 

78 def id_from_username(self, user_username: str) -> int | None: 

79 """Get user id from username. 

80 

81 Args: 

82 user_username: User username. 

83 

84 Returns: 

85 User id. 

86 """ 

87 if user_username not in self._username2id: 

88 obj_manager = self._connection.pygitlab.users 

89 try: 

90 user = list(obj_manager.list(username=user_username))[0] # noqa: RUF015 

91 self.map_user(user.id, user.username) 

92 except IndexError: 

93 self._username2id[user_username] = None 

94 return self._username2id[user_username]