1-
21# This file helps to compute a version number in source trees obtained from
32# git-archive tarball (such as those provided by githubs download-from-tag
43# feature). Distribution tarballs (built by setup.py sdist) and build
1211"""Git implementation of _version.py."""
1312
1413import errno
14+ import functools
1515import os
1616import re
1717import subprocess
1818import sys
1919from typing import Any , Callable , Dict , List , Optional , Tuple
20- import functools
2120
2221
2322def get_keywords () -> Dict [str , str ]:
@@ -68,12 +67,14 @@ class NotThisMethod(Exception):
6867
6968def register_vcs_handler (vcs : str , method : str ) -> Callable : # decorator
7069 """Create decorator to mark a method as the handler of a VCS."""
70+
7171 def decorate (f : Callable ) -> Callable :
7272 """Store f in HANDLERS[vcs][method]."""
7373 if vcs not in HANDLERS :
7474 HANDLERS [vcs ] = {}
7575 HANDLERS [vcs ][method ] = f
7676 return f
77+
7778 return decorate
7879
7980
@@ -100,10 +101,14 @@ def run_command(
100101 try :
101102 dispcmd = str ([command ] + args )
102103 # remember shell=False, so use git.cmd on windows, not just git
103- process = subprocess .Popen ([command ] + args , cwd = cwd , env = env ,
104- stdout = subprocess .PIPE ,
105- stderr = (subprocess .PIPE if hide_stderr
106- else None ), ** popen_kwargs )
104+ process = subprocess .Popen (
105+ [command ] + args ,
106+ cwd = cwd ,
107+ env = env ,
108+ stdout = subprocess .PIPE ,
109+ stderr = (subprocess .PIPE if hide_stderr else None ),
110+ ** popen_kwargs ,
111+ )
107112 break
108113 except OSError as e :
109114 if e .errno == errno .ENOENT :
@@ -114,7 +119,7 @@ def run_command(
114119 return None , None
115120 else :
116121 if verbose :
117- print ("unable to find command, tried %s" % (commands , ))
122+ print ("unable to find command, tried {}" . format (commands ))
118123 return None , None
119124 stdout = process .communicate ()[0 ].strip ().decode ()
120125 if process .returncode != 0 :
@@ -141,15 +146,21 @@ def versions_from_parentdir(
141146 for _ in range (3 ):
142147 dirname = os .path .basename (root )
143148 if dirname .startswith (parentdir_prefix ):
144- return {"version" : dirname [len (parentdir_prefix ):],
145- "full-revisionid" : None ,
146- "dirty" : False , "error" : None , "date" : None }
149+ return {
150+ "version" : dirname [len (parentdir_prefix ) :],
151+ "full-revisionid" : None ,
152+ "dirty" : False ,
153+ "error" : None ,
154+ "date" : None ,
155+ }
147156 rootdirs .append (root )
148157 root = os .path .dirname (root ) # up a level
149158
150159 if verbose :
151- print ("Tried directories %s but none started with prefix %s" %
152- (str (rootdirs ), parentdir_prefix ))
160+ print (
161+ "Tried directories %s but none started with prefix %s"
162+ % (str (rootdirs ), parentdir_prefix )
163+ )
153164 raise NotThisMethod ("rootdir doesn't start with parentdir_prefix" )
154165
155166
@@ -162,7 +173,7 @@ def git_get_keywords(versionfile_abs: str) -> Dict[str, str]:
162173 # _version.py.
163174 keywords : Dict [str , str ] = {}
164175 try :
165- with open (versionfile_abs , "r" ) as fobj :
176+ with open (versionfile_abs ) as fobj :
166177 for line in fobj :
167178 if line .strip ().startswith ("git_refnames =" ):
168179 mo = re .search (r'=\s*"(.*)"' , line )
@@ -212,7 +223,7 @@ def git_versions_from_keywords(
212223 # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
213224 # just "foo-1.0". If we see a "tag: " prefix, prefer those.
214225 TAG = "tag: "
215- tags = {r [len (TAG ):] for r in refs if r .startswith (TAG )}
226+ tags = {r [len (TAG ) :] for r in refs if r .startswith (TAG )}
216227 if not tags :
217228 # Either we're using git < 1.8.3, or there really are no tags. We use
218229 # a heuristic: assume all version tags have a digit. The old git %d
@@ -221,40 +232,44 @@ def git_versions_from_keywords(
221232 # between branches and tags. By ignoring refnames without digits, we
222233 # filter out many common branch names like "release" and
223234 # "stabilization", as well as "HEAD" and "master".
224- tags = {r for r in refs if re .search (r'\d' , r )}
235+ tags = {r for r in refs if re .search (r"\d" , r )}
225236 if verbose :
226237 print ("discarding '%s', no digits" % "," .join (refs - tags ))
227238 if verbose :
228239 print ("likely tags: %s" % "," .join (sorted (tags )))
229240 for ref in sorted (tags ):
230241 # sorting will prefer e.g. "2.0" over "2.0rc1"
231242 if ref .startswith (tag_prefix ):
232- r = ref [len (tag_prefix ):]
243+ r = ref [len (tag_prefix ) :]
233244 # Filter out refs that exactly match prefix or that don't start
234245 # with a number once the prefix is stripped (mostly a concern
235246 # when prefix is '')
236- if not re .match (r'\d' , r ):
247+ if not re .match (r"\d" , r ):
237248 continue
238249 if verbose :
239250 print ("picking %s" % r )
240- return {"version" : r ,
241- "full-revisionid" : keywords ["full" ].strip (),
242- "dirty" : False , "error" : None ,
243- "date" : date }
251+ return {
252+ "version" : r ,
253+ "full-revisionid" : keywords ["full" ].strip (),
254+ "dirty" : False ,
255+ "error" : None ,
256+ "date" : date ,
257+ }
244258 # no suitable tags, so version is "0+unknown", but full hex is still there
245259 if verbose :
246260 print ("no suitable tags, using unknown + full revision id" )
247- return {"version" : "0+unknown" ,
248- "full-revisionid" : keywords ["full" ].strip (),
249- "dirty" : False , "error" : "no suitable tags" , "date" : None }
261+ return {
262+ "version" : "0+unknown" ,
263+ "full-revisionid" : keywords ["full" ].strip (),
264+ "dirty" : False ,
265+ "error" : "no suitable tags" ,
266+ "date" : None ,
267+ }
250268
251269
252270@register_vcs_handler ("git" , "pieces_from_vcs" )
253271def git_pieces_from_vcs (
254- tag_prefix : str ,
255- root : str ,
256- verbose : bool ,
257- runner : Callable = run_command
272+ tag_prefix : str , root : str , verbose : bool , runner : Callable = run_command
258273) -> Dict [str , Any ]:
259274 """Get version from 'git describe' in the root of the source tree.
260275
@@ -273,19 +288,27 @@ def git_pieces_from_vcs(
273288 env .pop ("GIT_DIR" , None )
274289 runner = functools .partial (runner , env = env )
275290
276- _ , rc = runner (GITS , ["rev-parse" , "--git-dir" ], cwd = root ,
277- hide_stderr = not verbose )
291+ _ , rc = runner (GITS , ["rev-parse" , "--git-dir" ], cwd = root , hide_stderr = not verbose )
278292 if rc != 0 :
279293 if verbose :
280294 print ("Directory %s not under git control" % root )
281295 raise NotThisMethod ("'git rev-parse --git-dir' returned error" )
282296
283297 # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
284298 # if there isn't one, this yields HEX[-dirty] (no NUM)
285- describe_out , rc = runner (GITS , [
286- "describe" , "--tags" , "--dirty" , "--always" , "--long" ,
287- "--match" , f"{ tag_prefix } [[:digit:]]*"
288- ], cwd = root )
299+ describe_out , rc = runner (
300+ GITS ,
301+ [
302+ "describe" ,
303+ "--tags" ,
304+ "--dirty" ,
305+ "--always" ,
306+ "--long" ,
307+ "--match" ,
308+ f"{ tag_prefix } [[:digit:]]*" ,
309+ ],
310+ cwd = root ,
311+ )
289312 # --long was added in git-1.5.5
290313 if describe_out is None :
291314 raise NotThisMethod ("'git describe' failed" )
@@ -300,8 +323,7 @@ def git_pieces_from_vcs(
300323 pieces ["short" ] = full_out [:7 ] # maybe improved later
301324 pieces ["error" ] = None
302325
303- branch_name , rc = runner (GITS , ["rev-parse" , "--abbrev-ref" , "HEAD" ],
304- cwd = root )
326+ branch_name , rc = runner (GITS , ["rev-parse" , "--abbrev-ref" , "HEAD" ], cwd = root )
305327 # --abbrev-ref was added in git-1.6.3
306328 if rc != 0 or branch_name is None :
307329 raise NotThisMethod ("'git rev-parse --abbrev-ref' returned error" )
@@ -341,17 +363,16 @@ def git_pieces_from_vcs(
341363 dirty = git_describe .endswith ("-dirty" )
342364 pieces ["dirty" ] = dirty
343365 if dirty :
344- git_describe = git_describe [:git_describe .rindex ("-dirty" )]
366+ git_describe = git_describe [: git_describe .rindex ("-dirty" )]
345367
346368 # now we have TAG-NUM-gHEX or HEX
347369
348370 if "-" in git_describe :
349371 # TAG-NUM-gHEX
350- mo = re .search (r' ^(.+)-(\d+)-g([0-9a-f]+)$' , git_describe )
372+ mo = re .search (r" ^(.+)-(\d+)-g([0-9a-f]+)$" , git_describe )
351373 if not mo :
352374 # unparsable. Maybe git-describe is misbehaving?
353- pieces ["error" ] = ("unable to parse git-describe output: '%s'"
354- % describe_out )
375+ pieces ["error" ] = "unable to parse git-describe output: '%s'" % describe_out
355376 return pieces
356377
357378 # tag
@@ -360,10 +381,12 @@ def git_pieces_from_vcs(
360381 if verbose :
361382 fmt = "tag '%s' doesn't start with prefix '%s'"
362383 print (fmt % (full_tag , tag_prefix ))
363- pieces ["error" ] = ("tag '%s' doesn't start with prefix '%s'"
364- % (full_tag , tag_prefix ))
384+ pieces ["error" ] = "tag '%s' doesn't start with prefix '%s'" % (
385+ full_tag ,
386+ tag_prefix ,
387+ )
365388 return pieces
366- pieces ["closest-tag" ] = full_tag [len (tag_prefix ):]
389+ pieces ["closest-tag" ] = full_tag [len (tag_prefix ) :]
367390
368391 # distance: number of commits since tag
369392 pieces ["distance" ] = int (mo .group (2 ))
@@ -412,8 +435,7 @@ def render_pep440(pieces: Dict[str, Any]) -> str:
412435 rendered += ".dirty"
413436 else :
414437 # exception #1
415- rendered = "0+untagged.%d.g%s" % (pieces ["distance" ],
416- pieces ["short" ])
438+ rendered = "0+untagged.%d.g%s" % (pieces ["distance" ], pieces ["short" ])
417439 if pieces ["dirty" ]:
418440 rendered += ".dirty"
419441 return rendered
@@ -442,8 +464,7 @@ def render_pep440_branch(pieces: Dict[str, Any]) -> str:
442464 rendered = "0"
443465 if pieces ["branch" ] != "master" :
444466 rendered += ".dev0"
445- rendered += "+untagged.%d.g%s" % (pieces ["distance" ],
446- pieces ["short" ])
467+ rendered += "+untagged.%d.g%s" % (pieces ["distance" ], pieces ["short" ])
447468 if pieces ["dirty" ]:
448469 rendered += ".dirty"
449470 return rendered
@@ -604,11 +625,13 @@ def render_git_describe_long(pieces: Dict[str, Any]) -> str:
604625def render (pieces : Dict [str , Any ], style : str ) -> Dict [str , Any ]:
605626 """Render the given version pieces into the requested style."""
606627 if pieces ["error" ]:
607- return {"version" : "unknown" ,
608- "full-revisionid" : pieces .get ("long" ),
609- "dirty" : None ,
610- "error" : pieces ["error" ],
611- "date" : None }
628+ return {
629+ "version" : "unknown" ,
630+ "full-revisionid" : pieces .get ("long" ),
631+ "dirty" : None ,
632+ "error" : pieces ["error" ],
633+ "date" : None ,
634+ }
612635
613636 if not style or style == "default" :
614637 style = "pep440" # the default
@@ -632,9 +655,13 @@ def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]:
632655 else :
633656 raise ValueError ("unknown style '%s'" % style )
634657
635- return {"version" : rendered , "full-revisionid" : pieces ["long" ],
636- "dirty" : pieces ["dirty" ], "error" : None ,
637- "date" : pieces .get ("date" )}
658+ return {
659+ "version" : rendered ,
660+ "full-revisionid" : pieces ["long" ],
661+ "dirty" : pieces ["dirty" ],
662+ "error" : None ,
663+ "date" : pieces .get ("date" ),
664+ }
638665
639666
640667def get_versions () -> Dict [str , Any ]:
@@ -648,8 +675,7 @@ def get_versions() -> Dict[str, Any]:
648675 verbose = cfg .verbose
649676
650677 try :
651- return git_versions_from_keywords (get_keywords (), cfg .tag_prefix ,
652- verbose )
678+ return git_versions_from_keywords (get_keywords (), cfg .tag_prefix , verbose )
653679 except NotThisMethod :
654680 pass
655681
@@ -658,13 +684,16 @@ def get_versions() -> Dict[str, Any]:
658684 # versionfile_source is the relative path from the top of the source
659685 # tree (where the .git directory might live) to this file. Invert
660686 # this to find the root from __file__.
661- for _ in cfg .versionfile_source .split ('/' ):
687+ for _ in cfg .versionfile_source .split ("/" ):
662688 root = os .path .dirname (root )
663689 except NameError :
664- return {"version" : "0+unknown" , "full-revisionid" : None ,
665- "dirty" : None ,
666- "error" : "unable to find root of source tree" ,
667- "date" : None }
690+ return {
691+ "version" : "0+unknown" ,
692+ "full-revisionid" : None ,
693+ "dirty" : None ,
694+ "error" : "unable to find root of source tree" ,
695+ "date" : None ,
696+ }
668697
669698 try :
670699 pieces = git_pieces_from_vcs (cfg .tag_prefix , root , verbose )
@@ -678,6 +707,10 @@ def get_versions() -> Dict[str, Any]:
678707 except NotThisMethod :
679708 pass
680709
681- return {"version" : "0+unknown" , "full-revisionid" : None ,
682- "dirty" : None ,
683- "error" : "unable to compute version" , "date" : None }
710+ return {
711+ "version" : "0+unknown" ,
712+ "full-revisionid" : None ,
713+ "dirty" : None ,
714+ "error" : "unable to compute version" ,
715+ "date" : None ,
716+ }
0 commit comments