0
# Version Serialization
1
2
Convert Version objects to standards-compliant version strings with support for PEP 440, Semantic Versioning, Haskell PVP, and custom formats.
3
4
## Capabilities
5
6
### Dynamic Serialization
7
8
Convert Version objects to formatted strings with extensive customization options.
9
10
```python { .api }
11
def serialize(
12
self,
13
metadata: Optional[bool] = None,
14
dirty: bool = False,
15
format: Optional[Union[str, Callable[["Version"], str]]] = None,
16
style: Optional[Style] = None,
17
bump: bool = False,
18
tagged_metadata: bool = False,
19
commit_prefix: Optional[str] = None,
20
escape_with: Optional[str] = None,
21
) -> str
22
```
23
24
**Parameters**:
25
- `metadata`: Include commit ID and dirty flag (None=auto, True=always, False=never)
26
- `dirty`: Include dirty flag when metadata is enabled
27
- `format`: Custom format string or callable for output formatting
28
- `style`: Built-in format style (PEP 440, SemVer, PVP)
29
- `bump`: Increment version automatically
30
- `tagged_metadata`: Include tagged metadata in output
31
- `commit_prefix`: Prefix for commit ID (e.g., "g" for Git)
32
- `escape_with`: Character replacement for branch escaping
33
34
**Returns**: Formatted version string
35
36
**Usage Examples**:
37
38
```python
39
from dunamai import Version, Style
40
41
version = Version("1.2.3", stage=("rc", 1), distance=7, commit="29045e8", dirty=True)
42
43
# Default PEP 440 format
44
print(version.serialize())
45
# "1.2.3rc1.post7.dev0+29045e8"
46
47
# Force metadata inclusion
48
print(version.serialize(metadata=True))
49
# "1.2.3rc1.post7.dev0+29045e8"
50
51
# Include dirty flag
52
print(version.serialize(dirty=True))
53
# "1.2.3rc1.post7.dev0+29045e8.dirty"
54
55
# Semantic Versioning style
56
print(version.serialize(style=Style.SemVer))
57
# "1.2.3-rc.1.post.7+29045e8"
58
59
# Custom format string
60
print(version.serialize(format="v{base}-{stage}.{revision}+{distance}"))
61
# "v1.2.3-rc.1+7"
62
63
# Bump version automatically
64
print(version.serialize(bump=True))
65
# "1.2.4rc1"
66
```
67
68
### Custom Format Strings
69
70
Use format strings with placeholder substitution for complete control over output format.
71
72
**Available Placeholders**:
73
- `{base}` - Base version (e.g., "1.2.3")
74
- `{stage}` - Pre-release stage (e.g., "rc")
75
- `{revision}` - Pre-release revision (e.g., "1")
76
- `{distance}` - Commits since tag (e.g., "7")
77
- `{commit}` - Commit hash (e.g., "29045e8")
78
- `{dirty}` - "dirty" or "clean"
79
- `{tagged_metadata}` - Metadata from tag
80
- `{epoch}` - PEP 440 epoch
81
- `{branch}` - Branch name
82
- `{branch_escaped}` - Branch with special chars removed
83
- `{timestamp}` - Timestamp as YYYYmmddHHMMSS UTC
84
- `{major}` - Major version component
85
- `{minor}` - Minor version component
86
- `{patch}` - Patch version component
87
88
**Usage Examples**:
89
90
```python
91
from dunamai import Version
92
93
version = Version(
94
"1.2.3",
95
stage=("beta", 2),
96
distance=5,
97
commit="g29045e8",
98
branch="feature/new-api",
99
tagged_metadata="linux"
100
)
101
102
# Docker-style tags
103
print(version.serialize(format="{base}-{stage}.{revision}"))
104
# "1.2.3-beta.2"
105
106
# Build number format
107
print(version.serialize(format="{base}.{distance}"))
108
# "1.2.3.5"
109
110
# Full descriptive format
111
print(version.serialize(format="v{base}-{stage}.{revision}+{commit}.{dirty}"))
112
# "v1.2.3-beta.2+g29045e8.clean"
113
114
# Branch-aware format
115
print(version.serialize(format="{base}-{branch_escaped}+{commit}"))
116
# "1.2.3-featurenewapi+g29045e8"
117
118
# Component access
119
print(version.serialize(format="{major}.{minor}.{patch}-dev.{distance}"))
120
# "1.2.3-dev.5"
121
```
122
123
### Custom Format Functions
124
125
Use callable functions for complex formatting logic.
126
127
**Usage Examples**:
128
129
```python
130
from dunamai import Version
131
132
def custom_formatter(version):
133
if version.distance == 0:
134
return f"{version.base}"
135
elif version.stage:
136
return f"{version.base}-{version.stage}.{version.revision or 0}+dev.{version.distance}"
137
else:
138
return f"{version.base}+dev.{version.distance}"
139
140
version = Version("1.2.3", distance=5)
141
print(version.serialize(format=custom_formatter))
142
# "1.2.3+dev.5"
143
144
# Conditional formatting based on VCS
145
def vcs_aware_formatter(version):
146
prefix = {"git": "g", "mercurial": "hg"}.get(version.vcs.value, "")
147
return f"{version.base}+{prefix}{version.commit}"
148
149
version = Version("1.2.3", commit="29045e8", vcs=Vcs.Git)
150
print(version.serialize(format=vcs_aware_formatter))
151
# "1.2.3+g29045e8"
152
```
153
154
### PEP 440 Serialization
155
156
Create PEP 440 compliant version strings with fine-grained control over components.
157
158
```python { .api }
159
def serialize_pep440(
160
base: str,
161
stage: Optional[str] = None,
162
revision: Optional[int] = None,
163
post: Optional[int] = None,
164
dev: Optional[int] = None,
165
epoch: Optional[int] = None,
166
metadata: Optional[Sequence[Union[str, int]]] = None,
167
) -> str
168
```
169
170
**Parameters**:
171
- `base`: Release segment (e.g., "1.2.3")
172
- `stage`: Pre-release stage ("a", "b", "rc")
173
- `revision`: Pre-release revision number
174
- `post`: Post-release number
175
- `dev`: Development release number
176
- `epoch`: Epoch number
177
- `metadata`: Local version segments
178
179
**Usage Examples**:
180
181
```python
182
from dunamai import serialize_pep440
183
184
# Basic release
185
print(serialize_pep440("1.2.3"))
186
# "1.2.3"
187
188
# Pre-release
189
print(serialize_pep440("1.2.3", stage="rc", revision=1))
190
# "1.2.3rc1"
191
192
# Post-release
193
print(serialize_pep440("1.2.3", post=7))
194
# "1.2.3.post7"
195
196
# Development release
197
print(serialize_pep440("1.2.3", dev=0))
198
# "1.2.3.dev0"
199
200
# Complex version with all components
201
print(serialize_pep440(
202
"1.2.3",
203
stage="rc",
204
revision=1,
205
post=7,
206
dev=0,
207
epoch=2,
208
metadata=["g29045e8", "dirty"]
209
))
210
# "2!1.2.3rc1.post7.dev0+g29045e8.dirty"
211
```
212
213
### Semantic Versioning Serialization
214
215
Create Semantic Versioning compliant version strings.
216
217
```python { .api }
218
def serialize_semver(
219
base: str,
220
pre: Optional[Sequence[Union[str, int]]] = None,
221
metadata: Optional[Sequence[Union[str, int]]] = None,
222
) -> str
223
```
224
225
**Parameters**:
226
- `base`: Version core (e.g., "1.2.3")
227
- `pre`: Pre-release identifiers
228
- `metadata`: Build metadata identifiers
229
230
**Usage Examples**:
231
232
```python
233
from dunamai import serialize_semver
234
235
# Basic semantic version
236
print(serialize_semver("1.2.3"))
237
# "1.2.3"
238
239
# Pre-release
240
print(serialize_semver("1.2.3", pre=["rc", 1]))
241
# "1.2.3-rc.1"
242
243
# With build metadata
244
print(serialize_semver("1.2.3", metadata=["20230501", "g29045e8"]))
245
# "1.2.3+20230501.g29045e8"
246
247
# Pre-release with metadata
248
print(serialize_semver("1.2.3", pre=["beta", 2], metadata=["exp", "sha", "5"]))
249
# "1.2.3-beta.2+exp.sha.5"
250
```
251
252
### Haskell PVP Serialization
253
254
Create Haskell Package Versioning Policy compliant version strings.
255
256
```python { .api }
257
def serialize_pvp(base: str, metadata: Optional[Sequence[Union[str, int]]] = None) -> str
258
```
259
260
**Parameters**:
261
- `base`: Version core (e.g., "1.2.3")
262
- `metadata`: Version tag metadata
263
264
**Usage Examples**:
265
266
```python
267
from dunamai import serialize_pvp
268
269
# Basic PVP version
270
print(serialize_pvp("1.2.3"))
271
# "1.2.3"
272
273
# PVP with metadata
274
print(serialize_pvp("1.2.3", metadata=["candidate", "1"]))
275
# "1.2.3-candidate-1"
276
```
277
278
### Version Bumping
279
280
Automatically increment version components during serialization.
281
282
```python { .api }
283
def bump(self, index: int = -1, increment: int = 1, smart: bool = False) -> "Version"
284
```
285
286
**Usage Examples**:
287
288
```python
289
from dunamai import Version
290
291
version = Version("1.2.3", distance=5)
292
293
# Bump with serialize
294
print(version.serialize(bump=True))
295
# "1.2.4.dev5"
296
297
# Manual bump
298
bumped = version.bump()
299
print(bumped.serialize())
300
# "1.2.4.dev5"
301
302
# Bump specific component
303
bumped = version.bump(index=1) # Bump minor version
304
print(bumped.base)
305
# "1.3.0"
306
307
# Smart bump (considers pre-release state)
308
version = Version("1.2.3", stage=("rc", 1))
309
bumped = version.bump(smart=True)
310
print(bumped.serialize())
311
# "1.2.3rc2"
312
```
313
314
## Style Validation
315
316
All serialization functions validate output against their respective standards and raise `ValueError` for invalid versions.
317
318
**Usage Examples**:
319
320
```python
321
from dunamai import Version, Style, check_version
322
323
version = Version("1.2.3", distance=5)
324
325
# This will validate the output
326
try:
327
result = version.serialize(format="v{base}", style=Style.Pep440)
328
except ValueError as e:
329
print(f"Invalid PEP 440 version: {e}")
330
331
# Manual validation
332
try:
333
check_version("v1.2.3", Style.Pep440)
334
except ValueError as e:
335
print(f"Version 'v1.2.3' is not PEP 440 compliant: {e}")
336
```