Coverage for daklib/architecture.py: 82%

71 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2026-03-14 12:19 +0000

1"""architecture matching 

2 

3@copyright: 2014, Ansgar Burchardt <ansgar@debian.org> 

4@license: GPL-2+ 

5""" 

6 

7# This program is free software; you can redistribute it and/or modify 

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

9# the Free Software Foundation; either version 2 of the License, or 

10# (at your option) any later version. 

11# 

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

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

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

15# GNU General Public License for more details. 

16# 

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

18# along with this program; if not, write to the Free Software 

19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

20 

21import errno 

22from collections.abc import Sequence 

23from functools import cache 

24 

25 

26def _load_table(path: str) -> list[list[str]]: 

27 table = [] 

28 with open(path, "r") as fh: 

29 for line in fh: 

30 if not line or line.startswith("#"): 

31 continue 

32 table.append(line.split()) 

33 return table 

34 

35 

36@cache 

37def _cputable(): 

38 return _load_table("/usr/share/dpkg/cputable") 

39 

40 

41@cache 

42def _tupletable() -> tuple[dict[str, str], dict[str, str]]: 

43 try: 

44 tripletable = False 

45 table = _load_table("/usr/share/dpkg/tupletable") 

46 except OSError as e: 

47 if e.errno != errno.ENOENT: 

48 raise 

49 tripletable = True 

50 table = _load_table("/usr/share/dpkg/triplettable") 

51 

52 arch2tuple: dict[str, str] = {} 

53 tuple2arch: dict[str, str] = {} 

54 

55 def add_tuple(tuple, arch): 

56 if tripletable: 56 ↛ 57line 56 didn't jump to line 57 because the condition on line 56 was never true

57 tuple = "base-{}".format(tuple) 

58 arch2tuple[arch] = tuple 

59 tuple2arch[tuple] = arch 

60 

61 for row in table: 

62 if "<cpu>" in row[0] or "<cpu>" in row[1]: 

63 for cpu in _cputable(): 

64 replaced_row = [column.replace("<cpu>", cpu[0]) for column in row] 

65 add_tuple(replaced_row[0], replaced_row[1]) 

66 else: 

67 add_tuple(row[0], row[1]) 

68 

69 return tuple2arch, arch2tuple 

70 

71 

72class InvalidArchitecture(Exception): 

73 pass 

74 

75 

76def Debian_arch_to_Debian_tuple(arch: str) -> Sequence[str] | None: 

77 parts = arch.split("-") 

78 

79 # Handle architecture wildcards 

80 if "any" in parts: 

81 if len(parts) == 4: 81 ↛ 82line 81 didn't jump to line 82 because the condition on line 81 was never true

82 return parts 

83 elif len(parts) == 3: 83 ↛ 84line 83 didn't jump to line 84 because the condition on line 83 was never true

84 return "any", parts[0], parts[1], parts[2] 

85 elif len(parts) == 2: 85 ↛ 88line 85 didn't jump to line 88 because the condition on line 85 was always true

86 return "any", "any", parts[0], parts[1] 

87 else: 

88 return "any", "any", "any", "any" 

89 

90 if len(parts) == 2 and parts[0] == "linux": 

91 arch = parts[1] 

92 

93 tuple = _tupletable()[1].get(arch, None) 

94 if tuple is None: 94 ↛ 95line 94 didn't jump to line 95 because the condition on line 94 was never true

95 return None 

96 return tuple.split("-", 3) 

97 

98 

99def match_architecture(arch: str, wildcard: str) -> bool: 

100 # 'all' has no valid tuple 

101 if arch == "all" or wildcard == "all": 

102 return arch == wildcard 

103 if wildcard == "any" or arch == wildcard: 

104 return True 

105 

106 tuple_arch = Debian_arch_to_Debian_tuple(arch) 

107 tuple_wildcard = Debian_arch_to_Debian_tuple(wildcard) 

108 

109 if tuple_arch is None or len(tuple_arch) != 4: 109 ↛ 110line 109 didn't jump to line 110 because the condition on line 109 was never true

110 raise InvalidArchitecture("{0} is not a valid architecture name".format(arch)) 

111 if tuple_wildcard is None or len(tuple_wildcard) != 4: 111 ↛ 112line 111 didn't jump to line 112 because the condition on line 111 was never true

112 raise InvalidArchitecture( 

113 "{0} is not a valid architecture name or wildcard".format(wildcard) 

114 ) 

115 

116 for i in range(0, 4): 

117 if tuple_arch[i] != tuple_wildcard[i] and tuple_wildcard[i] != "any": 

118 return False 

119 return True