Use versionadded and versionchanged in doc
Document in which version new types and functions were added using ".. versionadded:: x.y". Document changes using ".. versionchanged:: x.y." For new modules, add the versionadded tag in the module top docstring, not on each type/function. Add fileutils to documentation. The doc part was forgotten during the graduation. Add docstrings to convert versions of versionutils. I used "git blame" + "git tag --contains=SHA1" to find these version, and then I checked manually each version. Change-Id: Ia2f00aa29eb36410a49fc1d350896a569a7737a1
This commit is contained in:
parent
6aa24675e8
commit
7f57de5bb2
7
doc/source/api/fileutils.rst
Normal file
7
doc/source/api/fileutils.rst
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
=============
|
||||||
|
fileutils
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. automodule:: oslo_utils.fileutils
|
||||||
|
:members:
|
||||||
|
|
@ -21,6 +21,7 @@ API Documentation
|
|||||||
api/encodeutils
|
api/encodeutils
|
||||||
api/eventletutils
|
api/eventletutils
|
||||||
api/excutils
|
api/excutils
|
||||||
|
api/fileutils
|
||||||
api/fixture
|
api/fixture
|
||||||
api/importutils
|
api/importutils
|
||||||
api/netutils
|
api/netutils
|
||||||
|
@ -104,6 +104,8 @@ def exception_to_unicode(exc):
|
|||||||
If the exception message is a bytes strings, try to decode it from UTF-8
|
If the exception message is a bytes strings, try to decode it from UTF-8
|
||||||
(superset of ASCII), from the locale encoding, or fallback to decoding it
|
(superset of ASCII), from the locale encoding, or fallback to decoding it
|
||||||
from ISO-8859-1 (which never fails).
|
from ISO-8859-1 (which never fails).
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
"""
|
"""
|
||||||
msg = None
|
msg = None
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Eventlet utils helper module.
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
"""
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
@ -35,6 +41,13 @@ _ALL_PATCH = frozenset(['__builtin__', 'MySQLdb', 'os',
|
|||||||
|
|
||||||
|
|
||||||
def fetch_current_thread_functor():
|
def fetch_current_thread_functor():
|
||||||
|
"""Get the current thread.
|
||||||
|
|
||||||
|
If eventlet is used to monkey-patch the threading module, return the
|
||||||
|
current eventlet greenthread. Otherwise, return the current Python thread.
|
||||||
|
|
||||||
|
.. versionadded:: 1.5
|
||||||
|
"""
|
||||||
# Until https://github.com/eventlet/eventlet/issues/172 is resolved
|
# Until https://github.com/eventlet/eventlet/issues/172 is resolved
|
||||||
# or addressed we have to use complicated workaround to get a object
|
# or addressed we have to use complicated workaround to get a object
|
||||||
# that will not be recycled; the usage of threading.current_thread()
|
# that will not be recycled; the usage of threading.current_thread()
|
||||||
|
@ -45,6 +45,8 @@ class CausedByException(Exception):
|
|||||||
should itself be an exception instance, this is useful for
|
should itself be an exception instance, this is useful for
|
||||||
creating a chain of exceptions for versions of python where
|
creating a chain of exceptions for versions of python where
|
||||||
this is not yet implemented/supported natively.
|
this is not yet implemented/supported natively.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4
|
||||||
"""
|
"""
|
||||||
def __init__(self, message, cause=None):
|
def __init__(self, message, cause=None):
|
||||||
super(CausedByException, self).__init__(message)
|
super(CausedByException, self).__init__(message)
|
||||||
@ -126,6 +128,8 @@ def raise_with_cause(exc_cls, message, *args, **kwargs):
|
|||||||
exceptions constructor.
|
exceptions constructor.
|
||||||
:param kwargs: any additional keyword arguments to pass to the
|
:param kwargs: any additional keyword arguments to pass to the
|
||||||
exceptions constructor.
|
exceptions constructor.
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
"""
|
"""
|
||||||
if 'cause' not in kwargs:
|
if 'cause' not in kwargs:
|
||||||
exc_type, exc, exc_tb = sys.exc_info()
|
exc_type, exc, exc_tb = sys.exc_info()
|
||||||
@ -174,6 +178,9 @@ class save_and_reraise_exception(object):
|
|||||||
[if statements to determine whether to raise a new exception]
|
[if statements to determine whether to raise a new exception]
|
||||||
# Not raising a new exception, so reraise
|
# Not raising a new exception, so reraise
|
||||||
ctxt.reraise = True
|
ctxt.reraise = True
|
||||||
|
|
||||||
|
.. versionchanged:: 1.4
|
||||||
|
Added *logger* optional parameter.
|
||||||
"""
|
"""
|
||||||
def __init__(self, reraise=True, logger=None):
|
def __init__(self, reraise=True, logger=None):
|
||||||
self.reraise = reraise
|
self.reraise = reraise
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
File utilities.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
"""
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import errno
|
import errno
|
||||||
import logging
|
import logging
|
||||||
@ -87,6 +93,8 @@ def write_to_tempfile(content, path=None, suffix='', prefix='tmp'):
|
|||||||
|
|
||||||
For example: it can be used in database tests for creating
|
For example: it can be used in database tests for creating
|
||||||
configuration files.
|
configuration files.
|
||||||
|
|
||||||
|
.. versionadded:: 1.9
|
||||||
"""
|
"""
|
||||||
if path:
|
if path:
|
||||||
ensure_tree(path)
|
ensure_tree(path)
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Test fixtures.
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
"""
|
||||||
|
|
||||||
import fixtures
|
import fixtures
|
||||||
|
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
|
@ -22,7 +22,10 @@ import traceback
|
|||||||
|
|
||||||
|
|
||||||
def import_class(import_str):
|
def import_class(import_str):
|
||||||
"""Returns a class from a string including module and class."""
|
"""Returns a class from a string including module and class.
|
||||||
|
|
||||||
|
.. versionadded:: 0.3
|
||||||
|
"""
|
||||||
mod_str, _sep, class_str = import_str.rpartition('.')
|
mod_str, _sep, class_str = import_str.rpartition('.')
|
||||||
__import__(mod_str)
|
__import__(mod_str)
|
||||||
try:
|
try:
|
||||||
@ -34,7 +37,10 @@ def import_class(import_str):
|
|||||||
|
|
||||||
|
|
||||||
def import_object(import_str, *args, **kwargs):
|
def import_object(import_str, *args, **kwargs):
|
||||||
"""Import a class and return an instance of it."""
|
"""Import a class and return an instance of it.
|
||||||
|
|
||||||
|
.. versionadded:: 0.3
|
||||||
|
"""
|
||||||
return import_class(import_str)(*args, **kwargs)
|
return import_class(import_str)(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +50,12 @@ def import_object_ns(name_space, import_str, *args, **kwargs):
|
|||||||
Imports a class and return an instance of it, first by trying
|
Imports a class and return an instance of it, first by trying
|
||||||
to find the class in a default namespace, then failing back to
|
to find the class in a default namespace, then failing back to
|
||||||
a full path if not found in the default namespace.
|
a full path if not found in the default namespace.
|
||||||
|
|
||||||
|
.. versionadded:: 0.3
|
||||||
|
|
||||||
|
.. versionchanged:: 2.6
|
||||||
|
Don't capture :exc:`ImportError` when instanciating the object, only
|
||||||
|
when importing the object class.
|
||||||
"""
|
"""
|
||||||
import_value = "%s.%s" % (name_space, import_str)
|
import_value = "%s.%s" % (name_space, import_str)
|
||||||
try:
|
try:
|
||||||
@ -54,12 +66,19 @@ def import_object_ns(name_space, import_str, *args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def import_module(import_str):
|
def import_module(import_str):
|
||||||
"""Import a module."""
|
"""Import a module.
|
||||||
|
|
||||||
|
.. versionadded:: 0.3
|
||||||
|
"""
|
||||||
__import__(import_str)
|
__import__(import_str)
|
||||||
return sys.modules[import_str]
|
return sys.modules[import_str]
|
||||||
|
|
||||||
|
|
||||||
def import_versioned_module(version, submodule=None):
|
def import_versioned_module(version, submodule=None):
|
||||||
|
"""Import a versioned module.
|
||||||
|
|
||||||
|
.. versionadded:: 0.3
|
||||||
|
"""
|
||||||
module = 'oslo.v%s' % version
|
module = 'oslo.v%s' % version
|
||||||
if submodule:
|
if submodule:
|
||||||
module = '.'.join((module, submodule))
|
module = '.'.join((module, submodule))
|
||||||
|
@ -87,6 +87,8 @@ def is_valid_ipv4(address):
|
|||||||
:param address: Value to verify
|
:param address: Value to verify
|
||||||
:type address: string
|
:type address: string
|
||||||
:returns: bool
|
:returns: bool
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return netaddr.valid_ipv4(address)
|
return netaddr.valid_ipv4(address)
|
||||||
@ -100,6 +102,8 @@ def is_valid_ipv6(address):
|
|||||||
:param address: Value to verify
|
:param address: Value to verify
|
||||||
:type address: string
|
:type address: string
|
||||||
:returns: bool
|
:returns: bool
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return netaddr.valid_ipv6(address)
|
return netaddr.valid_ipv6(address)
|
||||||
@ -117,6 +121,8 @@ def get_ipv6_addr_by_EUI64(prefix, mac):
|
|||||||
:param mac: IEEE 802 48-bit MAC address.
|
:param mac: IEEE 802 48-bit MAC address.
|
||||||
:returns: IPv6 address on success.
|
:returns: IPv6 address on success.
|
||||||
:raises ValueError, TypeError: For any invalid input.
|
:raises ValueError, TypeError: For any invalid input.
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
"""
|
"""
|
||||||
# Check if the prefix is an IPv4 address
|
# Check if the prefix is an IPv4 address
|
||||||
if netaddr.valid_ipv4(prefix):
|
if netaddr.valid_ipv4(prefix):
|
||||||
@ -143,6 +149,7 @@ def is_ipv6_enabled():
|
|||||||
|
|
||||||
:returns: True if the platform has IPv6 support, False otherwise.
|
:returns: True if the platform has IPv6 support, False otherwise.
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global _IS_IPV6_ENABLED
|
global _IS_IPV6_ENABLED
|
||||||
@ -164,12 +171,17 @@ def is_valid_ip(address):
|
|||||||
:param address: Value to verify
|
:param address: Value to verify
|
||||||
:type address: string
|
:type address: string
|
||||||
:returns: bool
|
:returns: bool
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
"""
|
"""
|
||||||
return is_valid_ipv4(address) or is_valid_ipv6(address)
|
return is_valid_ipv4(address) or is_valid_ipv6(address)
|
||||||
|
|
||||||
|
|
||||||
def is_valid_port(port):
|
def is_valid_port(port):
|
||||||
"""Verify that port represents a valid port number."""
|
"""Verify that port represents a valid port number.
|
||||||
|
|
||||||
|
.. versionadded:: 1.1.1
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
val = int(port)
|
val = int(port)
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
@ -185,6 +197,11 @@ def get_my_ipv4():
|
|||||||
were to be sent out to some well known address on the Internet. In this
|
were to be sent out to some well known address on the Internet. In this
|
||||||
case, IP from RFC5737 is used, but the specific address does not
|
case, IP from RFC5737 is used, but the specific address does not
|
||||||
matter much. No traffic is actually sent.
|
matter much. No traffic is actually sent.
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
|
|
||||||
|
.. versionchanged:: 1.2.1
|
||||||
|
Return ``'127.0.0.1'`` if there is no default interface.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Reflection module.
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
|
"""
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import types
|
import types
|
||||||
|
|
||||||
@ -31,7 +37,10 @@ _BUILTIN_MODULES = ('builtins', '__builtin__', '__builtins__', 'exceptions')
|
|||||||
|
|
||||||
|
|
||||||
def get_members(obj, exclude_hidden=True):
|
def get_members(obj, exclude_hidden=True):
|
||||||
"""Yields the members of an object, filtering by hidden/not hidden."""
|
"""Yields the members of an object, filtering by hidden/not hidden.
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
|
"""
|
||||||
for (name, value) in inspect.getmembers(obj):
|
for (name, value) in inspect.getmembers(obj):
|
||||||
if name.startswith("_") and exclude_hidden:
|
if name.startswith("_") and exclude_hidden:
|
||||||
continue
|
continue
|
||||||
|
@ -213,7 +213,7 @@ def to_slug(value, incoming=None, errors="strict"):
|
|||||||
|
|
||||||
|
|
||||||
def mask_password(message, secret="***"):
|
def mask_password(message, secret="***"):
|
||||||
"""Replace password with 'secret' in message.
|
"""Replace password with *secret* in message.
|
||||||
|
|
||||||
:param message: The string which includes security information.
|
:param message: The string which includes security information.
|
||||||
:param secret: value with which to replace passwords.
|
:param secret: value with which to replace passwords.
|
||||||
@ -231,6 +231,24 @@ def mask_password(message, secret="***"):
|
|||||||
"'original_password' : '***'"
|
"'original_password' : '***'"
|
||||||
>>> mask_password("u'original_password' : u'aaaaa'")
|
>>> mask_password("u'original_password' : u'aaaaa'")
|
||||||
"u'original_password' : u'***'"
|
"u'original_password' : u'***'"
|
||||||
|
|
||||||
|
.. versionadded:: 0.2
|
||||||
|
|
||||||
|
.. versionchanged:: 1.1
|
||||||
|
Replace also ``'auth_token'``, ``'new_pass'`` and ``'auth_password'``
|
||||||
|
keys.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.1.1
|
||||||
|
Replace also ``'secret_uuid'`` key.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.5
|
||||||
|
Replace also ``'sys_pswd'`` key.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.6
|
||||||
|
Replace also ``'token'`` key.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.7
|
||||||
|
Replace also ``'secret'`` key.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -262,6 +280,8 @@ def is_int_like(val):
|
|||||||
:param val: Value to verify
|
:param val: Value to verify
|
||||||
:type val: string
|
:type val: string
|
||||||
:returns: bool
|
:returns: bool
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return six.text_type(int(val)) == six.text_type(val)
|
return six.text_type(int(val)) == six.text_type(val)
|
||||||
|
@ -105,7 +105,12 @@ def normalize_time(timestamp):
|
|||||||
|
|
||||||
|
|
||||||
def is_older_than(before, seconds):
|
def is_older_than(before, seconds):
|
||||||
"""Return True if before is older than seconds."""
|
"""Return True if before is older than seconds.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.7
|
||||||
|
Accept datetime string with timezone information.
|
||||||
|
Fix comparison with timezone aware datetime.
|
||||||
|
"""
|
||||||
if isinstance(before, six.string_types):
|
if isinstance(before, six.string_types):
|
||||||
before = parse_isotime(before)
|
before = parse_isotime(before)
|
||||||
|
|
||||||
@ -115,7 +120,12 @@ def is_older_than(before, seconds):
|
|||||||
|
|
||||||
|
|
||||||
def is_newer_than(after, seconds):
|
def is_newer_than(after, seconds):
|
||||||
"""Return True if after is newer than seconds."""
|
"""Return True if after is newer than seconds.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.7
|
||||||
|
Accept datetime string with timezone information.
|
||||||
|
Fix comparison with timezone aware datetime.
|
||||||
|
"""
|
||||||
if isinstance(after, six.string_types):
|
if isinstance(after, six.string_types):
|
||||||
after = parse_isotime(after)
|
after = parse_isotime(after)
|
||||||
|
|
||||||
@ -129,6 +139,8 @@ def utcnow_ts(microsecond=False):
|
|||||||
|
|
||||||
See :py:class:`oslo_utils.fixture.TimeFixture`.
|
See :py:class:`oslo_utils.fixture.TimeFixture`.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.3
|
||||||
|
Added optional *microsecond* parameter.
|
||||||
"""
|
"""
|
||||||
if utcnow.override_time is None:
|
if utcnow.override_time is None:
|
||||||
# NOTE(kgriffs): This is several times faster
|
# NOTE(kgriffs): This is several times faster
|
||||||
@ -152,6 +164,8 @@ def utcnow(with_timezone=False):
|
|||||||
|
|
||||||
See :py:class:`oslo_utils.fixture.TimeFixture`.
|
See :py:class:`oslo_utils.fixture.TimeFixture`.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.6
|
||||||
|
Added *with_timezone* parameter.
|
||||||
"""
|
"""
|
||||||
if utcnow.override_time:
|
if utcnow.override_time:
|
||||||
try:
|
try:
|
||||||
@ -171,6 +185,9 @@ def utcnow(with_timezone=False):
|
|||||||
def iso8601_from_timestamp(timestamp, microsecond=False):
|
def iso8601_from_timestamp(timestamp, microsecond=False):
|
||||||
"""Returns an iso8601 formatted date from timestamp.
|
"""Returns an iso8601 formatted date from timestamp.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.3
|
||||||
|
Added optional *microsecond* parameter.
|
||||||
|
|
||||||
.. deprecated:: 1.5.0
|
.. deprecated:: 1.5.0
|
||||||
Use :func:`datetime.datetime.utcfromtimestamp` and
|
Use :func:`datetime.datetime.utcfromtimestamp` and
|
||||||
:func:`datetime.datetime.isoformat` instead.
|
:func:`datetime.datetime.isoformat` instead.
|
||||||
@ -227,7 +244,11 @@ def clear_time_override():
|
|||||||
|
|
||||||
|
|
||||||
def marshall_now(now=None):
|
def marshall_now(now=None):
|
||||||
"""Make an rpc-safe datetime with microseconds."""
|
"""Make an rpc-safe datetime with microseconds.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.6
|
||||||
|
Timezone information is now serialized instead of being stripped.
|
||||||
|
"""
|
||||||
if not now:
|
if not now:
|
||||||
now = utcnow()
|
now = utcnow()
|
||||||
d = dict(day=now.day, month=now.month, year=now.year, hour=now.hour,
|
d = dict(day=now.day, month=now.month, year=now.year, hour=now.hour,
|
||||||
@ -239,7 +260,14 @@ def marshall_now(now=None):
|
|||||||
|
|
||||||
|
|
||||||
def unmarshall_time(tyme):
|
def unmarshall_time(tyme):
|
||||||
"""Unmarshall a datetime dict."""
|
"""Unmarshall a datetime dict.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.5
|
||||||
|
Drop leap second.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.6
|
||||||
|
Added support for timezone information.
|
||||||
|
"""
|
||||||
|
|
||||||
# NOTE(ihrachys): datetime does not support leap seconds,
|
# NOTE(ihrachys): datetime does not support leap seconds,
|
||||||
# so the best thing we can do for now is dropping them
|
# so the best thing we can do for now is dropping them
|
||||||
@ -298,6 +326,8 @@ class Split(object):
|
|||||||
"""A *immutable* stopwatch split.
|
"""A *immutable* stopwatch split.
|
||||||
|
|
||||||
See: http://en.wikipedia.org/wiki/Stopwatch for what this is/represents.
|
See: http://en.wikipedia.org/wiki/Stopwatch for what this is/represents.
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ['_elapsed', '_length']
|
__slots__ = ['_elapsed', '_length']
|
||||||
@ -337,6 +367,8 @@ class StopWatch(object):
|
|||||||
depending on operating system and python version).
|
depending on operating system and python version).
|
||||||
|
|
||||||
.. _monotonic: https://pypi.python.org/pypi/monotonic/
|
.. _monotonic: https://pypi.python.org/pypi/monotonic/
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
"""
|
"""
|
||||||
_STARTED = 'STARTED'
|
_STARTED = 'STARTED'
|
||||||
_STOPPED = 'STOPPED'
|
_STOPPED = 'STOPPED'
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
UUID related utilities and helper functions.
|
UUID related utilities and helper functions.
|
||||||
|
|
||||||
|
.. versionadded:: 1.1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
@ -42,6 +44,9 @@ def is_uuid_like(val):
|
|||||||
:param val: Value to verify
|
:param val: Value to verify
|
||||||
:type val: string
|
:type val: string
|
||||||
:returns: bool
|
:returns: bool
|
||||||
|
|
||||||
|
.. versionchanged:: 1.1.1
|
||||||
|
Support non-lowercase UUIDs.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return str(uuid.UUID(val)).replace('-', '') == _format_uuid_string(val)
|
return str(uuid.UUID(val)).replace('-', '') == _format_uuid_string(val)
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
Helpers for comparing version strings.
|
Helpers for comparing version strings.
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -51,6 +53,12 @@ def is_compatible(requested_version, current_version, same_major=True):
|
|||||||
|
|
||||||
|
|
||||||
def convert_version_to_int(version):
|
def convert_version_to_int(version):
|
||||||
|
"""Convert a version to an integer.
|
||||||
|
|
||||||
|
*version* must be a string with dots or a tuple of integers.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
if isinstance(version, six.string_types):
|
if isinstance(version, six.string_types):
|
||||||
version = convert_version_to_tuple(version)
|
version = convert_version_to_tuple(version)
|
||||||
@ -62,6 +70,10 @@ def convert_version_to_int(version):
|
|||||||
|
|
||||||
|
|
||||||
def convert_version_to_str(version_int):
|
def convert_version_to_str(version_int):
|
||||||
|
"""Convert a version integer to a string with dots.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
"""
|
||||||
version_numbers = []
|
version_numbers = []
|
||||||
factor = 1000
|
factor = 1000
|
||||||
while version_int != 0:
|
while version_int != 0:
|
||||||
@ -73,4 +85,8 @@ def convert_version_to_str(version_int):
|
|||||||
|
|
||||||
|
|
||||||
def convert_version_to_tuple(version_str):
|
def convert_version_to_tuple(version_str):
|
||||||
|
"""Convert a version string with dots to a tuple.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
"""
|
||||||
return tuple(int(part) for part in version_str.split('.'))
|
return tuple(int(part) for part in version_str.split('.'))
|
||||||
|
Loading…
Reference in New Issue
Block a user