platform.py revision 9fe394c1be9401c2b207b943f82e30af4ee32ab6
1246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#!/usr/bin/env python
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
13246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    Python SourceForge Project Page and assign them to "lemburg".
14246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
15246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    Note: Please keep this module compatible to Python 1.5.2.
16246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
17246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    Still needed:
18246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * more support for WinCE
19246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for MS-DOS (PythonDX ?)
20246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for Amiga and other still unsupported platforms running Python
21246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    * support for additional Linux distributions
22246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
238ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon#    Many thanks to all those who helped adding platform-specific
24246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    checks (in no particular order):
25246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
26246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell,
27246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef
28246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg
29246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark
30246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#      Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support),
31fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#      Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter
32246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
33246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    History:
34380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#
35380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#    <see CVS and SVN checkin messages for history>
36380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg#
37fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.6 - added linux_distribution()
38fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.5 - fixed Java support to allow running the module on Jython
39fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters#    1.0.4 - added IronPython support
40cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg#    1.0.3 - added normalization of Windows system name
4191e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg#    1.0.2 - added more Windows support
42366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg#    1.0.1 - reformatted to make doc.py happy
43246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    1.0.0 - reformatted a bit and checked into Python CVS
44246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.8.0 - added sys.version parser and various new access
45246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            APIs (python_version(), python_compiler(), etc.)
46246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.2 - fixed architecture() to use sizeof(pointer) where available
47246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.1 - added support for Caldera OpenLinux
48246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.7.0 - some fixes for WinCE; untabified the source file
49246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and
50246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            vms_lib.getsyi() configured
51246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.1 - added code to prevent 'uname -p' on platforms which are
52246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            known not to support it
53246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k;
54246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            did some cleanup of the interfaces - some APIs have changed
55246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.5 - fixed another type in the MacOS code... should have
56246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            used more coffee today ;-)
57246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.4 - fixed a few typos in the MacOS code
58246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.3 - added experimental MacOS support; added better popen()
59246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            workarounds in _syscmd_ver() -- still not 100% elegant
60246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            though
61246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.2 - fixed uname() to return '' instead of 'unknown' in all
62246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            return values (the system uname command tends to return
63246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            'unknown' instead of just leaving the field emtpy)
64246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.1 - included code for slackware dist; added exception handlers
65246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            to cover up situations where platforms don't have os.popen
66246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            (e.g. Mac) or fail on socket.gethostname(); fixed libc
67246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            detection RE
68246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.5.0 - changed the API names referring to system commands to *syscmd*;
69246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            added java_ver(); made syscmd_ver() a private
70246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            API (was system_ver() in previous versions) -- use uname()
71246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            instead; extended the win32_ver() to also return processor
72246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            type information
73246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.4.0 - added win32_ver() and modified the platform() output for WinXX
74246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.4 - fixed a bug in _follow_symlinks()
75246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.3 - fixed popen() and "file" command invokation bugs
76246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.2 - added architecture() API and support for it in platform()
77246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.1 - fixed syscmd_ver() RE to support Windows NT
78246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.3.0 - added system alias support
79246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.3 - removed 'wince' again... oh well.
80246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.2 - added 'wince' to syscmd_ver() supported platforms
81246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.1 - added cache logic and changed the platform string format
82246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.2.0 - changed the API to use functions instead of module globals
83246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#            since some action take too long to be run on module import
84246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    0.1.0 - first release
85246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
86246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    You can always get the latest version of this module at:
87246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
88246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#             http://www.egenix.com/files/python/platform.py
89246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#
90246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg#    If that URL should fail, try contacting the author.
91246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
92246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg__copyright__ = """
93246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com
94fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    Copyright (c) 2000-2007, eGenix.com Software GmbH; mailto:info@egenix.com
95246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
96246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    Permission to use, copy, modify, and distribute this software and its
97246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    documentation for any purpose and without fee or royalty is hereby granted,
98246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    provided that the above copyright notice appear in all copies and that
99246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    both that copyright notice and this permission notice appear in
100246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    supporting documentation or portions thereof, including modifications,
101246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    that you make.
102246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
103246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO
104246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
105246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
106246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
107246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
108246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
109246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE !
110246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
111246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg"""
112246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
113fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters__version__ = '1.0.6'
114246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
115246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgimport sys,string,os,re
116246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
117246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Platform specific APIs
118246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
119366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg_libc_search = re.compile(r'(__libc_init)'
120366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg                          '|'
1210eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters                          '(GLIBC_([0-9.]+))'
1220eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters                          '|'
123366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg                          '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)')
124366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg
125246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef libc_ver(executable=sys.executable,lib='',version='',
126246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
127366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg             chunksize=2048):
128246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1298ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Tries to determine the libc version that the file executable
1308ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        (which defaults to the Python interpreter) is linked against.
131246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
132246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Returns a tuple of strings (lib,version) which default to the
133246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        given parameters in case the lookup fails.
134246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
135246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that the function has intimate knowledge of how different
1368ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        libc versions add symbols to the executable and thus is probably
1378ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        only useable for executables compiled using gcc.
138246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
139246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The file is read and scanned in chunks of chunksize bytes.
140246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
141246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
142fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if hasattr(os.path, 'realpath'):
143fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # Python 2.2 introduced os.path.realpath(); it is used
144fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # here to work around problems with Cygwin not being
145fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # able to open symlinks for reading
146fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        executable = os.path.realpath(executable)
147246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    f = open(executable,'rb')
148246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    binary = f.read(chunksize)
149246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    pos = 0
150246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while 1:
151366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg        m = _libc_search.search(binary,pos)
152246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if not m:
153246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            binary = f.read(chunksize)
154246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not binary:
155246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                break
156246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            pos = 0
157246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            continue
158246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        libcinit,glibc,glibcversion,so,threads,soversion = m.groups()
159246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if libcinit and not lib:
160246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            lib = 'libc'
161246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif glibc:
162246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if lib != 'glibc':
163246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                lib = 'glibc'
164246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = glibcversion
165246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            elif glibcversion > version:
166246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = glibcversion
167246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif so:
168246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if lib != 'glibc':
169246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                lib = 'libc'
170246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                if soversion > version:
171246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = soversion
172246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                if threads and version[-len(threads):] != threads:
173246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = version + threads
174246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        pos = m.end()
175246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    f.close()
176246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return lib,version
177246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
178246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _dist_try_harder(distname,version,id):
179246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1800eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters    """ Tries some special tricks to get the distribution
181246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        information in case the default method fails.
182246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
183246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Currently supports older SuSE Linux, Caldera OpenLinux and
184246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Slackware Linux distributions.
185246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
186246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
187246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.exists('/var/adm/inst-log/info'):
188246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # SuSE Linux stores distribution information in that file
189246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        info = open('/var/adm/inst-log/info').readlines()
190246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        distname = 'SuSE'
191246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        for line in info:
192246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            tv = string.split(line)
193246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if len(tv) == 2:
194246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                tag,value = tv
195246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            else:
196246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                continue
197246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if tag == 'MIN_DIST_VERSION':
198246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = string.strip(value)
199246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            elif tag == 'DIST_IDENT':
200246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                values = string.split(value,'-')
201246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                id = values[2]
202246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return distname,version,id
203246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
204246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.exists('/etc/.installed'):
205246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Caldera OpenLinux has some infos in that file (thanks to Colin Kong)
206246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        info = open('/etc/.installed').readlines()
207246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        for line in info:
208246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            pkg = string.split(line,'-')
209246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
210246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                # XXX does Caldera support non Intel platforms ? If yes,
211246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                #     where can we find the needed id ?
212246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                return 'OpenLinux',pkg[1],id
213246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
214246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.path.isdir('/usr/lib/setup'):
215246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Check for slackware verson tag file (thanks to Greg Andruk)
216246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        verfiles = os.listdir('/usr/lib/setup')
217843c734ddda3e317eee97dfdd32ff15ceede22fcGuido van Rossum        for n in range(len(verfiles)-1, -1, -1):
218246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if verfiles[n][:14] != 'slack-version-':
219246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                del verfiles[n]
220246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if verfiles:
221246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            verfiles.sort()
222246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            distname = 'slackware'
223246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = verfiles[-1][14:]
224246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            return distname,version,id
225246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
226246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return distname,version,id
227246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
228366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg_release_filename = re.compile(r'(\w+)[-_](release|version)')
229fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_lsb_release_version = re.compile(r'(.+)'
230fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                                   ' release '
231fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                                   '([\d.]+)'
232fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                                   '[^(]*(?:\((.+)\))?')
233fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_release_version = re.compile(r'([^0-9]+)'
234fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                               '(?: release )?'
235fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                               '([\d.]+)'
236fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                               '[^(]*(?:\((.+)\))?')
237fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
238fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# See also http://www.novell.com/coolsolutions/feature/11251.html
2399fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters# and http://linuxmafia.com/faq/Admin/release-files.html
240fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://data.linux-ntfs.org/rpm/whichrpm
241fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html
242fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
243fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_supported_dists = ('SuSE', 'debian', 'fedora', 'redhat', 'centos',
244fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                    'mandrake', 'rocks', 'slackware', 'yellowdog',
245fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                    'gentoo', 'UnitedLinux')
246fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
247fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _parse_release_file(firstline):
2489fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
249fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Parse the first line
250fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    m = _lsb_release_version.match(firstline)
251fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
252fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # LSB format: "distro release x.x (codename)"
253fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return tuple(m.groups())
254fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
255fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Pre-LSB format: "distro x.x (codename)"
256fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    m = _release_version.match(firstline)
257fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
258fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return tuple(m.groups())
259fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
260fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Unkown format... take the first two words
261fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    l = string.split(string.strip(firstline))
262fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if l:
263fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version = l[0]
264fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if len(l) > 1:
265fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            id = l[1]
266fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        else:
267fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            id = ''
268fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return '', version, id
269fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
270fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _test_parse_release_file():
2719fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
272fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    for input, output in (
273fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # Examples of release file contents:
274fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('SuSE Linux 9.3 (x86-64)', ('SuSE Linux ', '9.3', 'x86-64'))
275fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('SUSE LINUX 10.1 (X86-64)', ('SUSE LINUX ', '10.1', 'X86-64'))
276fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('SUSE LINUX 10.1 (i586)', ('SUSE LINUX ', '10.1', 'i586'))
277fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('Fedora Core release 5 (Bordeaux)', ('Fedora Core', '5', 'Bordeaux'))
278fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('Red Hat Linux release 8.0 (Psyche)', ('Red Hat Linux', '8.0', 'Psyche'))
279fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('Red Hat Linux release 9 (Shrike)', ('Red Hat Linux', '9', 'Shrike'))
280fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('Red Hat Enterprise Linux release 4 (Nahant)', ('Red Hat Enterprise Linux', '4', 'Nahant'))
281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('CentOS release 4', ('CentOS', '4', None))
282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('Rocks release 4.2.1 (Cydonia)', ('Rocks', '4.2.1', 'Cydonia'))
283fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ):
284fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        parsed = _parse_release_file(input)
285fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if parsed != output:
286fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            print (input, parsed)
287fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
288fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef linux_distribution(distname='', version='', id='',
289fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
290fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                       supported_dists=_supported_dists,
291fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                       full_distribution_name=1):
292246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
2938ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Tries to determine the name of the Linux OS distribution name.
294246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
295246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function first looks for a distribution release file in
296246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        /etc and then reverts to _dist_try_harder() in case no
297246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        suitable files are found.
298246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
299fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        supported_dists may be given to define the set of Linux
300fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distributions to look for. It defaults to a list of currently
301fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        supported Linux distributions identified by their release file
302fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name.
303fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
304fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If full_distribution_name is true (default), the full
305fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distribution read from the OS is returned. Otherwise the short
306fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name taken from supported_dists is used.
307fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
3088ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        Returns a tuple (distname,version,id) which default to the
309246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        args given as parameters.
310246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
311246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
312246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
313246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        etc = os.listdir('/etc')
314246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except os.error:
315246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Probably not a Unix system
316246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return distname,version,id
317fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    etc.sort()
318246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    for file in etc:
319366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg        m = _release_filename.match(file)
320fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if m is not None:
321246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            _distname,dummy = m.groups()
322246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if _distname in supported_dists:
323246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                distname = _distname
324246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                break
325246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
326246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return _dist_try_harder(distname,version,id)
3279fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
328fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Read the first line
329fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    f = open('/etc/'+file, 'r')
330246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    firstline = f.readline()
331246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    f.close()
332fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    _distname, _version, _id = _parse_release_file(firstline)
333fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
334fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _distname and full_distribution_name:
335fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        distname = _distname
336fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _version:
337fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version = _version
338fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if _id:
339fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        id = _id
340fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return distname, version, id
341fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
342fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# To maintain backwards compatibility:
3439fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
344fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef dist(distname='',version='',id='',
345fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
346fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters         supported_dists=_supported_dists):
347fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
348fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Tries to determine the name of the Linux OS distribution name.
349fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
350fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        The function first looks for a distribution release file in
351fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        /etc and then reverts to _dist_try_harder() in case no
352fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        suitable files are found.
353fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
354fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Returns a tuple (distname,version,id) which default to the
355fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        args given as parameters.
356fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
357fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
358fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return linux_distribution(distname, version, id,
359fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                              supported_dists=supported_dists,
360fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                              full_distribution_name=0)
361246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
362246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgclass _popen:
363246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
364246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Fairly portable (alternative) popen implementation.
365246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
366246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        This is mostly needed in case os.popen() is not available, or
367246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        doesn't work as advertised, e.g. in Win9X GUI programs like
368246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        PythonWin or IDLE.
369246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
370246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Writing to the pipe is currently not supported.
371246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
372246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
373246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    tmpfile = ''
374246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    pipe = None
375246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    bufsize = None
376246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    mode = 'r'
377246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
378246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    def __init__(self,cmd,mode='r',bufsize=None):
379246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
380246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if mode != 'r':
381246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            raise ValueError,'popen()-emulation only supports read mode'
382246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import tempfile
383246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        self.tmpfile = tmpfile = tempfile.mktemp()
384246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        os.system(cmd + ' > %s' % tmpfile)
385246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        self.pipe = open(tmpfile,'rb')
386246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        self.bufsize = bufsize
387246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        self.mode = mode
388246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
389246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    def read(self):
390246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
391246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return self.pipe.read()
392246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
393246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    def readlines(self):
394246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
395246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if self.bufsize is not None:
396246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            return self.pipe.readlines()
397246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
398246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    def close(self,
399246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
400246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg              remove=os.unlink,error=os.error):
401246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
402246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if self.pipe:
403246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            rc = self.pipe.close()
404246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
405246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            rc = 255
406246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if self.tmpfile:
407246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            try:
408246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                remove(self.tmpfile)
409246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            except error:
410246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                pass
411246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return rc
412246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
413246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Alias
414246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    __del__ = close
415246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
416246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef popen(cmd, mode='r', bufsize=None):
417246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
418246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Portable popen() interface.
419246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
420246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Find a working popen implementation preferring win32pipe.popen
421246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # over os.popen over _popen
422246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    popen = None
423246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if os.environ.get('OS','') == 'Windows_NT':
424246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # On NT win32pipe should work; on Win9x it hangs due to bugs
425246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # in the MS C lib (see MS KnowledgeBase article Q150956)
426246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
427246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            import win32pipe
428246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        except ImportError:
429246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            pass
430246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
431246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            popen = win32pipe.popen
432246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if popen is None:
433246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if hasattr(os,'popen'):
434246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            popen = os.popen
435246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # Check whether it works... it doesn't in GUI programs
436246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # on Windows platforms
437246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if sys.platform == 'win32': # XXX Others too ?
438246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                try:
439246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    popen('')
440246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                except os.error:
441246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    popen = _popen
442246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
443246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            popen = _popen
444246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if bufsize is None:
445246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return popen(cmd,mode)
446246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
447246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return popen(cmd,mode,bufsize)
448246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
449fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _norm_version(version, build=''):
450246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
4518ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Normalize the version and build strings and return a single
452e5a7fad356a98f931bbe0d2c9e4b18854510c3ddWalter Dörwald        version string using the format major.minor.build (or patchlevel).
453246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
454246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    l = string.split(version,'.')
455246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if build:
456246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        l.append(build)
457246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
458246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        ints = map(int,l)
459246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ValueError:
460246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        strings = l
461246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
462246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        strings = map(str,ints)
463246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    version = string.join(strings[:3],'.')
464246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return version
465246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
466366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
467366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg                         '.*'
468366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg                         'Version ([\d.]+))')
469366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg
470fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _syscmd_ver(system='', release='', version='',
471246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
472366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg               supported_platforms=('win32','win16','dos','os2')):
473246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
474246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Tries to figure out the OS version used and returns
475246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        a tuple (system,release,version).
4760eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
477246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        It uses the "ver" shell command for this which is known
478246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        to exists on Windows, DOS and OS/2. XXX Others too ?
479246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
480246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        In case this fails, the given parameters are used as
481246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        defaults.
482246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
483246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
484246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sys.platform not in supported_platforms:
485246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return system,release,version
486246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
487246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Try some common cmd strings
488246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    for cmd in ('ver','command /c ver','cmd /c ver'):
489246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
490246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            pipe = popen(cmd)
491246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            info = pipe.read()
492246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if pipe.close():
493246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                raise os.error,'command failed'
494246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # XXX How can I supress shell errors from being written
495246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            #     to stderr ?
496b940e113bf90ff71b0ef57414ea2beea9d2a4bc0Guido van Rossum        except os.error as why:
497246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            #print 'Command %s failed: %s' % (cmd,why)
498246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            continue
499b940e113bf90ff71b0ef57414ea2beea9d2a4bc0Guido van Rossum        except IOError as why:
500246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            #print 'Command %s failed: %s' % (cmd,why)
501246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            continue
502246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
503246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            break
504246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
505246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return system,release,version
506246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
507246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Parse the output
508246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    info = string.strip(info)
509366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg    m = _ver_output.match(info)
510fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if m is not None:
511246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system,release,version = m.groups()
512246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Strip trailing dots from version and release
513246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release[-1] == '.':
514246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = release[:-1]
515246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if version[-1] == '.':
516246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = version[:-1]
517246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Normalize the version and build strings (eliminating additional
518246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # zeros)
519246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = _norm_version(version)
520246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return system,release,version
521246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
522246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _win32_getvalue(key,name,default=''):
523246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
524246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Read a value for name from the registry key.
525246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
526246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        In case this fails, default is returned.
527246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
528246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
529246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    from win32api import RegQueryValueEx
530246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
531246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return RegQueryValueEx(key,name)
532246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except:
533246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
534246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
535246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef win32_ver(release='',version='',csd='',ptype=''):
536246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
537246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Get additional version information from the Windows Registry
538246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        and return a tuple (version,csd,ptype) referring to version
539246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        number, CSD level and OS type (multi/single
540246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor).
541246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
542246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        As a hint: ptype returns 'Uniprocessor Free' on single
543246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor NT machines and 'Multiprocessor Free' on multi
544246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor machines. The 'Free' refers to the OS version being
545246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        free of debugging code. It could also state 'Checked' which
546246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        means the OS version uses debugging code, i.e. code that
547246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        checks arguments, ranges, etc. (Thomas Heller).
548246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
54947c2ab6b5446b22daa592c70cb9fc29d27e1c503Andrew M. Kuchling        Note: this function only works if Mark Hammond's win32
550246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        package is installed and obviously only runs on Win32
551246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        compatible platforms.
552246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
553246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
554246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # XXX Is there any way to find out the processor type on WinXX ?
555246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # XXX Is win32 available on Windows CE ?
55691e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    #
557246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Adapted from code posted by Karl Putland to comp.lang.python.
55891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    #
55991e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    # The mappings between reg. values and release names can be found
56091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp
561246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
562246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Import the needed APIs
563246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
564246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import win32api
565246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
566246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,version,csd,ptype
567246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    from win32api import RegQueryValueEx,RegOpenKeyEx,RegCloseKey,GetVersionEx
568246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    from win32con import HKEY_LOCAL_MACHINE,VER_PLATFORM_WIN32_NT,\
569246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                         VER_PLATFORM_WIN32_WINDOWS
570246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
571246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Find out the registry key and some general version infos
572246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    maj,min,buildno,plat,csd = GetVersionEx()
573246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF)
574246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if csd[:13] == 'Service Pack ':
575246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        csd = 'SP' + csd[13:]
576246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if plat == VER_PLATFORM_WIN32_WINDOWS:
577246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
578246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try to guess the release name
579246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if maj == 4:
580246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if min == 0:
581246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                release = '95'
58291e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 10:
583246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                release = '98'
58491e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 90:
58591e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'Me'
58691e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            else:
58791e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'postMe'
588246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif maj == 5:
589246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = '2000'
590246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif plat == VER_PLATFORM_WIN32_NT:
591246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion'
592246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if maj <= 4:
593246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = 'NT'
594246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif maj == 5:
59591e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            if min == 0:
59691e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = '2000'
59791e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 1:
59891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'XP'
59991e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            elif min == 2:
60091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = '2003Server'
60191e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg            else:
60291e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg                release = 'post2003'
603246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
604246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if not release:
605246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # E.g. Win3.1 with win32s
606246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release = '%i.%i' % (maj,min)
607246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,version,csd,ptype
608246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
609246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Open the registry key
610246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
611246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regkey)
612246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Get a value to make sure the key exists...
613246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        RegQueryValueEx(keyCurVer,'SystemRoot')
614246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except:
615246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,version,csd,ptype
6160eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
617246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Parse values
618246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #subversion = _win32_getvalue(keyCurVer,
619246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #                            'SubVersionNumber',
620246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #                            ('',1))[0]
621246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #if subversion:
622246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    #   release = release + subversion # 95a, 95b, etc.
623246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    build = _win32_getvalue(keyCurVer,
624246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                            'CurrentBuildNumber',
625246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                            ('',1))[0]
626246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    ptype = _win32_getvalue(keyCurVer,
627246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                           'CurrentType',
628246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                           (ptype,1))[0]
629246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
630246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Normalize version
631246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    version = _norm_version(version,build)
632246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
633246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Close key
634246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    RegCloseKey(keyCurVer)
635246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return release,version,csd,ptype
636246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
637246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _mac_ver_lookup(selectors,default=None):
638246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
639246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    from gestalt import gestalt
640a290e3d7c6c15454496d5a8bb163af61f99f52c0Jack Jansen    import MacOS
641246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    l = []
642246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    append = l.append
643246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    for selector in selectors:
644246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
645246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            append(gestalt(selector))
646a290e3d7c6c15454496d5a8bb163af61f99f52c0Jack Jansen        except (RuntimeError, MacOS.Error):
647246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            append(default)
648246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return l
649246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
650246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _bcd2str(bcd):
651246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
652246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return hex(bcd)[2:]
653246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
654246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef mac_ver(release='',versioninfo=('','',''),machine=''):
655246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
656246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Get MacOS version information and return it as tuple (release,
657246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        versioninfo, machine) with versioninfo being a tuple (version,
658246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        dev_stage, non_release_version).
659246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
6608ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        Entries which cannot be determined are set to the paramter values
6618ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        which default to ''. All tuple entries are strings.
662246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
663246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Thanks to Mark R. Levinson for mailing documentation links and
664246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        code examples for this function. Documentation for the
665246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        gestalt() API is available online at:
666246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
667246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg           http://www.rgaros.nl/gestalt/
668246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
669246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
670246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Check whether the version info module is available
671246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
672246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import gestalt
673a290e3d7c6c15454496d5a8bb163af61f99f52c0Jack Jansen        import MacOS
674246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
675246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,versioninfo,machine
676246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get the infos
677246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    sysv,sysu,sysa = _mac_ver_lookup(('sysv','sysu','sysa'))
678246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Decode the infos
679246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sysv:
680246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        major = (sysv & 0xFF00) >> 8
681246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        minor = (sysv & 0x00F0) >> 4
682246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        patch = (sysv & 0x000F)
683246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        release = '%s.%i.%i' % (_bcd2str(major),minor,patch)
684246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sysu:
685e2a383d062434c05b73031f0da57fe82b9da8942Guido van Rossum        major =  int((sysu & 0xFF000000) >> 24)
686246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        minor =  (sysu & 0x00F00000) >> 20
687246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bugfix = (sysu & 0x000F0000) >> 16
688246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        stage =  (sysu & 0x0000FF00) >> 8
689246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        nonrel = (sysu & 0x000000FF)
690246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = '%s.%i.%i' % (_bcd2str(major),minor,bugfix)
691246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        nonrel = _bcd2str(nonrel)
692246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        stage = {0x20:'development',
693246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                 0x40:'alpha',
694246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                 0x60:'beta',
695246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                 0x80:'final'}.get(stage,'')
696246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        versioninfo = (version,stage,nonrel)
697246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sysa:
6980eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters        machine = {0x1: '68k',
69949fd7fa4431da299196d74087df4a04f99f9c46fThomas Wouters                   0x2: 'PowerPC',
70049fd7fa4431da299196d74087df4a04f99f9c46fThomas Wouters                   0xa: 'i386'}.get(sysa,'')
701246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return release,versioninfo,machine
702246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
7039b924c690eb2de515a1eda4221e15a483c6b7316Neal Norwitzdef _java_getprop(name,default):
704246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
705246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    from java.lang import System
706246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
707fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        value = System.getProperty(name)
708fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if value is None:
709fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            return default
710fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return value
711fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    except AttributeError:
712246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
713246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
714246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')):
7150eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
7168ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Version interface for Jython.
717246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
718246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being
719246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        a tuple (vm_name,vm_release,vm_vendor) and osinfo being a
720246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        tuple (os_name,os_version,os_arch).
721246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
722246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Values which cannot be determined are set to the defaults
723246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        given as parameters (which all default to '').
724246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
725246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
726246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Import the needed APIs
727246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
728246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import java.lang
729246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
730246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return release,vendor,vminfo,osinfo
731246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
732fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vendor = _java_getprop('java.vendor', vendor)
733fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    release = _java_getprop('java.version', release)
734fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_name, vm_release, vm_vendor = vminfo
735fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_name = _java_getprop('java.vm.name', vm_name)
736fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
737fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vm_release = _java_getprop('java.vm.version', vm_release)
738fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    vminfo = vm_name, vm_release, vm_vendor
739fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_name, os_version, os_arch = osinfo
740fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_arch = _java_getprop('java.os.arch', os_arch)
741fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_name = _java_getprop('java.os.name', os_name)
742fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    os_version = _java_getprop('java.os.version', os_version)
743fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    osinfo = os_name, os_version, os_arch
744fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
745fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return release, vendor, vminfo, osinfo
746246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
747246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### System name aliasing
748246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
749246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef system_alias(system,release,version):
750246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
751246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns (system,release,version) aliased to common
752246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        marketing names used for some systems.
753246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
754246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        It also does some reordering of the information in some cases
755246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        where it would otherwise cause confusion.
756246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
757246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
758246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'Rhapsody':
759246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Apple's BSD derivative
760246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX How can we determine the marketing release number ?
761246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return 'MacOS X Server',system+release,version
762246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
763246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'SunOS':
764246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Sun's OS
765246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release < '5':
766246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # These releases use the old name SunOS
767246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            return system,release,version
768246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Modify release (marketing release = SunOS release - 3)
769246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        l = string.split(release,'.')
770246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if l:
771246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            try:
772246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                major = int(l[0])
773246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            except ValueError:
774246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                pass
775246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            else:
776246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                major = major - 3
777246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                l[0] = str(major)
778246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                release = string.join(l,'.')
779246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if release < '6':
780246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Solaris'
781246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
782246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # XXX Whatever the new SunOS marketing name is...
783246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Solaris'
784246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
785246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'IRIX64':
786246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # IRIX reports IRIX64 on platforms with 64-bit support; yet it
787246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # is really a version and not a different platform, since 32-bit
788246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # apps are also supported..
789246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = 'IRIX'
790246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if version:
791246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = version + ' (64bit)'
792246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
793246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = '64bit'
794246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
795246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system in ('win32','win16'):
796246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # In case one of the other tricks
797246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = 'Windows'
798246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
799246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return system,release,version
800246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
801246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various internal helpers
802246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
803246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _platform(*args):
804246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
805246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Helper to format the platform string in a filename
806246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        compatible format e.g. "system-version-machine".
807246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
808246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Format the platform string
809246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = string.join(
810246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        map(string.strip,
811fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            filter(len, args)),
812246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        '-')
813246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
814246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Cleanup some possible filename obstacles...
815246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    replace = string.replace
816246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,' ','_')
817246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,'/','-')
818246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,'\\','-')
819246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,':','-')
820246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,';','-')
821246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,'"','-')
822246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,'(','-')
823246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,')','-')
824246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
825246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # No need to report 'unknown' information...
826246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    platform = replace(platform,'unknown','')
827246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
828246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Fold '--'s and remove trailing '-'
829246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while 1:
830246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        cleaned = replace(platform,'--','-')
831246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if cleaned == platform:
832246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            break
833246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platform = cleaned
834246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while platform[-1] == '-':
835246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platform = platform[:-1]
836246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
837246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return platform
838246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
839246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _node(default=''):
840246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
841246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Helper to determine the node name of this machine.
842246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
843246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
844246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import socket
845246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except ImportError:
846246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # No sockets...
847246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
848246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
849246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return socket.gethostname()
850246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except socket.error:
851246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Still not working...
852246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
853246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
854246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# os.path.abspath is new in Python 1.5.2:
855246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgif not hasattr(os.path,'abspath'):
856246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
857246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    def _abspath(path,
858246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
859246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                 isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd,
860246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                 normpath=os.path.normpath):
861246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
862246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if not isabs(path):
863246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            path = join(getcwd(), path)
864246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return normpath(path)
865246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
866246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgelse:
867246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
868246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    _abspath = os.path.abspath
869246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
870246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _follow_symlinks(filepath):
871246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
872246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ In case filepath is a symlink, follow it until a
873246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        real file is reached.
874246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
875246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    filepath = _abspath(filepath)
876246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    while os.path.islink(filepath):
877246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        filepath = os.path.normpath(
878246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            os.path.join(filepath,os.readlink(filepath)))
879246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return filepath
880246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
881246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _syscmd_uname(option,default=''):
882246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
883246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Interface to the system's uname command.
884246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
885246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if sys.platform in ('dos','win32','win16','os2'):
886246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX Others too ?
887246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
888246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
889246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        f = os.popen('uname %s 2> /dev/null' % option)
890246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except (AttributeError,os.error):
891246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
892246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    output = string.strip(f.read())
893246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    rc = f.close()
894246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not output or rc:
895246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
896246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
897246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return output
898246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
899246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _syscmd_file(target,default=''):
900246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
901246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Interface to the system's file command.
902246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
903246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function uses the -b option of the file command to have it
904246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        ommit the filename in its output and if possible the -L option
905246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        to have the command follow symlinks. It returns default in
906246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        case the command should fail.
907246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
908246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
909246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    target = _follow_symlinks(target)
910246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
911246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        f = os.popen('file %s 2> /dev/null' % target)
912246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except (AttributeError,os.error):
913246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
914246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    output = string.strip(f.read())
915246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    rc = f.close()
916246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not output or rc:
917246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return default
918246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
919246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return output
920246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
921246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Information about the used architecture
922246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
923246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Default values for architecture; non-empty strings override the
924246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# defaults given as parameters
925246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_default_architecture = {
926246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    'win32': ('','WindowsPE'),
927246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    'win16': ('','Windows'),
928246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    'dos': ('','MSDOS'),
929246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg}
930246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
931366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg_architecture_split = re.compile(r'[\s,]').split
932246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
933366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburgdef architecture(executable=sys.executable,bits='',linkage=''):
934246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
935246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Queries the given executable (defaults to the Python interpreter
9368ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        binary) for various architecture information.
937246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
9388ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        Returns a tuple (bits,linkage) which contains information about
939246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        the bit architecture and the linkage format used for the
940246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        executable. Both values are returned as strings.
941246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
942246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Values that cannot be determined are returned as given by the
943246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        parameter presets. If bits is given as '', the sizeof(pointer)
944246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        (or sizeof(long) on Python version < 1.5.2) is used as
945246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        indicator for the supported pointer size.
946246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
947246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The function relies on the system's "file" command to do the
948246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        actual work. This is available on most if not all Unix
9498ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        platforms. On some non-Unix platforms where the "file" command
9508ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        does not exist and the executable is set to the Python interpreter
9518ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        binary defaults from _default_architecture are used.
952246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
953246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
954246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Use the sizeof(pointer) as default number of bits if nothing
955246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # else is given as default.
956246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not bits:
957246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        import struct
958246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        try:
959246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            size = struct.calcsize('P')
960246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        except struct.error:
961246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # Older installations can only query longs
962246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            size = struct.calcsize('l')
963246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = str(size*8) + 'bit'
9640eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
965246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get data from the 'file' system command
966fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if executable:
967fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        output = _syscmd_file(executable, '')
968fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    else:
969fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        output = ''
970246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
971246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if not output and \
972246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg       executable == sys.executable:
973246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # "file" command did not return anything; we'll try to provide
9740eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters        # some sensible defaults then...
975e2b70bcf7401477936fba99a8bf4a1f759ecc8a3Guido van Rossum        if sys.platform in _default_architecture:
976246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            b,l = _default_architecture[sys.platform]
977246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if b:
978246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                bits = b
979246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if l:
980246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                linkage = l
981246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return bits,linkage
982246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
983246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Split the output into a list of strings omitting the filename
984366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg    fileout = _architecture_split(output)[1:]
9850eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
986246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if 'executable' not in fileout:
987246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Format not supported
988246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return bits,linkage
989246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
990246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Bits
991246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if '32-bit' in fileout:
992246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = '32bit'
993246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'N32' in fileout:
994246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # On Irix only
995246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = 'n32bit'
996246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif '64-bit' in fileout:
997246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        bits = '64bit'
998246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
999246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Linkage
1000246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if 'ELF' in fileout:
1001246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'ELF'
1002246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'PE' in fileout:
1003246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # E.g. Windows uses this format
1004246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if 'Windows' in fileout:
1005246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            linkage = 'WindowsPE'
1006246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1007246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            linkage = 'PE'
1008246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'COFF' in fileout:
1009246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'COFF'
1010246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif 'MS-DOS' in fileout:
1011246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        linkage = 'MSDOS'
1012246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
1013246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # XXX the A.OUT format also falls under this class...
1014246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        pass
1015246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1016246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return bits,linkage
1017246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1018246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Portable uname() interface
10190eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
1020246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_uname_cache = None
1021246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1022246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef uname():
1023246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1024246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Fairly portable uname interface. Returns a tuple
1025246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        of strings (system,node,release,version,machine,processor)
1026246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        identifying the underlying platform.
1027246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1028246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the os.uname function this also returns
10298ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        possible processor information as an additional tuple entry.
1030246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1031246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Entries which cannot be determined are set to ''.
1032246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1033246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1034246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    global _uname_cache
1035246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1036246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if _uname_cache is not None:
1037246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        return _uname_cache
1038246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1039246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get some infos from the builtin os.uname API...
1040246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    try:
1041246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system,node,release,version,machine = os.uname()
1042246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1043246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    except AttributeError:
1044246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Hmm, no uname... we'll have to poke around the system then.
1045246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = sys.platform
1046246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        release = ''
1047246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = ''
1048246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        node = _node()
1049246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        machine = ''
1050246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor = ''
1051246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        use_syscmd_ver = 1
1052246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1053246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try win32_ver() on win32 platforms
1054246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if system == 'win32':
1055246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release,version,csd,ptype = win32_ver()
1056246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if release and version:
1057246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                use_syscmd_ver = 0
1058fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # XXX Should try to parse the PROCESSOR_* environment variables
1059fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # available on Win XP and later; see
1060fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # http://support.microsoft.com/kb/888731 and
1061fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM
10620eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
1063246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Try the 'ver' system command available on some
1064246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # platforms
1065246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if use_syscmd_ver:
1066246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system,release,version = _syscmd_ver(system)
1067cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            # Normalize system to what win32_ver() normally returns
1068cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            # (_syscmd_ver() tends to return the vendor name as well)
1069cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg            if system == 'Microsoft Windows':
1070cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg                system = 'Windows'
1071246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1072246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # In case we still don't know anything useful, we'll try to
1073246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # help ourselves
1074246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if system in ('win32','win16'):
1075246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not version:
1076246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                if system == 'win32':
1077246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = '32bit'
1078246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                else:
1079246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    version = '16bit'
1080246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Windows'
1081246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1082246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif system[:4] == 'java':
1083246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release,vendor,vminfo,osinfo = java_ver()
1084246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'Java'
1085246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            version = string.join(vminfo,', ')
1086246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not version:
1087246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = vendor
1088246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1089246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        elif os.name == 'mac':
1090246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            release,(version,stage,nonrel),machine = mac_ver()
1091246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            system = 'MacOS'
1092246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1093246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
1094246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # System specific extensions
1095246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if system == 'OpenVMS':
1096246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # OpenVMS seems to have release and version mixed up
1097246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            if not release or release == '0':
1098246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                release = version
1099246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                version = ''
1100246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # Get processor information
1101246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            try:
1102246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                import vms_lib
1103246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            except ImportError:
1104246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                pass
1105246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            else:
1106246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
1107246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                if (cpu_number >= 128):
1108246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    processor = 'Alpha'
1109246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                else:
1110246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                    processor = 'VAX'
1111246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1112246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # Get processor information from the uname system command
1113246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            processor = _syscmd_uname('-p','')
1114246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1115246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # 'unknown' is not really any useful as information; we'll convert
1116246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # it to '' which is more portable
1117246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'unknown':
1118246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system = ''
1119246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if node == 'unknown':
1120246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        node = ''
1121246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if release == 'unknown':
1122246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        release = ''
1123246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if version == 'unknown':
1124246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = ''
1125246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if machine == 'unknown':
1126246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        machine = ''
1127246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if processor == 'unknown':
1128246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor = ''
1129246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    _uname_cache = system,node,release,version,machine,processor
1130246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return _uname_cache
1131246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1132246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Direct interfaces to some of the uname() return values
1133246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1134246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef system():
1135246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1136246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
1137246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1138246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1139246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1140246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1141246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return uname()[0]
1142246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1143246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef node():
1144246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
11458ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon    """ Returns the computer's network name (which may not be fully
11468ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon        qualified)
1147246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1148246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1149246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1150246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1151246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return uname()[1]
1152246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1153246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef release():
1154246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1155246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system's release, e.g. '2.2.0' or 'NT'
1156246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1157246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1158246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1159246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1160246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return uname()[2]
1161246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1162246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef version():
1163246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1164246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the system's release version, e.g. '#3 on degas'
1165246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1166246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1167246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1168246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1169246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return uname()[3]
1170246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1171246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef machine():
1172246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1173246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the machine type, e.g. 'i386'
1174246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1175246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be determined.
1176246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1177246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1178246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return uname()[4]
1179246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1180246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef processor():
1181246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1182246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the (true) processor name, e.g. 'amdk6'
1183246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1184246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        An empty string is returned if the value cannot be
1185246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        determined. Note that many platforms do not provide this
1186246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        information or simply return the same value as for machine(),
1187246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        e.g.  NetBSD does this.
1188246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1189246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1190246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return uname()[5]
1191246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1192246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various APIs for extracting information from sys.version
1193246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1194fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_parser = re.compile(
1195fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    r'([\w.+]+)\s*'
1196fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
1197fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    '\[([^\]]+)\]?')
1198fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1199fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_jython_sys_version_parser = re.compile(
1200fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    r'([\d\.]+)')
1201fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1202fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_ironpython_sys_version_parser = re.compile(
1203fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    r'IronPython\s*'
1204fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    '([\d\.]+)'
1205fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    '(?: \(([\d\.]+)\))?'
1206fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    ' on (.NET [\d\.]+)')
1207246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1208fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_cache = {}
1209fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1210fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _sys_version(sys_version=None):
1211246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1212246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a parsed version of Python's sys.version as tuple
1213fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters       (name, version, branch, revision, buildno, builddate, compiler)
1214fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters       referring to the Python implementation name, version, branch,
1215fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters       revision, build number, build date/time as string and the compiler
1216fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters       identification string.
1217246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1218246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1219246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        for the Python version will always include the patchlevel (it
1220246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        defaults to '.0').
1221246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1222fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        The function returns empty strings for tuple entries that
1223fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        cannot be determined.
1224fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1225fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        sys_version may be given to parse an alternative version
1226fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        string, e.g. if the version was read from a different Python
1227fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        interpreter.
1228fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1229246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1230fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Get the Python version
1231fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if sys_version is None:
1232fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        sys_version = sys.version
1233246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1234fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Try the cache first
1235fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    result = _sys_version_cache.get(sys_version, None)
1236fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if result is not None:
1237fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return result
1238fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1239fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Parse it
1240fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if sys_version[:10] == 'IronPython':
1241fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # IronPython
1242fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name = 'IronPython'
1243fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        match = _ironpython_sys_version_parser.match(sys_version)
1244fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1245fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1246fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse IronPython sys.version: %s' %
1247fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1248fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version, alt_version, compiler = match.groups()
1249fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        branch = ''
1250fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        revision = ''
1251fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        buildno = ''
1252fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        builddate = ''
1253fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1254fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    elif sys.platform[:4] == 'java':
1255fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # Jython
1256fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        name = 'Jython'
1257fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        match = _jython_sys_version_parser.match(sys_version)
1258fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1259fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1260fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse Jython sys.version: %s' %
1261fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1262fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version, = match.groups()
1263fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        branch = ''
1264fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        revision = ''
1265fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        compiler = sys.platform
1266fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        buildno = ''
1267fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        builddate = ''
1268fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1269fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    else:
1270fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        # CPython
1271fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        match = _sys_version_parser.match(sys_version)
1272fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if match is None:
1273fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            raise ValueError(
1274fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                'failed to parse CPython sys.version: %s' %
1275fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters                repr(sys_version))
1276fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        version, buildno, builddate, buildtime, compiler = \
1277fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters              match.groups()
1278fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if hasattr(sys, 'subversion'):
1279fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            # sys.subversion was added in Python 2.5
1280fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            name, branch, revision = sys.subversion
1281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        else:
1282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            name = 'CPython'
1283fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            branch = ''
1284fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            revision = ''
1285fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        builddate = builddate + ' ' + buildtime
1286fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1287fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Add the patchlevel version if missing
1288246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    l = string.split(version, '.')
1289246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if len(l) == 2:
1290246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        l.append('0')
1291246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        version = string.join(l, '.')
1292fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1293fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    # Build and cache the result
1294fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    result = (name, version, branch, revision, buildno, builddate, compiler)
1295fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    _sys_version_cache[sys_version] = result
1296fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return result
1297fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1298fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _test_sys_version():
1299fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1300fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    _sys_version_cache.clear()
1301fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    for input, output in (
1302fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]',
1303fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters         ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')),
1304fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('IronPython 1.0.60816 on .NET 2.0.50727.42',
1305fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters         ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')),
1306fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42',
1307fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters         ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')),
1308fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        ):
1309fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        parsed = _sys_version(input)
1310fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if parsed != output:
1311fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters            print (input, parsed)
1312fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1313fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_implementation():
1314fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1315fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation.
1316fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1317fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Currently, the following implementations are identified:
1318fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        'CPython' (C implementation of Python),
1319fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        'IronPython' (.NET implementation of Python),
1320fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        'Jython' (Java implementation of Python).
1321fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1322fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
1323fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[0]
1324246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1325246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version():
1326246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1327246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the Python version as string 'major.minor.patchlevel'
1328246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1329246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1330246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        will always include the patchlevel (it defaults to 0).
1331246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1332246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1333fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if hasattr(sys, 'version_info'):
1334fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return '%i.%i.%i' % sys.version_info[:3]
1335fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[1]
1336246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1337246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version_tuple():
1338246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1339246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns the Python version as tuple (major, minor, patchlevel)
1340246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        of strings.
1341246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1342246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Note that unlike the Python sys.version, the returned value
1343246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        will always include the patchlevel (it defaults to 0).
1344246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1345246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1346fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    if hasattr(sys, 'version_info'):
1347fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        return sys.version_info[:3]
1348fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return tuple(string.split(_sys_version()[1], '.'))
1349fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1350fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_branch():
1351fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1352fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation
1353fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        branch.
1354fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1355fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        For CPython this is the Subversion branch from which the
1356fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Python binary was built.
1357fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1358fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If not available, an empty string is returned.
1359fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1360fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
13619fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters
1362fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[2]
1363fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1364fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_revision():
1365fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1366fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """ Returns a string identifying the Python implementation
1367fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        revision.
1368fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1369fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        For CPython this is the Subversion revision from which the
1370fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        Python binary was built.
1371fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1372fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        If not available, an empty string is returned.
1373fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters
1374fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    """
1375fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[3]
1376246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1377246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_build():
1378246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1379246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a tuple (buildno, builddate) stating the Python
1380246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        build number and date as strings.
1381246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1382246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1383fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[4:6]
1384246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1385246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_compiler():
1386246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1387246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a string identifying the compiler used for compiling
1388246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Python.
1389246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1390246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
1391fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters    return _sys_version()[6]
1392246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1393246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### The Opus Magnum of platform strings :-)
1394246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
139591e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg_platform_cache = {}
1396246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1397246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef platform(aliased=0, terse=0):
1398246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1399246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """ Returns a single string identifying the underlying platform
1400246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        with as much useful information as possible (but no more :).
14010eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
1402246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        The output is intended to be human readable rather than
1403246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        machine parseable. It may look different on different
1404246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        platforms and this is intended.
1405246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1406246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        If "aliased" is true, the function will use aliases for
1407246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        various platforms that report system names which differ from
1408246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        their common names, e.g. SunOS will be reported as
1409246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Solaris. The system_alias() function is used to implement
1410246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        this.
1411246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1412246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        Setting terse to true causes the function to return only the
1413246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        absolute minimum information needed to identify the platform.
1414246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1415246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    """
141691e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    result = _platform_cache.get((aliased, terse), None)
141791e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    if result is not None:
141891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg        return result
1419246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1420246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Get uname information and then apply platform specific cosmetics
1421246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # to it...
1422246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    system,node,release,version,machine,processor = uname()
1423246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if machine == processor:
1424246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        processor = ''
1425246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if aliased:
1426246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        system,release,version = system_alias(system,release,version)
1427246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1428246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    if system == 'Windows':
1429246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # MS platforms
1430246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        rel,vers,csd,ptype = win32_ver(version)
1431246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1432246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release)
1433246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1434246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,version,csd)
1435246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1436246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system in ('Linux',):
1437246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Linux based systems
1438246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        distname,distversion,distid = dist('')
1439246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if distname and not terse:
1440246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine,processor,
1441246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'with',
1442246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 distname,distversion,distid)
1443246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1444246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            # If the distribution name is unknown check for libc vs. glibc
1445246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            libcname,libcversion = libc_ver(sys.executable)
1446246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine,processor,
1447246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'with',
1448246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 libcname+libcversion)
1449246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'Java':
1450246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Java platforms
1451246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        r,v,vminfo,(os_name,os_version,os_arch) = java_ver()
1452fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters        if terse or not os_name:
1453246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,version)
1454246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1455246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,version,
1456246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 'on',
1457246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg                                 os_name,os_version,os_arch)
1458246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1459246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    elif system == 'MacOS':
1460246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # MacOS platforms
1461246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1462246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release)
1463246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1464246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine)
1465246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1466246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    else:
1467246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        # Generic handler
1468246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        if terse:
1469246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release)
1470246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg        else:
1471246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            bits,linkage = architecture(sys.executable)
1472246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg            platform = _platform(system,release,machine,processor,bits,linkage)
14730eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters
147491e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg    _platform_cache[(aliased, terse)] = platform
1475246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    return platform
1476246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1477246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Command line interface
1478246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg
1479246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgif __name__ == '__main__':
1480246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    # Default is to print the aliased verbose platform string
14810eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters    terse = ('terse' in sys.argv or '--terse' in sys.argv)
1482246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv)
1483246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    print platform(aliased,terse)
1484246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg    sys.exit(0)
1485