summaryrefslogtreecommitdiffstats
path: root/Lib/platform.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/platform.py')
-rwxr-xr-xLib/platform.py198
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)