1 # -*- coding: utf-8 -*-
2 """
3 patchlevel.py
4 ~~~~~~~~~~~~~
5
6 Extract version info from Include/patchlevel.h.
7 Adapted from Doc/tools/getversioninfo.
8
9 :copyright: 2007-2008 by Georg Brandl.
10 :license: Python license.
11 """
12
13 from __future__ import print_function
14
15 import os
16 import re
17 import sys
18
19 def get_header_version_info(srcdir):
20 patchlevel_h = os.path.join(srcdir, '..', 'Include', 'patchlevel.h')
21
22 # This won't pick out all #defines, but it will pick up the ones we
23 # care about.
24 rx = re.compile(r'\s*#define\s+([a-zA-Z][a-zA-Z_0-9]*)\s+([a-zA-Z_0-9]+)')
25
26 d = {}
27 with open(patchlevel_h) as f:
28 for line in f:
29 m = rx.match(line)
30 if m is not None:
31 name, value = m.group(1, 2)
32 d[name] = value
33
34 release = version = '%s.%s' % (d['PY_MAJOR_VERSION'], d['PY_MINOR_VERSION'])
35 micro = int(d['PY_MICRO_VERSION'])
36 release += '.' + str(micro)
37
38 level = d['PY_RELEASE_LEVEL']
39 suffixes = {
40 'PY_RELEASE_LEVEL_ALPHA': 'a',
41 'PY_RELEASE_LEVEL_BETA': 'b',
42 'PY_RELEASE_LEVEL_GAMMA': 'rc',
43 }
44 if level != 'PY_RELEASE_LEVEL_FINAL':
45 release += suffixes[level] + str(int(d['PY_RELEASE_SERIAL']))
46 return version, release
47
48
49 def get_sys_version_info():
50 major, minor, micro, level, serial = sys.version_info
51 release = version = '%s.%s' % (major, minor)
52 release += '.%s' % micro
53 if level != 'final':
54 release += '%s%s' % (level[0], serial)
55 return version, release
56
57
58 def get_version_info():
59 try:
60 return get_header_version_info('.')
61 except (IOError, OSError):
62 version, release = get_sys_version_info()
63 print('Can\'t get version info from Include/patchlevel.h, ' \
64 'using version of this interpreter (%s).' % release, file=sys.stderr)
65 return version, release
66
67 if __name__ == '__main__':
68 print(get_header_version_info('.')[1])