190f5ba538bf40bcf4fd41049c7bf4296d3ffc9c7Benjamin Peterson#!/usr/bin/env python3
2246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
38ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon""" This module tries to retrieve as much platform-identifying data as
4246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    possible. It makes this information available via function APIs.
5246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
6246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    If called from the command line, it prints the platform
7246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    information concatenated as single string to stdout. The output
8246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    format is useable as part of a filename.
9246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
10246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg"""
11246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    This module is maintained by Marc-Andre Lemburg <mal@egenix.com>.
12246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    If you find problems, please submit bug reports/patches via the
134ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson#    Python bug tracker (http://bugs.python.org) and assign them to "lemburg".
14246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
15246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    Still needed:
16246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for MS-DOS (PythonDX ?)
17246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for Amiga and other still unsupported platforms running Python
18246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for additional Linux distributions
19246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
208ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon#    Many thanks to all those who helped adding platform-specific
21246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    checks (in no particular order):
22246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
23246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell,
24246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef
25246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg
26246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark
27246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support),
28b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower#      Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter, Steve
29b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower#      Dower
30246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
31246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    History:
32380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#
33380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#    <see CVS and SVN checkin messages for history>
34380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#
35b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower#    1.0.8 - changed Windows support to read version from kernel32.dll
36e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#    1.0.7 - added DEV_NULL
37fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.6 - added linux_distribution()
38fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.5 - fixed Java support to allow running the module on Jython
39fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.4 - added IronPython support
40cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg#    1.0.3 - added normalization of Windows system name
4191e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg#    1.0.2 - added more Windows support
42366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg#    1.0.1 - reformatted to make doc.py happy
43246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    1.0.0 - reformatted a bit and checked into Python CVS
44246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.8.0 - added sys.version parser and various new access
45246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            APIs (python_version(), python_compiler(), etc.)
46246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.2 - fixed architecture() to use sizeof(pointer) where available
47246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.1 - added support for Caldera OpenLinux
48246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.0 - some fixes for WinCE; untabified the source file
49246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and
50246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            vms_lib.getsyi() configured
51246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.1 - added code to prevent 'uname -p' on platforms which are
52246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            known not to support it
53246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k;
54246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            did some cleanup of the interfaces - some APIs have changed
55246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.5 - fixed another type in the MacOS code... should have
56246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            used more coffee today ;-)
57246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.4 - fixed a few typos in the MacOS code
58246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.3 - added experimental MacOS support; added better popen()
59246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            workarounds in _syscmd_ver() -- still not 100% elegant
60246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            though
61246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.2 - fixed uname() to return '' instead of 'unknown' in all
62246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            return values (the system uname command tends to return
63eb9957065acaafbf3d8ebee4770ecb13ea0c07c0Martin Panter#            'unknown' instead of just leaving the field empty)
64246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.1 - included code for slackware dist; added exception handlers
65246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            to cover up situations where platforms don't have os.popen
66246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            (e.g. Mac) or fail on socket.gethostname(); fixed libc
67246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            detection RE
68246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.0 - changed the API names referring to system commands to *syscmd*;
69246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            added java_ver(); made syscmd_ver() a private
70246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            API (was system_ver() in previous versions) -- use uname()
71246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            instead; extended the win32_ver() to also return processor
72246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            type information
73246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.4.0 - added win32_ver() and modified the platform() output for WinXX
74246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.4 - fixed a bug in _follow_symlinks()
75246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.3 - fixed popen() and "file" command invokation bugs
76246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.2 - added architecture() API and support for it in platform()
77246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.1 - fixed syscmd_ver() RE to support Windows NT
78246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.0 - added system alias support
79246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.3 - removed 'wince' again... oh well.
80246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.2 - added 'wince' to syscmd_ver() supported platforms
81246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.1 - added cache logic and changed the platform string format
82246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.0 - changed the API to use functions instead of module globals
83246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            since some action take too long to be run on module import
84246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.1.0 - first release
85246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
86246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    You can always get the latest version of this module at:
87246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
88246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#             http://www.egenix.com/files/python/platform.py
89246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
90246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    If that URL should fail, try contacting the author.
91246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
92246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg__copyright__ = """
93246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com
9446a9900e099a82cda7328b0de16d6fffe52ee62aBenjamin Peterson    Copyright (c) 2000-2010, eGenix.com Software GmbH; mailto:info@egenix.com
95246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
96246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    Permission to use, copy, modify, and distribute this software and its
97246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    documentation for any purpose and without fee or royalty is hereby granted,
98246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    provided that the above copyright notice appear in all copies and that
99246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    both that copyright notice and this permission notice appear in
100246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    supporting documentation or portions thereof, including modifications,
101246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    that you make.
102246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
103246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO
104246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
105246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
106246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
107246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
108246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
109246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
110246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
111246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg"""
112246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
113bb59d89ceeb1abfb4d73c7fc60b534e4464adf35Berker Peksag__version__ = '1.0.8'
114246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
11568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastingsimport collections
116fc990e942fb55be78e8352f4913749e91cac381dJesus Ceaimport sys, os, re, subprocess
117246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1181392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksagimport warnings
1191392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag
120e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti### Globals & Constants
121e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
122e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Determine the platform's /dev/null device
123e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalottitry:
124e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    DEV_NULL = os.devnull
125e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalottiexcept AttributeError:
126e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    # os.devnull was added in Python 2.4, so emulate it for earlier
127e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    # Python versions
128ced3936894cec493b93c1144c543d51048268288Victor Stinner    if sys.platform in ('dos', 'win32', 'win16'):
129e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        # Use the old CP/M NUL as device name
130e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        DEV_NULL = 'NUL'
131e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    else:
132e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        # Standard Unix uses /dev/null
133e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        DEV_NULL = '/dev/null'
134e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
135620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner# Directory to search for configuration information on Unix.
136620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner# Constant used by test_platform to test linux_distribution().
137620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner_UNIXCONFDIR = '/etc'
138620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner
139246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Platform specific APIs
140246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
141ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou_libc_search = re.compile(b'(__libc_init)'
142ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          b'|'
143ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          b'(GLIBC_([0-9.]+))'
144ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          b'|'
145ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)
146366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg
147ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef libc_ver(executable=sys.executable, lib='', version='',
148246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
149ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou             chunksize=16384):
150246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1518ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Tries to determine the libc version that the file executable
1528ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        (which defaults to the Python interpreter) is linked against.
153246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
154246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Returns a tuple of strings (lib,version) which default to the
155246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        given parameters in case the lookup fails.
156246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
157246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that the function has intimate knowledge of how different
1588ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        libc versions add symbols to the executable and thus is probably
1598ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        only useable for executables compiled using gcc.
160246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
161246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The file is read and scanned in chunks of chunksize bytes.
162246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
163246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
164fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if hasattr(os.path, 'realpath'):
165fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # Python 2.2 introduced os.path.realpath(); it is used
166fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # here to work around problems with Cygwin not being
167fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # able to open symlinks for reading
168fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        executable = os.path.realpath(executable)
16946ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka    with open(executable, 'rb') as f:
17046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka        binary = f.read(chunksize)
17146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka        pos = 0
17246ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka        while 1:
17346ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            if b'libc' in binary or b'GLIBC' in binary:
17446ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                m = _libc_search.search(binary, pos)
17546ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            else:
17646ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                m = None
17746ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            if not m:
17846ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                binary = f.read(chunksize)
17946ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                if not binary:
18046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                    break
18146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                pos = 0
18246ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                continue
18346ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            libcinit, glibc, glibcversion, so, threads, soversion = [
18446ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                s.decode('latin1') if s is not None else s
18546ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                for s in m.groups()]
18646ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            if libcinit and not lib:
187246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                lib = 'libc'
18846ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            elif glibc:
18946ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                if lib != 'glibc':
19046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                    lib = 'glibc'
19146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                    version = glibcversion
19246ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                elif glibcversion > version:
19346ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                    version = glibcversion
19446ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            elif so:
19546ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                if lib != 'glibc':
19646ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                    lib = 'libc'
19746ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                    if soversion and soversion > version:
19846ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                        version = soversion
19946ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                    if threads and version[-len(threads):] != threads:
20046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka                        version = version + threads
20146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka            pos = m.end()
202ced3936894cec493b93c1144c543d51048268288Victor Stinner    return lib, version
203246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
204ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _dist_try_harder(distname, version, id):
205246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
2060eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters    """ Tries some special tricks to get the distribution
207246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        information in case the default method fails.
208246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
209246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Currently supports older SuSE Linux, Caldera OpenLinux and
210246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Slackware Linux distributions.
211246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
212246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
213246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.exists('/var/adm/inst-log/info'):
214246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # SuSE Linux stores distribution information in that file
215246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        distname = 'SuSE'
2167dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        for line in open('/var/adm/inst-log/info'):
2179d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz            tv = line.split()
218246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if len(tv) == 2:
219ced3936894cec493b93c1144c543d51048268288Victor Stinner                tag, value = tv
220246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            else:
221246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                continue
222246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if tag == 'MIN_DIST_VERSION':
2239d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz                version = value.strip()
224246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            elif tag == 'DIST_IDENT':
2259d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz                values = value.split('-')
226246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                id = values[2]
227ced3936894cec493b93c1144c543d51048268288Victor Stinner        return distname, version, id
228246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
229246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.exists('/etc/.installed'):
230246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Caldera OpenLinux has some infos in that file (thanks to Colin Kong)
2317dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        for line in open('/etc/.installed'):
2329d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz            pkg = line.split('-')
233246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
234246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                # XXX does Caldera support non Intel platforms ? If yes,
235246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                #     where can we find the needed id ?
236ced3936894cec493b93c1144c543d51048268288Victor Stinner                return 'OpenLinux', pkg[1], id
237246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
238246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.isdir('/usr/lib/setup'):
23930b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti        # Check for slackware version tag file (thanks to Greg Andruk)
240246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        verfiles = os.listdir('/usr/lib/setup')
241843c734ddda3e317eee97dfdd32ff15ceede22fcGuido van Rossum        for n in range(len(verfiles)-1, -1, -1):
242246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if verfiles[n][:14] != 'slack-version-':
243246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                del verfiles[n]
244246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if verfiles:
245246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            verfiles.sort()
246246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            distname = 'slackware'
247246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = verfiles[-1][14:]
248ced3936894cec493b93c1144c543d51048268288Victor Stinner            return distname, version, id
249246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
250ced3936894cec493b93c1144c543d51048268288Victor Stinner    return distname, version, id
251246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
252fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou_release_filename = re.compile(r'(\w+)[-_](release|version)', re.ASCII)
253fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_lsb_release_version = re.compile(r'(.+)'
25444b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                                  r' release '
25544b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                                  r'([\d.]+)'
25644b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                                  r'[^(]*(?:\((.+)\))?', re.ASCII)
257fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_release_version = re.compile(r'([^0-9]+)'
25844b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                              r'(?: release )?'
25944b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                              r'([\d.]+)'
26044b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                              r'[^(]*(?:\((.+)\))?', re.ASCII)
261fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
262fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# See also http://www.novell.com/coolsolutions/feature/11251.html
2639fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters# and http://linuxmafia.com/faq/Admin/release-files.html
264fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://data.linux-ntfs.org/rpm/whichrpm
265fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html
266fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
267dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes_supported_dists = (
268dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes    'SuSE', 'debian', 'fedora', 'redhat', 'centos',
269dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes    'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
270ab88803a8addf36ae3fc7e9270ebbed869f7f191Antoine Pitrou    'UnitedLinux', 'turbolinux', 'arch', 'mageia')
271fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
272fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _parse_release_file(firstline):
2739fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
274250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    # Default to empty 'version' and 'id' strings.  Both defaults are used
275250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    # when 'firstline' is empty.  'id' defaults to empty when an id can not
276250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    # be deduced.
277250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    version = ''
278250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    id = ''
279250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson
280fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Parse the first line
281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    m = _lsb_release_version.match(firstline)
282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
283fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # LSB format: "distro release x.x (codename)"
284fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return tuple(m.groups())
285fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
286fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Pre-LSB format: "distro x.x (codename)"
287fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    m = _release_version.match(firstline)
288fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
289fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return tuple(m.groups())
290fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
29130b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti    # Unknown format... take the first two words
2929d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    l = firstline.strip().split()
293fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if l:
294fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version = l[0]
295fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if len(l) > 1:
296fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            id = l[1]
297fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return '', version, id
298fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
299fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef linux_distribution(distname='', version='', id='',
300fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
301fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                       supported_dists=_supported_dists,
302fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                       full_distribution_name=1):
3032f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag    import warnings
3042f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag    warnings.warn("dist() and linux_distribution() functions are deprecated "
3058d8221f0d674ea032337a82d1ad1d0d146510390Berker Peksag                  "in Python 3.5", PendingDeprecationWarning, stacklevel=2)
3062f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag    return _linux_distribution(distname, version, id, supported_dists,
3072f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag                               full_distribution_name)
3082f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag
3092f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksagdef _linux_distribution(distname, version, id, supported_dists,
3102f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag                        full_distribution_name):
311246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
3128ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Tries to determine the name of the Linux OS distribution name.
313246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
314246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function first looks for a distribution release file in
315246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        /etc and then reverts to _dist_try_harder() in case no
316246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        suitable files are found.
317246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
318fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        supported_dists may be given to define the set of Linux
319fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distributions to look for. It defaults to a list of currently
320fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        supported Linux distributions identified by their release file
321fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name.
322fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
323fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If full_distribution_name is true (default), the full
324fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distribution read from the OS is returned. Otherwise the short
325fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name taken from supported_dists is used.
326fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
327ced3936894cec493b93c1144c543d51048268288Victor Stinner        Returns a tuple (distname, version, id) which default to the
328246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        args given as parameters.
329246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
330246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
331246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
332620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner        etc = os.listdir(_UNIXCONFDIR)
333ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov    except OSError:
334246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Probably not a Unix system
335ced3936894cec493b93c1144c543d51048268288Victor Stinner        return distname, version, id
336fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    etc.sort()
337246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    for file in etc:
338366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg        m = _release_filename.match(file)
339fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if m is not None:
340ced3936894cec493b93c1144c543d51048268288Victor Stinner            _distname, dummy = m.groups()
341246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if _distname in supported_dists:
342246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                distname = _distname
343246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                break
344246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
345ced3936894cec493b93c1144c543d51048268288Victor Stinner        return _dist_try_harder(distname, version, id)
3469fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
347fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Read the first line
348620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner    with open(os.path.join(_UNIXCONFDIR, file), 'r',
349620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner              encoding='utf-8', errors='surrogateescape') as f:
3507dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        firstline = f.readline()
351fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    _distname, _version, _id = _parse_release_file(firstline)
352fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
353fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _distname and full_distribution_name:
354fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distname = _distname
355fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _version:
356fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version = _version
357fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _id:
358fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        id = _id
359fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return distname, version, id
360fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
361fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# To maintain backwards compatibility:
3629fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
363ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef dist(distname='', version='', id='',
364fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
365fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters         supported_dists=_supported_dists):
366fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
367fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Tries to determine the name of the Linux OS distribution name.
368fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
369fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        The function first looks for a distribution release file in
370fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        /etc and then reverts to _dist_try_harder() in case no
371fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        suitable files are found.
372fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
373ced3936894cec493b93c1144c543d51048268288Victor Stinner        Returns a tuple (distname, version, id) which default to the
374fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        args given as parameters.
375fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
376fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
3772f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag    import warnings
3782f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag    warnings.warn("dist() and linux_distribution() functions are deprecated "
3798d8221f0d674ea032337a82d1ad1d0d146510390Berker Peksag                  "in Python 3.5", PendingDeprecationWarning, stacklevel=2)
3802f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag    return _linux_distribution(distname, version, id,
3812f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag                               supported_dists=supported_dists,
3822f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag                               full_distribution_name=0)
383246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
384877766dee8e60c7971ed0cabba89fbe981c2ab1bAntoine Pitroudef popen(cmd, mode='r', bufsize=-1):
385246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
386246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Portable popen() interface.
387246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
38825000d4d31dfa5842776aa92f234ea6672489c67Victor Stinner    import warnings
38925000d4d31dfa5842776aa92f234ea6672489c67Victor Stinner    warnings.warn('use os.popen instead', DeprecationWarning, stacklevel=2)
3901dfd3803064f2ee4b6e0bae3c60ca39e5f3919caVictor Stinner    return os.popen(cmd, mode, bufsize)
391246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
392fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _norm_version(version, build=''):
393246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
3948ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Normalize the version and build strings and return a single
395e5a7fad356a98f931bbe0d2c9e4b18854510c3ddWalter Dörwald        version string using the format major.minor.build (or patchlevel).
396246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
3979d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    l = version.split('.')
398246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if build:
399246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        l.append(build)
400246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
401ced3936894cec493b93c1144c543d51048268288Victor Stinner        ints = map(int, l)
402246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ValueError:
403246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        strings = l
404246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
405ced3936894cec493b93c1144c543d51048268288Victor Stinner        strings = list(map(str, ints))
4069d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    version = '.'.join(strings[:3])
407246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return version
408246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
409366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
41044b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                         r'.*'
41144b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                         r'\[.* ([\d.]+)\])')
412e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
413e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Examples of VER command output:
414e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#
415e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#   Windows 2000:  Microsoft Windows 2000 [Version 5.00.2195]
416e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#   Windows XP:    Microsoft Windows XP [Version 5.1.2600]
417e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#   Windows Vista: Microsoft Windows [Version 6.0.6002]
418e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#
419e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Note that the "Version" string gets localized on different
420e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Windows versions.
421366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg
422fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _syscmd_ver(system='', release='', version='',
423246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
424ced3936894cec493b93c1144c543d51048268288Victor Stinner               supported_platforms=('win32', 'win16', 'dos')):
425246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
426246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Tries to figure out the OS version used and returns
427ced3936894cec493b93c1144c543d51048268288Victor Stinner        a tuple (system, release, version).
4280eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
429246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        It uses the "ver" shell command for this which is known
430f1af7057208da7b3d15703645688fea971a4fb5eJesus Cea        to exists on Windows, DOS. XXX Others too ?
431246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
432246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        In case this fails, the given parameters are used as
433246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        defaults.
434246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
435246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
436246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sys.platform not in supported_platforms:
437ced3936894cec493b93c1144c543d51048268288Victor Stinner        return system, release, version
438246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
439246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Try some common cmd strings
440ced3936894cec493b93c1144c543d51048268288Victor Stinner    for cmd in ('ver', 'command /c ver', 'cmd /c ver'):
441246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
442cae101f5ecd8fee38a37ce8fa46c141cd8a522efSteve Dower            pipe = os.popen(cmd)
443246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            info = pipe.read()
444246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if pipe.close():
445ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov                raise OSError('command failed')
44613925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti            # XXX How can I suppress shell errors from being written
447246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            #     to stderr ?
448ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov        except OSError as why:
449ced3936894cec493b93c1144c543d51048268288Victor Stinner            #print 'Command %s failed: %s' % (cmd, why)
450246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            continue
451246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
452246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            break
453246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
454ced3936894cec493b93c1144c543d51048268288Victor Stinner        return system, release, version
455246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
456246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Parse the output
4579d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    info = info.strip()
458366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg    m = _ver_output.match(info)
459fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
460ced3936894cec493b93c1144c543d51048268288Victor Stinner        system, release, version = m.groups()
461246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Strip trailing dots from version and release
462246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release[-1] == '.':
463246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = release[:-1]
464246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if version[-1] == '.':
465246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = version[:-1]
466246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Normalize the version and build strings (eliminating additional
467246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # zeros)
468246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = _norm_version(version)
469ced3936894cec493b93c1144c543d51048268288Victor Stinner    return system, release, version
470246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
471b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower_WIN32_CLIENT_RELEASES = {
472b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (5, 0): "2000",
473b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (5, 1): "XP",
474b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    # Strictly, 5.2 client is XP 64-bit, but platform.py historically
475b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    # has always called it 2003 Server
476b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (5, 2): "2003Server",
477b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (5, None): "post2003",
478b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower
479b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 0): "Vista",
480b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 1): "7",
481b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 2): "8",
482b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 3): "8.1",
483b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, None): "post8.1",
484b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower
485b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (10, 0): "10",
486b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (10, None): "post10",
487b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower}
488b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower
489b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower# Server release name lookup will default to client names if necessary
490b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower_WIN32_SERVER_RELEASES = {
491b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (5, 2): "2003Server",
492b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower
493b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 0): "2008Server",
494b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 1): "2008ServerR2",
495b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 2): "2012Server",
496b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, 3): "2012ServerR2",
497b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    (6, None): "post2012ServerR2",
498b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower}
499b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower
500b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dowerdef win32_ver(release='', version='', csd='', ptype=''):
5018f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower    try:
5028f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower        from sys import getwindowsversion
5038f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower    except ImportError:
5048f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower        return release, version, csd, ptype
50502781dc7541b79e499c06ead64535c317efc460eChristian Heimes    try:
506b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower        from winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE
507cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon    except ImportError:
508b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower        from _winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE
509246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
510b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    winver = getwindowsversion()
51174f4af7ac304baf8ea1eef95194b89982c3d683dSteve Dower    maj, min, build = winver.platform_version or winver[:3]
512b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    version = '{0}.{1}.{2}'.format(maj, min, build)
513246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
514b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    release = (_WIN32_CLIENT_RELEASES.get((maj, min)) or
515b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower               _WIN32_CLIENT_RELEASES.get((maj, None)) or
516b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower               release)
517246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
518b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    # getwindowsversion() reflect the compatibility mode Python is
519b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    # running under, and so the service pack value is only going to be
520b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    # valid if the versions match.
521b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    if winver[:2] == (maj, min):
52202781dc7541b79e499c06ead64535c317efc460eChristian Heimes        try:
523b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower            csd = 'SP{}'.format(winver.service_pack_major)
52402781dc7541b79e499c06ead64535c317efc460eChristian Heimes        except AttributeError:
525b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower            if csd[:13] == 'Service Pack ':
526b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower                csd = 'SP' + csd[13:]
527e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
528b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    # VER_NT_SERVER = 3
52941519b2ca84f47adccc3dc309d22bfa17c7ee39bSteve Dower    if getattr(winver, 'product_type', None) == 3:
530b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower        release = (_WIN32_SERVER_RELEASES.get((maj, min)) or
531b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower                   _WIN32_SERVER_RELEASES.get((maj, None)) or
532b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower                   release)
533246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
534b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    key = None
535246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
536b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower        key = OpenKeyEx(HKEY_LOCAL_MACHINE,
537b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower                        r'SOFTWARE\Microsoft\Windows NT\CurrentVersion')
538b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower        ptype = QueryValueEx(key, 'CurrentType')[0]
539246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except:
540b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower        pass
541b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower    finally:
542b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower        if key:
543b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower            CloseKey(key)
544b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower
545ced3936894cec493b93c1144c543d51048268288Victor Stinner    return release, version, csd, ptype
546246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
547b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower
548e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussorendef _mac_ver_xml():
549e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    fn = '/System/Library/CoreServices/SystemVersion.plist'
550e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    if not os.path.exists(fn):
551e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return None
552e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
553e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    try:
554e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        import plistlib
555cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon    except ImportError:
556e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return None
557e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
558936dfae2e22b5b58d01416ddf47218c20bfde5e6Ned Deily    with open(fn, 'rb') as f:
559936dfae2e22b5b58d01416ddf47218c20bfde5e6Ned Deily        pl = plistlib.load(f)
560e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    release = pl['ProductVersion']
561ced3936894cec493b93c1144c543d51048268288Victor Stinner    versioninfo = ('', '', '')
562605a62ddb1c19978ee194a40a458f072e3242a31Larry Hastings    machine = os.uname().machine
563fcd77016b31ea9fb5311695f5ca82cf6c235da87Ronald Oussoren    if machine in ('ppc', 'Power Macintosh'):
5649a3777e525b389ec5881c3f80a482fb821ab3ea5Ezio Melotti        # Canonical name
565e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        machine = 'PowerPC'
566e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
567ced3936894cec493b93c1144c543d51048268288Victor Stinner    return release, versioninfo, machine
568e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
569e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
570ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef mac_ver(release='', versioninfo=('', '', ''), machine=''):
571e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
572e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    """ Get MacOS version information and return it as tuple (release,
573e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        versioninfo, machine) with versioninfo being a tuple (version,
574e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        dev_stage, non_release_version).
575e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
57630b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti        Entries which cannot be determined are set to the parameter values
577e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        which default to ''. All tuple entries are strings.
578e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    """
579e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
580e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # First try reading the information from an XML file which should
581e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # always be present
582e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    info = _mac_ver_xml()
583e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    if info is not None:
584e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return info
585e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
586e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # If that also doesn't work return the default values
587ced3936894cec493b93c1144c543d51048268288Victor Stinner    return release, versioninfo, machine
588246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
589ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _java_getprop(name, default):
590246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
591246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    from java.lang import System
592246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
593fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        value = System.getProperty(name)
594fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if value is None:
595fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            return default
596fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return value
597fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    except AttributeError:
598246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
599246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
600ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', '')):
6010eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
6028ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Version interface for Jython.
603246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
604ced3936894cec493b93c1144c543d51048268288Victor Stinner        Returns a tuple (release, vendor, vminfo, osinfo) with vminfo being
605ced3936894cec493b93c1144c543d51048268288Victor Stinner        a tuple (vm_name, vm_release, vm_vendor) and osinfo being a
606ced3936894cec493b93c1144c543d51048268288Victor Stinner        tuple (os_name, os_version, os_arch).
607246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
608246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Values which cannot be determined are set to the defaults
609246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        given as parameters (which all default to '').
610246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
611246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
612246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Import the needed APIs
613246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
614246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import java.lang
615cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon    except ImportError:
616ced3936894cec493b93c1144c543d51048268288Victor Stinner        return release, vendor, vminfo, osinfo
617246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
618fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vendor = _java_getprop('java.vendor', vendor)
619fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    release = _java_getprop('java.version', release)
620fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_name, vm_release, vm_vendor = vminfo
621fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_name = _java_getprop('java.vm.name', vm_name)
622fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
623fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_release = _java_getprop('java.vm.version', vm_release)
624fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vminfo = vm_name, vm_release, vm_vendor
625fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_name, os_version, os_arch = osinfo
626fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_arch = _java_getprop('java.os.arch', os_arch)
627fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_name = _java_getprop('java.os.name', os_name)
628fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_version = _java_getprop('java.os.version', os_version)
629fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    osinfo = os_name, os_version, os_arch
630fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
631fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return release, vendor, vminfo, osinfo
632246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
633246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### System name aliasing
634246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
635ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef system_alias(system, release, version):
636246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
637ced3936894cec493b93c1144c543d51048268288Victor Stinner    """ Returns (system, release, version) aliased to common
638246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        marketing names used for some systems.
639246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
640246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        It also does some reordering of the information in some cases
641246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        where it would otherwise cause confusion.
642246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
643246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
644246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'Rhapsody':
645246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Apple's BSD derivative
646246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX How can we determine the marketing release number ?
647ced3936894cec493b93c1144c543d51048268288Victor Stinner        return 'MacOS X Server', system+release, version
648246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
649246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'SunOS':
650246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Sun's OS
651246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release < '5':
652246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # These releases use the old name SunOS
653ced3936894cec493b93c1144c543d51048268288Victor Stinner            return system, release, version
654246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Modify release (marketing release = SunOS release - 3)
6559d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz        l = release.split('.')
656246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if l:
657246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            try:
658246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                major = int(l[0])
659246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            except ValueError:
660246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                pass
661246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            else:
662246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                major = major - 3
663246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                l[0] = str(major)
6649d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz                release = '.'.join(l)
665246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release < '6':
666246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Solaris'
667246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
668246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # XXX Whatever the new SunOS marketing name is...
669246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Solaris'
670246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
671246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'IRIX64':
672246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # IRIX reports IRIX64 on platforms with 64-bit support; yet it
673246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # is really a version and not a different platform, since 32-bit
674246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # apps are also supported..
675246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = 'IRIX'
676246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if version:
677246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = version + ' (64bit)'
678246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
679246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = '64bit'
680246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
681ced3936894cec493b93c1144c543d51048268288Victor Stinner    elif system in ('win32', 'win16'):
682246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # In case one of the other tricks
683246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = 'Windows'
684246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
685ced3936894cec493b93c1144c543d51048268288Victor Stinner    return system, release, version
686246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
687246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various internal helpers
688246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
689246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _platform(*args):
690246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
691246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Helper to format the platform string in a filename
692246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        compatible format e.g. "system-version-machine".
693246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
694246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Format the platform string
6959d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = '-'.join(x.strip() for x in filter(len, args))
696246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
697246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Cleanup some possible filename obstacles...
698ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace(' ', '_')
699ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace('/', '-')
700ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace('\\', '-')
701ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace(':', '-')
702ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace(';', '-')
703ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace('"', '-')
704ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace('(', '-')
705ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace(')', '-')
706246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
707246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # No need to report 'unknown' information...
708ced3936894cec493b93c1144c543d51048268288Victor Stinner    platform = platform.replace('unknown', '')
709246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
710246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Fold '--'s and remove trailing '-'
711246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while 1:
712ced3936894cec493b93c1144c543d51048268288Victor Stinner        cleaned = platform.replace('--', '-')
713246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if cleaned == platform:
714246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            break
715246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platform = cleaned
716246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while platform[-1] == '-':
717246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platform = platform[:-1]
718246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
719246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return platform
720246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
721246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _node(default=''):
722246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
723246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Helper to determine the node name of this machine.
724246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
725246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
726246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import socket
727cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon    except ImportError:
728246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # No sockets...
729246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
730246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
731246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return socket.gethostname()
7320832af6628ca5ac02d0226899725297dd508470bAndrew Svetlov    except OSError:
733246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Still not working...
734246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
735246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
736246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _follow_symlinks(filepath):
737246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
738246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ In case filepath is a symlink, follow it until a
739246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        real file is reached.
740246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
741673f7efa08850e42d077cab38683be2e4764b876Georg Brandl    filepath = os.path.abspath(filepath)
742246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while os.path.islink(filepath):
743246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        filepath = os.path.normpath(
744ced3936894cec493b93c1144c543d51048268288Victor Stinner            os.path.join(os.path.dirname(filepath), os.readlink(filepath)))
745246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return filepath
746246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
747ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _syscmd_uname(option, default=''):
748246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
749246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Interface to the system's uname command.
750246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
751ced3936894cec493b93c1144c543d51048268288Victor Stinner    if sys.platform in ('dos', 'win32', 'win16'):
752246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX Others too ?
753246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
754246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
755e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        f = os.popen('uname %s 2> %s' % (option, DEV_NULL))
756ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov    except (AttributeError, OSError):
757246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
7589d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    output = f.read().strip()
759246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    rc = f.close()
760246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not output or rc:
761246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
762246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
763246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return output
764246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
765ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _syscmd_file(target, default=''):
766246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
767246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Interface to the system's file command.
768246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
769246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function uses the -b option of the file command to have it
770ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        omit the filename in its output. Follow the symlinks. It returns
771ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        default in case the command should fail.
772246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
773246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
774ced3936894cec493b93c1144c543d51048268288Victor Stinner    if sys.platform in ('dos', 'win32', 'win16'):
775d26782e8639df937fac1ef3f208986274138d5c1Hirokazu Yamamoto        # XXX Others too ?
776d26782e8639df937fac1ef3f208986274138d5c1Hirokazu Yamamoto        return default
777fc990e942fb55be78e8352f4913749e91cac381dJesus Cea    target = _follow_symlinks(target)
778246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
779685fffa8f427b3a768b232170752565d58c32112Jesus Cea        proc = subprocess.Popen(['file', target],
780685fffa8f427b3a768b232170752565d58c32112Jesus Cea                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
781e8801e2e44b4ffcfdfc6e2857e7afc90ba6abc38Jesus Cea
782ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov    except (AttributeError, OSError):
783246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
784cb95996fdc6956365642dd42f86dfb380f923fa5Jesus Cea    output = proc.communicate()[0].decode('latin-1')
785fc990e942fb55be78e8352f4913749e91cac381dJesus Cea    rc = proc.wait()
786246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not output or rc:
787246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
788246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
789246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return output
790246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
791246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Information about the used architecture
792246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
793246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Default values for architecture; non-empty strings override the
794246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# defaults given as parameters
795246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_default_architecture = {
796ced3936894cec493b93c1144c543d51048268288Victor Stinner    'win32': ('', 'WindowsPE'),
797ced3936894cec493b93c1144c543d51048268288Victor Stinner    'win16': ('', 'Windows'),
798ced3936894cec493b93c1144c543d51048268288Victor Stinner    'dos': ('', 'MSDOS'),
799246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg}
800246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
801ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef architecture(executable=sys.executable, bits='', linkage=''):
802246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
803246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Queries the given executable (defaults to the Python interpreter
8048ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        binary) for various architecture information.
805246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
806ced3936894cec493b93c1144c543d51048268288Victor Stinner        Returns a tuple (bits, linkage) which contains information about
807246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        the bit architecture and the linkage format used for the
808246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        executable. Both values are returned as strings.
809246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
810246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Values that cannot be determined are returned as given by the
811246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        parameter presets. If bits is given as '', the sizeof(pointer)
812246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        (or sizeof(long) on Python version < 1.5.2) is used as
813246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        indicator for the supported pointer size.
814246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
815246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function relies on the system's "file" command to do the
816246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        actual work. This is available on most if not all Unix
8178ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        platforms. On some non-Unix platforms where the "file" command
8188ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        does not exist and the executable is set to the Python interpreter
8198ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        binary defaults from _default_architecture are used.
820246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
821246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
822246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Use the sizeof(pointer) as default number of bits if nothing
823246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # else is given as default.
824246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not bits:
825246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import struct
826246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
827246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            size = struct.calcsize('P')
828246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        except struct.error:
829246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # Older installations can only query longs
830246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            size = struct.calcsize('l')
831246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = str(size*8) + 'bit'
8320eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
833246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get data from the 'file' system command
834fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if executable:
835ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        fileout = _syscmd_file(executable, '')
836fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    else:
837ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        fileout = ''
838246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
839ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner    if not fileout and \
840246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg       executable == sys.executable:
841246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # "file" command did not return anything; we'll try to provide
8420eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters        # some sensible defaults then...
843e2b70bcf7401477936fba99a8bf4a1f759ecc8a3Guido van Rossum        if sys.platform in _default_architecture:
844ced3936894cec493b93c1144c543d51048268288Victor Stinner            b, l = _default_architecture[sys.platform]
845246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if b:
846246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                bits = b
847246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if l:
848246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                linkage = l
849ced3936894cec493b93c1144c543d51048268288Victor Stinner        return bits, linkage
850246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
851246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if 'executable' not in fileout:
852246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Format not supported
853ced3936894cec493b93c1144c543d51048268288Victor Stinner        return bits, linkage
854246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
855246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Bits
856246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if '32-bit' in fileout:
857246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = '32bit'
858246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'N32' in fileout:
859246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # On Irix only
860246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = 'n32bit'
861246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif '64-bit' in fileout:
862246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = '64bit'
863246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
864246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Linkage
865246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if 'ELF' in fileout:
866246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'ELF'
867246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'PE' in fileout:
868246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # E.g. Windows uses this format
869246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if 'Windows' in fileout:
870246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            linkage = 'WindowsPE'
871246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
872246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            linkage = 'PE'
873246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'COFF' in fileout:
874246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'COFF'
875246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'MS-DOS' in fileout:
876246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'MSDOS'
877246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
878246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX the A.OUT format also falls under this class...
879246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        pass
880246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
881ced3936894cec493b93c1144c543d51048268288Victor Stinner    return bits, linkage
882246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
883246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Portable uname() interface
8840eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
88568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastingsuname_result = collections.namedtuple("uname_result",
88668386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings                    "system node release version machine processor")
88768386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings
888246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_uname_cache = None
889246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
890246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef uname():
891246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
892246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Fairly portable uname interface. Returns a tuple
893ced3936894cec493b93c1144c543d51048268288Victor Stinner        of strings (system, node, release, version, machine, processor)
894246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        identifying the underlying platform.
895246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
896246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the os.uname function this also returns
8978ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        possible processor information as an additional tuple entry.
898246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
899246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Entries which cannot be determined are set to ''.
900246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
901246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
902246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    global _uname_cache
90335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    no_os_uname = 0
904246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
905246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if _uname_cache is not None:
906246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return _uname_cache
907246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
90835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    processor = ''
90935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc
910246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get some infos from the builtin os.uname API...
911246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
912ced3936894cec493b93c1144c543d51048268288Victor Stinner        system, node, release, version, machine = os.uname()
913246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except AttributeError:
91435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        no_os_uname = 1
91535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc
91662e2ca219311a111873892910ad441659faeaefaGeorg Brandl    if no_os_uname or not list(filter(None, (system, node, release, version, machine))):
91735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # Hmm, no there is either no uname or uname has returned
91835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        #'unknowns'... we'll have to poke around the system then.
91935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        if no_os_uname:
92035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            system = sys.platform
92135c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            release = ''
92235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            version = ''
92335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            node = _node()
92435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            machine = ''
92535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc
9267a01984aba532b731dd6a06610b0ce523bef4f5eAmaury Forgeot d'Arc        use_syscmd_ver = 1
927246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
928246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try win32_ver() on win32 platforms
929246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if system == 'win32':
930ced3936894cec493b93c1144c543d51048268288Victor Stinner            release, version, csd, ptype = win32_ver()
931246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if release and version:
932246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                use_syscmd_ver = 0
93302781dc7541b79e499c06ead64535c317efc460eChristian Heimes            # Try to use the PROCESSOR_* environment variables
934fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # available on Win XP and later; see
935fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # http://support.microsoft.com/kb/888731 and
936fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM
93735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            if not machine:
938ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                # WOW64 processes mask the native architecture
939ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                if "PROCESSOR_ARCHITEW6432" in os.environ:
940ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                    machine = os.environ.get("PROCESSOR_ARCHITEW6432", '')
941ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                else:
942ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                    machine = os.environ.get('PROCESSOR_ARCHITECTURE', '')
94335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            if not processor:
94435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc                processor = os.environ.get('PROCESSOR_IDENTIFIER', machine)
9450eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
946246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try the 'ver' system command available on some
947246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # platforms
948246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if use_syscmd_ver:
949ced3936894cec493b93c1144c543d51048268288Victor Stinner            system, release, version = _syscmd_ver(system)
950cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            # Normalize system to what win32_ver() normally returns
951cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            # (_syscmd_ver() tends to return the vendor name as well)
952cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            if system == 'Microsoft Windows':
953cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg                system = 'Windows'
954cd16bf640405065e4702539632ce577536207d88Guido van Rossum            elif system == 'Microsoft' and release == 'Windows':
955cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # Under Windows Vista and Windows Server 2008,
956cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # Microsoft changed the output of the ver command. The
957cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # release is no longer printed.  This causes the
958cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # system and release to be misidentified.
959cd16bf640405065e4702539632ce577536207d88Guido van Rossum                system = 'Windows'
960cd16bf640405065e4702539632ce577536207d88Guido van Rossum                if '6.0' == version[:3]:
961cd16bf640405065e4702539632ce577536207d88Guido van Rossum                    release = 'Vista'
962cd16bf640405065e4702539632ce577536207d88Guido van Rossum                else:
963cd16bf640405065e4702539632ce577536207d88Guido van Rossum                    release = ''
964246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
965246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # In case we still don't know anything useful, we'll try to
966246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # help ourselves
967ced3936894cec493b93c1144c543d51048268288Victor Stinner        if system in ('win32', 'win16'):
968246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not version:
969246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                if system == 'win32':
970246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = '32bit'
971246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                else:
972246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = '16bit'
973246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Windows'
974246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
975246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif system[:4] == 'java':
976ced3936894cec493b93c1144c543d51048268288Victor Stinner            release, vendor, vminfo, osinfo = java_ver()
977246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Java'
9789d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz            version = ', '.join(vminfo)
979246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not version:
980246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = vendor
981246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
98235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    # System specific extensions
98335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    if system == 'OpenVMS':
98435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # OpenVMS seems to have release and version mixed up
98535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        if not release or release == '0':
98635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            release = version
98735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            version = ''
98835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # Get processor information
98935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        try:
99035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            import vms_lib
991cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon        except ImportError:
99235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            pass
993246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
994ced3936894cec493b93c1144c543d51048268288Victor Stinner            csid, cpu_number = vms_lib.getsyi('SYI$_CPU', 0)
99535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            if (cpu_number >= 128):
99635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc                processor = 'Alpha'
99735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            else:
99835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc                processor = 'VAX'
99935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    if not processor:
100035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # Get processor information from the uname system command
1001ced3936894cec493b93c1144c543d51048268288Victor Stinner        processor = _syscmd_uname('-p', '')
1002246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
100335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    #If any unknowns still exist, replace them with ''s, which are more portable
1004246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'unknown':
1005246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = ''
1006246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if node == 'unknown':
1007246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        node = ''
1008246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if release == 'unknown':
1009246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        release = ''
1010246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if version == 'unknown':
1011246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = ''
1012246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if machine == 'unknown':
1013246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        machine = ''
1014246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if processor == 'unknown':
1015246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor = ''
10161b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters
10171b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters    #  normalize name
10181b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters    if system == 'Microsoft' and release == 'Windows':
10191b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters        system = 'Windows'
10201b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters        release = 'Vista'
10211b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters
1022ced3936894cec493b93c1144c543d51048268288Victor Stinner    _uname_cache = uname_result(system, node, release, version,
1023ced3936894cec493b93c1144c543d51048268288Victor Stinner                                machine, processor)
1024246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return _uname_cache
1025246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1026246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Direct interfaces to some of the uname() return values
1027246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1028246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef system():
1029246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1030246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
1031246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1032246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1033246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1034246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
103568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().system
1036246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1037246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef node():
1038246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
10398ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Returns the computer's network name (which may not be fully
10408ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        qualified)
1041246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1042246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1043246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1044246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
104568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().node
1046246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1047246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef release():
1048246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1049246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system's release, e.g. '2.2.0' or 'NT'
1050246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1051246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1052246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1053246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
105468386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().release
1055246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1056246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef version():
1057246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1058246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system's release version, e.g. '#3 on degas'
1059246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1060246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1061246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1062246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
106368386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().version
1064246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1065246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef machine():
1066246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1067246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the machine type, e.g. 'i386'
1068246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1069246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1070246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1071246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
107268386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().machine
1073246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1074246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef processor():
1075246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1076246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the (true) processor name, e.g. 'amdk6'
1077246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1078246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be
1079246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        determined. Note that many platforms do not provide this
1080246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        information or simply return the same value as for machine(),
1081246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        e.g.  NetBSD does this.
1082246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1083246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
108468386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().processor
1085246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1086246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various APIs for extracting information from sys.version
1087246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1088fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_parser = re.compile(
10894e50553823c16a65d80f6734b4ac303c18640380Martin Panter    r'([\w.+]+)\s*'  # "version<space>"
10904e50553823c16a65d80f6734b4ac303c18640380Martin Panter    r'\(#?([^,]+)'  # "(#buildno"
10914e50553823c16a65d80f6734b4ac303c18640380Martin Panter    r'(?:,\s*([\w ]*)'  # ", builddate"
10924e50553823c16a65d80f6734b4ac303c18640380Martin Panter    r'(?:,\s*([\w :]*))?)?\)\s*'  # ", buildtime)<space>"
10934e50553823c16a65d80f6734b4ac303c18640380Martin Panter    r'\[([^\]]+)\]?', re.ASCII)  # "[compiler]"
1094fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1095fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_ironpython_sys_version_parser = re.compile(
1096fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    r'IronPython\s*'
109744b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r'([\d\.]+)'
109844b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r'(?: \(([\d\.]+)\))?'
109944b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r' on (.NET [\d\.]+)', re.ASCII)
1100246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1101f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti# IronPython covering 2.6 and 2.7
1102f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti_ironpython26_sys_version_parser = re.compile(
1103f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti    r'([\d.]+)\s*'
110444b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r'\(IronPython\s*'
110544b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r'[\d.]+\s*'
110644b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r'\(([\d.]+)\) on ([\w.]+ [\d.]+(?: \(\d+-bit\))?)\)'
1107f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti)
1108f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti
1109e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson_pypy_sys_version_parser = re.compile(
1110e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    r'([\w.+]+)\s*'
111144b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
111244b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray    r'\[PyPy [^\]]+\]?')
1113e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson
1114fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_cache = {}
1115fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1116fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _sys_version(sys_version=None):
1117246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1118246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a parsed version of Python's sys.version as tuple
11195f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        (name, version, branch, revision, buildno, builddate, compiler)
11205f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        referring to the Python implementation name, version, branch,
11215f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        revision, build number, build date/time as string and the compiler
11225f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        identification string.
1123246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1124246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1125246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        for the Python version will always include the patchlevel (it
1126246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        defaults to '.0').
1127246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1128fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        The function returns empty strings for tuple entries that
1129fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        cannot be determined.
1130fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1131fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        sys_version may be given to parse an alternative version
1132fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        string, e.g. if the version was read from a different Python
1133fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        interpreter.
1134fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1135246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1136fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Get the Python version
1137fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if sys_version is None:
1138fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        sys_version = sys.version
1139246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1140fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Try the cache first
1141fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    result = _sys_version_cache.get(sys_version, None)
1142fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if result is not None:
1143fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return result
1144fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1145fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Parse it
1146f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti    if 'IronPython' in sys_version:
1147fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # IronPython
1148fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name = 'IronPython'
1149f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti        if sys_version.startswith('IronPython'):
1150f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti            match = _ironpython_sys_version_parser.match(sys_version)
1151f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti        else:
1152f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti            match = _ironpython26_sys_version_parser.match(sys_version)
1153f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti
1154fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1155fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1156fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse IronPython sys.version: %s' %
1157fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1158f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti
1159fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version, alt_version, compiler = match.groups()
1160fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        buildno = ''
1161fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        builddate = ''
1162fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1163f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti    elif sys.platform.startswith('java'):
1164fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # Jython
1165fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name = 'Jython'
1166e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        match = _sys_version_parser.match(sys_version)
1167fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1168fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1169fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse Jython sys.version: %s' %
1170fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1171e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        version, buildno, builddate, buildtime, _ = match.groups()
11724e50553823c16a65d80f6734b4ac303c18640380Martin Panter        if builddate is None:
11734e50553823c16a65d80f6734b4ac303c18640380Martin Panter            builddate = ''
1174fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        compiler = sys.platform
1175e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson
1176e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    elif "PyPy" in sys_version:
1177e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        # PyPy
1178e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        name = "PyPy"
1179e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        match = _pypy_sys_version_parser.match(sys_version)
1180e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        if match is None:
1181e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson            raise ValueError("failed to parse PyPy sys.version: %s" %
1182e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson                             repr(sys_version))
1183e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        version, buildno, builddate, buildtime = match.groups()
1184e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        compiler = ""
1185fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1186fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    else:
1187fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # CPython
1188fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        match = _sys_version_parser.match(sys_version)
1189fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1190fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1191fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse CPython sys.version: %s' %
1192fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1193fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version, buildno, builddate, buildtime, compiler = \
1194fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters              match.groups()
1195e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        name = 'CPython'
11964e50553823c16a65d80f6734b4ac303c18640380Martin Panter        if builddate is None:
11974e50553823c16a65d80f6734b4ac303c18640380Martin Panter            builddate = ''
11984e50553823c16a65d80f6734b4ac303c18640380Martin Panter        elif buildtime:
11994e50553823c16a65d80f6734b4ac303c18640380Martin Panter            builddate = builddate + ' ' + buildtime
1200fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
120195c50e5aed9e5683676e18349dd94b11901a66b3Ned Deily    if hasattr(sys, '_git'):
120295c50e5aed9e5683676e18349dd94b11901a66b3Ned Deily        _, branch, revision = sys._git
120395c50e5aed9e5683676e18349dd94b11901a66b3Ned Deily    elif hasattr(sys, '_mercurial'):
12048256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl        _, branch, revision = sys._mercurial
12058256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl    elif hasattr(sys, 'subversion'):
1206e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        # sys.subversion was added in Python 2.5
1207e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        _, branch, revision = sys.subversion
1208e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    else:
1209e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        branch = ''
1210e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        revision = ''
1211e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson
1212fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Add the patchlevel version if missing
12139d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    l = version.split('.')
1214246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if len(l) == 2:
1215246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        l.append('0')
12169d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz        version = '.'.join(l)
1217fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1218fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Build and cache the result
1219fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    result = (name, version, branch, revision, buildno, builddate, compiler)
1220fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    _sys_version_cache[sys_version] = result
1221fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return result
1222fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1223fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_implementation():
1224fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1225fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation.
1226fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1227fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Currently, the following implementations are identified:
1228f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'CPython' (C implementation of Python),
1229f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'IronPython' (.NET implementation of Python),
1230f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'Jython' (Java implementation of Python),
1231f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'PyPy' (Python implementation of Python).
1232fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1233fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
1234fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[0]
1235246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1236246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version():
1237246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1238246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the Python version as string 'major.minor.patchlevel'
1239246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1240246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1241246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        will always include the patchlevel (it defaults to 0).
1242246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1243246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1244fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[1]
1245246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1246246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version_tuple():
1247246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1248246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the Python version as tuple (major, minor, patchlevel)
1249246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        of strings.
1250246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1251246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1252246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        will always include the patchlevel (it defaults to 0).
1253246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1254246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
12559d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    return tuple(_sys_version()[1].split('.'))
1256fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1257fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_branch():
1258fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1259fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation
1260fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        branch.
1261fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1262fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        For CPython this is the Subversion branch from which the
1263fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Python binary was built.
1264fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1265fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If not available, an empty string is returned.
1266fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1267fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
12689fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
1269fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[2]
1270fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1271fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_revision():
1272fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1273fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation
1274fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        revision.
1275fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1276fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        For CPython this is the Subversion revision from which the
1277fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Python binary was built.
1278fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1279fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If not available, an empty string is returned.
1280fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
1282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[3]
1283246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1284246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_build():
1285246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1286246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a tuple (buildno, builddate) stating the Python
1287246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        build number and date as strings.
1288246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1289246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1290fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[4:6]
1291246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1292246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_compiler():
1293246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1294246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a string identifying the compiler used for compiling
1295246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Python.
1296246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1297246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1298fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[6]
1299246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1300246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### The Opus Magnum of platform strings :-)
1301246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
130291e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg_platform_cache = {}
1303246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1304246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef platform(aliased=0, terse=0):
1305246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1306246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a single string identifying the underlying platform
1307246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        with as much useful information as possible (but no more :).
13080eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
1309246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The output is intended to be human readable rather than
1310246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        machine parseable. It may look different on different
1311246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platforms and this is intended.
1312246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1313246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        If "aliased" is true, the function will use aliases for
1314246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        various platforms that report system names which differ from
1315246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        their common names, e.g. SunOS will be reported as
1316246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Solaris. The system_alias() function is used to implement
1317246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        this.
1318246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1319246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Setting terse to true causes the function to return only the
1320246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        absolute minimum information needed to identify the platform.
1321246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1322246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
132391e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    result = _platform_cache.get((aliased, terse), None)
132491e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    if result is not None:
132591e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg        return result
1326246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1327246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get uname information and then apply platform specific cosmetics
1328246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # to it...
1329ced3936894cec493b93c1144c543d51048268288Victor Stinner    system, node, release, version, machine, processor = uname()
1330246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if machine == processor:
1331246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor = ''
1332246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if aliased:
1333ced3936894cec493b93c1144c543d51048268288Victor Stinner        system, release, version = system_alias(system, release, version)
1334246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1335246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'Windows':
1336246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # MS platforms
1337ced3936894cec493b93c1144c543d51048268288Victor Stinner        rel, vers, csd, ptype = win32_ver(version)
1338246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1339ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release)
1340246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1341ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release, version, csd)
1342246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1343246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system in ('Linux',):
1344246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Linux based systems
13451392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag        with warnings.catch_warnings():
13461392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag            # see issue #1322 for more information
13471392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag            warnings.filterwarnings(
13481392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag                'ignore',
134944b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray                r'dist\(\) and linux_distribution\(\) '
13501392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag                'functions are deprecated .*',
13511392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag                PendingDeprecationWarning,
13521392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag            )
13531392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag            distname, distversion, distid = dist('')
1354246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if distname and not terse:
1355ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release, machine, processor,
1356246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'with',
1357ced3936894cec493b93c1144c543d51048268288Victor Stinner                                 distname, distversion, distid)
1358246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1359246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # If the distribution name is unknown check for libc vs. glibc
1360ced3936894cec493b93c1144c543d51048268288Victor Stinner            libcname, libcversion = libc_ver(sys.executable)
1361ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release, machine, processor,
1362246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'with',
1363246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 libcname+libcversion)
1364246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'Java':
1365246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Java platforms
1366ced3936894cec493b93c1144c543d51048268288Victor Stinner        r, v, vminfo, (os_name, os_version, os_arch) = java_ver()
1367fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if terse or not os_name:
1368ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release, version)
1369246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1370ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release, version,
1371246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'on',
1372ced3936894cec493b93c1144c543d51048268288Victor Stinner                                 os_name, os_version, os_arch)
1373246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1374246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'MacOS':
1375246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # MacOS platforms
1376246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1377ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release)
1378246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1379ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release, machine)
1380246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1381246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
1382246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Generic handler
1383246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1384ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release)
1385246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1386ced3936894cec493b93c1144c543d51048268288Victor Stinner            bits, linkage = architecture(sys.executable)
1387ced3936894cec493b93c1144c543d51048268288Victor Stinner            platform = _platform(system, release, machine,
1388ced3936894cec493b93c1144c543d51048268288Victor Stinner                                 processor, bits, linkage)
13890eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
139091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    _platform_cache[(aliased, terse)] = platform
1391246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return platform
1392246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1393246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Command line interface
1394246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1395246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgif __name__ == '__main__':
1396246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Default is to print the aliased verbose platform string
13970eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters    terse = ('terse' in sys.argv or '--terse' in sys.argv)
1398246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
1399ced3936894cec493b93c1144c543d51048268288Victor Stinner    print(platform(aliased, terse))
1400246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    sys.exit(0)
1401