¡@

Home 

OpenStack Study: versionutils.py

OpenStack Index

**** CubicPower OpenStack Study ****

# Copyright (c) 2013 OpenStack Foundation

# All Rights Reserved.

#

# Licensed under the Apache License, Version 2.0 (the "License"); you may

# not use this file except in compliance with the License. You may obtain

# a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

# License for the specific language governing permissions and limitations

# under the License.

"""

Helpers for comparing version strings.

"""

import functools

import pkg_resources

from keystone.openstack.common.gettextutils import _

from keystone.openstack.common import log as logging

LOG = logging.getLogger(__name__)

**** CubicPower OpenStack Study ****

class deprecated(object):

"""A decorator to mark callables as deprecated.

deprecated logs a deprecation message when the callable it decorates

is used. The message will include the release where the callable was

deprecated, the release where is may be removed and possibly an

optional replacement.

Examples:

1. Specifing the required deprecated release

>>> @deprecated(as_of=deprecated.ICEHOUSE)

...

**** CubicPower OpenStack Study ****

    def __init__(self, as_of, in_favor_of=None, remove_in=2, what=None):

        """Initialize decorator

        :param as_of: the release deprecating the callable. Constants

            are define in this class for convenience.

        :param in_favor_of: the replacement for the callable (optional)

        :param remove_in: an integer specifying how many releases to wait

            before removing (default: 2)

        :param what: name of the thing being deprecated (default: the

            callable's name)

        """

        self.as_of = as_of

        self.in_favor_of = in_favor_of

        self.remove_in = remove_in

        self.what = what

**** CubicPower OpenStack Study ****

    def __call__(self, func):

        if not self.what:

            self.what = func.__name__ + '()'

        @functools.wraps(func)

        def wrapped(*args, **kwargs):

            msg, details = self._build_message()

            LOG.deprecated(msg, details)

            return func(*args, **kwargs)

        return wrapped

**** CubicPower OpenStack Study ****

        def wrapped(*args, **kwargs):

            msg, details = self._build_message()

            LOG.deprecated(msg, details)

            return func(*args, **kwargs)

        return wrapped

**** CubicPower OpenStack Study ****

    def _get_safe_to_remove_release(self, release):

        # TODO(dstanek): this method will have to be reimplemented once

        #    when we get to the X release because once we get to the Y

        #    release, what is Y+2?

        new_release = chr(ord(release) + self.remove_in)

        if new_release in self._RELEASES:

            return self._RELEASES[new_release]

        else:

            return new_release

**** CubicPower OpenStack Study ****

    def _build_message(self):

        details = dict(what=self.what,

                       as_of=self._RELEASES[self.as_of],

                       remove_in=self._get_safe_to_remove_release(self.as_of))

        if self.in_favor_of:

            details['in_favor_of'] = self.in_favor_of

            msg = self._deprecated_msg_with_alternative

        else:

            msg = self._deprecated_msg_no_alternative

        return msg, details

def is_compatible(requested_version, current_version, same_major=True):

    """Determine whether `requested_version` is satisfied by

    `current_version`; in other words, `current_version` is >=

    `requested_version`.

    :param requested_version: version to check for compatibility

    :param current_version: version to check against

    :param same_major: if True, the major version must be identical between

        `requested_version` and `current_version`. This is used when a

        major-version difference indicates incompatibility between the two

        versions. Since this is the common-case in practice, the default is

        True.

    :returns: True if compatible, False if not

    """

    requested_parts = pkg_resources.parse_version(requested_version)

    current_parts = pkg_resources.parse_version(current_version)

    if same_major and (requested_parts[0] != current_parts[0]):

        return False

    return current_parts >= requested_parts

**** CubicPower OpenStack Study ****

def is_compatible(requested_version, current_version, same_major=True):

    """Determine whether `requested_version` is satisfied by

    `current_version`; in other words, `current_version` is >=

    `requested_version`.

    :param requested_version: version to check for compatibility

    :param current_version: version to check against

    :param same_major: if True, the major version must be identical between

        `requested_version` and `current_version`. This is used when a

        major-version difference indicates incompatibility between the two

        versions. Since this is the common-case in practice, the default is

        True.

    :returns: True if compatible, False if not

    """

    requested_parts = pkg_resources.parse_version(requested_version)

    current_parts = pkg_resources.parse_version(current_version)

    if same_major and (requested_parts[0] != current_parts[0]):

        return False

    return current_parts >= requested_parts