Coverage for kwant/version.py : 51%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright 2011-2017 Kwant authors.
2#
3# This file is part of Kwant. It is subject to the license terms in the file
4# LICENSE.rst found in the top-level directory of this distribution and at
5# https://kwant-project.org/license. A list of Kwant authors can be found in
6# the file AUTHORS.rst at the top-level directory of this distribution and at
7# https://kwant-project.org/authors.
9# This module must also work with Python 2.
10from __future__ import print_function
12import sys
13import subprocess
14import os
16# No public API
17__all__ = []
19package_root = os.path.dirname(os.path.realpath(__file__))
20distr_root = os.path.dirname(package_root)
22def ensure_python(required_version=(3, 5)):
23 v = sys.version_info
24 if v[:3] < required_version: 24 ↛ 25line 24 didn't jump to line 25, because the condition on line 24 was never true
25 error = "This version of Kwant requires Python {} or above.".format(
26 ".".join(str(p) for p in required_version))
27 if v[0] == 2:
28 error += "\nKwant 1.1 is the last version to support Python 2."
29 print(error, file=sys.stderr)
30 sys.exit(1)
33def get_version_from_git():
34 try:
35 p = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'],
36 cwd=distr_root,
37 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
38 except OSError:
39 return
40 if p.wait() != 0: 40 ↛ 41line 40 didn't jump to line 41, because the condition on line 40 was never true
41 return
42 if not os.path.samefile(p.communicate()[0].decode().rstrip('\n'), 42 ↛ 47line 42 didn't jump to line 47, because the condition on line 42 was never true
43 distr_root):
44 # The top-level directory of the current Git repository is not the same
45 # as the root directory of the Kwant distribution: do not extract the
46 # version from Git.
47 return
49 # git describe --first-parent does not take into account tags from branches
50 # that were merged-in.
51 for opts in [['--first-parent'], []]: 51 ↛ 61line 51 didn't jump to line 61, because the loop on line 51 didn't complete
52 try:
53 p = subprocess.Popen(['git', 'describe', '--long'] + opts,
54 cwd=distr_root,
55 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
56 except OSError:
57 return
58 if p.wait() == 0: 58 ↛ 51line 58 didn't jump to line 51, because the condition on line 58 was never false
59 break
60 else:
61 return
62 description = p.communicate()[0].decode().strip('v').rstrip('\n')
64 release, dev, git = description.rsplit('-', 2)
65 version = [release]
66 labels = []
67 if dev != "0": 67 ↛ 71line 67 didn't jump to line 71, because the condition on line 67 was never false
68 version.append(".dev{}".format(dev))
69 labels.append(git)
71 try:
72 p = subprocess.Popen(['git', 'diff', '--quiet'], cwd=distr_root)
73 except OSError:
74 labels.append('confused') # This should never happen.
75 else:
76 if p.wait() == 1: 76 ↛ 77line 76 didn't jump to line 77, because the condition on line 76 was never true
77 labels.append('dirty')
79 if labels: 79 ↛ 83line 79 didn't jump to line 83, because the condition on line 79 was never false
80 version.append('+')
81 version.append(".".join(labels))
83 return "".join(version)
86# TODO: change this logic when there is a git pretty-format
87# that gives the same output as 'git describe'.
88# Currently we can only tell the tag the current commit is
89# pointing to, or its hash (with no version info)
90# if it is not tagged.
91def get_version_from_git_archive(version_info):
92 try:
93 refnames = version_info['refnames']
94 git_hash = version_info['git_hash']
95 except KeyError:
96 # These fields are not present if we are running from an sdist.
97 # Execution should never reach here, though
98 return None
100 if git_hash.startswith('$Format') or refnames.startswith('$Format'):
101 # variables not expanded during 'git archive'
102 return None
104 VTAG = 'tag: v' # Our version tags always start with 'v'
105 refs = set(r.strip() for r in refnames.split(","))
106 version_tags = set(r[len(VTAG):] for r in refs if r.startswith(VTAG))
107 if version_tags:
108 release, *_ = sorted(version_tags) # prefer e.g. "2.0" over "2.0rc1"
109 return release
110 else:
111 return ''.join(('unknown', '+g', git_hash))
114def init(version_file='_kwant_version.py'):
115 global version, version_is_from_git
116 version_info = {}
117 with open(os.path.join(package_root, version_file), 'rb') as f:
118 exec(f.read(), {}, version_info)
119 version = version_info['version']
120 version_is_from_git = (version == "__use_git__")
121 if version_is_from_git: 121 ↛ exitline 121 didn't return from function 'init', because the condition on line 121 was never false
122 version = get_version_from_git()
123 if not version: 123 ↛ 124line 123 didn't jump to line 124, because the condition on line 123 was never true
124 version = get_version_from_git_archive(version_info)
125 if not version: 125 ↛ 126line 125 didn't jump to line 126, because the condition on line 125 was never true
126 version = "unknown"
128init()