Coverage for bioimageio/spec/_internal/version_type.py: 96%

57 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-02 14:21 +0000

1from __future__ import annotations 

2 

3from typing import Any, Optional, Tuple, Union 

4 

5import packaging.version 

6from pydantic import PrivateAttr, RootModel 

7 

8 

9class Version(RootModel[Union[str, int, float]]): 

10 """wraps a packaging.version.Version instance for validation in pydantic models""" 

11 

12 _version: packaging.version.Version = PrivateAttr() 

13 

14 def __str__(self): 

15 return str(self._version) 

16 

17 def model_post_init(self, __context: Any) -> None: 

18 """set `_version` attribute @private""" 

19 self._version = packaging.version.Version(str(self.root)) 

20 return super().model_post_init(__context) 

21 

22 def __lt__(self, other: Version): 

23 return self._version < other._version 

24 

25 def __eq__(self, other: Version): 

26 return self._version == other._version 

27 

28 # the properties below are adopted from and mirror properties of packaging.version.Version 

29 @property 

30 def epoch(self) -> int: 

31 """The epoch of the version. 

32 

33 >>> Version("2.0.0").epoch 

34 0 

35 >>> Version("1!2.0.0").epoch 

36 1 

37 """ 

38 return self._version.epoch 

39 

40 @property 

41 def release(self) -> Tuple[int, ...]: 

42 """The components of the "release" segment of the version. 

43 

44 >>> Version("1.2.3").release 

45 (1, 2, 3) 

46 >>> Version("2.0.0").release 

47 (2, 0, 0) 

48 >>> Version("1!2.0.0.post0").release 

49 (2, 0, 0) 

50 

51 Includes trailing zeroes but not the epoch or any pre-release / development / 

52 post-release suffixes. 

53 """ 

54 return self._version.release 

55 

56 @property 

57 def pre(self) -> Optional[Tuple[str, int]]: 

58 """The pre-release segment of the version. 

59 

60 >>> print(Version("1.2.3").pre) 

61 None 

62 >>> Version("1.2.3a1").pre 

63 ('a', 1) 

64 >>> Version("1.2.3b1").pre 

65 ('b', 1) 

66 >>> Version("1.2.3rc1").pre 

67 ('rc', 1) 

68 """ 

69 return self._version.pre 

70 

71 @property 

72 def post(self) -> Optional[int]: 

73 """The post-release number of the version. 

74 

75 >>> print(Version("1.2.3").post) 

76 None 

77 >>> Version("1.2.3.post1").post 

78 1 

79 """ 

80 return self._version.post 

81 

82 @property 

83 def dev(self) -> Optional[int]: 

84 """The development number of the version. 

85 

86 >>> print(Version("1.2.3").dev) 

87 None 

88 >>> Version("1.2.3.dev1").dev 

89 1 

90 """ 

91 return self._version.dev 

92 

93 @property 

94 def local(self) -> Optional[str]: 

95 """The local version segment of the version. 

96 

97 >>> print(Version("1.2.3").local) 

98 None 

99 >>> Version("1.2.3+abc").local 

100 'abc' 

101 """ 

102 return self._version.local 

103 

104 @property 

105 def public(self) -> str: 

106 """The public portion of the version. 

107 

108 >>> Version("1.2.3").public 

109 '1.2.3' 

110 >>> Version("1.2.3+abc").public 

111 '1.2.3' 

112 >>> Version("1.2.3+abc.dev1").public 

113 '1.2.3' 

114 """ 

115 return self._version.public 

116 

117 @property 

118 def base_version(self) -> str: 

119 """The "base version" of the version. 

120 

121 >>> Version("1.2.3").base_version 

122 '1.2.3' 

123 >>> Version("1.2.3+abc").base_version 

124 '1.2.3' 

125 >>> Version("1!1.2.3+abc.dev1").base_version 

126 '1!1.2.3' 

127 

128 The "base version" is the public version of the project without any pre or post 

129 release markers. 

130 """ 

131 return self._version.base_version 

132 

133 @property 

134 def is_prerelease(self) -> bool: 

135 """Whether this version is a pre-release. 

136 

137 >>> Version("1.2.3").is_prerelease 

138 False 

139 >>> Version("1.2.3a1").is_prerelease 

140 True 

141 >>> Version("1.2.3b1").is_prerelease 

142 True 

143 >>> Version("1.2.3rc1").is_prerelease 

144 True 

145 >>> Version("1.2.3dev1").is_prerelease 

146 True 

147 """ 

148 return self._version.is_prerelease 

149 

150 @property 

151 def is_postrelease(self) -> bool: 

152 """Whether this version is a post-release. 

153 

154 >>> Version("1.2.3").is_postrelease 

155 False 

156 >>> Version("1.2.3.post1").is_postrelease 

157 True 

158 """ 

159 return self._version.is_postrelease 

160 

161 @property 

162 def is_devrelease(self) -> bool: 

163 """Whether this version is a development release. 

164 

165 >>> Version("1.2.3").is_devrelease 

166 False 

167 >>> Version("1.2.3.dev1").is_devrelease 

168 True 

169 """ 

170 return self._version.is_devrelease 

171 

172 @property 

173 def major(self) -> int: 

174 """The first item of :attr:`release` or ``0`` if unavailable. 

175 

176 >>> Version("1.2.3").major 

177 1 

178 """ 

179 return self._version.major 

180 

181 @property 

182 def minor(self) -> int: 

183 """The second item of :attr:`release` or ``0`` if unavailable. 

184 

185 >>> Version("1.2.3").minor 

186 2 

187 >>> Version("1").minor 

188 0 

189 """ 

190 return self._version.minor 

191 

192 @property 

193 def micro(self) -> int: 

194 """The third item of :attr:`release` or ``0`` if unavailable. 

195 

196 >>> Version("1.2.3").micro 

197 3 

198 >>> Version("1").micro 

199 0 

200 """ 

201 return self._version.micro