diff options
author | Andrey Kurilin <akurilin@mirantis.com> | 2014-08-04 15:05:40 +0300 |
---|---|---|
committer | Andrey Kurilin <akurilin@mirantis.com> | 2014-08-11 17:33:52 +0300 |
commit | 6065b21b15b1b772cea281a99704c3c8d92c61cb (patch) | |
tree | 758aeaffcd77a09c20a6c98d69a93376b99fa64a | |
parent | 3cb592775d063df9afdb65e0d59338b31363d089 (diff) | |
download | oslo-db-6065b21b15b1b772cea281a99704c3c8d92c61cb.tar.gz |
Move to oslo.utils
`oslo.db` uses several modules(`importutils` and `timeutils`) from
`oslo-incubator`. This modules are already incubated and we should use them
from `oslo.utils`.
Change-Id: I09881ea3e115ca95bbd06ff5d1c0d5e253ed7640
-rw-r--r-- | openstack-common.conf | 2 | ||||
-rw-r--r-- | oslo/db/api.py | 8 | ||||
-rw-r--r-- | oslo/db/openstack/common/importutils.py | 73 | ||||
-rw-r--r-- | oslo/db/openstack/common/timeutils.py | 210 | ||||
-rw-r--r-- | oslo/db/sqlalchemy/models.py | 3 | ||||
-rw-r--r-- | oslo/db/sqlalchemy/session.py | 2 | ||||
-rw-r--r-- | oslo/db/sqlalchemy/utils.py | 2 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
-rw-r--r-- | tests/test_api.py | 6 |
9 files changed, 14 insertions, 293 deletions
diff --git a/openstack-common.conf b/openstack-common.conf index e910dc2..5b62234 100644 --- a/openstack-common.conf +++ b/openstack-common.conf @@ -2,9 +2,7 @@ # The list of modules to copy from oslo-incubator.git module=gettextutils -module=importutils module=fixture.config -module=timeutils # The base module to hold the copy of openstack.common base=oslo.db diff --git a/oslo/db/api.py b/oslo/db/api.py index 16d4157..87f111d 100644 --- a/oslo/db/api.py +++ b/oslo/db/api.py @@ -28,9 +28,10 @@ import logging import threading import time +from oslo.utils import importutils + from oslo.db import exception from oslo.db.openstack.common.gettextutils import _LE -from oslo.db.openstack.common import importutils from oslo.db import options @@ -176,7 +177,10 @@ class DBAPI(object): # Import the untranslated name if we don't have a mapping backend_path = self._backend_mapping.get(self._backend_name, self._backend_name) - backend_mod = importutils.import_module(backend_path) + backend_mod = importutils.try_import(backend_path) + if not backend_mod: + raise ImportError("Unable to import backend '%s'" % + self._backend_name) self._backend = backend_mod.get_backend() def __getattr__(self, key): diff --git a/oslo/db/openstack/common/importutils.py b/oslo/db/openstack/common/importutils.py deleted file mode 100644 index f40a843..0000000 --- a/oslo/db/openstack/common/importutils.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2011 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. - -""" -Import related utilities and helper functions. -""" - -import sys -import traceback - - -def import_class(import_str): - """Returns a class from a string including module and class.""" - mod_str, _sep, class_str = import_str.rpartition('.') - try: - __import__(mod_str) - return getattr(sys.modules[mod_str], class_str) - except (ValueError, AttributeError): - raise ImportError('Class %s cannot be found (%s)' % - (class_str, - traceback.format_exception(*sys.exc_info()))) - - -def import_object(import_str, *args, **kwargs): - """Import a class and return an instance of it.""" - return import_class(import_str)(*args, **kwargs) - - -def import_object_ns(name_space, import_str, *args, **kwargs): - """Tries to import object from default namespace. - - Imports a class and return an instance of it, first by trying - to find the class in a default namespace, then failing back to - a full path if not found in the default namespace. - """ - import_value = "%s.%s" % (name_space, import_str) - try: - return import_class(import_value)(*args, **kwargs) - except ImportError: - return import_class(import_str)(*args, **kwargs) - - -def import_module(import_str): - """Import a module.""" - __import__(import_str) - return sys.modules[import_str] - - -def import_versioned_module(version, submodule=None): - module = 'oslo.db.v%s' % version - if submodule: - module = '.'.join((module, submodule)) - return import_module(module) - - -def try_import(import_str, default=None): - """Try to import a module and if it fails return default.""" - try: - return import_module(import_str) - except ImportError: - return default diff --git a/oslo/db/openstack/common/timeutils.py b/oslo/db/openstack/common/timeutils.py deleted file mode 100644 index 52688a0..0000000 --- a/oslo/db/openstack/common/timeutils.py +++ /dev/null @@ -1,210 +0,0 @@ -# Copyright 2011 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. - -""" -Time related utilities and helper functions. -""" - -import calendar -import datetime -import time - -import iso8601 -import six - - -# ISO 8601 extended time format with microseconds -_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f' -_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S' -PERFECT_TIME_FORMAT = _ISO8601_TIME_FORMAT_SUBSECOND - - -def isotime(at=None, subsecond=False): - """Stringify time in ISO 8601 format.""" - if not at: - at = utcnow() - st = at.strftime(_ISO8601_TIME_FORMAT - if not subsecond - else _ISO8601_TIME_FORMAT_SUBSECOND) - tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC' - st += ('Z' if tz == 'UTC' else tz) - return st - - -def parse_isotime(timestr): - """Parse time from ISO 8601 format.""" - try: - return iso8601.parse_date(timestr) - except iso8601.ParseError as e: - raise ValueError(six.text_type(e)) - except TypeError as e: - raise ValueError(six.text_type(e)) - - -def strtime(at=None, fmt=PERFECT_TIME_FORMAT): - """Returns formatted utcnow.""" - if not at: - at = utcnow() - return at.strftime(fmt) - - -def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT): - """Turn a formatted time back into a datetime.""" - return datetime.datetime.strptime(timestr, fmt) - - -def normalize_time(timestamp): - """Normalize time in arbitrary timezone to UTC naive object.""" - offset = timestamp.utcoffset() - if offset is None: - return timestamp - return timestamp.replace(tzinfo=None) - offset - - -def is_older_than(before, seconds): - """Return True if before is older than seconds.""" - if isinstance(before, six.string_types): - before = parse_strtime(before).replace(tzinfo=None) - else: - before = before.replace(tzinfo=None) - - return utcnow() - before > datetime.timedelta(seconds=seconds) - - -def is_newer_than(after, seconds): - """Return True if after is newer than seconds.""" - if isinstance(after, six.string_types): - after = parse_strtime(after).replace(tzinfo=None) - else: - after = after.replace(tzinfo=None) - - return after - utcnow() > datetime.timedelta(seconds=seconds) - - -def utcnow_ts(): - """Timestamp version of our utcnow function.""" - if utcnow.override_time is None: - # NOTE(kgriffs): This is several times faster - # than going through calendar.timegm(...) - return int(time.time()) - - return calendar.timegm(utcnow().timetuple()) - - -def utcnow(): - """Overridable version of utils.utcnow.""" - if utcnow.override_time: - try: - return utcnow.override_time.pop(0) - except AttributeError: - return utcnow.override_time - return datetime.datetime.utcnow() - - -def iso8601_from_timestamp(timestamp): - """Returns a iso8601 formatted date from timestamp.""" - return isotime(datetime.datetime.utcfromtimestamp(timestamp)) - - -utcnow.override_time = None - - -def set_time_override(override_time=None): - """Overrides utils.utcnow. - - Make it return a constant time or a list thereof, one at a time. - - :param override_time: datetime instance or list thereof. If not - given, defaults to the current UTC time. - """ - utcnow.override_time = override_time or datetime.datetime.utcnow() - - -def advance_time_delta(timedelta): - """Advance overridden time using a datetime.timedelta.""" - assert(not utcnow.override_time is None) - try: - for dt in utcnow.override_time: - dt += timedelta - except TypeError: - utcnow.override_time += timedelta - - -def advance_time_seconds(seconds): - """Advance overridden time by seconds.""" - advance_time_delta(datetime.timedelta(0, seconds)) - - -def clear_time_override(): - """Remove the overridden time.""" - utcnow.override_time = None - - -def marshall_now(now=None): - """Make an rpc-safe datetime with microseconds. - - Note: tzinfo is stripped, but not required for relative times. - """ - if not now: - now = utcnow() - return dict(day=now.day, month=now.month, year=now.year, hour=now.hour, - minute=now.minute, second=now.second, - microsecond=now.microsecond) - - -def unmarshall_time(tyme): - """Unmarshall a datetime dict.""" - return datetime.datetime(day=tyme['day'], - month=tyme['month'], - year=tyme['year'], - hour=tyme['hour'], - minute=tyme['minute'], - second=tyme['second'], - microsecond=tyme['microsecond']) - - -def delta_seconds(before, after): - """Return the difference between two timing objects. - - Compute the difference in seconds between two date, time, or - datetime objects (as a float, to microsecond resolution). - """ - delta = after - before - return total_seconds(delta) - - -def total_seconds(delta): - """Return the total seconds of datetime.timedelta object. - - Compute total seconds of datetime.timedelta, datetime.timedelta - doesn't have method total_seconds in Python2.6, calculate it manually. - """ - try: - return delta.total_seconds() - except AttributeError: - return ((delta.days * 24 * 3600) + delta.seconds + - float(delta.microseconds) / (10 ** 6)) - - -def is_soon(dt, window): - """Determines if time is going to happen in the next window seconds. - - :param dt: the time - :param window: minimum seconds to remain to consider the time not soon - - :return: True if expiration is within the given duration - """ - soon = (utcnow() + datetime.timedelta(seconds=window)) - return normalize_time(dt) <= soon diff --git a/oslo/db/sqlalchemy/models.py b/oslo/db/sqlalchemy/models.py index f3401a0..ae01bb3 100644 --- a/oslo/db/sqlalchemy/models.py +++ b/oslo/db/sqlalchemy/models.py @@ -22,12 +22,11 @@ SQLAlchemy models. import six +from oslo.utils import timeutils from sqlalchemy import Column, Integer from sqlalchemy import DateTime from sqlalchemy.orm import object_mapper -from oslo.db.openstack.common import timeutils - class ModelBase(six.Iterator): """Base class for models.""" diff --git a/oslo/db/sqlalchemy/session.py b/oslo/db/sqlalchemy/session.py index 2ff3caa..c2470c2 100644 --- a/oslo/db/sqlalchemy/session.py +++ b/oslo/db/sqlalchemy/session.py @@ -284,6 +284,7 @@ import logging import re import time +from oslo.utils import timeutils import six from sqlalchemy.interfaces import PoolListener import sqlalchemy.orm @@ -293,7 +294,6 @@ from sqlalchemy.sql.expression import select from oslo.db import exception from oslo.db.openstack.common.gettextutils import _LW -from oslo.db.openstack.common import timeutils from oslo.db import options from oslo.db.sqlalchemy import exc_filters diff --git a/oslo/db/sqlalchemy/utils.py b/oslo/db/sqlalchemy/utils.py index 5aa9341..bc99850 100644 --- a/oslo/db/sqlalchemy/utils.py +++ b/oslo/db/sqlalchemy/utils.py @@ -19,6 +19,7 @@ import logging import re +from oslo.utils import timeutils import sqlalchemy from sqlalchemy import Boolean from sqlalchemy import CheckConstraint @@ -37,7 +38,6 @@ from sqlalchemy.types import NullType from oslo.db import exception from oslo.db.openstack.common.gettextutils import _, _LI, _LW -from oslo.db.openstack.common import timeutils from oslo.db.sqlalchemy import models # NOTE(ochuprykov): Add references for backwards compatibility diff --git a/requirements.txt b/requirements.txt index b8b4400..a86e8a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ alembic>=0.6.4 Babel>=1.3 iso8601>=0.1.9 oslo.config>=1.4.0.0a3 +oslo.utils>=0.1.1 # Apache-2.0 SQLAlchemy>=0.8.4,<=0.8.99,>=0.9.7,<=0.9.99 sqlalchemy-migrate>=0.9.1 stevedore>=0.14 diff --git a/tests/test_api.py b/tests/test_api.py index 98c618f..2168cd5 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -17,13 +17,15 @@ import mock from oslo.config import cfg +from oslo.utils import importutils from oslo.db import api from oslo.db import exception -from oslo.db.openstack.common import importutils from tests import utils as test_utils -sqla = importutils.import_module('sqlalchemy') +sqla = importutils.try_import('sqlalchemy') +if not sqla: + raise ImportError("Unable to import module 'sqlalchemy'.") def get_backend(): |