44# directories (produced by setup.py build) will contain a much shorter file
55# that just contains the computed version number.
66
7- # This file is released into the public domain. Generated by
8- # versioneer-0.20 (https://github.com/python-versioneer/python-versioneer)
7+ # This file is released into the public domain.
8+ # Generated by versioneer-0.29
9+ # https://github.com/python-versioneer/python-versioneer
910
1011"""Git implementation of _version.py."""
1112
1213import errno
14+ import functools
1315import os
1416import re
1517import subprocess
1618import sys
19+ from typing import Any , Callable , Dict , List , Optional , Tuple
1720
1821
19- def get_keywords ():
22+ def get_keywords () -> Dict [ str , str ] :
2023 """Get the keywords needed to look up the version information."""
2124 # these strings will be replaced by git during git-archive.
2225 # setup.py/versioneer.py will grep for the variable names, so they must
@@ -29,11 +32,18 @@ def get_keywords():
2932 return keywords
3033
3134
32- class VersioneerConfig : # pylint: disable=too-few-public-methods
35+ class VersioneerConfig :
3336 """Container for Versioneer configuration parameters."""
3437
38+ VCS : str
39+ style : str
40+ tag_prefix : str
41+ parentdir_prefix : str
42+ versionfile_source : str
43+ verbose : bool
3544
36- def get_config ():
45+
46+ def get_config () -> VersioneerConfig :
3747 """Create, populate and return the VersioneerConfig() object."""
3848 # these strings are filled in when 'setup.py versioneer' creates
3949 # _version.py
@@ -51,13 +61,14 @@ class NotThisMethod(Exception):
5161 """Exception raised if a method is not valid for the current scenario."""
5262
5363
54- HANDLERS = {}
64+ LONG_VERSION_PY : Dict [str , str ] = {}
65+ HANDLERS : Dict [str , Dict [str , Callable ]] = {}
5566
5667
57- def register_vcs_handler (vcs , method ) : # decorator
68+ def register_vcs_handler (vcs : str , method : str ) -> Callable : # decorator
5869 """Create decorator to mark a method as the handler of a VCS."""
5970
60- def decorate (f ) :
71+ def decorate (f : Callable ) -> Callable :
6172 """Store f in HANDLERS[vcs][method]."""
6273 if vcs not in HANDLERS :
6374 HANDLERS [vcs ] = {}
@@ -67,11 +78,25 @@ def decorate(f):
6778 return decorate
6879
6980
70- # pylint:disable=too-many-arguments,consider-using-with # noqa
71- def run_command (commands , args , cwd = None , verbose = False , hide_stderr = False , env = None ):
81+ def run_command (
82+ commands : List [str ],
83+ args : List [str ],
84+ cwd : Optional [str ] = None ,
85+ verbose : bool = False ,
86+ hide_stderr : bool = False ,
87+ env : Optional [Dict [str , str ]] = None ,
88+ ) -> Tuple [Optional [str ], Optional [int ]]:
7289 """Call the given command(s)."""
7390 assert isinstance (commands , list )
7491 process = None
92+
93+ popen_kwargs : Dict [str , Any ] = {}
94+ if sys .platform == "win32" :
95+ # This hides the console window if pythonw.exe is used
96+ startupinfo = subprocess .STARTUPINFO ()
97+ startupinfo .dwFlags |= subprocess .STARTF_USESHOWWINDOW
98+ popen_kwargs ["startupinfo" ] = startupinfo
99+
75100 for command in commands :
76101 try :
77102 dispcmd = str ([command ] + args )
@@ -82,10 +107,10 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=
82107 env = env ,
83108 stdout = subprocess .PIPE ,
84109 stderr = (subprocess .PIPE if hide_stderr else None ),
110+ ** popen_kwargs ,
85111 )
86112 break
87- except EnvironmentError :
88- e = sys .exc_info ()[1 ]
113+ except OSError as e :
89114 if e .errno == errno .ENOENT :
90115 continue
91116 if verbose :
@@ -105,7 +130,11 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=
105130 return stdout , process .returncode
106131
107132
108- def versions_from_parentdir (parentdir_prefix , root , verbose ):
133+ def versions_from_parentdir (
134+ parentdir_prefix : str ,
135+ root : str ,
136+ verbose : bool ,
137+ ) -> Dict [str , Any ]:
109138 """Try to determine the version from the parent directory name.
110139
111140 Source tarballs conventionally unpack into a directory that includes both
@@ -136,13 +165,13 @@ def versions_from_parentdir(parentdir_prefix, root, verbose):
136165
137166
138167@register_vcs_handler ("git" , "get_keywords" )
139- def git_get_keywords (versionfile_abs ) :
168+ def git_get_keywords (versionfile_abs : str ) -> Dict [ str , str ] :
140169 """Extract version information from the given file."""
141170 # the code embedded in _version.py can just fetch the value of these
142171 # keywords. When used from setup.py, we don't want to import _version.py,
143172 # so we do it with a regexp instead. This function is not used from
144173 # _version.py.
145- keywords = {}
174+ keywords : Dict [ str , str ] = {}
146175 try :
147176 with open (versionfile_abs , "r" ) as fobj :
148177 for line in fobj :
@@ -158,13 +187,17 @@ def git_get_keywords(versionfile_abs):
158187 mo = re .search (r'=\s*"(.*)"' , line )
159188 if mo :
160189 keywords ["date" ] = mo .group (1 )
161- except EnvironmentError :
190+ except OSError :
162191 pass
163192 return keywords
164193
165194
166195@register_vcs_handler ("git" , "keywords" )
167- def git_versions_from_keywords (keywords , tag_prefix , verbose ):
196+ def git_versions_from_keywords (
197+ keywords : Dict [str , str ],
198+ tag_prefix : str ,
199+ verbose : bool ,
200+ ) -> Dict [str , Any ]:
168201 """Get version information from git keywords."""
169202 if "refnames" not in keywords :
170203 raise NotThisMethod ("Short version file found" )
@@ -235,7 +268,9 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
235268
236269
237270@register_vcs_handler ("git" , "pieces_from_vcs" )
238- def git_pieces_from_vcs (tag_prefix , root , verbose , runner = run_command ):
271+ def git_pieces_from_vcs (
272+ tag_prefix : str , root : str , verbose : bool , runner : Callable = run_command
273+ ) -> Dict [str , Any ]:
239274 """Get version from 'git describe' in the root of the source tree.
240275
241276 This only gets called if the git-archive 'subst' keywords were *not*
@@ -246,7 +281,14 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
246281 if sys .platform == "win32" :
247282 GITS = ["git.cmd" , "git.exe" ]
248283
249- _ , rc = runner (GITS , ["rev-parse" , "--git-dir" ], cwd = root , hide_stderr = True )
284+ # GIT_DIR can interfere with correct operation of Versioneer.
285+ # It may be intended to be passed to the Versioneer-versioned project,
286+ # but that should not change where we get our version from.
287+ env = os .environ .copy ()
288+ env .pop ("GIT_DIR" , None )
289+ runner = functools .partial (runner , env = env )
290+
291+ _ , rc = runner (GITS , ["rev-parse" , "--git-dir" ], cwd = root , hide_stderr = not verbose )
250292 if rc != 0 :
251293 if verbose :
252294 print ("Directory %s not under git control" % root )
@@ -263,7 +305,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
263305 "--always" ,
264306 "--long" ,
265307 "--match" ,
266- "%s*" % tag_prefix ,
308+ f" { tag_prefix } [[:digit:]]*" ,
267309 ],
268310 cwd = root ,
269311 )
@@ -276,7 +318,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
276318 raise NotThisMethod ("'git rev-parse' failed" )
277319 full_out = full_out .strip ()
278320
279- pieces = {}
321+ pieces : Dict [ str , Any ] = {}
280322 pieces ["long" ] = full_out
281323 pieces ["short" ] = full_out [:7 ] # maybe improved later
282324 pieces ["error" ] = None
@@ -355,8 +397,8 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
355397 else :
356398 # HEX: no tags
357399 pieces ["closest-tag" ] = None
358- count_out , rc = runner (GITS , ["rev-list" , "HEAD" , "--count " ], cwd = root )
359- pieces ["distance" ] = int ( count_out ) # total number of commits
400+ out , rc = runner (GITS , ["rev-list" , "HEAD" , "--left-right " ], cwd = root )
401+ pieces ["distance" ] = len ( out . split () ) # total number of commits
360402
361403 # commit date: see ISO-8601 comment in git_versions_from_keywords()
362404 date = runner (GITS , ["show" , "-s" , "--format=%ci" , "HEAD" ], cwd = root )[0 ].strip ()
@@ -368,14 +410,14 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
368410 return pieces
369411
370412
371- def plus_or_dot (pieces ) :
413+ def plus_or_dot (pieces : Dict [ str , Any ]) -> str :
372414 """Return a + if we don't already have one, else return a ."""
373415 if "+" in pieces .get ("closest-tag" , "" ):
374416 return "."
375417 return "+"
376418
377419
378- def render_pep440 (pieces ) :
420+ def render_pep440 (pieces : Dict [ str , Any ]) -> str :
379421 """Build up version string, with post-release "local version identifier".
380422
381423 Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
@@ -399,7 +441,7 @@ def render_pep440(pieces):
399441 return rendered
400442
401443
402- def render_pep440_branch (pieces ) :
444+ def render_pep440_branch (pieces : Dict [ str , Any ]) -> str :
403445 """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] .
404446
405447 The ".dev0" means not master branch. Note that .dev0 sorts backwards
@@ -428,23 +470,41 @@ def render_pep440_branch(pieces):
428470 return rendered
429471
430472
431- def render_pep440_pre (pieces ):
432- """TAG[.post0.devDISTANCE] -- No -dirty.
473+ def pep440_split_post (ver : str ) -> Tuple [str , Optional [int ]]:
474+ """Split pep440 version string at the post-release segment.
475+
476+ Returns the release segments before the post-release and the
477+ post-release version number (or -1 if no post-release segment is present).
478+ """
479+ vc = str .split (ver , ".post" )
480+ return vc [0 ], int (vc [1 ] or 0 ) if len (vc ) == 2 else None
481+
482+
483+ def render_pep440_pre (pieces : Dict [str , Any ]) -> str :
484+ """TAG[.postN.devDISTANCE] -- No -dirty.
433485
434486 Exceptions:
435487 1: no tags. 0.post0.devDISTANCE
436488 """
437489 if pieces ["closest-tag" ]:
438- rendered = pieces ["closest-tag" ]
439490 if pieces ["distance" ]:
440- rendered += ".post0.dev%d" % pieces ["distance" ]
491+ # update the post release segment
492+ tag_version , post_version = pep440_split_post (pieces ["closest-tag" ])
493+ rendered = tag_version
494+ if post_version is not None :
495+ rendered += ".post%d.dev%d" % (post_version + 1 , pieces ["distance" ])
496+ else :
497+ rendered += ".post0.dev%d" % (pieces ["distance" ])
498+ else :
499+ # no commits, use the tag as the version
500+ rendered = pieces ["closest-tag" ]
441501 else :
442502 # exception #1
443503 rendered = "0.post0.dev%d" % pieces ["distance" ]
444504 return rendered
445505
446506
447- def render_pep440_post (pieces ) :
507+ def render_pep440_post (pieces : Dict [ str , Any ]) -> str :
448508 """TAG[.postDISTANCE[.dev0]+gHEX] .
449509
450510 The ".dev0" means dirty. Note that .dev0 sorts backwards
@@ -471,7 +531,7 @@ def render_pep440_post(pieces):
471531 return rendered
472532
473533
474- def render_pep440_post_branch (pieces ) :
534+ def render_pep440_post_branch (pieces : Dict [ str , Any ]) -> str :
475535 """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] .
476536
477537 The ".dev0" means not master branch.
@@ -500,7 +560,7 @@ def render_pep440_post_branch(pieces):
500560 return rendered
501561
502562
503- def render_pep440_old (pieces ) :
563+ def render_pep440_old (pieces : Dict [ str , Any ]) -> str :
504564 """TAG[.postDISTANCE[.dev0]] .
505565
506566 The ".dev0" means dirty.
@@ -522,7 +582,7 @@ def render_pep440_old(pieces):
522582 return rendered
523583
524584
525- def render_git_describe (pieces ) :
585+ def render_git_describe (pieces : Dict [ str , Any ]) -> str :
526586 """TAG[-DISTANCE-gHEX][-dirty].
527587
528588 Like 'git describe --tags --dirty --always'.
@@ -542,7 +602,7 @@ def render_git_describe(pieces):
542602 return rendered
543603
544604
545- def render_git_describe_long (pieces ) :
605+ def render_git_describe_long (pieces : Dict [ str , Any ]) -> str :
546606 """TAG-DISTANCE-gHEX[-dirty].
547607
548608 Like 'git describe --tags --dirty --always -long'.
@@ -562,7 +622,7 @@ def render_git_describe_long(pieces):
562622 return rendered
563623
564624
565- def render (pieces , style ) :
625+ def render (pieces : Dict [ str , Any ], style : str ) -> Dict [ str , Any ] :
566626 """Render the given version pieces into the requested style."""
567627 if pieces ["error" ]:
568628 return {
@@ -604,7 +664,7 @@ def render(pieces, style):
604664 }
605665
606666
607- def get_versions ():
667+ def get_versions () -> Dict [ str , Any ] :
608668 """Get version information or return default if unable to do so."""
609669 # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
610670 # __file__, we can work backwards from there to the root. Some
0 commit comments