platform.py revision cb95996fdc6956365642dd42f86dfb380f923fa5
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#    * more support for WinCE
17246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for MS-DOS (PythonDX ?)
18246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for Amiga and other still unsupported platforms running Python
19246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for additional Linux distributions
20246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
218ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon#    Many thanks to all those who helped adding platform-specific
22246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    checks (in no particular order):
23246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
24246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell,
25246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef
26246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg
27246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark
28246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support),
29fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#      Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter
30246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
31246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    History:
32380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#
33380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#    <see CVS and SVN checkin messages for history>
34380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#
35e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#    1.0.7 - added DEV_NULL
36fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.6 - added linux_distribution()
37fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.5 - fixed Java support to allow running the module on Jython
38fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.4 - added IronPython support
39cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg#    1.0.3 - added normalization of Windows system name
4091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg#    1.0.2 - added more Windows support
41366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg#    1.0.1 - reformatted to make doc.py happy
42246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    1.0.0 - reformatted a bit and checked into Python CVS
43246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.8.0 - added sys.version parser and various new access
44246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            APIs (python_version(), python_compiler(), etc.)
45246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.2 - fixed architecture() to use sizeof(pointer) where available
46246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.1 - added support for Caldera OpenLinux
47246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.0 - some fixes for WinCE; untabified the source file
48246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and
49246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            vms_lib.getsyi() configured
50246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.1 - added code to prevent 'uname -p' on platforms which are
51246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            known not to support it
52246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k;
53246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            did some cleanup of the interfaces - some APIs have changed
54246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.5 - fixed another type in the MacOS code... should have
55246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            used more coffee today ;-)
56246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.4 - fixed a few typos in the MacOS code
57246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.3 - added experimental MacOS support; added better popen()
58246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            workarounds in _syscmd_ver() -- still not 100% elegant
59246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            though
60246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.2 - fixed uname() to return '' instead of 'unknown' in all
61246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            return values (the system uname command tends to return
62246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            'unknown' instead of just leaving the field emtpy)
63246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.1 - included code for slackware dist; added exception handlers
64246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            to cover up situations where platforms don't have os.popen
65246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            (e.g. Mac) or fail on socket.gethostname(); fixed libc
66246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            detection RE
67246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.0 - changed the API names referring to system commands to *syscmd*;
68246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            added java_ver(); made syscmd_ver() a private
69246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            API (was system_ver() in previous versions) -- use uname()
70246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            instead; extended the win32_ver() to also return processor
71246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            type information
72246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.4.0 - added win32_ver() and modified the platform() output for WinXX
73246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.4 - fixed a bug in _follow_symlinks()
74246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.3 - fixed popen() and "file" command invokation bugs
75246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.2 - added architecture() API and support for it in platform()
76246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.1 - fixed syscmd_ver() RE to support Windows NT
77246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.0 - added system alias support
78246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.3 - removed 'wince' again... oh well.
79246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.2 - added 'wince' to syscmd_ver() supported platforms
80246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.1 - added cache logic and changed the platform string format
81246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.0 - changed the API to use functions instead of module globals
82246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            since some action take too long to be run on module import
83246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.1.0 - first release
84246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
85246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    You can always get the latest version of this module at:
86246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
87246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#             http://www.egenix.com/files/python/platform.py
88246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
89246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    If that URL should fail, try contacting the author.
90246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
91246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg__copyright__ = """
92246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com
9346a9900e099a82cda7328b0de16d6fffe52ee62aBenjamin Peterson    Copyright (c) 2000-2010, eGenix.com Software GmbH; mailto:info@egenix.com
94246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
95246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    Permission to use, copy, modify, and distribute this software and its
96246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    documentation for any purpose and without fee or royalty is hereby granted,
97246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    provided that the above copyright notice appear in all copies and that
98246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    both that copyright notice and this permission notice appear in
99246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    supporting documentation or portions thereof, including modifications,
100246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    that you make.
101246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
102246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO
103246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
104246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
105246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
106246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
107246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
108246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
109246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
110246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg"""
111246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
112e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti__version__ = '1.0.7'
113246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
11468386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastingsimport collections
115fc990e942fb55be78e8352f4913749e91cac381dJesus Ceaimport sys, os, re, subprocess
116246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
117e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti### Globals & Constants
118e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
119e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Determine the platform's /dev/null device
120e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalottitry:
121e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    DEV_NULL = os.devnull
122e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalottiexcept AttributeError:
123e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    # os.devnull was added in Python 2.4, so emulate it for earlier
124e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    # Python versions
125e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    if sys.platform in ('dos','win32','win16','os2'):
126e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        # Use the old CP/M NUL as device name
127e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        DEV_NULL = 'NUL'
128e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti    else:
129e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        # Standard Unix uses /dev/null
130e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        DEV_NULL = '/dev/null'
131e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
132246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Platform specific APIs
133246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
134ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou_libc_search = re.compile(b'(__libc_init)'
135ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          b'|'
136ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          b'(GLIBC_([0-9.]+))'
137ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          b'|'
138ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou                          br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)
139366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg
140246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef libc_ver(executable=sys.executable,lib='',version='',
141246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
142ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou             chunksize=16384):
143246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1448ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Tries to determine the libc version that the file executable
1458ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        (which defaults to the Python interpreter) is linked against.
146246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
147246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Returns a tuple of strings (lib,version) which default to the
148246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        given parameters in case the lookup fails.
149246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
150246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that the function has intimate knowledge of how different
1518ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        libc versions add symbols to the executable and thus is probably
1528ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        only useable for executables compiled using gcc.
153246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
154246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The file is read and scanned in chunks of chunksize bytes.
155246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
156246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
157fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if hasattr(os.path, 'realpath'):
158fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # Python 2.2 introduced os.path.realpath(); it is used
159fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # here to work around problems with Cygwin not being
160fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # able to open symlinks for reading
161fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        executable = os.path.realpath(executable)
162246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    f = open(executable,'rb')
163ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou    binary = f.read(chunksize)
164246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    pos = 0
165246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while 1:
166ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou        if b'libc' in binary or b'GLIBC' in binary:
167ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou            m = _libc_search.search(binary,pos)
168ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou        else:
169ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou            m = None
170246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if not m:
171ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou            binary = f.read(chunksize)
172246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not binary:
173246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                break
174246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            pos = 0
175246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            continue
176ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou        libcinit,glibc,glibcversion,so,threads,soversion = [
177ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou            s.decode('latin1') if s is not None else s
178ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou            for s in m.groups()]
179246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if libcinit and not lib:
180246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            lib = 'libc'
181246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif glibc:
182246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if lib != 'glibc':
183246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                lib = 'glibc'
184246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = glibcversion
185246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            elif glibcversion > version:
186246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = glibcversion
187246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif so:
188246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if lib != 'glibc':
189246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                lib = 'libc'
19087448819abd4900bcb36857c6706d8562c97a099Victor Stinner                if soversion and soversion > version:
191246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = soversion
192246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                if threads and version[-len(threads):] != threads:
193246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = version + threads
194246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        pos = m.end()
195246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    f.close()
196246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return lib,version
197246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
198246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _dist_try_harder(distname,version,id):
199246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
2000eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters    """ Tries some special tricks to get the distribution
201246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        information in case the default method fails.
202246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
203246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Currently supports older SuSE Linux, Caldera OpenLinux and
204246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Slackware Linux distributions.
205246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
206246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
207246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.exists('/var/adm/inst-log/info'):
208246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # SuSE Linux stores distribution information in that file
209246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        distname = 'SuSE'
2107dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        for line in open('/var/adm/inst-log/info'):
2119d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz            tv = line.split()
212246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if len(tv) == 2:
213246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                tag,value = tv
214246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            else:
215246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                continue
216246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if tag == 'MIN_DIST_VERSION':
2179d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz                version = value.strip()
218246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            elif tag == 'DIST_IDENT':
2199d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz                values = value.split('-')
220246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                id = values[2]
221246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return distname,version,id
222246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
223246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.exists('/etc/.installed'):
224246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Caldera OpenLinux has some infos in that file (thanks to Colin Kong)
2257dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        for line in open('/etc/.installed'):
2269d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz            pkg = line.split('-')
227246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
228246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                # XXX does Caldera support non Intel platforms ? If yes,
229246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                #     where can we find the needed id ?
230246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                return 'OpenLinux',pkg[1],id
231246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
232246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.isdir('/usr/lib/setup'):
233246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Check for slackware verson tag file (thanks to Greg Andruk)
234246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        verfiles = os.listdir('/usr/lib/setup')
235843c734ddda3e317eee97dfdd32ff15ceede22fcGuido van Rossum        for n in range(len(verfiles)-1, -1, -1):
236246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if verfiles[n][:14] != 'slack-version-':
237246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                del verfiles[n]
238246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if verfiles:
239246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            verfiles.sort()
240246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            distname = 'slackware'
241246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = verfiles[-1][14:]
242246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            return distname,version,id
243246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
244246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return distname,version,id
245246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
246fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou_release_filename = re.compile(r'(\w+)[-_](release|version)', re.ASCII)
247fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_lsb_release_version = re.compile(r'(.+)'
248fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                                   ' release '
249fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                                   '([\d.]+)'
250fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou                                   '[^(]*(?:\((.+)\))?', re.ASCII)
251fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_release_version = re.compile(r'([^0-9]+)'
252fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                               '(?: release )?'
253fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                               '([\d.]+)'
254fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou                               '[^(]*(?:\((.+)\))?', re.ASCII)
255fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
256fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# See also http://www.novell.com/coolsolutions/feature/11251.html
2579fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters# and http://linuxmafia.com/faq/Admin/release-files.html
258fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://data.linux-ntfs.org/rpm/whichrpm
259fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html
260fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
261dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes_supported_dists = (
262dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes    'SuSE', 'debian', 'fedora', 'redhat', 'centos',
263dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes    'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
264ab88803a8addf36ae3fc7e9270ebbed869f7f191Antoine Pitrou    'UnitedLinux', 'turbolinux', 'arch', 'mageia')
265fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
266fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _parse_release_file(firstline):
2679fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
268250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    # Default to empty 'version' and 'id' strings.  Both defaults are used
269250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    # when 'firstline' is empty.  'id' defaults to empty when an id can not
270250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    # be deduced.
271250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    version = ''
272250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson    id = ''
273250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson
274fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Parse the first line
275fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    m = _lsb_release_version.match(firstline)
276fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
277fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # LSB format: "distro release x.x (codename)"
278fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return tuple(m.groups())
279fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
280fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Pre-LSB format: "distro x.x (codename)"
281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    m = _release_version.match(firstline)
282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
283fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return tuple(m.groups())
284fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
285fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Unkown format... take the first two words
2869d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    l = firstline.strip().split()
287fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if l:
288fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version = l[0]
289fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if len(l) > 1:
290fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            id = l[1]
291fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return '', version, id
292fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
293fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef linux_distribution(distname='', version='', id='',
294fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
295fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                       supported_dists=_supported_dists,
296fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                       full_distribution_name=1):
297246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
2988ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Tries to determine the name of the Linux OS distribution name.
299246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
300246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function first looks for a distribution release file in
301246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        /etc and then reverts to _dist_try_harder() in case no
302246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        suitable files are found.
303246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
304fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        supported_dists may be given to define the set of Linux
305fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distributions to look for. It defaults to a list of currently
306fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        supported Linux distributions identified by their release file
307fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name.
308fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
309fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If full_distribution_name is true (default), the full
310fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distribution read from the OS is returned. Otherwise the short
311fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name taken from supported_dists is used.
312fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
3138ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        Returns a tuple (distname,version,id) which default to the
314246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        args given as parameters.
315246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
316246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
317246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
318246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        etc = os.listdir('/etc')
319246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except os.error:
320246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Probably not a Unix system
321246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return distname,version,id
322fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    etc.sort()
323246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    for file in etc:
324366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg        m = _release_filename.match(file)
325fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if m is not None:
326246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            _distname,dummy = m.groups()
327246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if _distname in supported_dists:
328246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                distname = _distname
329246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                break
330246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
331246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return _dist_try_harder(distname,version,id)
3329fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
333fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Read the first line
3347dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna    with open('/etc/'+file, 'r') as f:
3357dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna        firstline = f.readline()
336fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    _distname, _version, _id = _parse_release_file(firstline)
337fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
338fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _distname and full_distribution_name:
339fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distname = _distname
340fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _version:
341fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version = _version
342fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _id:
343fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        id = _id
344fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return distname, version, id
345fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
346fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# To maintain backwards compatibility:
3479fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
348fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef dist(distname='',version='',id='',
349fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
350fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters         supported_dists=_supported_dists):
351fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
352fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Tries to determine the name of the Linux OS distribution name.
353fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
354fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        The function first looks for a distribution release file in
355fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        /etc and then reverts to _dist_try_harder() in case no
356fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        suitable files are found.
357fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
358fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Returns a tuple (distname,version,id) which default to the
359fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        args given as parameters.
360fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
361fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
362fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return linux_distribution(distname, version, id,
363fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                              supported_dists=supported_dists,
364fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                              full_distribution_name=0)
365246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
366877766dee8e60c7971ed0cabba89fbe981c2ab1bAntoine Pitroudef popen(cmd, mode='r', bufsize=-1):
367246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
368246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Portable popen() interface.
369246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
37025000d4d31dfa5842776aa92f234ea6672489c67Victor Stinner    import warnings
37125000d4d31dfa5842776aa92f234ea6672489c67Victor Stinner    warnings.warn('use os.popen instead', DeprecationWarning, stacklevel=2)
3721dfd3803064f2ee4b6e0bae3c60ca39e5f3919caVictor Stinner    return os.popen(cmd, mode, bufsize)
373246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
374fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _norm_version(version, build=''):
375246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
3768ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Normalize the version and build strings and return a single
377e5a7fad356a98f931bbe0d2c9e4b18854510c3ddWalter Dörwald        version string using the format major.minor.build (or patchlevel).
378246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
3799d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    l = version.split('.')
380246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if build:
381246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        l.append(build)
382246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
383246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        ints = map(int,l)
384246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ValueError:
385246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        strings = l
386246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
38778a70bd870e8f047f9e2aee37047266e658fab8fNeal Norwitz        strings = list(map(str,ints))
3889d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    version = '.'.join(strings[:3])
389246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return version
390246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
391366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
392366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg                         '.*'
393e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti                         '\[.* ([\d.]+)\])')
394e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
395e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Examples of VER command output:
396e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#
397e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#   Windows 2000:  Microsoft Windows 2000 [Version 5.00.2195]
398e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#   Windows XP:    Microsoft Windows XP [Version 5.1.2600]
399e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#   Windows Vista: Microsoft Windows [Version 6.0.6002]
400e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti#
401e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Note that the "Version" string gets localized on different
402e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Windows versions.
403366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg
404fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _syscmd_ver(system='', release='', version='',
405246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
406366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg               supported_platforms=('win32','win16','dos','os2')):
407246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
408246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Tries to figure out the OS version used and returns
409246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        a tuple (system,release,version).
4100eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
411246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        It uses the "ver" shell command for this which is known
412246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        to exists on Windows, DOS and OS/2. XXX Others too ?
413246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
414246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        In case this fails, the given parameters are used as
415246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        defaults.
416246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
417246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
418246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sys.platform not in supported_platforms:
419246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return system,release,version
420246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
421246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Try some common cmd strings
422246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    for cmd in ('ver','command /c ver','cmd /c ver'):
423246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
424246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            pipe = popen(cmd)
425246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            info = pipe.read()
426246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if pipe.close():
427ce36ad8a467d914eb5c91f33835b9eaea18ee93bCollin Winter                raise os.error('command failed')
42813925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti            # XXX How can I suppress shell errors from being written
429246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            #     to stderr ?
430b940e113bf90ff71b0ef57414ea2beea9d2a4bc0Guido van Rossum        except os.error as why:
431246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            #print 'Command %s failed: %s' % (cmd,why)
432246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            continue
433b940e113bf90ff71b0ef57414ea2beea9d2a4bc0Guido van Rossum        except IOError as why:
434246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            #print 'Command %s failed: %s' % (cmd,why)
435246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            continue
436246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
437246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            break
438246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
439246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return system,release,version
440246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
441246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Parse the output
4429d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    info = info.strip()
443366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg    m = _ver_output.match(info)
444fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
445246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system,release,version = m.groups()
446246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Strip trailing dots from version and release
447246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release[-1] == '.':
448246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = release[:-1]
449246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if version[-1] == '.':
450246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = version[:-1]
451246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Normalize the version and build strings (eliminating additional
452246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # zeros)
453246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = _norm_version(version)
454246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return system,release,version
455246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
456246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _win32_getvalue(key,name,default=''):
457246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
458246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Read a value for name from the registry key.
459246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
460246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        In case this fails, default is returned.
461246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
462246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
46302781dc7541b79e499c06ead64535c317efc460eChristian Heimes    try:
46402781dc7541b79e499c06ead64535c317efc460eChristian Heimes        # Use win32api if available
46502781dc7541b79e499c06ead64535c317efc460eChristian Heimes        from win32api import RegQueryValueEx
46602781dc7541b79e499c06ead64535c317efc460eChristian Heimes    except ImportError:
46738feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl        # On Python 2.0 and later, emulate using winreg
46838feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl        import winreg
46938feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl        RegQueryValueEx = winreg.QueryValueEx
470246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
471246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return RegQueryValueEx(key,name)
472246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except:
473246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
474246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
475246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef win32_ver(release='',version='',csd='',ptype=''):
476246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
477246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Get additional version information from the Windows Registry
478246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        and return a tuple (version,csd,ptype) referring to version
47910dda6e029b70aa95c51fe7ba2a61b729527c73bBrian Curtin        number, CSD level (service pack), and OS type (multi/single
480246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor).
481246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
482246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        As a hint: ptype returns 'Uniprocessor Free' on single
483246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor NT machines and 'Multiprocessor Free' on multi
484246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor machines. The 'Free' refers to the OS version being
485246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        free of debugging code. It could also state 'Checked' which
486246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        means the OS version uses debugging code, i.e. code that
487246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        checks arguments, ranges, etc. (Thomas Heller).
488246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
48902781dc7541b79e499c06ead64535c317efc460eChristian Heimes        Note: this function works best with Mark Hammond's win32
49002781dc7541b79e499c06ead64535c317efc460eChristian Heimes        package installed, but also on Python 2.3 and later. It
49102781dc7541b79e499c06ead64535c317efc460eChristian Heimes        obviously only runs on Win32 compatible platforms.
492246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
493246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
494246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # XXX Is there any way to find out the processor type on WinXX ?
495246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # XXX Is win32 available on Windows CE ?
49691e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    #
497246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Adapted from code posted by Karl Putland to comp.lang.python.
49891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    #
49991e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    # The mappings between reg. values and release names can be found
50091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp
501246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
502246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Import the needed APIs
503246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
504246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import win32api
50502781dc7541b79e499c06ead64535c317efc460eChristian Heimes        from win32api import RegQueryValueEx, RegOpenKeyEx, \
50602781dc7541b79e499c06ead64535c317efc460eChristian Heimes             RegCloseKey, GetVersionEx
50702781dc7541b79e499c06ead64535c317efc460eChristian Heimes        from win32con import HKEY_LOCAL_MACHINE, VER_PLATFORM_WIN32_NT, \
50802781dc7541b79e499c06ead64535c317efc460eChristian Heimes             VER_PLATFORM_WIN32_WINDOWS, VER_NT_WORKSTATION
509246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
51002781dc7541b79e499c06ead64535c317efc460eChristian Heimes        # Emulate the win32api module using Python APIs
51102781dc7541b79e499c06ead64535c317efc460eChristian Heimes        try:
51202781dc7541b79e499c06ead64535c317efc460eChristian Heimes            sys.getwindowsversion
51302781dc7541b79e499c06ead64535c317efc460eChristian Heimes        except AttributeError:
51402781dc7541b79e499c06ead64535c317efc460eChristian Heimes            # No emulation possible, so return the defaults...
51502781dc7541b79e499c06ead64535c317efc460eChristian Heimes            return release,version,csd,ptype
51602781dc7541b79e499c06ead64535c317efc460eChristian Heimes        else:
51738feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl            # Emulation using winreg (added in Python 2.0) and
51802781dc7541b79e499c06ead64535c317efc460eChristian Heimes            # sys.getwindowsversion() (added in Python 2.3)
51938feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl            import winreg
52002781dc7541b79e499c06ead64535c317efc460eChristian Heimes            GetVersionEx = sys.getwindowsversion
52138feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl            RegQueryValueEx = winreg.QueryValueEx
52238feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl            RegOpenKeyEx = winreg.OpenKeyEx
52338feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl            RegCloseKey = winreg.CloseKey
52438feaf0fef244879411f094a7e68f542a6771deaGeorg Brandl            HKEY_LOCAL_MACHINE = winreg.HKEY_LOCAL_MACHINE
52502781dc7541b79e499c06ead64535c317efc460eChristian Heimes            VER_PLATFORM_WIN32_WINDOWS = 1
52602781dc7541b79e499c06ead64535c317efc460eChristian Heimes            VER_PLATFORM_WIN32_NT = 2
52702781dc7541b79e499c06ead64535c317efc460eChristian Heimes            VER_NT_WORKSTATION = 1
5286e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            VER_NT_SERVER = 3
5296e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            REG_SZ = 1
530246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
531246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Find out the registry key and some general version infos
5326e2824dc35685fc27f551f96418761e383e91faeBrian Curtin    winver = GetVersionEx()
5336e2824dc35685fc27f551f96418761e383e91faeBrian Curtin    maj,min,buildno,plat,csd = winver
534246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF)
5356e2824dc35685fc27f551f96418761e383e91faeBrian Curtin    if hasattr(winver, "service_pack"):
5366e2824dc35685fc27f551f96418761e383e91faeBrian Curtin        if winver.service_pack != "":
5376e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            csd = 'SP%s' % winver.service_pack_major
5386e2824dc35685fc27f551f96418761e383e91faeBrian Curtin    else:
5396e2824dc35685fc27f551f96418761e383e91faeBrian Curtin        if csd[:13] == 'Service Pack ':
5406e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            csd = 'SP' + csd[13:]
541e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
542246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if plat == VER_PLATFORM_WIN32_WINDOWS:
543246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
544246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try to guess the release name
545246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if maj == 4:
546246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if min == 0:
547246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                release = '95'
54891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 10:
549246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                release = '98'
55091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 90:
55191e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'Me'
55291e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            else:
55391e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'postMe'
554246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif maj == 5:
555246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = '2000'
556e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
557246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif plat == VER_PLATFORM_WIN32_NT:
558246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'
559246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if maj <= 4:
560246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = 'NT'
561246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif maj == 5:
56291e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            if min == 0:
56391e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = '2000'
56491e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 1:
56591e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'XP'
56691e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 2:
56791e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = '2003Server'
56891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            else:
56991e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'post2003'
570cd16bf640405065e4702539632ce577536207d88Guido van Rossum        elif maj == 6:
5716e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            if hasattr(winver, "product_type"):
5726e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                product_type = winver.product_type
5736e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            else:
5746e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                product_type = VER_NT_WORKSTATION
5756e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                # Without an OSVERSIONINFOEX capable sys.getwindowsversion(),
5766e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                # or help from the registry, we cannot properly identify
5776e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                # non-workstation versions.
57802781dc7541b79e499c06ead64535c317efc460eChristian Heimes                try:
5796e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
5806e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    name, type = RegQueryValueEx(key, "ProductName")
5816e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    # Discard any type that isn't REG_SZ
5826e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    if type == REG_SZ and name.find("Server") != -1:
5836e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                        product_type = VER_NT_SERVER
5846e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                except WindowsError:
5856e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    # Use default of VER_NT_WORKSTATION
5866e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    pass
5876e2824dc35685fc27f551f96418761e383e91faeBrian Curtin
5886e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            if min == 0:
5896e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                if product_type == VER_NT_WORKSTATION:
590cd16bf640405065e4702539632ce577536207d88Guido van Rossum                    release = 'Vista'
591cd16bf640405065e4702539632ce577536207d88Guido van Rossum                else:
5926e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    release = '2008Server'
5936e2824dc35685fc27f551f96418761e383e91faeBrian Curtin            elif min == 1:
5946e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                if product_type == VER_NT_WORKSTATION:
5956e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    release = '7'
5966e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                else:
5976e2824dc35685fc27f551f96418761e383e91faeBrian Curtin                    release = '2008ServerR2'
598cd16bf640405065e4702539632ce577536207d88Guido van Rossum            else:
599cd16bf640405065e4702539632ce577536207d88Guido van Rossum                release = 'post2008Server'
600e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti
601246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
602246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if not release:
603246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # E.g. Win3.1 with win32s
604246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = '%i.%i' % (maj,min)
605246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,version,csd,ptype
606246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
607246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Open the registry key
608246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
60902781dc7541b79e499c06ead64535c317efc460eChristian Heimes        keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey)
610246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Get a value to make sure the key exists...
61102781dc7541b79e499c06ead64535c317efc460eChristian Heimes        RegQueryValueEx(keyCurVer, 'SystemRoot')
612246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except:
613246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,version,csd,ptype
6140eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
615246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Parse values
616246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #subversion = _win32_getvalue(keyCurVer,
617246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #                            'SubVersionNumber',
618246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #                            ('',1))[0]
619246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #if subversion:
620246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #   release = release + subversion # 95a, 95b, etc.
621246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    build = _win32_getvalue(keyCurVer,
622246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                            'CurrentBuildNumber',
623246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                            ('',1))[0]
624246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    ptype = _win32_getvalue(keyCurVer,
625246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                           'CurrentType',
626246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                           (ptype,1))[0]
627246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
628246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Normalize version
629246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    version = _norm_version(version,build)
630246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
631246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Close key
632246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    RegCloseKey(keyCurVer)
633246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return release,version,csd,ptype
634246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
635246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _mac_ver_lookup(selectors,default=None):
636246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
637ebacd26869220b2f300d1b88c59ec3efc60ac00dBenjamin Peterson    from _gestalt import gestalt
638246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    l = []
639246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    append = l.append
640246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    for selector in selectors:
641246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
642246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            append(gestalt(selector))
643ebacd26869220b2f300d1b88c59ec3efc60ac00dBenjamin Peterson        except (RuntimeError, OSError):
644246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            append(default)
645246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return l
646246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
647246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _bcd2str(bcd):
648246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
649246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return hex(bcd)[2:]
650246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
651e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussorendef _mac_ver_gestalt():
652e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    """
653246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Thanks to Mark R. Levinson for mailing documentation links and
654246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        code examples for this function. Documentation for the
655246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        gestalt() API is available online at:
656246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
657246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg           http://www.rgaros.nl/gestalt/
658246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
659246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Check whether the version info module is available
660246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
661ebacd26869220b2f300d1b88c59ec3efc60ac00dBenjamin Peterson        import _gestalt
662246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
663e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return None
664246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get the infos
66519258d5a352c375bbe0da4bb569e556671b9b04fRonald Oussoren    sysv, sysa = _mac_ver_lookup(('sysv','sysa'))
666246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Decode the infos
667246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sysv:
668246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        major = (sysv & 0xFF00) >> 8
669246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        minor = (sysv & 0x00F0) >> 4
670246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        patch = (sysv & 0x000F)
671e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes
672e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes        if (major, minor) >= (10, 4):
673e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            # the 'sysv' gestald cannot return patchlevels
674e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            # higher than 9. Apple introduced 3 new
675e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            # gestalt codes in 10.4 to deal with this
676e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            # issue (needed because patch levels can
677e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            # run higher than 9, such as 10.4.11)
678e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            major,minor,patch = _mac_ver_lookup(('sys1','sys2','sys3'))
679e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            release = '%i.%i.%i' %(major, minor, patch)
680e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes        else:
681e4ca8156ef146174c64d537d9fa07a880231e699Christian Heimes            release = '%s.%i.%i' % (_bcd2str(major),minor,patch)
682856ff5f986b248e9568d7efdb71f4ab6d232a51dBenjamin Peterson
683246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sysa:
6840eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters        machine = {0x1: '68k',
68549fd7fa4431da299196d74087df4a04f99f9c46fThomas Wouters                   0x2: 'PowerPC',
68649fd7fa4431da299196d74087df4a04f99f9c46fThomas Wouters                   0xa: 'i386'}.get(sysa,'')
687e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
68858e3350bd48d59c273e320c408f2546e6d09146eNed Deily    versioninfo=('', '', '')
689e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    return release,versioninfo,machine
690e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
691e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussorendef _mac_ver_xml():
692e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    fn = '/System/Library/CoreServices/SystemVersion.plist'
693e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    if not os.path.exists(fn):
694e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return None
695e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
696e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    try:
697e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        import plistlib
698e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    except ImportError:
699e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return None
700e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
701e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    pl = plistlib.readPlist(fn)
702e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    release = pl['ProductVersion']
703e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    versioninfo=('', '', '')
704605a62ddb1c19978ee194a40a458f072e3242a31Larry Hastings    machine = os.uname().machine
705fcd77016b31ea9fb5311695f5ca82cf6c235da87Ronald Oussoren    if machine in ('ppc', 'Power Macintosh'):
706e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        # for compatibility with the gestalt based code
707e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        machine = 'PowerPC'
708e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
709e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    return release,versioninfo,machine
710e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
711e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
712e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussorendef mac_ver(release='',versioninfo=('','',''),machine=''):
713e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
714e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    """ Get MacOS version information and return it as tuple (release,
715e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        versioninfo, machine) with versioninfo being a tuple (version,
716e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        dev_stage, non_release_version).
717e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
718e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        Entries which cannot be determined are set to the paramter values
719e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        which default to ''. All tuple entries are strings.
720e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    """
721e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
722e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # First try reading the information from an XML file which should
723e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # always be present
724e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    info = _mac_ver_xml()
725e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    if info is not None:
726e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return info
727e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
728e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # If that doesn't work for some reason fall back to reading the
729e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # information using gestalt calls.
730e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    info = _mac_ver_gestalt()
731e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    if info is not None:
732e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren        return info
733e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren
734e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren    # If that also doesn't work return the default values
735246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return release,versioninfo,machine
736246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
7379b924c690eb2de515a1eda4221e15a483c6b7316Neal Norwitzdef _java_getprop(name,default):
738246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
739246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    from java.lang import System
740246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
741fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        value = System.getProperty(name)
742fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if value is None:
743fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            return default
744fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return value
745fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    except AttributeError:
746246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
747246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
748246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')):
7490eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
7508ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Version interface for Jython.
751246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
752246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being
753246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        a tuple (vm_name,vm_release,vm_vendor) and osinfo being a
754246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        tuple (os_name,os_version,os_arch).
755246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
756246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Values which cannot be determined are set to the defaults
757246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        given as parameters (which all default to '').
758246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
759246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
760246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Import the needed APIs
761246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
762246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import java.lang
763246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
764246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,vendor,vminfo,osinfo
765246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
766fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vendor = _java_getprop('java.vendor', vendor)
767fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    release = _java_getprop('java.version', release)
768fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_name, vm_release, vm_vendor = vminfo
769fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_name = _java_getprop('java.vm.name', vm_name)
770fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
771fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_release = _java_getprop('java.vm.version', vm_release)
772fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vminfo = vm_name, vm_release, vm_vendor
773fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_name, os_version, os_arch = osinfo
774fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_arch = _java_getprop('java.os.arch', os_arch)
775fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_name = _java_getprop('java.os.name', os_name)
776fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_version = _java_getprop('java.os.version', os_version)
777fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    osinfo = os_name, os_version, os_arch
778fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
779fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return release, vendor, vminfo, osinfo
780246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
781246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### System name aliasing
782246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
783246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef system_alias(system,release,version):
784246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
785246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns (system,release,version) aliased to common
786246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        marketing names used for some systems.
787246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
788246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        It also does some reordering of the information in some cases
789246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        where it would otherwise cause confusion.
790246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
791246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
792246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'Rhapsody':
793246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Apple's BSD derivative
794246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX How can we determine the marketing release number ?
795246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return 'MacOS X Server',system+release,version
796246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
797246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'SunOS':
798246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Sun's OS
799246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release < '5':
800246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # These releases use the old name SunOS
801246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            return system,release,version
802246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Modify release (marketing release = SunOS release - 3)
8039d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz        l = release.split('.')
804246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if l:
805246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            try:
806246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                major = int(l[0])
807246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            except ValueError:
808246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                pass
809246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            else:
810246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                major = major - 3
811246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                l[0] = str(major)
8129d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz                release = '.'.join(l)
813246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release < '6':
814246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Solaris'
815246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
816246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # XXX Whatever the new SunOS marketing name is...
817246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Solaris'
818246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
819246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'IRIX64':
820246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # IRIX reports IRIX64 on platforms with 64-bit support; yet it
821246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # is really a version and not a different platform, since 32-bit
822246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # apps are also supported..
823246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = 'IRIX'
824246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if version:
825246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = version + ' (64bit)'
826246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
827246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = '64bit'
828246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
829246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system in ('win32','win16'):
830246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # In case one of the other tricks
831246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = 'Windows'
832246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
833246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return system,release,version
834246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
835246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various internal helpers
836246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
837246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _platform(*args):
838246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
839246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Helper to format the platform string in a filename
840246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        compatible format e.g. "system-version-machine".
841246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
842246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Format the platform string
8439d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = '-'.join(x.strip() for x in filter(len, args))
844246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
845246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Cleanup some possible filename obstacles...
8469d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace(' ','_')
8479d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace('/','-')
8489d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace('\\','-')
8499d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace(':','-')
8509d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace(';','-')
8519d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace('"','-')
8529d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace('(','-')
8539d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace(')','-')
854246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
855246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # No need to report 'unknown' information...
8569d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    platform = platform.replace('unknown','')
857246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
858246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Fold '--'s and remove trailing '-'
859246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while 1:
8609d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz        cleaned = platform.replace('--','-')
861246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if cleaned == platform:
862246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            break
863246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platform = cleaned
864246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while platform[-1] == '-':
865246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platform = platform[:-1]
866246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
867246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return platform
868246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
869246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _node(default=''):
870246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
871246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Helper to determine the node name of this machine.
872246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
873246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
874246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import socket
875246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
876246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # No sockets...
877246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
878246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
879246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return socket.gethostname()
880246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except socket.error:
881246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Still not working...
882246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
883246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
884246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _follow_symlinks(filepath):
885246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
886246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ In case filepath is a symlink, follow it until a
887246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        real file is reached.
888246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
889673f7efa08850e42d077cab38683be2e4764b876Georg Brandl    filepath = os.path.abspath(filepath)
890246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while os.path.islink(filepath):
891246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        filepath = os.path.normpath(
892b12716b9460f1592506943b6934a4873edaca846Hirokazu Yamamoto            os.path.join(os.path.dirname(filepath),os.readlink(filepath)))
893246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return filepath
894246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
895246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _syscmd_uname(option,default=''):
896246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
897246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Interface to the system's uname command.
898246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
899246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sys.platform in ('dos','win32','win16','os2'):
900246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX Others too ?
901246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
902246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
903e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti        f = os.popen('uname %s 2> %s' % (option, DEV_NULL))
904246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except (AttributeError,os.error):
905246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
9069d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    output = f.read().strip()
907246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    rc = f.close()
908246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not output or rc:
909246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
910246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
911246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return output
912246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
913246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _syscmd_file(target,default=''):
914246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
915246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Interface to the system's file command.
916246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
917246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function uses the -b option of the file command to have it
918ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        omit the filename in its output. Follow the symlinks. It returns
919ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        default in case the command should fail.
920246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
921246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
922d26782e8639df937fac1ef3f208986274138d5c1Hirokazu Yamamoto    if sys.platform in ('dos','win32','win16','os2'):
923d26782e8639df937fac1ef3f208986274138d5c1Hirokazu Yamamoto        # XXX Others too ?
924d26782e8639df937fac1ef3f208986274138d5c1Hirokazu Yamamoto        return default
925fc990e942fb55be78e8352f4913749e91cac381dJesus Cea    target = _follow_symlinks(target)
926246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
927685fffa8f427b3a768b232170752565d58c32112Jesus Cea        proc = subprocess.Popen(['file', target],
928685fffa8f427b3a768b232170752565d58c32112Jesus Cea                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
929e8801e2e44b4ffcfdfc6e2857e7afc90ba6abc38Jesus Cea
930246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except (AttributeError,os.error):
931246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
932cb95996fdc6956365642dd42f86dfb380f923fa5Jesus Cea    output = proc.communicate()[0].decode('latin-1')
933fc990e942fb55be78e8352f4913749e91cac381dJesus Cea    rc = proc.wait()
934246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not output or rc:
935246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
936246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
937246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return output
938246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
939246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Information about the used architecture
940246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
941246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Default values for architecture; non-empty strings override the
942246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# defaults given as parameters
943246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_default_architecture = {
944246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    'win32': ('','WindowsPE'),
945246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    'win16': ('','Windows'),
946246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    'dos': ('','MSDOS'),
947246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg}
948246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
949366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburgdef architecture(executable=sys.executable,bits='',linkage=''):
950246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
951246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Queries the given executable (defaults to the Python interpreter
9528ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        binary) for various architecture information.
953246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
9548ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        Returns a tuple (bits,linkage) which contains information about
955246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        the bit architecture and the linkage format used for the
956246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        executable. Both values are returned as strings.
957246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
958246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Values that cannot be determined are returned as given by the
959246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        parameter presets. If bits is given as '', the sizeof(pointer)
960246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        (or sizeof(long) on Python version < 1.5.2) is used as
961246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        indicator for the supported pointer size.
962246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
963246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function relies on the system's "file" command to do the
964246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        actual work. This is available on most if not all Unix
9658ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        platforms. On some non-Unix platforms where the "file" command
9668ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        does not exist and the executable is set to the Python interpreter
9678ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        binary defaults from _default_architecture are used.
968246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
969246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
970246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Use the sizeof(pointer) as default number of bits if nothing
971246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # else is given as default.
972246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not bits:
973246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import struct
974246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
975246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            size = struct.calcsize('P')
976246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        except struct.error:
977246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # Older installations can only query longs
978246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            size = struct.calcsize('l')
979246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = str(size*8) + 'bit'
9800eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
981246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get data from the 'file' system command
982fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if executable:
983ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        fileout = _syscmd_file(executable, '')
984fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    else:
985ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner        fileout = ''
986246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
987ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner    if not fileout and \
988246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg       executable == sys.executable:
989246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # "file" command did not return anything; we'll try to provide
9900eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters        # some sensible defaults then...
991e2b70bcf7401477936fba99a8bf4a1f759ecc8a3Guido van Rossum        if sys.platform in _default_architecture:
992246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            b,l = _default_architecture[sys.platform]
993246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if b:
994246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                bits = b
995246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if l:
996246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                linkage = l
997246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return bits,linkage
998246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
999246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if 'executable' not in fileout:
1000246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Format not supported
1001246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return bits,linkage
1002246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1003246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Bits
1004246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if '32-bit' in fileout:
1005246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = '32bit'
1006246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'N32' in fileout:
1007246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # On Irix only
1008246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = 'n32bit'
1009246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif '64-bit' in fileout:
1010246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = '64bit'
1011246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1012246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Linkage
1013246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if 'ELF' in fileout:
1014246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'ELF'
1015246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'PE' in fileout:
1016246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # E.g. Windows uses this format
1017246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if 'Windows' in fileout:
1018246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            linkage = 'WindowsPE'
1019246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1020246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            linkage = 'PE'
1021246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'COFF' in fileout:
1022246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'COFF'
1023246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'MS-DOS' in fileout:
1024246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'MSDOS'
1025246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
1026246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX the A.OUT format also falls under this class...
1027246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        pass
1028246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1029246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return bits,linkage
1030246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1031246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Portable uname() interface
10320eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
103368386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastingsuname_result = collections.namedtuple("uname_result",
103468386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings                    "system node release version machine processor")
103568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings
1036246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_uname_cache = None
1037246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1038246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef uname():
1039246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1040246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Fairly portable uname interface. Returns a tuple
1041246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        of strings (system,node,release,version,machine,processor)
1042246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        identifying the underlying platform.
1043246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1044246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the os.uname function this also returns
10458ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        possible processor information as an additional tuple entry.
1046246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1047246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Entries which cannot be determined are set to ''.
1048246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1049246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1050246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    global _uname_cache
105135c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    no_os_uname = 0
1052246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1053246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if _uname_cache is not None:
1054246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return _uname_cache
1055246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
105635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    processor = ''
105735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc
1058246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get some infos from the builtin os.uname API...
1059246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
1060246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system,node,release,version,machine = os.uname()
1061246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except AttributeError:
106235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        no_os_uname = 1
106335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc
106462e2ca219311a111873892910ad441659faeaefaGeorg Brandl    if no_os_uname or not list(filter(None, (system, node, release, version, machine))):
106535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # Hmm, no there is either no uname or uname has returned
106635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        #'unknowns'... we'll have to poke around the system then.
106735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        if no_os_uname:
106835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            system = sys.platform
106935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            release = ''
107035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            version = ''
107135c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            node = _node()
107235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            machine = ''
107335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc
10747a01984aba532b731dd6a06610b0ce523bef4f5eAmaury Forgeot d'Arc        use_syscmd_ver = 1
1075246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1076246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try win32_ver() on win32 platforms
1077246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if system == 'win32':
1078246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release,version,csd,ptype = win32_ver()
1079246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if release and version:
1080246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                use_syscmd_ver = 0
108102781dc7541b79e499c06ead64535c317efc460eChristian Heimes            # Try to use the PROCESSOR_* environment variables
1082fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # available on Win XP and later; see
1083fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # http://support.microsoft.com/kb/888731 and
1084fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM
108535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            if not machine:
1086ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                # WOW64 processes mask the native architecture
1087ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                if "PROCESSOR_ARCHITEW6432" in os.environ:
1088ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                    machine = os.environ.get("PROCESSOR_ARCHITEW6432", '')
1089ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                else:
1090ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray                    machine = os.environ.get('PROCESSOR_ARCHITECTURE', '')
109135c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            if not processor:
109235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc                processor = os.environ.get('PROCESSOR_IDENTIFIER', machine)
10930eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
1094246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try the 'ver' system command available on some
1095246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # platforms
1096246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if use_syscmd_ver:
1097246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system,release,version = _syscmd_ver(system)
1098cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            # Normalize system to what win32_ver() normally returns
1099cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            # (_syscmd_ver() tends to return the vendor name as well)
1100cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            if system == 'Microsoft Windows':
1101cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg                system = 'Windows'
1102cd16bf640405065e4702539632ce577536207d88Guido van Rossum            elif system == 'Microsoft' and release == 'Windows':
1103cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # Under Windows Vista and Windows Server 2008,
1104cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # Microsoft changed the output of the ver command. The
1105cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # release is no longer printed.  This causes the
1106cd16bf640405065e4702539632ce577536207d88Guido van Rossum                # system and release to be misidentified.
1107cd16bf640405065e4702539632ce577536207d88Guido van Rossum                system = 'Windows'
1108cd16bf640405065e4702539632ce577536207d88Guido van Rossum                if '6.0' == version[:3]:
1109cd16bf640405065e4702539632ce577536207d88Guido van Rossum                    release = 'Vista'
1110cd16bf640405065e4702539632ce577536207d88Guido van Rossum                else:
1111cd16bf640405065e4702539632ce577536207d88Guido van Rossum                    release = ''
1112246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1113246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # In case we still don't know anything useful, we'll try to
1114246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # help ourselves
1115246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if system in ('win32','win16'):
1116246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not version:
1117246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                if system == 'win32':
1118246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = '32bit'
1119246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                else:
1120246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = '16bit'
1121246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Windows'
1122246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1123246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif system[:4] == 'java':
1124246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release,vendor,vminfo,osinfo = java_ver()
1125246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Java'
11269d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz            version = ', '.join(vminfo)
1127246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not version:
1128246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = vendor
1129246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
113035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    # System specific extensions
113135c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    if system == 'OpenVMS':
113235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # OpenVMS seems to have release and version mixed up
113335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        if not release or release == '0':
113435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            release = version
113535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            version = ''
113635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # Get processor information
113735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        try:
113835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            import vms_lib
113935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        except ImportError:
114035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            pass
1141246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
114235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
114335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            if (cpu_number >= 128):
114435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc                processor = 'Alpha'
114535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc            else:
114635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc                processor = 'VAX'
114735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    if not processor:
114835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        # Get processor information from the uname system command
114935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc        processor = _syscmd_uname('-p','')
1150246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
115135c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc    #If any unknowns still exist, replace them with ''s, which are more portable
1152246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'unknown':
1153246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = ''
1154246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if node == 'unknown':
1155246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        node = ''
1156246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if release == 'unknown':
1157246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        release = ''
1158246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if version == 'unknown':
1159246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = ''
1160246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if machine == 'unknown':
1161246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        machine = ''
1162246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if processor == 'unknown':
1163246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor = ''
11641b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters
11651b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters    #  normalize name
11661b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters    if system == 'Microsoft' and release == 'Windows':
11671b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters        system = 'Windows'
11681b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters        release = 'Vista'
11691b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters
117068386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    _uname_cache = uname_result(system,node,release,version,machine,processor)
1171246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return _uname_cache
1172246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1173246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Direct interfaces to some of the uname() return values
1174246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1175246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef system():
1176246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1177246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
1178246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1179246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1180246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1181246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
118268386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().system
1183246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1184246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef node():
1185246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
11868ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Returns the computer's network name (which may not be fully
11878ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        qualified)
1188246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1189246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1190246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1191246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
119268386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().node
1193246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1194246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef release():
1195246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1196246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system's release, e.g. '2.2.0' or 'NT'
1197246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1198246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1199246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1200246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
120168386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().release
1202246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1203246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef version():
1204246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1205246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system's release version, e.g. '#3 on degas'
1206246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1207246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1208246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1209246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
121068386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().version
1211246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1212246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef machine():
1213246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1214246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the machine type, e.g. 'i386'
1215246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1216246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1217246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1218246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
121968386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().machine
1220246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1221246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef processor():
1222246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1223246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the (true) processor name, e.g. 'amdk6'
1224246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1225246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be
1226246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        determined. Note that many platforms do not provide this
1227246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        information or simply return the same value as for machine(),
1228246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        e.g.  NetBSD does this.
1229246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1230246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
123168386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings    return uname().processor
1232246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1233246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various APIs for extracting information from sys.version
1234246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1235fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_parser = re.compile(
1236fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    r'([\w.+]+)\s*'
1237fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
1238fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou    '\[([^\]]+)\]?', re.ASCII)
1239fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1240fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_ironpython_sys_version_parser = re.compile(
1241fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    r'IronPython\s*'
1242fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    '([\d\.]+)'
1243fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    '(?: \(([\d\.]+)\))?'
1244fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou    ' on (.NET [\d\.]+)', re.ASCII)
1245246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1246e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson_pypy_sys_version_parser = re.compile(
1247e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    r'([\w.+]+)\s*'
1248e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
1249e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    '\[PyPy [^\]]+\]?')
1250e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson
1251fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_cache = {}
1252fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1253fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _sys_version(sys_version=None):
1254246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1255246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a parsed version of Python's sys.version as tuple
12565f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        (name, version, branch, revision, buildno, builddate, compiler)
12575f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        referring to the Python implementation name, version, branch,
12585f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        revision, build number, build date/time as string and the compiler
12595f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson        identification string.
1260246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1261246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1262246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        for the Python version will always include the patchlevel (it
1263246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        defaults to '.0').
1264246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1265fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        The function returns empty strings for tuple entries that
1266fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        cannot be determined.
1267fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1268fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        sys_version may be given to parse an alternative version
1269fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        string, e.g. if the version was read from a different Python
1270fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        interpreter.
1271fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1272246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1273fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Get the Python version
1274fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if sys_version is None:
1275fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        sys_version = sys.version
1276246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1277fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Try the cache first
1278fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    result = _sys_version_cache.get(sys_version, None)
1279fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if result is not None:
1280fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return result
1281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Parse it
1283fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if sys_version[:10] == 'IronPython':
1284fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # IronPython
1285fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name = 'IronPython'
1286fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        match = _ironpython_sys_version_parser.match(sys_version)
1287fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1288fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1289fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse IronPython sys.version: %s' %
1290fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1291fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version, alt_version, compiler = match.groups()
1292fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        buildno = ''
1293fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        builddate = ''
1294fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1295fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    elif sys.platform[:4] == 'java':
1296fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # Jython
1297fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name = 'Jython'
1298e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        match = _sys_version_parser.match(sys_version)
1299fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1300fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1301fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse Jython sys.version: %s' %
1302fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1303e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        version, buildno, builddate, buildtime, _ = match.groups()
1304fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        compiler = sys.platform
1305e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson
1306e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    elif "PyPy" in sys_version:
1307e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        # PyPy
1308e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        name = "PyPy"
1309e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        match = _pypy_sys_version_parser.match(sys_version)
1310e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        if match is None:
1311e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson            raise ValueError("failed to parse PyPy sys.version: %s" %
1312e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson                             repr(sys_version))
1313e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        version, buildno, builddate, buildtime = match.groups()
1314e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        compiler = ""
1315fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1316fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    else:
1317fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # CPython
1318fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        match = _sys_version_parser.match(sys_version)
1319fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1320fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1321fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse CPython sys.version: %s' %
1322fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1323fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version, buildno, builddate, buildtime, compiler = \
1324fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters              match.groups()
1325e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        name = 'CPython'
1326fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        builddate = builddate + ' ' + buildtime
1327fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
13288256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl    if hasattr(sys, '_mercurial'):
13298256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl        _, branch, revision = sys._mercurial
13308256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl    elif hasattr(sys, 'subversion'):
1331e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        # sys.subversion was added in Python 2.5
1332e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        _, branch, revision = sys.subversion
1333e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson    else:
1334e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        branch = ''
1335e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson        revision = ''
1336e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson
1337fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Add the patchlevel version if missing
13389d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    l = version.split('.')
1339246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if len(l) == 2:
1340246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        l.append('0')
13419d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz        version = '.'.join(l)
1342fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1343fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Build and cache the result
1344fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    result = (name, version, branch, revision, buildno, builddate, compiler)
1345fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    _sys_version_cache[sys_version] = result
1346fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return result
1347fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1348fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_implementation():
1349fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1350fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation.
1351fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1352fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Currently, the following implementations are identified:
1353f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'CPython' (C implementation of Python),
1354f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'IronPython' (.NET implementation of Python),
1355f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'Jython' (Java implementation of Python),
1356f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti          'PyPy' (Python implementation of Python).
1357fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1358fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
1359fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[0]
1360246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1361246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version():
1362246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1363246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the Python version as string 'major.minor.patchlevel'
1364246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1365246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1366246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        will always include the patchlevel (it defaults to 0).
1367246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1368246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1369fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[1]
1370246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1371246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version_tuple():
1372246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1373246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the Python version as tuple (major, minor, patchlevel)
1374246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        of strings.
1375246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1376246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1377246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        will always include the patchlevel (it defaults to 0).
1378246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1379246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
13809d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz    return tuple(_sys_version()[1].split('.'))
1381fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1382fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_branch():
1383fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1384fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation
1385fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        branch.
1386fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1387fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        For CPython this is the Subversion branch from which the
1388fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Python binary was built.
1389fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1390fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If not available, an empty string is returned.
1391fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1392fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
13939fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
1394fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[2]
1395fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1396fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_revision():
1397fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1398fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation
1399fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        revision.
1400fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1401fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        For CPython this is the Subversion revision from which the
1402fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Python binary was built.
1403fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1404fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If not available, an empty string is returned.
1405fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1406fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
1407fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[3]
1408246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1409246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_build():
1410246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1411246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a tuple (buildno, builddate) stating the Python
1412246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        build number and date as strings.
1413246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1414246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1415fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[4:6]
1416246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1417246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_compiler():
1418246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1419246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a string identifying the compiler used for compiling
1420246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Python.
1421246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1422246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1423fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[6]
1424246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1425246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### The Opus Magnum of platform strings :-)
1426246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
142791e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg_platform_cache = {}
1428246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1429246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef platform(aliased=0, terse=0):
1430246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1431246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a single string identifying the underlying platform
1432246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        with as much useful information as possible (but no more :).
14330eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
1434246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The output is intended to be human readable rather than
1435246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        machine parseable. It may look different on different
1436246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platforms and this is intended.
1437246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1438246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        If "aliased" is true, the function will use aliases for
1439246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        various platforms that report system names which differ from
1440246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        their common names, e.g. SunOS will be reported as
1441246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Solaris. The system_alias() function is used to implement
1442246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        this.
1443246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1444246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Setting terse to true causes the function to return only the
1445246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        absolute minimum information needed to identify the platform.
1446246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1447246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
144891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    result = _platform_cache.get((aliased, terse), None)
144991e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    if result is not None:
145091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg        return result
1451246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1452246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get uname information and then apply platform specific cosmetics
1453246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # to it...
1454246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    system,node,release,version,machine,processor = uname()
1455246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if machine == processor:
1456246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor = ''
1457246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if aliased:
1458246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system,release,version = system_alias(system,release,version)
1459246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1460246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'Windows':
1461246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # MS platforms
1462246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        rel,vers,csd,ptype = win32_ver(version)
1463246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1464246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release)
1465246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1466246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,version,csd)
1467246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1468246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system in ('Linux',):
1469246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Linux based systems
1470246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        distname,distversion,distid = dist('')
1471246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if distname and not terse:
1472246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine,processor,
1473246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'with',
1474246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 distname,distversion,distid)
1475246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1476246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # If the distribution name is unknown check for libc vs. glibc
1477246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            libcname,libcversion = libc_ver(sys.executable)
1478246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine,processor,
1479246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'with',
1480246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 libcname+libcversion)
1481246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'Java':
1482246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Java platforms
1483246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        r,v,vminfo,(os_name,os_version,os_arch) = java_ver()
1484fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if terse or not os_name:
1485246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,version)
1486246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1487246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,version,
1488246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'on',
1489246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 os_name,os_version,os_arch)
1490246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1491246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'MacOS':
1492246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # MacOS platforms
1493246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1494246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release)
1495246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1496246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine)
1497246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1498246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
1499246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Generic handler
1500246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1501246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release)
1502246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1503246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            bits,linkage = architecture(sys.executable)
1504246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine,processor,bits,linkage)
15050eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
150691e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    _platform_cache[(aliased, terse)] = platform
1507246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return platform
1508246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1509246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Command line interface
1510246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1511246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgif __name__ == '__main__':
1512246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Default is to print the aliased verbose platform string
15130eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters    terse = ('terse' in sys.argv or '--terse' in sys.argv)
1514246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
1515be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum    print(platform(aliased,terse))
1516246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    sys.exit(0)
1517