diff options
Diffstat (limited to 'Lib/platform.py')
| -rwxr-xr-x | Lib/platform.py | 198 |
1 files changed, 73 insertions, 125 deletions
diff --git a/Lib/platform.py b/Lib/platform.py index c0016a8..686a045 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ This module tries to retrieve as much platform-identifying data as possible. It makes this information available via function APIs. @@ -12,8 +12,6 @@ # If you find problems, please submit bug reports/patches via the # Python bug tracker (http://bugs.python.org) and assign them to "lemburg". # -# Note: Please keep this module compatible to Python 1.5.2. -# # Still needed: # * more support for WinCE # * support for MS-DOS (PythonDX ?) @@ -113,7 +111,7 @@ __copyright__ = """ __version__ = '1.0.7' -import sys,string,os,re +import sys, os, re, subprocess ### Globals & Constants @@ -136,7 +134,7 @@ _libc_search = re.compile(r'(__libc_init)' '|' '(GLIBC_([0-9.]+))' '|' - '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)') + '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII) def libc_ver(executable=sys.executable,lib='',version='', @@ -161,12 +159,12 @@ def libc_ver(executable=sys.executable,lib='',version='', # able to open symlinks for reading executable = os.path.realpath(executable) f = open(executable,'rb') - binary = f.read(chunksize) + binary = f.read(chunksize).decode('latin-1') pos = 0 while 1: m = _libc_search.search(binary,pos) if not m: - binary = f.read(chunksize) + binary = f.read(chunksize).decode('latin-1') if not binary: break pos = 0 @@ -202,26 +200,24 @@ def _dist_try_harder(distname,version,id): """ if os.path.exists('/var/adm/inst-log/info'): # SuSE Linux stores distribution information in that file - info = open('/var/adm/inst-log/info').readlines() distname = 'SuSE' - for line in info: - tv = string.split(line) + for line in open('/var/adm/inst-log/info'): + tv = line.split() if len(tv) == 2: tag,value = tv else: continue if tag == 'MIN_DIST_VERSION': - version = string.strip(value) + version = value.strip() elif tag == 'DIST_IDENT': - values = string.split(value,'-') + values = value.split('-') id = values[2] return distname,version,id if os.path.exists('/etc/.installed'): # Caldera OpenLinux has some infos in that file (thanks to Colin Kong) - info = open('/etc/.installed').readlines() - for line in info: - pkg = string.split(line,'-') + for line in open('/etc/.installed'): + pkg = line.split('-') if len(pkg) >= 2 and pkg[0] == 'OpenLinux': # XXX does Caldera support non Intel platforms ? If yes, # where can we find the needed id ? @@ -241,15 +237,15 @@ def _dist_try_harder(distname,version,id): return distname,version,id -_release_filename = re.compile(r'(\w+)[-_](release|version)') +_release_filename = re.compile(r'(\w+)[-_](release|version)', re.ASCII) _lsb_release_version = re.compile(r'(.+)' ' release ' '([\d.]+)' - '[^(]*(?:\((.+)\))?') + '[^(]*(?:\((.+)\))?', re.ASCII) _release_version = re.compile(r'([^0-9]+)' '(?: release )?' '([\d.]+)' - '[^(]*(?:\((.+)\))?') + '[^(]*(?:\((.+)\))?', re.ASCII) # See also http://www.novell.com/coolsolutions/feature/11251.html # and http://linuxmafia.com/faq/Admin/release-files.html @@ -281,7 +277,7 @@ def _parse_release_file(firstline): return tuple(m.groups()) # Unkown format... take the first two words - l = string.split(string.strip(firstline)) + l = firstline.strip().split() if l: version = l[0] if len(l) > 1: @@ -329,9 +325,8 @@ def linux_distribution(distname='', version='', id='', return _dist_try_harder(distname,version,id) # Read the first line - f = open('/etc/'+file, 'r') - firstline = f.readline() - f.close() + with open('/etc/'+file, 'r') as f: + firstline = f.readline() _distname, _version, _id = _parse_release_file(firstline) if _distname and full_distribution_name: @@ -381,7 +376,7 @@ class _popen: def __init__(self,cmd,mode='r',bufsize=None): if mode != 'r': - raise ValueError,'popen()-emulation only supports read mode' + raise ValueError('popen()-emulation only supports read mode') import tempfile self.tmpfile = tmpfile = tempfile.mktemp() os.system(cmd + ' > %s' % tmpfile) @@ -416,7 +411,7 @@ class _popen: # Alias __del__ = close -def popen(cmd, mode='r', bufsize=None): +def popen(cmd, mode='r', bufsize=-1): """ Portable popen() interface. """ @@ -454,7 +449,7 @@ def _norm_version(version, build=''): """ Normalize the version and build strings and return a single version string using the format major.minor.build (or patchlevel). """ - l = string.split(version,'.') + l = version.split('.') if build: l.append(build) try: @@ -462,8 +457,8 @@ def _norm_version(version, build=''): except ValueError: strings = l else: - strings = map(str,ints) - version = string.join(strings[:3],'.') + strings = list(map(str,ints)) + version = '.'.join(strings[:3]) return version _ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' @@ -502,13 +497,13 @@ def _syscmd_ver(system='', release='', version='', pipe = popen(cmd) info = pipe.read() if pipe.close(): - raise os.error,'command failed' + raise os.error('command failed') # XXX How can I suppress shell errors from being written # to stderr ? - except os.error,why: + except os.error as why: #print 'Command %s failed: %s' % (cmd,why) continue - except IOError,why: + except IOError as why: #print 'Command %s failed: %s' % (cmd,why) continue else: @@ -517,7 +512,7 @@ def _syscmd_ver(system='', release='', version='', return system,release,version # Parse the output - info = string.strip(info) + info = info.strip() m = _ver_output.match(info) if m is not None: system,release,version = m.groups() @@ -542,9 +537,9 @@ def _win32_getvalue(key,name,default=''): # Use win32api if available from win32api import RegQueryValueEx except ImportError: - # On Python 2.0 and later, emulate using _winreg - import _winreg - RegQueryValueEx = _winreg.QueryValueEx + # On Python 2.0 and later, emulate using winreg + import winreg + RegQueryValueEx = winreg.QueryValueEx try: return RegQueryValueEx(key,name) except: @@ -592,14 +587,14 @@ def win32_ver(release='',version='',csd='',ptype=''): # No emulation possible, so return the defaults... return release,version,csd,ptype else: - # Emulation using _winreg (added in Python 2.0) and + # Emulation using winreg (added in Python 2.0) and # sys.getwindowsversion() (added in Python 2.3) - import _winreg + import winreg GetVersionEx = sys.getwindowsversion - RegQueryValueEx = _winreg.QueryValueEx - RegOpenKeyEx = _winreg.OpenKeyEx - RegCloseKey = _winreg.CloseKey - HKEY_LOCAL_MACHINE = _winreg.HKEY_LOCAL_MACHINE + RegQueryValueEx = winreg.QueryValueEx + RegOpenKeyEx = winreg.OpenKeyEx + RegCloseKey = winreg.CloseKey + HKEY_LOCAL_MACHINE = winreg.HKEY_LOCAL_MACHINE VER_PLATFORM_WIN32_WINDOWS = 1 VER_PLATFORM_WIN32_NT = 2 VER_NT_WORKSTATION = 1 @@ -717,14 +712,13 @@ def win32_ver(release='',version='',csd='',ptype=''): def _mac_ver_lookup(selectors,default=None): - from gestalt import gestalt - import MacOS + from _gestalt import gestalt l = [] append = l.append for selector in selectors: try: append(gestalt(selector)) - except (RuntimeError, MacOS.Error): + except (RuntimeError, OSError): append(default) return l @@ -742,12 +736,11 @@ def _mac_ver_gestalt(): """ # Check whether the version info module is available try: - import gestalt - import MacOS + import _gestalt except ImportError: return None # Get the infos - sysv,sysa = _mac_ver_lookup(('sysv','sysa')) + sysv, sysa = _mac_ver_lookup(('sysv','sysa')) # Decode the infos if sysv: major = (sysv & 0xFF00) >> 8 @@ -885,7 +878,7 @@ def system_alias(system,release,version): # These releases use the old name SunOS return system,release,version # Modify release (marketing release = SunOS release - 3) - l = string.split(release,'.') + l = release.split('.') if l: try: major = int(l[0]) @@ -894,7 +887,7 @@ def system_alias(system,release,version): else: major = major - 3 l[0] = str(major) - release = string.join(l,'.') + release = '.'.join(l) if release < '6': system = 'Solaris' else: @@ -925,28 +918,24 @@ def _platform(*args): compatible format e.g. "system-version-machine". """ # Format the platform string - platform = string.join( - map(string.strip, - filter(len, args)), - '-') + platform = '-'.join(x.strip() for x in filter(len, args)) # Cleanup some possible filename obstacles... - replace = string.replace - platform = replace(platform,' ','_') - platform = replace(platform,'/','-') - platform = replace(platform,'\\','-') - platform = replace(platform,':','-') - platform = replace(platform,';','-') - platform = replace(platform,'"','-') - platform = replace(platform,'(','-') - platform = replace(platform,')','-') + platform = platform.replace(' ','_') + platform = platform.replace('/','-') + platform = platform.replace('\\','-') + platform = platform.replace(':','-') + platform = platform.replace(';','-') + platform = platform.replace('"','-') + platform = platform.replace('(','-') + platform = platform.replace(')','-') # No need to report 'unknown' information... - platform = replace(platform,'unknown','') + platform = platform.replace('unknown','') # Fold '--'s and remove trailing '-' while 1: - cleaned = replace(platform,'--','-') + cleaned = platform.replace('--','-') if cleaned == platform: break platform = cleaned @@ -970,28 +959,12 @@ def _node(default=''): # Still not working... return default -# os.path.abspath is new in Python 1.5.2: -if not hasattr(os.path,'abspath'): - - def _abspath(path, - - isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd, - normpath=os.path.normpath): - - if not isabs(path): - path = join(getcwd(), path) - return normpath(path) - -else: - - _abspath = os.path.abspath - def _follow_symlinks(filepath): """ In case filepath is a symlink, follow it until a real file is reached. """ - filepath = _abspath(filepath) + filepath = os.path.abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( os.path.join(os.path.dirname(filepath),os.readlink(filepath))) @@ -1008,7 +981,7 @@ def _syscmd_uname(option,default=''): f = os.popen('uname %s 2> %s' % (option, DEV_NULL)) except (AttributeError,os.error): return default - output = string.strip(f.read()) + output = f.read().strip() rc = f.close() if not output or rc: return default @@ -1020,31 +993,10 @@ def _syscmd_file(target,default=''): """ Interface to the system's file command. The function uses the -b option of the file command to have it - ommit the filename in its output and if possible the -L option - to have the command follow symlinks. It returns default in - case the command should fail. + omit the filename in its output. Follow the symlinks. It returns + default in case the command should fail. """ - - # We do the import here to avoid a bootstrap issue. - # See c73b90b6dadd changeset. - # - # [..] - # ranlib libpython2.7.a - # gcc -o python \ - # Modules/python.o \ - # libpython2.7.a -lsocket -lnsl -ldl -lm - # Traceback (most recent call last): - # File "./setup.py", line 8, in <module> - # from platform import machine as platform_machine - # File "[..]/build/Lib/platform.py", line 116, in <module> - # import sys,string,os,re,subprocess - # File "[..]/build/Lib/subprocess.py", line 429, in <module> - # import select - # ImportError: No module named select - - import subprocess - if sys.platform in ('dos','win32','win16','os2'): # XXX Others too ? return default @@ -1052,10 +1004,9 @@ def _syscmd_file(target,default=''): try: proc = subprocess.Popen(['file', target], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - except (AttributeError,os.error): return default - output = proc.communicate()[0] + output = proc.communicate()[0].decode("latin-1") rc = proc.wait() if not output or rc: return default @@ -1072,8 +1023,6 @@ _default_architecture = { 'dos': ('','MSDOS'), } -_architecture_split = re.compile(r'[\s,]').split - def architecture(executable=sys.executable,bits='',linkage=''): """ Queries the given executable (defaults to the Python interpreter @@ -1108,24 +1057,21 @@ def architecture(executable=sys.executable,bits='',linkage=''): # Get data from the 'file' system command if executable: - output = _syscmd_file(executable, '') + fileout = _syscmd_file(executable, '') else: - output = '' + fileout = '' - if not output and \ + if not fileout and \ executable == sys.executable: # "file" command did not return anything; we'll try to provide # some sensible defaults then... if sys.platform in _default_architecture: - b, l = _default_architecture[sys.platform] + b,l = _default_architecture[sys.platform] if b: bits = b if l: linkage = l - return bits, linkage - - # Split the output into a list of strings omitting the filename - fileout = _architecture_split(output)[1:] + return bits,linkage if 'executable' not in fileout: # Format not supported @@ -1189,7 +1135,7 @@ def uname(): except AttributeError: no_os_uname = 1 - if no_os_uname or not filter(None, (system, node, release, version, machine)): + if no_os_uname or not list(filter(None, (system, node, release, version, machine))): # Hmm, no there is either no uname or uname has returned #'unknowns'... we'll have to poke around the system then. if no_os_uname: @@ -1251,7 +1197,7 @@ def uname(): elif system[:4] == 'java': release,vendor,vminfo,osinfo = java_ver() system = 'Java' - version = string.join(vminfo,', ') + version = ', '.join(vminfo) if not version: version = vendor @@ -1363,13 +1309,13 @@ def processor(): _sys_version_parser = re.compile( r'([\w.+]+)\s*' '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' - '\[([^\]]+)\]?') + '\[([^\]]+)\]?', re.ASCII) _ironpython_sys_version_parser = re.compile( r'IronPython\s*' '([\d\.]+)' '(?: \(([\d\.]+)\))?' - ' on (.NET [\d\.]+)') + ' on (.NET [\d\.]+)', re.ASCII) _pypy_sys_version_parser = re.compile( r'([\w.+]+)\s*' @@ -1453,7 +1399,9 @@ def _sys_version(sys_version=None): name = 'CPython' builddate = builddate + ' ' + buildtime - if hasattr(sys, 'subversion'): + if hasattr(sys, '_mercurial'): + _, branch, revision = sys._mercurial + elif hasattr(sys, 'subversion'): # sys.subversion was added in Python 2.5 _, branch, revision = sys.subversion else: @@ -1461,10 +1409,10 @@ def _sys_version(sys_version=None): revision = '' # Add the patchlevel version if missing - l = string.split(version, '.') + l = version.split('.') if len(l) == 2: l.append('0') - version = string.join(l, '.') + version = '.'.join(l) # Build and cache the result result = (name, version, branch, revision, buildno, builddate, compiler) @@ -1503,7 +1451,7 @@ def python_version_tuple(): will always include the patchlevel (it defaults to 0). """ - return tuple(string.split(_sys_version()[1], '.')) + return tuple(_sys_version()[1].split('.')) def python_branch(): @@ -1638,5 +1586,5 @@ if __name__ == '__main__': # Default is to print the aliased verbose platform string terse = ('terse' in sys.argv or '--terse' in sys.argv) aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv) - print platform(aliased,terse) + print(platform(aliased,terse)) sys.exit(0) |
