platform.py revision eb9957065acaafbf3d8ebee4770ecb13ea0c07c0
190f5ba538bf40bcf4fd41049c7bf4296d3ffc9c7Benjamin Peterson#!/usr/bin/env python3 2246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 38ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon""" This module tries to retrieve as much platform-identifying data as 4246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg possible. It makes this information available via function APIs. 5246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 6246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg If called from the command line, it prints the platform 7246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg information concatenated as single string to stdout. The output 8246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg format is useable as part of a filename. 9246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 10246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg""" 11246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# This module is maintained by Marc-Andre Lemburg <mal@egenix.com>. 12246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# If you find problems, please submit bug reports/patches via the 134ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson# Python bug tracker (http://bugs.python.org) and assign them to "lemburg". 14246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 15246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Still needed: 16246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# * more support for WinCE 17246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# * support for MS-DOS (PythonDX ?) 18246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# * support for Amiga and other still unsupported platforms running Python 19246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# * support for additional Linux distributions 20246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 218ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon# Many thanks to all those who helped adding platform-specific 22246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# checks (in no particular order): 23246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 24246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell, 25246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef 26246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg 27246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark 28246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support), 29b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower# Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter, Steve 30b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower# Dower 31246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 32246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# History: 33380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg# 34380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg# <see CVS and SVN checkin messages for history> 35380f417e15dd36e6656a4f65e9c5ccd75134b8c1Marc-André Lemburg# 36b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower# 1.0.8 - changed Windows support to read version from kernel32.dll 37e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# 1.0.7 - added DEV_NULL 38fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# 1.0.6 - added linux_distribution() 39fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# 1.0.5 - fixed Java support to allow running the module on Jython 40fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# 1.0.4 - added IronPython support 41cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg# 1.0.3 - added normalization of Windows system name 4291e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg# 1.0.2 - added more Windows support 43366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg# 1.0.1 - reformatted to make doc.py happy 44246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 1.0.0 - reformatted a bit and checked into Python CVS 45246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.8.0 - added sys.version parser and various new access 46246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# APIs (python_version(), python_compiler(), etc.) 47246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.7.2 - fixed architecture() to use sizeof(pointer) where available 48246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.7.1 - added support for Caldera OpenLinux 49246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.7.0 - some fixes for WinCE; untabified the source file 50246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and 51246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# vms_lib.getsyi() configured 52246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.6.1 - added code to prevent 'uname -p' on platforms which are 53246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# known not to support it 54246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k; 55246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# did some cleanup of the interfaces - some APIs have changed 56246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.5.5 - fixed another type in the MacOS code... should have 57246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# used more coffee today ;-) 58246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.5.4 - fixed a few typos in the MacOS code 59246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.5.3 - added experimental MacOS support; added better popen() 60246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# workarounds in _syscmd_ver() -- still not 100% elegant 61246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# though 62246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.5.2 - fixed uname() to return '' instead of 'unknown' in all 63246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# return values (the system uname command tends to return 64eb9957065acaafbf3d8ebee4770ecb13ea0c07c0Martin Panter# 'unknown' instead of just leaving the field empty) 65246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.5.1 - included code for slackware dist; added exception handlers 66246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# to cover up situations where platforms don't have os.popen 67246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# (e.g. Mac) or fail on socket.gethostname(); fixed libc 68246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# detection RE 69246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.5.0 - changed the API names referring to system commands to *syscmd*; 70246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# added java_ver(); made syscmd_ver() a private 71246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# API (was system_ver() in previous versions) -- use uname() 72246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# instead; extended the win32_ver() to also return processor 73246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# type information 74246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.4.0 - added win32_ver() and modified the platform() output for WinXX 75246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.3.4 - fixed a bug in _follow_symlinks() 76246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.3.3 - fixed popen() and "file" command invokation bugs 77246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.3.2 - added architecture() API and support for it in platform() 78246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.3.1 - fixed syscmd_ver() RE to support Windows NT 79246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.3.0 - added system alias support 80246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.2.3 - removed 'wince' again... oh well. 81246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.2.2 - added 'wince' to syscmd_ver() supported platforms 82246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.2.1 - added cache logic and changed the platform string format 83246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.2.0 - changed the API to use functions instead of module globals 84246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# since some action take too long to be run on module import 85246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 0.1.0 - first release 86246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 87246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# You can always get the latest version of this module at: 88246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 89246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# http://www.egenix.com/files/python/platform.py 90246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# 91246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# If that URL should fail, try contacting the author. 92246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 93246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg__copyright__ = """ 94246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com 9546a9900e099a82cda7328b0de16d6fffe52ee62aBenjamin Peterson Copyright (c) 2000-2010, eGenix.com Software GmbH; mailto:info@egenix.com 96246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 97246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Permission to use, copy, modify, and distribute this software and its 98246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg documentation for any purpose and without fee or royalty is hereby granted, 99246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg provided that the above copyright notice appear in all copies and that 100246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg both that copyright notice and this permission notice appear in 101246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg supporting documentation or portions thereof, including modifications, 102246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg that you make. 103246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 104246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO 105246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 106246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, 107246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 108246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 109246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 110246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg WITH THE USE OR PERFORMANCE OF THIS SOFTWARE ! 111246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 112246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg""" 113246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 114e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti__version__ = '1.0.7' 115246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 11668386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastingsimport collections 117fc990e942fb55be78e8352f4913749e91cac381dJesus Ceaimport sys, os, re, subprocess 118246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1191392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksagimport warnings 1201392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag 121e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti### Globals & Constants 122e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti 123e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Determine the platform's /dev/null device 124e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalottitry: 125e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti DEV_NULL = os.devnull 126e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalottiexcept AttributeError: 127e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti # os.devnull was added in Python 2.4, so emulate it for earlier 128e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti # Python versions 129ced3936894cec493b93c1144c543d51048268288Victor Stinner if sys.platform in ('dos', 'win32', 'win16'): 130e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti # Use the old CP/M NUL as device name 131e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti DEV_NULL = 'NUL' 132e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti else: 133e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti # Standard Unix uses /dev/null 134e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti DEV_NULL = '/dev/null' 135e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti 136620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner# Directory to search for configuration information on Unix. 137620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner# Constant used by test_platform to test linux_distribution(). 138620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner_UNIXCONFDIR = '/etc' 139620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner 140246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Platform specific APIs 141246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 142ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou_libc_search = re.compile(b'(__libc_init)' 143ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou b'|' 144ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou b'(GLIBC_([0-9.]+))' 145ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou b'|' 146ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII) 147366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg 148ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef libc_ver(executable=sys.executable, lib='', version='', 149246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 150ba7c226095703f63c78b00e56f1db8d99ac3a54aAntoine Pitrou chunksize=16384): 151246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1528ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon """ Tries to determine the libc version that the file executable 1538ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon (which defaults to the Python interpreter) is linked against. 154246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 155246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Returns a tuple of strings (lib,version) which default to the 156246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg given parameters in case the lookup fails. 157246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 158246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Note that the function has intimate knowledge of how different 1598ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon libc versions add symbols to the executable and thus is probably 1608ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon only useable for executables compiled using gcc. 161246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 162246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg The file is read and scanned in chunks of chunksize bytes. 163246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 164246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 165fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if hasattr(os.path, 'realpath'): 166fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Python 2.2 introduced os.path.realpath(); it is used 167fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # here to work around problems with Cygwin not being 168fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # able to open symlinks for reading 169fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters executable = os.path.realpath(executable) 17046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka with open(executable, 'rb') as f: 17146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka binary = f.read(chunksize) 17246ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka pos = 0 17346ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka while 1: 17446ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if b'libc' in binary or b'GLIBC' in binary: 17546ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka m = _libc_search.search(binary, pos) 17646ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka else: 17746ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka m = None 17846ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if not m: 17946ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka binary = f.read(chunksize) 18046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if not binary: 18146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka break 18246ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka pos = 0 18346ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka continue 18446ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka libcinit, glibc, glibcversion, so, threads, soversion = [ 18546ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka s.decode('latin1') if s is not None else s 18646ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka for s in m.groups()] 18746ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if libcinit and not lib: 188246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg lib = 'libc' 18946ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka elif glibc: 19046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if lib != 'glibc': 19146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka lib = 'glibc' 19246ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka version = glibcversion 19346ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka elif glibcversion > version: 19446ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka version = glibcversion 19546ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka elif so: 19646ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if lib != 'glibc': 19746ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka lib = 'libc' 19846ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if soversion and soversion > version: 19946ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka version = soversion 20046ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka if threads and version[-len(threads):] != threads: 20146ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka version = version + threads 20246ba6c8563922f043cad6423202ee0119614c807Serhiy Storchaka pos = m.end() 203ced3936894cec493b93c1144c543d51048268288Victor Stinner return lib, version 204246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 205ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _dist_try_harder(distname, version, id): 206246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 2070eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters """ Tries some special tricks to get the distribution 208246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg information in case the default method fails. 209246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 210246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Currently supports older SuSE Linux, Caldera OpenLinux and 211246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Slackware Linux distributions. 212246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 213246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 214246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if os.path.exists('/var/adm/inst-log/info'): 215246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # SuSE Linux stores distribution information in that file 216246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg distname = 'SuSE' 2177dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna for line in open('/var/adm/inst-log/info'): 2189d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz tv = line.split() 219246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if len(tv) == 2: 220ced3936894cec493b93c1144c543d51048268288Victor Stinner tag, value = tv 221246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 222246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg continue 223246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if tag == 'MIN_DIST_VERSION': 2249d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz version = value.strip() 225246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif tag == 'DIST_IDENT': 2269d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz values = value.split('-') 227246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg id = values[2] 228ced3936894cec493b93c1144c543d51048268288Victor Stinner return distname, version, id 229246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 230246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if os.path.exists('/etc/.installed'): 231246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Caldera OpenLinux has some infos in that file (thanks to Colin Kong) 2327dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna for line in open('/etc/.installed'): 2339d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz pkg = line.split('-') 234246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if len(pkg) >= 2 and pkg[0] == 'OpenLinux': 235246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # XXX does Caldera support non Intel platforms ? If yes, 236246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # where can we find the needed id ? 237ced3936894cec493b93c1144c543d51048268288Victor Stinner return 'OpenLinux', pkg[1], id 238246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 239246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if os.path.isdir('/usr/lib/setup'): 24030b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti # Check for slackware version tag file (thanks to Greg Andruk) 241246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg verfiles = os.listdir('/usr/lib/setup') 242843c734ddda3e317eee97dfdd32ff15ceede22fcGuido van Rossum for n in range(len(verfiles)-1, -1, -1): 243246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if verfiles[n][:14] != 'slack-version-': 244246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg del verfiles[n] 245246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if verfiles: 246246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg verfiles.sort() 247246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg distname = 'slackware' 248246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = verfiles[-1][14:] 249ced3936894cec493b93c1144c543d51048268288Victor Stinner return distname, version, id 250246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 251ced3936894cec493b93c1144c543d51048268288Victor Stinner return distname, version, id 252246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 253fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou_release_filename = re.compile(r'(\w+)[-_](release|version)', re.ASCII) 254fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_lsb_release_version = re.compile(r'(.+)' 255fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters ' release ' 256fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters '([\d.]+)' 257fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou '[^(]*(?:\((.+)\))?', re.ASCII) 258fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_release_version = re.compile(r'([^0-9]+)' 259fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters '(?: release )?' 260fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters '([\d.]+)' 261fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou '[^(]*(?:\((.+)\))?', re.ASCII) 262fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 263fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# See also http://www.novell.com/coolsolutions/feature/11251.html 2649fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters# and http://linuxmafia.com/faq/Admin/release-files.html 265fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://data.linux-ntfs.org/rpm/whichrpm 266fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html 267fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 268dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes_supported_dists = ( 269dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes 'SuSE', 'debian', 'fedora', 'redhat', 'centos', 270dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes 'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo', 271ab88803a8addf36ae3fc7e9270ebbed869f7f191Antoine Pitrou 'UnitedLinux', 'turbolinux', 'arch', 'mageia') 272fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 273fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _parse_release_file(firstline): 2749fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters 275250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson # Default to empty 'version' and 'id' strings. Both defaults are used 276250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson # when 'firstline' is empty. 'id' defaults to empty when an id can not 277250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson # be deduced. 278250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson version = '' 279250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson id = '' 280250014793e9ed7d6cfc6e25ac502bcb124895d23Benjamin Peterson 281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Parse the first line 282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters m = _lsb_release_version.match(firstline) 283fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if m is not None: 284fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # LSB format: "distro release x.x (codename)" 285fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return tuple(m.groups()) 286fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 287fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Pre-LSB format: "distro x.x (codename)" 288fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters m = _release_version.match(firstline) 289fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if m is not None: 290fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return tuple(m.groups()) 291fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 29230b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti # Unknown format... take the first two words 2939d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz l = firstline.strip().split() 294fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if l: 295fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters version = l[0] 296fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if len(l) > 1: 297fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters id = l[1] 298fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return '', version, id 299fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 300fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef linux_distribution(distname='', version='', id='', 301fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 302fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters supported_dists=_supported_dists, 303fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters full_distribution_name=1): 3042f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag import warnings 3052f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag warnings.warn("dist() and linux_distribution() functions are deprecated " 3068d8221f0d674ea032337a82d1ad1d0d146510390Berker Peksag "in Python 3.5", PendingDeprecationWarning, stacklevel=2) 3072f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag return _linux_distribution(distname, version, id, supported_dists, 3082f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag full_distribution_name) 3092f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag 3102f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksagdef _linux_distribution(distname, version, id, supported_dists, 3112f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag full_distribution_name): 312246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 3138ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon """ Tries to determine the name of the Linux OS distribution name. 314246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 315246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg The function first looks for a distribution release file in 316246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg /etc and then reverts to _dist_try_harder() in case no 317246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg suitable files are found. 318246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 319fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters supported_dists may be given to define the set of Linux 320fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters distributions to look for. It defaults to a list of currently 321fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters supported Linux distributions identified by their release file 322fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters name. 323fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 324fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters If full_distribution_name is true (default), the full 325fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters distribution read from the OS is returned. Otherwise the short 326fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters name taken from supported_dists is used. 327fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 328ced3936894cec493b93c1144c543d51048268288Victor Stinner Returns a tuple (distname, version, id) which default to the 329246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg args given as parameters. 330246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 331246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 332246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 333620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner etc = os.listdir(_UNIXCONFDIR) 334ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov except OSError: 335246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Probably not a Unix system 336ced3936894cec493b93c1144c543d51048268288Victor Stinner return distname, version, id 337fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters etc.sort() 338246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg for file in etc: 339366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg m = _release_filename.match(file) 340fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if m is not None: 341ced3936894cec493b93c1144c543d51048268288Victor Stinner _distname, dummy = m.groups() 342246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if _distname in supported_dists: 343246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg distname = _distname 344246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg break 345246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 346ced3936894cec493b93c1144c543d51048268288Victor Stinner return _dist_try_harder(distname, version, id) 3479fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters 348fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Read the first line 349620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner with open(os.path.join(_UNIXCONFDIR, file), 'r', 350620c48b7ea7a1ad3af23725afdac1e6a2b3e6cefVictor Stinner encoding='utf-8', errors='surrogateescape') as f: 3517dde792e62c8adeaf5d633dc89e18d16067add8eFlorent Xicluna firstline = f.readline() 352fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters _distname, _version, _id = _parse_release_file(firstline) 353fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 354fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if _distname and full_distribution_name: 355fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters distname = _distname 356fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if _version: 357fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters version = _version 358fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if _id: 359fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters id = _id 360fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return distname, version, id 361fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 362fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters# To maintain backwards compatibility: 3639fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters 364ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef dist(distname='', version='', id='', 365fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 366fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters supported_dists=_supported_dists): 367fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 368fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ Tries to determine the name of the Linux OS distribution name. 369fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 370fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters The function first looks for a distribution release file in 371fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters /etc and then reverts to _dist_try_harder() in case no 372fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters suitable files are found. 373fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 374ced3936894cec493b93c1144c543d51048268288Victor Stinner Returns a tuple (distname, version, id) which default to the 375fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters args given as parameters. 376fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 377fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ 3782f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag import warnings 3792f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag warnings.warn("dist() and linux_distribution() functions are deprecated " 3808d8221f0d674ea032337a82d1ad1d0d146510390Berker Peksag "in Python 3.5", PendingDeprecationWarning, stacklevel=2) 3812f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag return _linux_distribution(distname, version, id, 3822f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag supported_dists=supported_dists, 3832f3742b0d8dbe025f2f9e496938a6d344e6881adBerker Peksag full_distribution_name=0) 384246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 385877766dee8e60c7971ed0cabba89fbe981c2ab1bAntoine Pitroudef popen(cmd, mode='r', bufsize=-1): 386246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 387246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Portable popen() interface. 388246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 38925000d4d31dfa5842776aa92f234ea6672489c67Victor Stinner import warnings 39025000d4d31dfa5842776aa92f234ea6672489c67Victor Stinner warnings.warn('use os.popen instead', DeprecationWarning, stacklevel=2) 3911dfd3803064f2ee4b6e0bae3c60ca39e5f3919caVictor Stinner return os.popen(cmd, mode, bufsize) 392246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 393fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _norm_version(version, build=''): 394246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 3958ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon """ Normalize the version and build strings and return a single 396e5a7fad356a98f931bbe0d2c9e4b18854510c3ddWalter Dörwald version string using the format major.minor.build (or patchlevel). 397246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 3989d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz l = version.split('.') 399246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if build: 400246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg l.append(build) 401246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 402ced3936894cec493b93c1144c543d51048268288Victor Stinner ints = map(int, l) 403246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg except ValueError: 404246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg strings = l 405246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 406ced3936894cec493b93c1144c543d51048268288Victor Stinner strings = list(map(str, ints)) 4079d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz version = '.'.join(strings[:3]) 408246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return version 409246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 410366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' 411366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg '.*' 412e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti '\[.* ([\d.]+)\])') 413e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti 414e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Examples of VER command output: 415e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# 416e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Windows 2000: Microsoft Windows 2000 [Version 5.00.2195] 417e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Windows XP: Microsoft Windows XP [Version 5.1.2600] 418e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Windows Vista: Microsoft Windows [Version 6.0.6002] 419e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# 420e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Note that the "Version" string gets localized on different 421e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti# Windows versions. 422366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg 423fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _syscmd_ver(system='', release='', version='', 424246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 425ced3936894cec493b93c1144c543d51048268288Victor Stinner supported_platforms=('win32', 'win16', 'dos')): 426246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 427246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Tries to figure out the OS version used and returns 428ced3936894cec493b93c1144c543d51048268288Victor Stinner a tuple (system, release, version). 4290eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters 430246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg It uses the "ver" shell command for this which is known 431f1af7057208da7b3d15703645688fea971a4fb5eJesus Cea to exists on Windows, DOS. XXX Others too ? 432246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 433246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg In case this fails, the given parameters are used as 434246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg defaults. 435246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 436246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 437246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if sys.platform not in supported_platforms: 438ced3936894cec493b93c1144c543d51048268288Victor Stinner return system, release, version 439246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 440246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Try some common cmd strings 441ced3936894cec493b93c1144c543d51048268288Victor Stinner for cmd in ('ver', 'command /c ver', 'cmd /c ver'): 442246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 443cae101f5ecd8fee38a37ce8fa46c141cd8a522efSteve Dower pipe = os.popen(cmd) 444246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg info = pipe.read() 445246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if pipe.close(): 446ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov raise OSError('command failed') 44713925008dc11f2a235627dc8c0440c0ce99171d9Ezio Melotti # XXX How can I suppress shell errors from being written 448246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # to stderr ? 449ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov except OSError as why: 450ced3936894cec493b93c1144c543d51048268288Victor Stinner #print 'Command %s failed: %s' % (cmd, why) 451246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg continue 452246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 453246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg break 454246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 455ced3936894cec493b93c1144c543d51048268288Victor Stinner return system, release, version 456246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 457246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Parse the output 4589d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz info = info.strip() 459366a0feb9a7794a9f72ab0b37d36b6427e6d3bd1Marc-André Lemburg m = _ver_output.match(info) 460fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if m is not None: 461ced3936894cec493b93c1144c543d51048268288Victor Stinner system, release, version = m.groups() 462246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Strip trailing dots from version and release 463246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if release[-1] == '.': 464246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg release = release[:-1] 465246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if version[-1] == '.': 466246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = version[:-1] 467246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Normalize the version and build strings (eliminating additional 468246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # zeros) 469246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = _norm_version(version) 470ced3936894cec493b93c1144c543d51048268288Victor Stinner return system, release, version 471246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 472b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower_WIN32_CLIENT_RELEASES = { 473b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (5, 0): "2000", 474b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (5, 1): "XP", 475b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # Strictly, 5.2 client is XP 64-bit, but platform.py historically 476b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # has always called it 2003 Server 477b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (5, 2): "2003Server", 478b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (5, None): "post2003", 479b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 480b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 0): "Vista", 481b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 1): "7", 482b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 2): "8", 483b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 3): "8.1", 484b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, None): "post8.1", 485b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 486b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (10, 0): "10", 487b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (10, None): "post10", 488b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower} 489b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 490b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower# Server release name lookup will default to client names if necessary 491b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower_WIN32_SERVER_RELEASES = { 492b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (5, 2): "2003Server", 493b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 494b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 0): "2008Server", 495b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 1): "2008ServerR2", 496b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 2): "2012Server", 497b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, 3): "2012ServerR2", 498b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower (6, None): "post2012ServerR2", 499b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower} 500b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 501b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dowerdef _get_real_winver(maj, min, build): 502b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if maj < 6 or (maj == 6 and min < 2): 503b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower return maj, min, build 504b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 505b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower from ctypes import (c_buffer, POINTER, byref, create_unicode_buffer, 506b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower Structure, WinDLL) 507b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower from ctypes.wintypes import DWORD, HANDLE 508b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 509b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower class VS_FIXEDFILEINFO(Structure): 510b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower _fields_ = [ 511b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwSignature", DWORD), 512b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwStrucVersion", DWORD), 513b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileVersionMS", DWORD), 514b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileVersionLS", DWORD), 515b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwProductVersionMS", DWORD), 516b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwProductVersionLS", DWORD), 517b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileFlagsMask", DWORD), 518b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileFlags", DWORD), 519b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileOS", DWORD), 520b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileType", DWORD), 521b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileSubtype", DWORD), 522b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileDateMS", DWORD), 523b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ("dwFileDateLS", DWORD), 524b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ] 525b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 526b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower kernel32 = WinDLL('kernel32') 527b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower version = WinDLL('version') 528b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 529b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # We will immediately double the length up to MAX_PATH, but the 530b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # path may be longer, so we retry until the returned string is 531b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # shorter than our buffer. 532b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower name_len = actual_len = 130 533b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower while actual_len == name_len: 534b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower name_len *= 2 535b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower name = create_unicode_buffer(name_len) 536b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower actual_len = kernel32.GetModuleFileNameW(HANDLE(kernel32._handle), 537b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower name, len(name)) 538b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if not actual_len: 539b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower return maj, min, build 540b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 541b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower size = version.GetFileVersionInfoSizeW(name, None) 542b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if not size: 543b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower return maj, min, build 544b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 545b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ver_block = c_buffer(size) 546b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if (not version.GetFileVersionInfoW(name, None, size, ver_block) or 547b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower not ver_block): 548b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower return maj, min, build 549b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 550b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower pvi = POINTER(VS_FIXEDFILEINFO)() 551b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if not version.VerQueryValueW(ver_block, "", byref(pvi), byref(DWORD())): 552b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower return maj, min, build 553b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 554b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower maj = pvi.contents.dwProductVersionMS >> 16 555b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower min = pvi.contents.dwProductVersionMS & 0xFFFF 556b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower build = pvi.contents.dwProductVersionLS >> 16 557b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 558b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower return maj, min, build 559246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 560b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dowerdef win32_ver(release='', version='', csd='', ptype=''): 5618f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower try: 5628f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower from sys import getwindowsversion 5638f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower except ImportError: 5648f278f166255bb02dbee21e98689bb2fed58b3dfSteve Dower return release, version, csd, ptype 56502781dc7541b79e499c06ead64535c317efc460eChristian Heimes try: 566b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower from winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE 567cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon except ImportError: 568b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower from _winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE 569246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 570b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower winver = getwindowsversion() 571b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower maj, min, build = _get_real_winver(*winver[:3]) 572b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower version = '{0}.{1}.{2}'.format(maj, min, build) 573246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 574b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower release = (_WIN32_CLIENT_RELEASES.get((maj, min)) or 575b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower _WIN32_CLIENT_RELEASES.get((maj, None)) or 576b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower release) 577246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 578b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # getwindowsversion() reflect the compatibility mode Python is 579b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # running under, and so the service pack value is only going to be 580b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # valid if the versions match. 581b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if winver[:2] == (maj, min): 58202781dc7541b79e499c06ead64535c317efc460eChristian Heimes try: 583b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower csd = 'SP{}'.format(winver.service_pack_major) 58402781dc7541b79e499c06ead64535c317efc460eChristian Heimes except AttributeError: 585b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if csd[:13] == 'Service Pack ': 586b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower csd = 'SP' + csd[13:] 587e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti 588b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower # VER_NT_SERVER = 3 589126c9c17efedc6f69d5d86de4b660f3b44e635e4Steve Dower if getattr(winver, 'product', None) == 3: 590b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower release = (_WIN32_SERVER_RELEASES.get((maj, min)) or 591b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower _WIN32_SERVER_RELEASES.get((maj, None)) or 592b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower release) 593246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 594b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower key = None 595246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 596b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower key = OpenKeyEx(HKEY_LOCAL_MACHINE, 597b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower r'SOFTWARE\Microsoft\Windows NT\CurrentVersion') 598b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower ptype = QueryValueEx(key, 'CurrentType')[0] 599246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg except: 600b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower pass 601b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower finally: 602b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower if key: 603b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower CloseKey(key) 604b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 605ced3936894cec493b93c1144c543d51048268288Victor Stinner return release, version, csd, ptype 606246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 607b9f4feab1b9c9ffa8ea29af3d82bc536f9f3005aSteve Dower 608e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussorendef _mac_ver_xml(): 609e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren fn = '/System/Library/CoreServices/SystemVersion.plist' 610e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren if not os.path.exists(fn): 611e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren return None 612e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 613e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren try: 614e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren import plistlib 615cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon except ImportError: 616e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren return None 617e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 618936dfae2e22b5b58d01416ddf47218c20bfde5e6Ned Deily with open(fn, 'rb') as f: 619936dfae2e22b5b58d01416ddf47218c20bfde5e6Ned Deily pl = plistlib.load(f) 620e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren release = pl['ProductVersion'] 621ced3936894cec493b93c1144c543d51048268288Victor Stinner versioninfo = ('', '', '') 622605a62ddb1c19978ee194a40a458f072e3242a31Larry Hastings machine = os.uname().machine 623fcd77016b31ea9fb5311695f5ca82cf6c235da87Ronald Oussoren if machine in ('ppc', 'Power Macintosh'): 6249a3777e525b389ec5881c3f80a482fb821ab3ea5Ezio Melotti # Canonical name 625e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren machine = 'PowerPC' 626e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 627ced3936894cec493b93c1144c543d51048268288Victor Stinner return release, versioninfo, machine 628e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 629e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 630ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef mac_ver(release='', versioninfo=('', '', ''), machine=''): 631e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 632e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren """ Get MacOS version information and return it as tuple (release, 633e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren versioninfo, machine) with versioninfo being a tuple (version, 634e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren dev_stage, non_release_version). 635e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 63630b9d5d3af043fc2687ad11a188a34fe355e20efEzio Melotti Entries which cannot be determined are set to the parameter values 637e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren which default to ''. All tuple entries are strings. 638e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren """ 639e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 640e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren # First try reading the information from an XML file which should 641e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren # always be present 642e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren info = _mac_ver_xml() 643e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren if info is not None: 644e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren return info 645e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren 646e186e384f4fb11158b448d94f37aaf2a3ed6b45eRonald Oussoren # If that also doesn't work return the default values 647ced3936894cec493b93c1144c543d51048268288Victor Stinner return release, versioninfo, machine 648246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 649ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _java_getprop(name, default): 650246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 651246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg from java.lang import System 652246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 653fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters value = System.getProperty(name) 654fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if value is None: 655fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return default 656fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return value 657fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters except AttributeError: 658246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 659246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 660ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', '')): 6610eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters 6628ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon """ Version interface for Jython. 663246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 664ced3936894cec493b93c1144c543d51048268288Victor Stinner Returns a tuple (release, vendor, vminfo, osinfo) with vminfo being 665ced3936894cec493b93c1144c543d51048268288Victor Stinner a tuple (vm_name, vm_release, vm_vendor) and osinfo being a 666ced3936894cec493b93c1144c543d51048268288Victor Stinner tuple (os_name, os_version, os_arch). 667246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 668246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Values which cannot be determined are set to the defaults 669246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg given as parameters (which all default to ''). 670246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 671246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 672246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Import the needed APIs 673246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 674246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg import java.lang 675cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon except ImportError: 676ced3936894cec493b93c1144c543d51048268288Victor Stinner return release, vendor, vminfo, osinfo 677246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 678fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters vendor = _java_getprop('java.vendor', vendor) 679fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters release = _java_getprop('java.version', release) 680fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters vm_name, vm_release, vm_vendor = vminfo 681fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters vm_name = _java_getprop('java.vm.name', vm_name) 682fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters vm_vendor = _java_getprop('java.vm.vendor', vm_vendor) 683fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters vm_release = _java_getprop('java.vm.version', vm_release) 684fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters vminfo = vm_name, vm_release, vm_vendor 685fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters os_name, os_version, os_arch = osinfo 686fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters os_arch = _java_getprop('java.os.arch', os_arch) 687fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters os_name = _java_getprop('java.os.name', os_name) 688fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters os_version = _java_getprop('java.os.version', os_version) 689fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters osinfo = os_name, os_version, os_arch 690fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 691fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return release, vendor, vminfo, osinfo 692246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 693246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### System name aliasing 694246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 695ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef system_alias(system, release, version): 696246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 697ced3936894cec493b93c1144c543d51048268288Victor Stinner """ Returns (system, release, version) aliased to common 698246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg marketing names used for some systems. 699246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 700246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg It also does some reordering of the information in some cases 701246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg where it would otherwise cause confusion. 702246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 703246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 704246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if system == 'Rhapsody': 705246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Apple's BSD derivative 706246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # XXX How can we determine the marketing release number ? 707ced3936894cec493b93c1144c543d51048268288Victor Stinner return 'MacOS X Server', system+release, version 708246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 709246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif system == 'SunOS': 710246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Sun's OS 711246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if release < '5': 712246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # These releases use the old name SunOS 713ced3936894cec493b93c1144c543d51048268288Victor Stinner return system, release, version 714246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Modify release (marketing release = SunOS release - 3) 7159d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz l = release.split('.') 716246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if l: 717246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 718246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg major = int(l[0]) 719246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg except ValueError: 720246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg pass 721246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 722246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg major = major - 3 723246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg l[0] = str(major) 7249d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz release = '.'.join(l) 725246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if release < '6': 726246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg system = 'Solaris' 727246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 728246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # XXX Whatever the new SunOS marketing name is... 729246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg system = 'Solaris' 730246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 731246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif system == 'IRIX64': 732246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # IRIX reports IRIX64 on platforms with 64-bit support; yet it 733246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # is really a version and not a different platform, since 32-bit 734246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # apps are also supported.. 735246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg system = 'IRIX' 736246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if version: 737246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = version + ' (64bit)' 738246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 739246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = '64bit' 740246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 741ced3936894cec493b93c1144c543d51048268288Victor Stinner elif system in ('win32', 'win16'): 742246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # In case one of the other tricks 743246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg system = 'Windows' 744246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 745ced3936894cec493b93c1144c543d51048268288Victor Stinner return system, release, version 746246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 747246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various internal helpers 748246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 749246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _platform(*args): 750246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 751246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Helper to format the platform string in a filename 752246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg compatible format e.g. "system-version-machine". 753246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 754246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Format the platform string 7559d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz platform = '-'.join(x.strip() for x in filter(len, args)) 756246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 757246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Cleanup some possible filename obstacles... 758ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace(' ', '_') 759ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace('/', '-') 760ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace('\\', '-') 761ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace(':', '-') 762ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace(';', '-') 763ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace('"', '-') 764ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace('(', '-') 765ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace(')', '-') 766246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 767246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # No need to report 'unknown' information... 768ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = platform.replace('unknown', '') 769246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 770246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Fold '--'s and remove trailing '-' 771246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg while 1: 772ced3936894cec493b93c1144c543d51048268288Victor Stinner cleaned = platform.replace('--', '-') 773246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if cleaned == platform: 774246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg break 775246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg platform = cleaned 776246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg while platform[-1] == '-': 777246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg platform = platform[:-1] 778246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 779246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return platform 780246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 781246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _node(default=''): 782246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 783246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Helper to determine the node name of this machine. 784246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 785246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 786246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg import socket 787cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon except ImportError: 788246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # No sockets... 789246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 790246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 791246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return socket.gethostname() 7920832af6628ca5ac02d0226899725297dd508470bAndrew Svetlov except OSError: 793246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Still not working... 794246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 795246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 796246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef _follow_symlinks(filepath): 797246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 798246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ In case filepath is a symlink, follow it until a 799246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg real file is reached. 800246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 801673f7efa08850e42d077cab38683be2e4764b876Georg Brandl filepath = os.path.abspath(filepath) 802246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg while os.path.islink(filepath): 803246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg filepath = os.path.normpath( 804ced3936894cec493b93c1144c543d51048268288Victor Stinner os.path.join(os.path.dirname(filepath), os.readlink(filepath))) 805246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return filepath 806246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 807ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _syscmd_uname(option, default=''): 808246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 809246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Interface to the system's uname command. 810246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 811ced3936894cec493b93c1144c543d51048268288Victor Stinner if sys.platform in ('dos', 'win32', 'win16'): 812246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # XXX Others too ? 813246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 814246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 815e52e3786c67e16b7b8adba71227f9e3c5350d7a6Alexandre Vassalotti f = os.popen('uname %s 2> %s' % (option, DEV_NULL)) 816ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov except (AttributeError, OSError): 817246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 8189d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz output = f.read().strip() 819246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg rc = f.close() 820246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if not output or rc: 821246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 822246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 823246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return output 824246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 825ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef _syscmd_file(target, default=''): 826246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 827246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Interface to the system's file command. 828246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 829246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg The function uses the -b option of the file command to have it 830ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner omit the filename in its output. Follow the symlinks. It returns 831ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner default in case the command should fail. 832246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 833246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 834ced3936894cec493b93c1144c543d51048268288Victor Stinner if sys.platform in ('dos', 'win32', 'win16'): 835d26782e8639df937fac1ef3f208986274138d5c1Hirokazu Yamamoto # XXX Others too ? 836d26782e8639df937fac1ef3f208986274138d5c1Hirokazu Yamamoto return default 837fc990e942fb55be78e8352f4913749e91cac381dJesus Cea target = _follow_symlinks(target) 838246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 839685fffa8f427b3a768b232170752565d58c32112Jesus Cea proc = subprocess.Popen(['file', target], 840685fffa8f427b3a768b232170752565d58c32112Jesus Cea stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 841e8801e2e44b4ffcfdfc6e2857e7afc90ba6abc38Jesus Cea 842ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov except (AttributeError, OSError): 843246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 844cb95996fdc6956365642dd42f86dfb380f923fa5Jesus Cea output = proc.communicate()[0].decode('latin-1') 845fc990e942fb55be78e8352f4913749e91cac381dJesus Cea rc = proc.wait() 846246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if not output or rc: 847246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return default 848246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 849246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return output 850246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 851246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Information about the used architecture 852246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 853246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# Default values for architecture; non-empty strings override the 854246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg# defaults given as parameters 855246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_default_architecture = { 856ced3936894cec493b93c1144c543d51048268288Victor Stinner 'win32': ('', 'WindowsPE'), 857ced3936894cec493b93c1144c543d51048268288Victor Stinner 'win16': ('', 'Windows'), 858ced3936894cec493b93c1144c543d51048268288Victor Stinner 'dos': ('', 'MSDOS'), 859246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg} 860246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 861ced3936894cec493b93c1144c543d51048268288Victor Stinnerdef architecture(executable=sys.executable, bits='', linkage=''): 862246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 863246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Queries the given executable (defaults to the Python interpreter 8648ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon binary) for various architecture information. 865246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 866ced3936894cec493b93c1144c543d51048268288Victor Stinner Returns a tuple (bits, linkage) which contains information about 867246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg the bit architecture and the linkage format used for the 868246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg executable. Both values are returned as strings. 869246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 870246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Values that cannot be determined are returned as given by the 871246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg parameter presets. If bits is given as '', the sizeof(pointer) 872246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg (or sizeof(long) on Python version < 1.5.2) is used as 873246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg indicator for the supported pointer size. 874246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 875246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg The function relies on the system's "file" command to do the 876246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg actual work. This is available on most if not all Unix 8778ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon platforms. On some non-Unix platforms where the "file" command 8788ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon does not exist and the executable is set to the Python interpreter 8798ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon binary defaults from _default_architecture are used. 880246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 881246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 882246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Use the sizeof(pointer) as default number of bits if nothing 883246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # else is given as default. 884246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if not bits: 885246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg import struct 886246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 887246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg size = struct.calcsize('P') 888246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg except struct.error: 889246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Older installations can only query longs 890246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg size = struct.calcsize('l') 891246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg bits = str(size*8) + 'bit' 8920eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters 893246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Get data from the 'file' system command 894fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if executable: 895ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner fileout = _syscmd_file(executable, '') 896fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters else: 897ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner fileout = '' 898246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 899ddfb2c3a338a8c1550774648f816e96c41f59de1Victor Stinner if not fileout and \ 900246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg executable == sys.executable: 901246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # "file" command did not return anything; we'll try to provide 9020eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters # some sensible defaults then... 903e2b70bcf7401477936fba99a8bf4a1f759ecc8a3Guido van Rossum if sys.platform in _default_architecture: 904ced3936894cec493b93c1144c543d51048268288Victor Stinner b, l = _default_architecture[sys.platform] 905246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if b: 906246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg bits = b 907246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if l: 908246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg linkage = l 909ced3936894cec493b93c1144c543d51048268288Victor Stinner return bits, linkage 910246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 911246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if 'executable' not in fileout: 912246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Format not supported 913ced3936894cec493b93c1144c543d51048268288Victor Stinner return bits, linkage 914246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 915246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Bits 916246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if '32-bit' in fileout: 917246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg bits = '32bit' 918246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif 'N32' in fileout: 919246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # On Irix only 920246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg bits = 'n32bit' 921246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif '64-bit' in fileout: 922246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg bits = '64bit' 923246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 924246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Linkage 925246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if 'ELF' in fileout: 926246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg linkage = 'ELF' 927246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif 'PE' in fileout: 928246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # E.g. Windows uses this format 929246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if 'Windows' in fileout: 930246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg linkage = 'WindowsPE' 931246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 932246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg linkage = 'PE' 933246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif 'COFF' in fileout: 934246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg linkage = 'COFF' 935246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif 'MS-DOS' in fileout: 936246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg linkage = 'MSDOS' 937246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 938246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # XXX the A.OUT format also falls under this class... 939246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg pass 940246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 941ced3936894cec493b93c1144c543d51048268288Victor Stinner return bits, linkage 942246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 943246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Portable uname() interface 9440eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters 94568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastingsuname_result = collections.namedtuple("uname_result", 94668386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings "system node release version machine processor") 94768386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings 948246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg_uname_cache = None 949246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 950246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef uname(): 951246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 952246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Fairly portable uname interface. Returns a tuple 953ced3936894cec493b93c1144c543d51048268288Victor Stinner of strings (system, node, release, version, machine, processor) 954246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg identifying the underlying platform. 955246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 956246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Note that unlike the os.uname function this also returns 9578ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon possible processor information as an additional tuple entry. 958246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 959246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Entries which cannot be determined are set to ''. 960246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 961246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 962246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg global _uname_cache 96335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc no_os_uname = 0 964246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 965246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if _uname_cache is not None: 966246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return _uname_cache 967246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 96835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc processor = '' 96935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc 970246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Get some infos from the builtin os.uname API... 971246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg try: 972ced3936894cec493b93c1144c543d51048268288Victor Stinner system, node, release, version, machine = os.uname() 973246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg except AttributeError: 97435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc no_os_uname = 1 97535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc 97662e2ca219311a111873892910ad441659faeaefaGeorg Brandl if no_os_uname or not list(filter(None, (system, node, release, version, machine))): 97735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc # Hmm, no there is either no uname or uname has returned 97835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc #'unknowns'... we'll have to poke around the system then. 97935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc if no_os_uname: 98035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc system = sys.platform 98135c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc release = '' 98235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc version = '' 98335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc node = _node() 98435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc machine = '' 98535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc 9867a01984aba532b731dd6a06610b0ce523bef4f5eAmaury Forgeot d'Arc use_syscmd_ver = 1 987246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 988246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Try win32_ver() on win32 platforms 989246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if system == 'win32': 990ced3936894cec493b93c1144c543d51048268288Victor Stinner release, version, csd, ptype = win32_ver() 991246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if release and version: 992246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg use_syscmd_ver = 0 99302781dc7541b79e499c06ead64535c317efc460eChristian Heimes # Try to use the PROCESSOR_* environment variables 994fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # available on Win XP and later; see 995fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # http://support.microsoft.com/kb/888731 and 996fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM 99735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc if not machine: 998ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray # WOW64 processes mask the native architecture 999ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray if "PROCESSOR_ARCHITEW6432" in os.environ: 1000ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray machine = os.environ.get("PROCESSOR_ARCHITEW6432", '') 1001ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray else: 1002ca2edce67695b73e21a64a352632feedc08ccf29R. David Murray machine = os.environ.get('PROCESSOR_ARCHITECTURE', '') 100335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc if not processor: 100435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc processor = os.environ.get('PROCESSOR_IDENTIFIER', machine) 10050eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters 1006246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Try the 'ver' system command available on some 1007246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # platforms 1008246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if use_syscmd_ver: 1009ced3936894cec493b93c1144c543d51048268288Victor Stinner system, release, version = _syscmd_ver(system) 1010cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg # Normalize system to what win32_ver() normally returns 1011cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg # (_syscmd_ver() tends to return the vendor name as well) 1012cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg if system == 'Microsoft Windows': 1013cdc7923f6d1c9731d81f299569b1ea72de7eb212Marc-André Lemburg system = 'Windows' 1014cd16bf640405065e4702539632ce577536207d88Guido van Rossum elif system == 'Microsoft' and release == 'Windows': 1015cd16bf640405065e4702539632ce577536207d88Guido van Rossum # Under Windows Vista and Windows Server 2008, 1016cd16bf640405065e4702539632ce577536207d88Guido van Rossum # Microsoft changed the output of the ver command. The 1017cd16bf640405065e4702539632ce577536207d88Guido van Rossum # release is no longer printed. This causes the 1018cd16bf640405065e4702539632ce577536207d88Guido van Rossum # system and release to be misidentified. 1019cd16bf640405065e4702539632ce577536207d88Guido van Rossum system = 'Windows' 1020cd16bf640405065e4702539632ce577536207d88Guido van Rossum if '6.0' == version[:3]: 1021cd16bf640405065e4702539632ce577536207d88Guido van Rossum release = 'Vista' 1022cd16bf640405065e4702539632ce577536207d88Guido van Rossum else: 1023cd16bf640405065e4702539632ce577536207d88Guido van Rossum release = '' 1024246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1025246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # In case we still don't know anything useful, we'll try to 1026246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # help ourselves 1027ced3936894cec493b93c1144c543d51048268288Victor Stinner if system in ('win32', 'win16'): 1028246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if not version: 1029246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if system == 'win32': 1030246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = '32bit' 1031246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1032246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = '16bit' 1033246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg system = 'Windows' 1034246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1035246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif system[:4] == 'java': 1036ced3936894cec493b93c1144c543d51048268288Victor Stinner release, vendor, vminfo, osinfo = java_ver() 1037246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg system = 'Java' 10389d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz version = ', '.join(vminfo) 1039246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if not version: 1040246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = vendor 1041246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 104235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc # System specific extensions 104335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc if system == 'OpenVMS': 104435c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc # OpenVMS seems to have release and version mixed up 104535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc if not release or release == '0': 104635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc release = version 104735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc version = '' 104835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc # Get processor information 104935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc try: 105035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc import vms_lib 1051cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannon except ImportError: 105235c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc pass 1053246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1054ced3936894cec493b93c1144c543d51048268288Victor Stinner csid, cpu_number = vms_lib.getsyi('SYI$_CPU', 0) 105535c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc if (cpu_number >= 128): 105635c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc processor = 'Alpha' 105735c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc else: 105835c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc processor = 'VAX' 105935c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc if not processor: 106035c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc # Get processor information from the uname system command 1061ced3936894cec493b93c1144c543d51048268288Victor Stinner processor = _syscmd_uname('-p', '') 1062246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 106335c8658a74d9b51c6c4755514b02fe3f9d6bb6b8Amaury Forgeot d'Arc #If any unknowns still exist, replace them with ''s, which are more portable 1064246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if system == 'unknown': 1065246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg system = '' 1066246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if node == 'unknown': 1067246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg node = '' 1068246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if release == 'unknown': 1069246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg release = '' 1070246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if version == 'unknown': 1071246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg version = '' 1072246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if machine == 'unknown': 1073246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg machine = '' 1074246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if processor == 'unknown': 1075246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg processor = '' 10761b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters 10771b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters # normalize name 10781b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters if system == 'Microsoft' and release == 'Windows': 10791b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters system = 'Windows' 10801b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters release = 'Vista' 10811b7f891f416830d0c46ca1c9e1bfe62f05cda655Thomas Wouters 1082ced3936894cec493b93c1144c543d51048268288Victor Stinner _uname_cache = uname_result(system, node, release, version, 1083ced3936894cec493b93c1144c543d51048268288Victor Stinner machine, processor) 1084246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return _uname_cache 1085246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1086246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Direct interfaces to some of the uname() return values 1087246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1088246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef system(): 1089246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1090246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'. 1091246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1092246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg An empty string is returned if the value cannot be determined. 1093246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1094246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 109568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings return uname().system 1096246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1097246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef node(): 1098246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 10998ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon """ Returns the computer's network name (which may not be fully 11008ab27dfa135dc1f3f3f156db2ae5e13c46eeb5a4Brett Cannon qualified) 1101246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1102246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg An empty string is returned if the value cannot be determined. 1103246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1104246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 110568386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings return uname().node 1106246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1107246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef release(): 1108246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1109246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns the system's release, e.g. '2.2.0' or 'NT' 1110246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1111246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg An empty string is returned if the value cannot be determined. 1112246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1113246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 111468386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings return uname().release 1115246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1116246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef version(): 1117246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1118246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns the system's release version, e.g. '#3 on degas' 1119246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1120246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg An empty string is returned if the value cannot be determined. 1121246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1122246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 112368386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings return uname().version 1124246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1125246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef machine(): 1126246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1127246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns the machine type, e.g. 'i386' 1128246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1129246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg An empty string is returned if the value cannot be determined. 1130246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1131246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 113268386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings return uname().machine 1133246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1134246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef processor(): 1135246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1136246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns the (true) processor name, e.g. 'amdk6' 1137246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1138246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg An empty string is returned if the value cannot be 1139246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg determined. Note that many platforms do not provide this 1140246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg information or simply return the same value as for machine(), 1141246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg e.g. NetBSD does this. 1142246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1143246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 114468386bc0b88eb4b7c9aeb4f753114dc85f8df5b6Larry Hastings return uname().processor 1145246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1146246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Various APIs for extracting information from sys.version 1147246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1148fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_parser = re.compile( 11494e50553823c16a65d80f6734b4ac303c18640380Martin Panter r'([\w.+]+)\s*' # "version<space>" 11504e50553823c16a65d80f6734b4ac303c18640380Martin Panter r'\(#?([^,]+)' # "(#buildno" 11514e50553823c16a65d80f6734b4ac303c18640380Martin Panter r'(?:,\s*([\w ]*)' # ", builddate" 11524e50553823c16a65d80f6734b4ac303c18640380Martin Panter r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)<space>" 11534e50553823c16a65d80f6734b4ac303c18640380Martin Panter r'\[([^\]]+)\]?', re.ASCII) # "[compiler]" 1154fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1155fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_ironpython_sys_version_parser = re.compile( 1156fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters r'IronPython\s*' 1157fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters '([\d\.]+)' 1158fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters '(?: \(([\d\.]+)\))?' 1159fd036451bf0e0ade8783e21df801abf7be96d020Antoine Pitrou ' on (.NET [\d\.]+)', re.ASCII) 1160246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1161f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti# IronPython covering 2.6 and 2.7 1162f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti_ironpython26_sys_version_parser = re.compile( 1163f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti r'([\d.]+)\s*' 1164f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti '\(IronPython\s*' 1165f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti '[\d.]+\s*' 1166f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti '\(([\d.]+)\) on ([\w.]+ [\d.]+(?: \(\d+-bit\))?)\)' 1167f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti) 1168f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti 1169e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson_pypy_sys_version_parser = re.compile( 1170e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson r'([\w.+]+)\s*' 1171e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' 1172e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson '\[PyPy [^\]]+\]?') 1173e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson 1174fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters_sys_version_cache = {} 1175fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1176fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef _sys_version(sys_version=None): 1177246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1178246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns a parsed version of Python's sys.version as tuple 11795f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson (name, version, branch, revision, buildno, builddate, compiler) 11805f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson referring to the Python implementation name, version, branch, 11815f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson revision, build number, build date/time as string and the compiler 11825f28b7b7978ad96fef83e2b41017bdd7ab8a082fBenjamin Peterson identification string. 1183246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1184246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Note that unlike the Python sys.version, the returned value 1185246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg for the Python version will always include the patchlevel (it 1186246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg defaults to '.0'). 1187246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1188fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters The function returns empty strings for tuple entries that 1189fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters cannot be determined. 1190fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1191fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters sys_version may be given to parse an alternative version 1192fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters string, e.g. if the version was read from a different Python 1193fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters interpreter. 1194fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1195246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 1196fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Get the Python version 1197fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if sys_version is None: 1198fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters sys_version = sys.version 1199246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1200fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Try the cache first 1201fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters result = _sys_version_cache.get(sys_version, None) 1202fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if result is not None: 1203fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return result 1204fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1205fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Parse it 1206f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti if 'IronPython' in sys_version: 1207fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # IronPython 1208fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters name = 'IronPython' 1209f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti if sys_version.startswith('IronPython'): 1210f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti match = _ironpython_sys_version_parser.match(sys_version) 1211f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti else: 1212f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti match = _ironpython26_sys_version_parser.match(sys_version) 1213f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti 1214fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if match is None: 1215fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters raise ValueError( 1216fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 'failed to parse IronPython sys.version: %s' % 1217fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters repr(sys_version)) 1218f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti 1219fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters version, alt_version, compiler = match.groups() 1220fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters buildno = '' 1221fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters builddate = '' 1222fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1223f076f53386c422060517b8f088eadff3a80e48e6Ezio Melotti elif sys.platform.startswith('java'): 1224fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Jython 1225fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters name = 'Jython' 1226e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson match = _sys_version_parser.match(sys_version) 1227fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if match is None: 1228fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters raise ValueError( 1229fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 'failed to parse Jython sys.version: %s' % 1230fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters repr(sys_version)) 1231e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson version, buildno, builddate, buildtime, _ = match.groups() 12324e50553823c16a65d80f6734b4ac303c18640380Martin Panter if builddate is None: 12334e50553823c16a65d80f6734b4ac303c18640380Martin Panter builddate = '' 1234fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters compiler = sys.platform 1235e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson 1236e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson elif "PyPy" in sys_version: 1237e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson # PyPy 1238e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson name = "PyPy" 1239e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson match = _pypy_sys_version_parser.match(sys_version) 1240e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson if match is None: 1241e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson raise ValueError("failed to parse PyPy sys.version: %s" % 1242e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson repr(sys_version)) 1243e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson version, buildno, builddate, buildtime = match.groups() 1244e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson compiler = "" 1245fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1246fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters else: 1247fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # CPython 1248fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters match = _sys_version_parser.match(sys_version) 1249fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if match is None: 1250fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters raise ValueError( 1251fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 'failed to parse CPython sys.version: %s' % 1252fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters repr(sys_version)) 1253fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters version, buildno, builddate, buildtime, compiler = \ 1254fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters match.groups() 1255e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson name = 'CPython' 12564e50553823c16a65d80f6734b4ac303c18640380Martin Panter if builddate is None: 12574e50553823c16a65d80f6734b4ac303c18640380Martin Panter builddate = '' 12584e50553823c16a65d80f6734b4ac303c18640380Martin Panter elif buildtime: 12594e50553823c16a65d80f6734b4ac303c18640380Martin Panter builddate = builddate + ' ' + buildtime 1260fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 12618256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl if hasattr(sys, '_mercurial'): 12628256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl _, branch, revision = sys._mercurial 12638256242b30005b8a1b52e79149558ad36f1307d6Georg Brandl elif hasattr(sys, 'subversion'): 1264e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson # sys.subversion was added in Python 2.5 1265e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson _, branch, revision = sys.subversion 1266e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson else: 1267e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson branch = '' 1268e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson revision = '' 1269e549ead8263819ac47f60cdd0239592750888f0bBenjamin Peterson 1270fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Add the patchlevel version if missing 12719d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz l = version.split('.') 1272246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if len(l) == 2: 1273246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg l.append('0') 12749d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz version = '.'.join(l) 1275fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1276fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters # Build and cache the result 1277fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters result = (name, version, branch, revision, buildno, builddate, compiler) 1278fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters _sys_version_cache[sys_version] = result 1279fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return result 1280fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1281fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_implementation(): 1282fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1283fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ Returns a string identifying the Python implementation. 1284fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1285fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters Currently, the following implementations are identified: 1286f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti 'CPython' (C implementation of Python), 1287f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti 'IronPython' (.NET implementation of Python), 1288f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti 'Jython' (Java implementation of Python), 1289f16898bc80fafeaf025606ea00e841c310b8df39Ezio Melotti 'PyPy' (Python implementation of Python). 1290fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1291fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ 1292fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return _sys_version()[0] 1293246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1294246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version(): 1295246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1296246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns the Python version as string 'major.minor.patchlevel' 1297246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1298246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Note that unlike the Python sys.version, the returned value 1299246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg will always include the patchlevel (it defaults to 0). 1300246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1301246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 1302fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return _sys_version()[1] 1303246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1304246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_version_tuple(): 1305246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1306246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns the Python version as tuple (major, minor, patchlevel) 1307246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg of strings. 1308246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1309246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Note that unlike the Python sys.version, the returned value 1310246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg will always include the patchlevel (it defaults to 0). 1311246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1312246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 13139d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz return tuple(_sys_version()[1].split('.')) 1314fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1315fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_branch(): 1316fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1317fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ Returns a string identifying the Python implementation 1318fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters branch. 1319fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1320fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters For CPython this is the Subversion branch from which the 1321fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters Python binary was built. 1322fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1323fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters If not available, an empty string is returned. 1324fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1325fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ 13269fe394c1be9401c2b207b943f82e30af4ee32ab6Thomas Wouters 1327fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return _sys_version()[2] 1328fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1329fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Woutersdef python_revision(): 1330fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1331fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ Returns a string identifying the Python implementation 1332fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters revision. 1333fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1334fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters For CPython this is the Subversion revision from which the 1335fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters Python binary was built. 1336fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1337fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters If not available, an empty string is returned. 1338fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1339fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ 1340fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return _sys_version()[3] 1341246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1342246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_build(): 1343246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1344246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns a tuple (buildno, builddate) stating the Python 1345246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg build number and date as strings. 1346246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1347246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 1348fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return _sys_version()[4:6] 1349246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1350246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef python_compiler(): 1351246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1352246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns a string identifying the compiler used for compiling 1353246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Python. 1354246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1355246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 1356fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters return _sys_version()[6] 1357246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1358246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### The Opus Magnum of platform strings :-) 1359246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 136091e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg_platform_cache = {} 1361246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1362246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgdef platform(aliased=0, terse=0): 1363246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1364246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ Returns a single string identifying the underlying platform 1365246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg with as much useful information as possible (but no more :). 13660eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters 1367246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg The output is intended to be human readable rather than 1368246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg machine parseable. It may look different on different 1369246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg platforms and this is intended. 1370246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1371246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg If "aliased" is true, the function will use aliases for 1372246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg various platforms that report system names which differ from 1373246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg their common names, e.g. SunOS will be reported as 1374246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Solaris. The system_alias() function is used to implement 1375246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg this. 1376246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1377246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg Setting terse to true causes the function to return only the 1378246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg absolute minimum information needed to identify the platform. 1379246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1380246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg """ 138191e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg result = _platform_cache.get((aliased, terse), None) 138291e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg if result is not None: 138391e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg return result 1384246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1385246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Get uname information and then apply platform specific cosmetics 1386246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # to it... 1387ced3936894cec493b93c1144c543d51048268288Victor Stinner system, node, release, version, machine, processor = uname() 1388246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if machine == processor: 1389246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg processor = '' 1390246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if aliased: 1391ced3936894cec493b93c1144c543d51048268288Victor Stinner system, release, version = system_alias(system, release, version) 1392246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1393246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if system == 'Windows': 1394246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # MS platforms 1395ced3936894cec493b93c1144c543d51048268288Victor Stinner rel, vers, csd, ptype = win32_ver(version) 1396246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if terse: 1397ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release) 1398246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1399ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release, version, csd) 1400246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1401246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif system in ('Linux',): 1402246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Linux based systems 14031392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag with warnings.catch_warnings(): 14041392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag # see issue #1322 for more information 14051392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag warnings.filterwarnings( 14061392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag 'ignore', 14071392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag 'dist\(\) and linux_distribution\(\) ' 14081392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag 'functions are deprecated .*', 14091392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag PendingDeprecationWarning, 14101392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag ) 14111392f71c3927c9d81969200f5dfff9fb832cde0bBerker Peksag distname, distversion, distid = dist('') 1412246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if distname and not terse: 1413ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release, machine, processor, 1414246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 'with', 1415ced3936894cec493b93c1144c543d51048268288Victor Stinner distname, distversion, distid) 1416246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1417246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # If the distribution name is unknown check for libc vs. glibc 1418ced3936894cec493b93c1144c543d51048268288Victor Stinner libcname, libcversion = libc_ver(sys.executable) 1419ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release, machine, processor, 1420246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 'with', 1421246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg libcname+libcversion) 1422246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif system == 'Java': 1423246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Java platforms 1424ced3936894cec493b93c1144c543d51048268288Victor Stinner r, v, vminfo, (os_name, os_version, os_arch) = java_ver() 1425fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters if terse or not os_name: 1426ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release, version) 1427246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1428ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release, version, 1429246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 'on', 1430ced3936894cec493b93c1144c543d51048268288Victor Stinner os_name, os_version, os_arch) 1431246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1432246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg elif system == 'MacOS': 1433246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # MacOS platforms 1434246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if terse: 1435ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release) 1436246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1437ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release, machine) 1438246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1439246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1440246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Generic handler 1441246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg if terse: 1442ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release) 1443246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg else: 1444ced3936894cec493b93c1144c543d51048268288Victor Stinner bits, linkage = architecture(sys.executable) 1445ced3936894cec493b93c1144c543d51048268288Victor Stinner platform = _platform(system, release, machine, 1446ced3936894cec493b93c1144c543d51048268288Victor Stinner processor, bits, linkage) 14470eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters 144891e83e209d66d4b7a892c9360f9e524d6e282191Marc-André Lemburg _platform_cache[(aliased, terse)] = platform 1449246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg return platform 1450246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1451246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg### Command line interface 1452246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg 1453246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburgif __name__ == '__main__': 1454246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg # Default is to print the aliased verbose platform string 14550eadaac7dc3ae49974c105ff9e8c1e98a04d7d5aTim Peters terse = ('terse' in sys.argv or '--terse' in sys.argv) 1456246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv) 1457ced3936894cec493b93c1144c543d51048268288Victor Stinner print(platform(aliased, terse)) 1458246d847475d041a823dbc3cc3aceae46e97de937Marc-André Lemburg sys.exit(0) 1459