or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-functions.mdexceptions.mdindex.mdrepository-holders.mdutilities.mdversion-handling.md

version-handling.mddocs/

0

# Version Handling

1

2

Enhanced version class and utilities for parsing, normalizing, and comparing software versions. Extends PEP 440 with intelligent handling of real-world version inconsistencies found across different software projects and platforms.

3

4

## Capabilities

5

6

### Version Class

7

8

Enhanced version class that extends packaging.version.Version with additional normalization and transformation capabilities for handling inconsistent real-world version formats.

9

10

```python { .api }

11

class Version(PackagingVersion):

12

"""

13

Enhanced version class implementing PEP 440 with additional normalization.

14

15

This class extends packaging.version.Version with specialized transformations

16

to handle common version format inconsistencies found in real-world software

17

projects across different platforms and release practices.

18

"""

19

20

def __init__(self, version: str):

21

"""

22

Initialize Version with intelligent normalization.

23

24

Parameters:

25

- version: Version string to parse and normalize

26

27

Raises:

28

- InvalidVersion: If version cannot be normalized to PEP 440 format

29

"""

30

31

@staticmethod

32

def special_cases_transformation(version: str) -> str:

33

"""

34

Apply specialized transformations for common version format issues.

35

36

Handles cases like:

37

- Release candidate formats (rc1.2 → rc1)

38

- Post-release patterns (p1 → post1)

39

- Preview/early access versions

40

- Beta-RC combinations

41

- Dashed pre-release formats

42

43

Parameters:

44

- version: Raw version string

45

46

Returns:

47

- Transformed version string compatible with PEP 440

48

"""

49

```

50

51

### Version Transformation Patterns

52

53

The Version class applies various regex-based transformations to normalize version strings:

54

55

```python { .api }

56

# Dashed substitution patterns applied during normalization

57

regex_dashed_substitutions = [

58

(re.compile(r"-p(\d+)$"), "-post\\1"), # -p1 → -post1

59

(re.compile(r"-preview-(\d+)"), "-pre\\1"), # -preview-1 → -pre1

60

(re.compile(r"-early-access-(\d+)"), "-alpha\\1"), # -early-access-1 → -alpha1

61

(re.compile(r"-pre-(\d+)"), "-pre\\1"), # -pre-1 → -pre1

62

(re.compile(r"-beta[-.]rc(\d+)"), "-beta\\1"), # -beta-rc1 → -beta1

63

(re.compile(r"^pre-(.*)"), "\\1-pre0"), # pre-1.0 → 1.0-pre0

64

]

65

66

# Part normalization mapping for common pre-release identifiers

67

part_to_pypi_dict = {

68

"devel": "dev0",

69

"test": "dev0",

70

"dev": "dev0",

71

"alpha": "a0",

72

"beta": "b0",

73

"rc": "rc0",

74

"preview": "rc0",

75

"pre": "rc0",

76

}

77

```

78

79

### Version Parsing Utilities

80

81

Utility functions for extracting and parsing version information from various sources.

82

83

```python { .api }

84

def parse_version(tag: str) -> Version:

85

"""

86

Parse version from git tag or other version source.

87

88

Extracts version information from tag strings that may contain

89

prefixes, suffixes, or other metadata beyond the core version.

90

91

Parameters:

92

- tag: Tag string or version identifier

93

94

Returns:

95

- Version object with parsed and normalized version

96

97

Raises:

98

- InvalidVersion: If no valid version can be extracted

99

"""

100

```

101

102

## Usage Examples

103

104

### Basic Version Operations

105

106

```python

107

from lastversion.version import Version

108

109

# Create version objects

110

v1 = Version("1.2.3")

111

v2 = Version("1.2.4")

112

113

# Version comparison

114

print(v1 < v2) # True

115

print(v1 == v2) # False

116

print(max(v1, v2)) # Version('1.2.4')

117

118

# String representation

119

print(str(v1)) # "1.2.3"

120

print(repr(v1)) # "<Version('1.2.3')>"

121

```

122

123

### Handling Inconsistent Formats

124

125

```python

126

from lastversion.version import Version

127

128

# Normalize various real-world version formats

129

versions = [

130

"v1.2.3-rc1", # Git tag with prefix

131

"release-1.2.3", # Release prefix

132

"1.2.3-p1", # Post-release

133

"1.2.3-preview-1", # Preview release

134

"1.2.3-beta-rc2", # Beta release candidate

135

"pre-1.2.3", # Pre-release prefix

136

]

137

138

normalized = [Version(v) for v in versions]

139

for orig, norm in zip(versions, normalized):

140

print(f"{orig} → {norm}")

141

```

142

143

### Version Filtering and Selection

144

145

```python

146

from lastversion.version import Version

147

from packaging.version import InvalidVersion

148

149

def filter_stable_versions(version_strings):

150

"""Filter out pre-release and invalid versions."""

151

stable_versions = []

152

153

for version_str in version_strings:

154

try:

155

version = Version(version_str)

156

# Check if it's a stable release (no pre-release components)

157

if not version.is_prerelease:

158

stable_versions.append(version)

159

except InvalidVersion:

160

continue # Skip invalid versions

161

162

return sorted(stable_versions)

163

164

# Example usage

165

raw_versions = ["1.0.0", "1.1.0-beta", "1.1.0", "2.0.0-rc1", "2.0.0"]

166

stable = filter_stable_versions(raw_versions)

167

print(f"Latest stable: {max(stable)}") # Version('2.0.0')

168

```

169

170

### Integration with Core Functions

171

172

```python

173

from lastversion import latest

174

from lastversion.version import Version

175

176

# Get version object directly

177

version_obj = latest("mautic/mautic", output_format="version")

178

179

# Version objects support all comparison operations

180

if version_obj >= Version("4.0.0"):

181

print("Major version 4 or higher")

182

183

# Check version properties

184

print(f"Is prerelease: {version_obj.is_prerelease}")

185

print(f"Is devrelease: {version_obj.is_devrelease}")

186

print(f"Major version: {version_obj.major}")

187

print(f"Minor version: {version_obj.minor}")

188

print(f"Micro version: {version_obj.micro}")

189

```

190

191

### Custom Version Transformations

192

193

```python

194

from lastversion.version import Version

195

196

# Example of how special_cases_transformation works

197

test_versions = [

198

"1.0.0-p1", # Post release

199

"2.0.0-preview-1", # Preview

200

"3.0.0-beta-rc2", # Beta release candidate

201

"pre-4.0.0", # Pre-prefixed version

202

]

203

204

for version_str in test_versions:

205

transformed = Version.special_cases_transformation(version_str)

206

version_obj = Version(transformed)

207

print(f"{version_str} → {transformed} → {version_obj}")

208

```

209

210

## Error Handling

211

212

```python

213

from lastversion.version import Version

214

from packaging.version import InvalidVersion

215

216

def safe_version_parse(version_str):

217

"""Safely parse version with error handling."""

218

try:

219

return Version(version_str)

220

except InvalidVersion as e:

221

print(f"Invalid version '{version_str}': {e}")

222

return None

223

224

# Example usage

225

versions = ["1.2.3", "invalid", "1.2.3-rc1", "not.a.version"]

226

parsed = [safe_version_parse(v) for v in versions]

227

valid_versions = [v for v in parsed if v is not None]

228

```