1# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions 5# are met: 6# 1. Redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer. 8# 2. Redistributions in binary form must reproduce the above copyright 9# notice, this list of conditions and the following disclaimer in the 10# documentation and/or other materials provided with the distribution. 11# 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 13# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR 16# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 20# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 21# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 23"""Supports Python version checking.""" 24 25import logging 26import sys 27 28_log = logging.getLogger("webkitpy.python24.versioning") 29 30# The minimum Python version the webkitpy package supports. 31_MINIMUM_SUPPORTED_PYTHON_VERSION = "2.5" 32 33 34def compare_version(sysmodule=None, target_version=None): 35 """Compare the current Python version with a target version. 36 37 Args: 38 sysmodule: An object with version and version_info data attributes 39 used to detect the current Python version. The attributes 40 should have the same semantics as sys.version and 41 sys.version_info. This parameter should only be used 42 for unit testing. Defaults to sys. 43 target_version: A string representing the Python version to compare 44 the current version against. The string should have 45 one of the following three forms: 2, 2.5, or 2.5.3. 46 Defaults to the minimum version that the webkitpy 47 package supports. 48 49 Returns: 50 A triple of (comparison, current_version, target_version). 51 52 comparison: An integer representing the result of comparing the 53 current version with the target version. A positive 54 number means the current version is greater than the 55 target, 0 means they are the same, and a negative number 56 means the current version is less than the target. 57 This method compares version information only up 58 to the precision of the given target version. For 59 example, if the target version is 2.6 and the current 60 version is 2.5.3, this method uses 2.5 for the purposes 61 of comparing with the target. 62 current_version: A string representing the current Python version, for 63 example 2.5.3. 64 target_version: A string representing the version that the current 65 version was compared against, for example 2.5. 66 67 """ 68 if sysmodule is None: 69 sysmodule = sys 70 if target_version is None: 71 target_version = _MINIMUM_SUPPORTED_PYTHON_VERSION 72 73 # The number of version parts to compare. 74 precision = len(target_version.split(".")) 75 76 # We use sys.version_info rather than sys.version since its first 77 # three elements are guaranteed to be integers. 78 current_version_info_to_compare = sysmodule.version_info[:precision] 79 # Convert integers to strings. 80 current_version_info_to_compare = map(str, current_version_info_to_compare) 81 current_version_to_compare = ".".join(current_version_info_to_compare) 82 83 # Compare version strings lexicographically. 84 if current_version_to_compare > target_version: 85 comparison = 1 86 elif current_version_to_compare == target_version: 87 comparison = 0 88 else: 89 comparison = -1 90 91 # The version number portion of the current version string, for 92 # example "2.6.4". 93 current_version = sysmodule.version.split()[0] 94 95 return (comparison, current_version, target_version) 96 97 98# FIXME: Add a logging level parameter to allow the version message 99# to be logged at levels other than WARNING, for example CRITICAL. 100def check_version(log=None, sysmodule=None, target_version=None): 101 """Check the current Python version against a target version. 102 103 Logs a warning message if the current version is less than the 104 target version. 105 106 Args: 107 log: A logging.logger instance to use when logging the version warning. 108 Defaults to the logger of this module. 109 sysmodule: See the compare_version() docstring. 110 target_version: See the compare_version() docstring. 111 112 Returns: 113 A boolean value of whether the current version is greater than 114 or equal to the target version. 115 116 """ 117 if log is None: 118 log = _log 119 120 (comparison, current_version, target_version) = \ 121 compare_version(sysmodule, target_version) 122 123 if comparison >= 0: 124 # Then the current version is at least the minimum version. 125 return True 126 127 message = ("WebKit Python scripts do not support your current Python " 128 "version (%s). The minimum supported version is %s.\n" 129 " See the following page to upgrade your Python version:\n\n" 130 " http://trac.webkit.org/wiki/PythonGuidelines\n" 131 % (current_version, target_version)) 132 log.warn(message) 133 return False 134