Index: Lib/platform.py =================================================================== --- Lib/platform.py (revision 66568) +++ Lib/platform.py (working copy) @@ -286,8 +286,93 @@ if parsed != output: print (input, parsed) -def linux_distribution(distname='', version='', id='', +_distributor_id_cmdline_re = re.compile("(?:Distributor ID:)\s*(.*)", re.I) +_release_cmdline_re = re.compile("(?:Release:)\s*(.*)", re.I) +_codename_cmdline_re = re.compile("(?:Codename:)\s*(.*)", re.I) +_distributor_id_file_re = re.compile("(?:DISTRIB_ID\s*=)\s*(.*)", re.I) +_release_file_re = re.compile("(?:DISTRIB_RELEASE\s*=)\s*(.*)", re.I) +_codename_file_re = re.compile("(?:DISTRIB_CODENAME\s*=)\s*(.*)", re.I) + +def linux_distribution(distname='',version='',id='', full_distribution_name=1): + """ Tries to determine the name of the Linux OS distribution name. + + First, try to parse a file named "/etc/lsb-release". If it exists, and + contains the "DISTRIB_ID=" line and the "DISTRIB_RELEASE=" line, then return + the strings parsed from that file. The reason we try this first is because + it is faster than the official method of invoking "lsb_release" (which takes + half a second on my high-performance Athlon64 Ubuntu workstation). Also + because some distributions (at least Debian/Ubuntu) have /etc/lsb-release in + the "base-files" package (Priority: required) but /usr/bin/lsb_release in + the "lsb-release" package (Priority: important), so it is possible that + /etc/lsb-release is there even if /usr/bin/lsb_release isn't. + + If parsing /etc/lsb-release doesn't work, then try to execute "lsb_release", + as standardized in 2001: + + http://refspecs.freestandards.org/LSB_1.0.0/gLSB/lsbrelease.html + + The current version of the standard is here: + + http://refspecs.freestandards.org/LSB_3.2.0/LSB-Core-generic/LSB-Core-generic/lsbrelease.html + + If executing "lsb_release" raises no exception, and returns exit code 0, and + both the "distributor id" and "release" results are non-empty after being + stripped of whitespace, then return a two-tuple containing the information + that lsb_release emitted, as strings. + + If that doesn't work, then invoke _linux_distribution_try_a_little_harder() + and return whatever it returns. + + Returns a tuple (distname,version,id). Distname is what LSB calls a + "distributor id", e.g. "Ubuntu". Version is what LSB calls a "release", + e.g. "8.04". ID is what LSB calls a "codename", e.g. "hardy". + """ + _distname = None + _version = None + _id = None + + try: + etclsbrel = open("/etc/lsb-release", "rU") + for line in etclsbrel: + m = _distributor_id_file_re.search(line) + if m: + _distname = m.group(1).strip() + m = _release_file_re.search(line) + if m: + _version = m.group(1).strip() + m = _codename_file_re.search(line) + if m: + _id = m.group(1).strip() + if _distname and _version: + return (_distname, _version,_id) + except EnvironmentError: + pass + + try: + p = subprocess.Popen(["lsb_release", "--all"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + rc = p.wait() + if rc == 0: + for line in p.stdout.readlines(): + m = _distributor_id_cmdline_re.search(line) + if m: + _distname = m.group(1).strip() + m = _release_cmdline_re.search(p.stdout.read()) + if m: + _version = m.group(1).strip() + m = _codename_cmdline_re.search(p.stdout.read()) + if m: + _id = m.group(1).strip() + + if _distname and _version: + return (_distname, _version,_id) + except EnvironmentError: + pass + + return _linux_distribution_try_a_little_harder(distname, version, id, full_distribution_name=full_distribution_name) + +def _linux_distribution_try_a_little_harder(distname='', version='', id='', + supported_dists=_supported_dists, full_distribution_name=1):