Elron commited on
Commit
2fb8752
1 Parent(s): 99fde4e

Upload _version.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. _version.py +708 -0
_version.py ADDED
@@ -0,0 +1,708 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file helps to compute a version number in source trees obtained from
2
+ # git-archive tarball (such as those provided by githubs download-from-tag
3
+ # feature). Distribution tarballs (built by setup.py sdist) and build
4
+ # directories (produced by setup.py build) will contain a much shorter file
5
+ # that just contains the computed version number.
6
+
7
+ # This file is released into the public domain.
8
+ # Generated by versioneer-0.29
9
+ # https://github.com/python-versioneer/python-versioneer
10
+
11
+ """Git implementation of _version.py."""
12
+
13
+ import errno
14
+ import functools
15
+ import os
16
+ import re
17
+ import subprocess
18
+ import sys
19
+ from typing import Any, Callable, Dict, List, Optional, Tuple
20
+
21
+ import versioneer
22
+
23
+ hardcoded_version = None
24
+
25
+
26
+ def get_current_version():
27
+ if hardcoded_version is not None:
28
+ return hardcoded_version
29
+ return versioneer.get_version()
30
+
31
+
32
+ def get_keywords() -> Dict[str, str]:
33
+ """Get the keywords needed to look up the version information."""
34
+ # these strings will be replaced by git during git-archive.
35
+ # setup.py/versioneer.py will grep for the variable names, so they must
36
+ # each be defined on a line of their own. _version.py will just call
37
+ # get_keywords().
38
+ git_refnames = "$Format:%d$"
39
+ git_full = "$Format:%H$"
40
+ git_date = "$Format:%ci$"
41
+ keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
42
+ return keywords
43
+
44
+
45
+ class VersioneerConfig:
46
+ """Container for Versioneer configuration parameters."""
47
+
48
+ VCS: str
49
+ style: str
50
+ tag_prefix: str
51
+ parentdir_prefix: str
52
+ versionfile_source: str
53
+ verbose: bool
54
+
55
+
56
+ def get_config() -> VersioneerConfig:
57
+ """Create, populate and return the VersioneerConfig() object."""
58
+ # these strings are filled in when 'setup.py versioneer' creates
59
+ # _version.py
60
+ cfg = VersioneerConfig()
61
+ cfg.VCS = "git"
62
+ cfg.style = "pep440"
63
+ cfg.tag_prefix = ""
64
+ cfg.parentdir_prefix = ""
65
+ cfg.versionfile_source = "src/unitxt/_version.py"
66
+ cfg.verbose = False
67
+ return cfg
68
+
69
+
70
+ class NotThisMethod(Exception):
71
+ """Exception raised if a method is not valid for the current scenario."""
72
+
73
+
74
+ LONG_VERSION_PY: Dict[str, str] = {}
75
+ HANDLERS: Dict[str, Dict[str, Callable]] = {}
76
+
77
+
78
+ def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator
79
+ """Create decorator to mark a method as the handler of a VCS."""
80
+
81
+ def decorate(f: Callable) -> Callable:
82
+ """Store f in HANDLERS[vcs][method]."""
83
+ if vcs not in HANDLERS:
84
+ HANDLERS[vcs] = {}
85
+ HANDLERS[vcs][method] = f
86
+ return f
87
+
88
+ return decorate
89
+
90
+
91
+ def run_command(
92
+ commands: List[str],
93
+ args: List[str],
94
+ cwd: Optional[str] = None,
95
+ verbose: bool = False,
96
+ hide_stderr: bool = False,
97
+ env: Optional[Dict[str, str]] = None,
98
+ ) -> Tuple[Optional[str], Optional[int]]:
99
+ """Call the given command(s)."""
100
+ assert isinstance(commands, list)
101
+ process = None
102
+
103
+ popen_kwargs: Dict[str, Any] = {}
104
+ if sys.platform == "win32":
105
+ # This hides the console window if pythonw.exe is used
106
+ startupinfo = subprocess.STARTUPINFO()
107
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
108
+ popen_kwargs["startupinfo"] = startupinfo
109
+
110
+ for command in commands:
111
+ try:
112
+ dispcmd = str([command] + args)
113
+ # remember shell=False, so use git.cmd on windows, not just git
114
+ process = subprocess.Popen(
115
+ [command] + args,
116
+ cwd=cwd,
117
+ env=env,
118
+ stdout=subprocess.PIPE,
119
+ stderr=(subprocess.PIPE if hide_stderr else None),
120
+ **popen_kwargs,
121
+ )
122
+ break
123
+ except OSError as e:
124
+ if e.errno == errno.ENOENT:
125
+ continue
126
+ if verbose:
127
+ print("unable to run %s" % dispcmd)
128
+ print(e)
129
+ return None, None
130
+ else:
131
+ if verbose:
132
+ print("unable to find command, tried %s" % (commands,))
133
+ return None, None
134
+ stdout = process.communicate()[0].strip().decode()
135
+ if process.returncode != 0:
136
+ if verbose:
137
+ print("unable to run %s (error)" % dispcmd)
138
+ print("stdout was %s" % stdout)
139
+ return None, process.returncode
140
+ return stdout, process.returncode
141
+
142
+
143
+ def versions_from_parentdir(
144
+ parentdir_prefix: str,
145
+ root: str,
146
+ verbose: bool,
147
+ ) -> Dict[str, Any]:
148
+ """Try to determine the version from the parent directory name.
149
+
150
+ Source tarballs conventionally unpack into a directory that includes both
151
+ the project name and a version string. We will also support searching up
152
+ two directory levels for an appropriately named parent directory
153
+ """
154
+ rootdirs = []
155
+
156
+ for _ in range(3):
157
+ dirname = os.path.basename(root)
158
+ if dirname.startswith(parentdir_prefix):
159
+ return {
160
+ "version": dirname[len(parentdir_prefix) :],
161
+ "full-revisionid": None,
162
+ "dirty": False,
163
+ "error": None,
164
+ "date": None,
165
+ }
166
+ rootdirs.append(root)
167
+ root = os.path.dirname(root) # up a level
168
+
169
+ if verbose:
170
+ print("Tried directories %s but none started with prefix %s" % (str(rootdirs), parentdir_prefix))
171
+ raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
172
+
173
+
174
+ @register_vcs_handler("git", "get_keywords")
175
+ def git_get_keywords(versionfile_abs: str) -> Dict[str, str]:
176
+ """Extract version information from the given file."""
177
+ # the code embedded in _version.py can just fetch the value of these
178
+ # keywords. When used from setup.py, we don't want to import _version.py,
179
+ # so we do it with a regexp instead. This function is not used from
180
+ # _version.py.
181
+ keywords: Dict[str, str] = {}
182
+ try:
183
+ with open(versionfile_abs, "r") as fobj:
184
+ for line in fobj:
185
+ if line.strip().startswith("git_refnames ="):
186
+ mo = re.search(r'=\s*"(.*)"', line)
187
+ if mo:
188
+ keywords["refnames"] = mo.group(1)
189
+ if line.strip().startswith("git_full ="):
190
+ mo = re.search(r'=\s*"(.*)"', line)
191
+ if mo:
192
+ keywords["full"] = mo.group(1)
193
+ if line.strip().startswith("git_date ="):
194
+ mo = re.search(r'=\s*"(.*)"', line)
195
+ if mo:
196
+ keywords["date"] = mo.group(1)
197
+ except OSError:
198
+ pass
199
+ return keywords
200
+
201
+
202
+ @register_vcs_handler("git", "keywords")
203
+ def git_versions_from_keywords(
204
+ keywords: Dict[str, str],
205
+ tag_prefix: str,
206
+ verbose: bool,
207
+ ) -> Dict[str, Any]:
208
+ """Get version information from git keywords."""
209
+ if "refnames" not in keywords:
210
+ raise NotThisMethod("Short version file found")
211
+ date = keywords.get("date")
212
+ if date is not None:
213
+ # Use only the last line. Previous lines may contain GPG signature
214
+ # information.
215
+ date = date.splitlines()[-1]
216
+
217
+ # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
218
+ # datestamp. However we prefer "%ci" (which expands to an "ISO-8601
219
+ # -like" string, which we must then edit to make compliant), because
220
+ # it's been around since git-1.5.3, and it's too difficult to
221
+ # discover which version we're using, or to work around using an
222
+ # older one.
223
+ date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
224
+ refnames = keywords["refnames"].strip()
225
+ if refnames.startswith("$Format"):
226
+ if verbose:
227
+ print("keywords are unexpanded, not using")
228
+ raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
229
+ refs = {r.strip() for r in refnames.strip("()").split(",")}
230
+ # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
231
+ # just "foo-1.0". If we see a "tag: " prefix, prefer those.
232
+ TAG = "tag: "
233
+ tags = {r[len(TAG) :] for r in refs if r.startswith(TAG)}
234
+ if not tags:
235
+ # Either we're using git < 1.8.3, or there really are no tags. We use
236
+ # a heuristic: assume all version tags have a digit. The old git %d
237
+ # expansion behaves like git log --decorate=short and strips out the
238
+ # refs/heads/ and refs/tags/ prefixes that would let us distinguish
239
+ # between branches and tags. By ignoring refnames without digits, we
240
+ # filter out many common branch names like "release" and
241
+ # "stabilization", as well as "HEAD" and "master".
242
+ tags = {r for r in refs if re.search(r"\d", r)}
243
+ if verbose:
244
+ print("discarding '%s', no digits" % ",".join(refs - tags))
245
+ if verbose:
246
+ print("likely tags: %s" % ",".join(sorted(tags)))
247
+ for ref in sorted(tags):
248
+ # sorting will prefer e.g. "2.0" over "2.0rc1"
249
+ if ref.startswith(tag_prefix):
250
+ r = ref[len(tag_prefix) :]
251
+ # Filter out refs that exactly match prefix or that don't start
252
+ # with a number once the prefix is stripped (mostly a concern
253
+ # when prefix is '')
254
+ if not re.match(r"\d", r):
255
+ continue
256
+ if verbose:
257
+ print("picking %s" % r)
258
+ return {
259
+ "version": r,
260
+ "full-revisionid": keywords["full"].strip(),
261
+ "dirty": False,
262
+ "error": None,
263
+ "date": date,
264
+ }
265
+ # no suitable tags, so version is "0+unknown", but full hex is still there
266
+ if verbose:
267
+ print("no suitable tags, using unknown + full revision id")
268
+ return {
269
+ "version": "0+unknown",
270
+ "full-revisionid": keywords["full"].strip(),
271
+ "dirty": False,
272
+ "error": "no suitable tags",
273
+ "date": None,
274
+ }
275
+
276
+
277
+ @register_vcs_handler("git", "pieces_from_vcs")
278
+ def git_pieces_from_vcs(tag_prefix: str, root: str, verbose: bool, runner: Callable = run_command) -> Dict[str, Any]:
279
+ """Get version from 'git describe' in the root of the source tree.
280
+
281
+ This only gets called if the git-archive 'subst' keywords were *not*
282
+ expanded, and _version.py hasn't already been rewritten with a short
283
+ version string, meaning we're inside a checked out source tree.
284
+ """
285
+ GITS = ["git"]
286
+ if sys.platform == "win32":
287
+ GITS = ["git.cmd", "git.exe"]
288
+
289
+ # GIT_DIR can interfere with correct operation of Versioneer.
290
+ # It may be intended to be passed to the Versioneer-versioned project,
291
+ # but that should not change where we get our version from.
292
+ env = os.environ.copy()
293
+ env.pop("GIT_DIR", None)
294
+ runner = functools.partial(runner, env=env)
295
+
296
+ _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=not verbose)
297
+ if rc != 0:
298
+ if verbose:
299
+ print("Directory %s not under git control" % root)
300
+ raise NotThisMethod("'git rev-parse --git-dir' returned error")
301
+
302
+ # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
303
+ # if there isn't one, this yields HEX[-dirty] (no NUM)
304
+ describe_out, rc = runner(
305
+ GITS, ["describe", "--tags", "--dirty", "--always", "--long", "--match", f"{tag_prefix}[[:digit:]]*"], cwd=root
306
+ )
307
+ # --long was added in git-1.5.5
308
+ if describe_out is None:
309
+ raise NotThisMethod("'git describe' failed")
310
+ describe_out = describe_out.strip()
311
+ full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root)
312
+ if full_out is None:
313
+ raise NotThisMethod("'git rev-parse' failed")
314
+ full_out = full_out.strip()
315
+
316
+ pieces: Dict[str, Any] = {}
317
+ pieces["long"] = full_out
318
+ pieces["short"] = full_out[:7] # maybe improved later
319
+ pieces["error"] = None
320
+
321
+ branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root)
322
+ # --abbrev-ref was added in git-1.6.3
323
+ if rc != 0 or branch_name is None:
324
+ raise NotThisMethod("'git rev-parse --abbrev-ref' returned error")
325
+ branch_name = branch_name.strip()
326
+
327
+ if branch_name == "HEAD":
328
+ # If we aren't exactly on a branch, pick a branch which represents
329
+ # the current commit. If all else fails, we are on a branchless
330
+ # commit.
331
+ branches, rc = runner(GITS, ["branch", "--contains"], cwd=root)
332
+ # --contains was added in git-1.5.4
333
+ if rc != 0 or branches is None:
334
+ raise NotThisMethod("'git branch --contains' returned error")
335
+ branches = branches.split("\n")
336
+
337
+ # Remove the first line if we're running detached
338
+ if "(" in branches[0]:
339
+ branches.pop(0)
340
+
341
+ # Strip off the leading "* " from the list of branches.
342
+ branches = [branch[2:] for branch in branches]
343
+ if "master" in branches:
344
+ branch_name = "master"
345
+ elif not branches:
346
+ branch_name = None
347
+ else:
348
+ # Pick the first branch that is returned. Good or bad.
349
+ branch_name = branches[0]
350
+
351
+ pieces["branch"] = branch_name
352
+
353
+ # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
354
+ # TAG might have hyphens.
355
+ git_describe = describe_out
356
+
357
+ # look for -dirty suffix
358
+ dirty = git_describe.endswith("-dirty")
359
+ pieces["dirty"] = dirty
360
+ if dirty:
361
+ git_describe = git_describe[: git_describe.rindex("-dirty")]
362
+
363
+ # now we have TAG-NUM-gHEX or HEX
364
+
365
+ if "-" in git_describe:
366
+ # TAG-NUM-gHEX
367
+ mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe)
368
+ if not mo:
369
+ # unparsable. Maybe git-describe is misbehaving?
370
+ pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out
371
+ return pieces
372
+
373
+ # tag
374
+ full_tag = mo.group(1)
375
+ if not full_tag.startswith(tag_prefix):
376
+ if verbose:
377
+ fmt = "tag '%s' doesn't start with prefix '%s'"
378
+ print(fmt % (full_tag, tag_prefix))
379
+ pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % (full_tag, tag_prefix)
380
+ return pieces
381
+ pieces["closest-tag"] = full_tag[len(tag_prefix) :]
382
+
383
+ # distance: number of commits since tag
384
+ pieces["distance"] = int(mo.group(2))
385
+
386
+ # commit: short hex revision ID
387
+ pieces["short"] = mo.group(3)
388
+
389
+ else:
390
+ # HEX: no tags
391
+ pieces["closest-tag"] = None
392
+ out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root)
393
+ pieces["distance"] = len(out.split()) # total number of commits
394
+
395
+ # commit date: see ISO-8601 comment in git_versions_from_keywords()
396
+ date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip()
397
+ # Use only the last line. Previous lines may contain GPG signature
398
+ # information.
399
+ date = date.splitlines()[-1]
400
+ pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
401
+
402
+ return pieces
403
+
404
+
405
+ def plus_or_dot(pieces: Dict[str, Any]) -> str:
406
+ """Return a + if we don't already have one, else return a ."""
407
+ if "+" in pieces.get("closest-tag", ""):
408
+ return "."
409
+ return "+"
410
+
411
+
412
+ def render_pep440(pieces: Dict[str, Any]) -> str:
413
+ """Build up version string, with post-release "local version identifier".
414
+
415
+ Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
416
+ get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
417
+
418
+ Exceptions:
419
+ 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
420
+ """
421
+ if pieces["closest-tag"]:
422
+ rendered = pieces["closest-tag"]
423
+ if pieces["distance"] or pieces["dirty"]:
424
+ rendered += plus_or_dot(pieces)
425
+ rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
426
+ if pieces["dirty"]:
427
+ rendered += ".dirty"
428
+ else:
429
+ # exception #1
430
+ rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"])
431
+ if pieces["dirty"]:
432
+ rendered += ".dirty"
433
+ return rendered
434
+
435
+
436
+ def render_pep440_branch(pieces: Dict[str, Any]) -> str:
437
+ """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] .
438
+
439
+ The ".dev0" means not master branch. Note that .dev0 sorts backwards
440
+ (a feature branch will appear "older" than the master branch).
441
+
442
+ Exceptions:
443
+ 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty]
444
+ """
445
+ if pieces["closest-tag"]:
446
+ rendered = pieces["closest-tag"]
447
+ if pieces["distance"] or pieces["dirty"]:
448
+ if pieces["branch"] != "master":
449
+ rendered += ".dev0"
450
+ rendered += plus_or_dot(pieces)
451
+ rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
452
+ if pieces["dirty"]:
453
+ rendered += ".dirty"
454
+ else:
455
+ # exception #1
456
+ rendered = "0"
457
+ if pieces["branch"] != "master":
458
+ rendered += ".dev0"
459
+ rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"])
460
+ if pieces["dirty"]:
461
+ rendered += ".dirty"
462
+ return rendered
463
+
464
+
465
+ def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]:
466
+ """Split pep440 version string at the post-release segment.
467
+
468
+ Returns the release segments before the post-release and the
469
+ post-release version number (or -1 if no post-release segment is present).
470
+ """
471
+ vc = str.split(ver, ".post")
472
+ return vc[0], int(vc[1] or 0) if len(vc) == 2 else None
473
+
474
+
475
+ def render_pep440_pre(pieces: Dict[str, Any]) -> str:
476
+ """TAG[.postN.devDISTANCE] -- No -dirty.
477
+
478
+ Exceptions:
479
+ 1: no tags. 0.post0.devDISTANCE
480
+ """
481
+ if pieces["closest-tag"]:
482
+ if pieces["distance"]:
483
+ # update the post release segment
484
+ tag_version, post_version = pep440_split_post(pieces["closest-tag"])
485
+ rendered = tag_version
486
+ if post_version is not None:
487
+ rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"])
488
+ else:
489
+ rendered += ".post0.dev%d" % (pieces["distance"])
490
+ else:
491
+ # no commits, use the tag as the version
492
+ rendered = pieces["closest-tag"]
493
+ else:
494
+ # exception #1
495
+ rendered = "0.post0.dev%d" % pieces["distance"]
496
+ return rendered
497
+
498
+
499
+ def render_pep440_post(pieces: Dict[str, Any]) -> str:
500
+ """TAG[.postDISTANCE[.dev0]+gHEX] .
501
+
502
+ The ".dev0" means dirty. Note that .dev0 sorts backwards
503
+ (a dirty tree will appear "older" than the corresponding clean one),
504
+ but you shouldn't be releasing software with -dirty anyways.
505
+
506
+ Exceptions:
507
+ 1: no tags. 0.postDISTANCE[.dev0]
508
+ """
509
+ if pieces["closest-tag"]:
510
+ rendered = pieces["closest-tag"]
511
+ if pieces["distance"] or pieces["dirty"]:
512
+ rendered += ".post%d" % pieces["distance"]
513
+ if pieces["dirty"]:
514
+ rendered += ".dev0"
515
+ rendered += plus_or_dot(pieces)
516
+ rendered += "g%s" % pieces["short"]
517
+ else:
518
+ # exception #1
519
+ rendered = "0.post%d" % pieces["distance"]
520
+ if pieces["dirty"]:
521
+ rendered += ".dev0"
522
+ rendered += "+g%s" % pieces["short"]
523
+ return rendered
524
+
525
+
526
+ def render_pep440_post_branch(pieces: Dict[str, Any]) -> str:
527
+ """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] .
528
+
529
+ The ".dev0" means not master branch.
530
+
531
+ Exceptions:
532
+ 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty]
533
+ """
534
+ if pieces["closest-tag"]:
535
+ rendered = pieces["closest-tag"]
536
+ if pieces["distance"] or pieces["dirty"]:
537
+ rendered += ".post%d" % pieces["distance"]
538
+ if pieces["branch"] != "master":
539
+ rendered += ".dev0"
540
+ rendered += plus_or_dot(pieces)
541
+ rendered += "g%s" % pieces["short"]
542
+ if pieces["dirty"]:
543
+ rendered += ".dirty"
544
+ else:
545
+ # exception #1
546
+ rendered = "0.post%d" % pieces["distance"]
547
+ if pieces["branch"] != "master":
548
+ rendered += ".dev0"
549
+ rendered += "+g%s" % pieces["short"]
550
+ if pieces["dirty"]:
551
+ rendered += ".dirty"
552
+ return rendered
553
+
554
+
555
+ def render_pep440_old(pieces: Dict[str, Any]) -> str:
556
+ """TAG[.postDISTANCE[.dev0]] .
557
+
558
+ The ".dev0" means dirty.
559
+
560
+ Exceptions:
561
+ 1: no tags. 0.postDISTANCE[.dev0]
562
+ """
563
+ if pieces["closest-tag"]:
564
+ rendered = pieces["closest-tag"]
565
+ if pieces["distance"] or pieces["dirty"]:
566
+ rendered += ".post%d" % pieces["distance"]
567
+ if pieces["dirty"]:
568
+ rendered += ".dev0"
569
+ else:
570
+ # exception #1
571
+ rendered = "0.post%d" % pieces["distance"]
572
+ if pieces["dirty"]:
573
+ rendered += ".dev0"
574
+ return rendered
575
+
576
+
577
+ def render_git_describe(pieces: Dict[str, Any]) -> str:
578
+ """TAG[-DISTANCE-gHEX][-dirty].
579
+
580
+ Like 'git describe --tags --dirty --always'.
581
+
582
+ Exceptions:
583
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
584
+ """
585
+ if pieces["closest-tag"]:
586
+ rendered = pieces["closest-tag"]
587
+ if pieces["distance"]:
588
+ rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
589
+ else:
590
+ # exception #1
591
+ rendered = pieces["short"]
592
+ if pieces["dirty"]:
593
+ rendered += "-dirty"
594
+ return rendered
595
+
596
+
597
+ def render_git_describe_long(pieces: Dict[str, Any]) -> str:
598
+ """TAG-DISTANCE-gHEX[-dirty].
599
+
600
+ Like 'git describe --tags --dirty --always -long'.
601
+ The distance/hash is unconditional.
602
+
603
+ Exceptions:
604
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
605
+ """
606
+ if pieces["closest-tag"]:
607
+ rendered = pieces["closest-tag"]
608
+ rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
609
+ else:
610
+ # exception #1
611
+ rendered = pieces["short"]
612
+ if pieces["dirty"]:
613
+ rendered += "-dirty"
614
+ return rendered
615
+
616
+
617
+ def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]:
618
+ """Render the given version pieces into the requested style."""
619
+ if pieces["error"]:
620
+ return {
621
+ "version": "unknown",
622
+ "full-revisionid": pieces.get("long"),
623
+ "dirty": None,
624
+ "error": pieces["error"],
625
+ "date": None,
626
+ }
627
+
628
+ if not style or style == "default":
629
+ style = "pep440" # the default
630
+
631
+ if style == "pep440":
632
+ rendered = render_pep440(pieces)
633
+ elif style == "pep440-branch":
634
+ rendered = render_pep440_branch(pieces)
635
+ elif style == "pep440-pre":
636
+ rendered = render_pep440_pre(pieces)
637
+ elif style == "pep440-post":
638
+ rendered = render_pep440_post(pieces)
639
+ elif style == "pep440-post-branch":
640
+ rendered = render_pep440_post_branch(pieces)
641
+ elif style == "pep440-old":
642
+ rendered = render_pep440_old(pieces)
643
+ elif style == "git-describe":
644
+ rendered = render_git_describe(pieces)
645
+ elif style == "git-describe-long":
646
+ rendered = render_git_describe_long(pieces)
647
+ else:
648
+ raise ValueError("unknown style '%s'" % style)
649
+
650
+ return {
651
+ "version": rendered,
652
+ "full-revisionid": pieces["long"],
653
+ "dirty": pieces["dirty"],
654
+ "error": None,
655
+ "date": pieces.get("date"),
656
+ }
657
+
658
+
659
+ def get_versions() -> Dict[str, Any]:
660
+ """Get version information or return default if unable to do so."""
661
+ # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
662
+ # __file__, we can work backwards from there to the root. Some
663
+ # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
664
+ # case we can only use expanded keywords.
665
+
666
+ cfg = get_config()
667
+ verbose = cfg.verbose
668
+
669
+ try:
670
+ return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose)
671
+ except NotThisMethod:
672
+ pass
673
+
674
+ try:
675
+ root = os.path.realpath(__file__)
676
+ # versionfile_source is the relative path from the top of the source
677
+ # tree (where the .git directory might live) to this file. Invert
678
+ # this to find the root from __file__.
679
+ for _ in cfg.versionfile_source.split("/"):
680
+ root = os.path.dirname(root)
681
+ except NameError:
682
+ return {
683
+ "version": "0+unknown",
684
+ "full-revisionid": None,
685
+ "dirty": None,
686
+ "error": "unable to find root of source tree",
687
+ "date": None,
688
+ }
689
+
690
+ try:
691
+ pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
692
+ return render(pieces, cfg.style)
693
+ except NotThisMethod:
694
+ pass
695
+
696
+ try:
697
+ if cfg.parentdir_prefix:
698
+ return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
699
+ except NotThisMethod:
700
+ pass
701
+
702
+ return {
703
+ "version": "0+unknown",
704
+ "full-revisionid": None,
705
+ "dirty": None,
706
+ "error": "unable to compute version",
707
+ "date": None,
708
+ }