diff options
author | Ask Solem <ask@celeryproject.org> | 2011-09-07 15:21:47 +0100 |
---|---|---|
committer | Ask Solem <ask@celeryproject.org> | 2011-09-07 15:21:47 +0100 |
commit | 66ef95038ffb3351592623309119946418c639bf (patch) | |
tree | c8189a6f578d6ee9196e1968f6c15be460fbc0bd /kombu | |
parent | 0b29991566b3d510d39ac61861576ec3e2ef1ae7 (diff) | |
download | kombu-66ef95038ffb3351592623309119946418c639bf.tar.gz |
2.0-devel: No longer supports Python 2.4
Diffstat (limited to 'kombu')
57 files changed, 281 insertions, 430 deletions
diff --git a/kombu/__init__.py b/kombu/__init__.py index fcdc3080..a2fb6748 100644 --- a/kombu/__init__.py +++ b/kombu/__init__.py @@ -1,13 +1,22 @@ """AMQP Messaging Framework for Python""" -VERSION = (1, 3, 1) +from __future__ import absolute_import + +VERSION = (2, 0, 0, "a1") __version__ = ".".join(map(str, VERSION[0:3])) + "".join(VERSION[3:]) __author__ = "Ask Solem" __contact__ = "ask@celeryproject.org" __homepage__ = "http://github.com/ask/kombu/" __docformat__ = "restructuredtext en" + import os import sys + +if sys.version_info < (2, 5): + raise Exception( + "Python 2.4 is not supported by this version. " + "Please use Kombu versions 1.3.x or earlier.") + if not os.environ.get("KOMBU_NO_EVAL", False): # Lazy loading. # - See werkzeug/__init__.py for the rationale behind this. @@ -61,5 +70,5 @@ if not os.environ.get("KOMBU_NO_EVAL", False): if os.environ.get("KOMBU_LOG_DEBUG"): os.environ.update(KOMBU_LOG_CHANNEL="1", KOMBU_LOG_CONNECTION="1") - from kombu.utils import debug + from .utils import debug debug.setup_logging() diff --git a/kombu/abstract.py b/kombu/abstract.py index e613ad32..31614f49 100644 --- a/kombu/abstract.py +++ b/kombu/abstract.py @@ -8,9 +8,11 @@ Object utilities. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + from copy import copy -from kombu.exceptions import NotBoundError +from .exceptions import NotBoundError class Object(object): diff --git a/kombu/clocks.py b/kombu/clocks.py index 8b926fea..36e80468 100644 --- a/kombu/clocks.py +++ b/kombu/clocks.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + from threading import Lock diff --git a/kombu/common.py b/kombu/common.py index 9dc06bb0..b05551fb 100644 --- a/kombu/common.py +++ b/kombu/common.py @@ -1,5 +1,7 @@ -from kombu import entity -from kombu.utils import gen_unique_id as uuid +from __future__ import absolute_import + +from . import entity +from .utils import gen_unique_id as uuid # noqa def entry_to_queue(queue, **options): diff --git a/kombu/compat.py b/kombu/compat.py index 5d490475..9da1a3ac 100644 --- a/kombu/compat.py +++ b/kombu/compat.py @@ -10,11 +10,12 @@ See http://packages.python.org/pypi/carrot for documentation. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import from itertools import count -from kombu import entity -from kombu import messaging -from kombu.common import entry_to_queue +from . import entity +from . import messaging +from .common import entry_to_queue def _iterconsume(connection, consumer, no_ack=False, limit=None): diff --git a/kombu/compression.py b/kombu/compression.py index 98d016d8..e3cf2649 100644 --- a/kombu/compression.py +++ b/kombu/compression.py @@ -8,6 +8,8 @@ Compression utilities. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import zlib _aliases = {} diff --git a/kombu/connection.py b/kombu/connection.py index 51bd8878..4e0180bf 100644 --- a/kombu/connection.py +++ b/kombu/connection.py @@ -8,20 +8,22 @@ Broker connection and pools. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import os import sys import socket from copy import copy +from functools import wraps from itertools import count from Queue import Empty from urlparse import urlparse, parse_qsl -from kombu import exceptions -from kombu.transport import get_transport_cls -from kombu.utils import kwdict, partition, retry_over_time -from kombu.utils.compat import OrderedDict, LifoQueue as _LifoQueue -from kombu.utils.functional import wraps +from . import exceptions +from .transport import get_transport_cls +from .utils import kwdict, retry_over_time +from .utils.compat import OrderedDict, LifoQueue as _LifoQueue _LOG_CONNECTION = os.environ.get("KOMBU_LOG_CONNECTION", False) _LOG_CHANNEL = os.environ.get("KOMBU_LOG_CHANNEL", False) @@ -39,9 +41,9 @@ def parse_url(url): parts = urlparse(url.replace("%s://" % (scheme, ), "http://")) netloc = parts.netloc if '@' in netloc: - auth, _, netloc = partition(parts.netloc, '@') - userid, _, password = partition(auth, ':') - hostname, _, port = partition(netloc, ':') + auth, _, netloc = parts.netloc.partition('@') + userid, _, password = auth.partition(':') + hostname, _, port = netloc.partition(':') path = parts.path or "" if path and path[0] == '/': path = path[path.index('/') + 1:] @@ -70,7 +72,7 @@ class BrokerConnection(object): :keyword ssl: Use ssl to connect to the server. Default is ``False``. :keyword transport: Transport class to use. Can be a class, or a string specifying the path to the class. (e.g. - ``kombu.transport.pyamqplib.Transport``), or one of the aliases: + ``kombu.transport.amqplib.Transport``), or one of the aliases: ``amqplib``, ``pika``, ``redis``, ``memory``. :keyword connect_timeout: Timeout in seconds for connecting to the server. May not be suported by the specified transport. @@ -131,7 +133,7 @@ class BrokerConnection(object): self.transport_options = transport_options if _LOG_CONNECTION: - from kombu.utils.log import get_logger + from .utils.log import get_logger self._logger = get_logger("kombu.connection") def _init_params(self, hostname, userid, password, virtual_host, port, @@ -162,7 +164,7 @@ class BrokerConnection(object): self._debug("create channel") chan = self.transport.create_channel(self.connection) if _LOG_CHANNEL: - from kombu.utils.debug import Logwrapped + from .utils.debug import Logwrapped return Logwrapped(chan, "kombu.channel", "[Kombu channel:%(channel_id)s] ") return chan @@ -457,13 +459,13 @@ class BrokerConnection(object): return ChannelPool(self, limit, preload) def Producer(self, channel=None, *args, **kwargs): - from kombu.messaging import Producer + from .messaging import Producer if channel is None: channel = self # use default channel support. return Producer(channel, *args, **kwargs) def Consumer(self, channel=None, *args, **kwargs): - from kombu.messaging import Consumer + from .messaging import Consumer if channel is None: channel = self # use default channel support. return Consumer(channel, *args, **kwargs) @@ -491,7 +493,7 @@ class BrokerConnection(object): object. """ - from kombu.simple import SimpleQueue + from .simple import SimpleQueue channel_autoclose = False if channel is None: @@ -511,7 +513,7 @@ class BrokerConnection(object): and acknowledgements are disabled (``no_ack``). """ - from kombu.simple import SimpleBuffer + from .simple import SimpleBuffer channel_autoclose = False if channel is None: diff --git a/kombu/entity.py b/kombu/entity.py index 7810e0e5..c1947109 100644 --- a/kombu/entity.py +++ b/kombu/entity.py @@ -8,8 +8,10 @@ Exchange and Queue declarations. :license: BSD, see LICENSE for more details. """ -from kombu.abstract import MaybeChannelBound -from kombu.syn import blocking as _SYN +from __future__ import absolute_import + +from .abstract import MaybeChannelBound +from .syn import blocking as _SYN TRANSIENT_DELIVERY_MODE = 1 PERSISTENT_DELIVERY_MODE = 2 diff --git a/kombu/exceptions.py b/kombu/exceptions.py index bac4ac86..925f37cd 100644 --- a/kombu/exceptions.py +++ b/kombu/exceptions.py @@ -8,6 +8,7 @@ Exceptions. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import class NotBoundError(Exception): diff --git a/kombu/messaging.py b/kombu/messaging.py index bb471d12..f8671852 100644 --- a/kombu/messaging.py +++ b/kombu/messaging.py @@ -8,13 +8,15 @@ Sending and receiving messages. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + from itertools import count -from kombu import entity -from kombu.compression import compress -from kombu.serialization import encode -from kombu.syn import blocking as _SYN -from kombu.utils import maybe_list +from . import entity +from .compression import compress +from .serialization import encode +from .syn import blocking as _SYN +from .utils import maybe_list Exchange = entity.Exchange Queue = entity.Queue @@ -64,7 +66,7 @@ class Producer(object): def __init__(self, channel, exchange=None, routing_key=None, serializer=None, auto_declare=None, compression=None, on_return=None): - from kombu.connection import BrokerConnection + from .connection import BrokerConnection if isinstance(channel, BrokerConnection): channel = channel.default_channel self.channel = channel @@ -229,7 +231,7 @@ class Consumer(object): def __init__(self, channel, queues, no_ack=None, auto_declare=None, callbacks=None, on_decode_error=None): - from kombu.connection import BrokerConnection + from .connection import BrokerConnection if isinstance(channel, BrokerConnection): channel = channel.default_channel self.channel = channel diff --git a/kombu/pidbox.py b/kombu/pidbox.py index ad624e82..a462a46f 100644 --- a/kombu/pidbox.py +++ b/kombu/pidbox.py @@ -8,15 +8,16 @@ Generic process mailbox. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import import socket from copy import copy from itertools import count -from kombu.entity import Exchange, Queue -from kombu.messaging import Consumer, Producer -from kombu.utils import kwdict, uuid +from .entity import Exchange, Queue +from .messaging import Consumer, Producer +from .utils import kwdict, uuid class Node(object): diff --git a/kombu/pools.py b/kombu/pools.py index f2d92678..eca1c4fa 100644 --- a/kombu/pools.py +++ b/kombu/pools.py @@ -1,5 +1,7 @@ -from kombu.connection import Resource -from kombu.messaging import Producer +from __future__ import absolute_import + +from .connection import Resource +from .messaging import Producer from itertools import chain diff --git a/kombu/serialization.py b/kombu/serialization.py index 884a748d..7e0455b9 100644 --- a/kombu/serialization.py +++ b/kombu/serialization.py @@ -8,6 +8,8 @@ Serialization utilities. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import codecs import sys diff --git a/kombu/simple.py b/kombu/simple.py index f473aaa3..6f4ec0eb 100644 --- a/kombu/simple.py +++ b/kombu/simple.py @@ -8,14 +8,16 @@ Simple interface. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import socket from collections import deque from time import time from Queue import Empty -from kombu import entity -from kombu import messaging +from . import entity +from . import messaging class SimpleBase(object): diff --git a/kombu/syn.py b/kombu/syn.py index ae26d5d1..05754776 100644 --- a/kombu/syn.py +++ b/kombu/syn.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import sys #: current blocking method diff --git a/kombu/tests/__init__.py b/kombu/tests/__init__.py index d1bb075f..27b5e13e 100644 --- a/kombu/tests/__init__.py +++ b/kombu/tests/__init__.py @@ -1,25 +1,30 @@ +from __future__ import absolute_import + moduleindex = ("kombu.abstract", "kombu.compat", + "kombu.common", + "kombu.clocks", "kombu.compression", "kombu.connection", "kombu.entity", "kombu.exceptions", "kombu.messaging", "kombu.pidbox", + "kombu.pools", "kombu.serialization", "kombu.simple", "kombu.utils", "kombu.utils.compat", - "kombu.utils.functional", "kombu.transport", "kombu.transport.base", "kombu.transport.beanstalk", "kombu.transport.memory", "kombu.transport.mongodb", - "kombu.transport.pyamqplib", - "kombu.transport.pycouchdb", - "kombu.transport.pypika", - "kombu.transport.pyredis", + "kombu.transport.amqplib", + "kombu.transport.couchdb", + "kombu.transport.pika", + "kombu.transport.redis", + "kombu.transport.SQS", "kombu.transport.virtual", "kombu.transport.virtual.exchange", "kombu.transport.virtual.scheduling") diff --git a/kombu/tests/mocks.py b/kombu/tests/mocks.py index f07e04c2..ac94c4b9 100644 --- a/kombu/tests/mocks.py +++ b/kombu/tests/mocks.py @@ -1,8 +1,10 @@ +from __future__ import absolute_import + from itertools import count import anyjson -from kombu.transport import base +from ..transport import base class Message(base.Message): diff --git a/kombu/tests/test_compat.py b/kombu/tests/test_compat.py index d0cb5a67..e0dec1c3 100644 --- a/kombu/tests/test_compat.py +++ b/kombu/tests/test_compat.py @@ -1,9 +1,11 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu import BrokerConnection, Exchange -from kombu import compat -from kombu.tests.mocks import Transport, Channel +from .. import BrokerConnection, Exchange +from .. import compat + +from .mocks import Transport, Channel +from .utils import unittest class test_misc(unittest.TestCase): diff --git a/kombu/tests/test_compression.py b/kombu/tests/test_compression.py index 0f6a66c5..9c1ff3ff 100644 --- a/kombu/tests/test_compression.py +++ b/kombu/tests/test_compression.py @@ -1,7 +1,9 @@ +from __future__ import absolute_import + from nose import SkipTest -from kombu import compression -from kombu.tests.utils import unittest +from .. import compression +from .utils import unittest class test_compression(unittest.TestCase): diff --git a/kombu/tests/test_connection.py b/kombu/tests/test_connection.py index b01fbd44..2193618f 100644 --- a/kombu/tests/test_connection.py +++ b/kombu/tests/test_connection.py @@ -1,9 +1,11 @@ +from __future__ import absolute_import import pickle -from kombu.tests.utils import unittest -from kombu.connection import BrokerConnection, Resource -from kombu.tests.mocks import Transport +from ..connection import BrokerConnection, Resource + +from .mocks import Transport +from .utils import unittest class test_Connection(unittest.TestCase): diff --git a/kombu/tests/test_entities.py b/kombu/tests/test_entities.py index 2f32bc30..e16e15cd 100644 --- a/kombu/tests/test_entities.py +++ b/kombu/tests/test_entities.py @@ -1,10 +1,11 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu import Connection -from kombu.entity import Exchange, Queue -from kombu.exceptions import NotBoundError +from .. import Connection +from ..entity import Exchange, Queue +from ..exceptions import NotBoundError -from kombu.tests.mocks import Transport +from .mocks import Transport +from .utils import unittest def get_conn(): diff --git a/kombu/tests/test_messaging.py b/kombu/tests/test_messaging.py index de5be1dc..f0f5c537 100644 --- a/kombu/tests/test_messaging.py +++ b/kombu/tests/test_messaging.py @@ -1,13 +1,14 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import import anyjson -from kombu.connection import BrokerConnection -from kombu.exceptions import MessageStateError -from kombu.messaging import Consumer, Producer -from kombu.entity import Exchange, Queue +from ..connection import BrokerConnection +from ..exceptions import MessageStateError +from ..messaging import Consumer, Producer +from ..entity import Exchange, Queue -from kombu.tests.mocks import Transport +from .mocks import Transport +from .utils import unittest class test_Producer(unittest.TestCase): diff --git a/kombu/tests/test_pidbox.py b/kombu/tests/test_pidbox.py index 5520924b..fa77d71e 100644 --- a/kombu/tests/test_pidbox.py +++ b/kombu/tests/test_pidbox.py @@ -1,8 +1,10 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu import pidbox -from kombu.connection import BrokerConnection -from kombu.utils import uuid +from .. import pidbox +from ..connection import BrokerConnection +from ..utils import uuid + +from .utils import unittest class test_Mailbox(unittest.TestCase): diff --git a/kombu/tests/test_serialization.py b/kombu/tests/test_serialization.py index 5e416fe6..9f87c857 100644 --- a/kombu/tests/test_serialization.py +++ b/kombu/tests/test_serialization.py @@ -1,15 +1,16 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +from __future__ import absolute_import import sys -from kombu.serialization import registry, register, SerializerNotInstalled, \ - raw_encode, register_yaml, register_msgpack, \ - decode, bytes_type, pickle, \ - unregister, register_pickle +from ..serialization import (registry, register, SerializerNotInstalled, + raw_encode, register_yaml, register_msgpack, + decode, bytes_type, pickle, + unregister, register_pickle) -from kombu.tests.utils import unittest -from kombu.tests.utils import mask_modules, skip_if_not_module +from .utils import unittest +from .utils import mask_modules, skip_if_not_module # For content_encoding tests unicode_string = u'abcdé\u8463' diff --git a/kombu/tests/test_simple.py b/kombu/tests/test_simple.py index eaa9a877..d1c0f2c0 100644 --- a/kombu/tests/test_simple.py +++ b/kombu/tests/test_simple.py @@ -1,8 +1,9 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import from Queue import Empty -from kombu import BrokerConnection, Exchange, Queue +from .. import BrokerConnection, Exchange, Queue +from .utils import unittest class SimpleBase(unittest.TestCase): diff --git a/kombu/tests/test_transport.py b/kombu/tests/test_transport.py index af677f46..b7246ed0 100644 --- a/kombu/tests/test_transport.py +++ b/kombu/tests/test_transport.py @@ -1,8 +1,9 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu import transport +from .. import transport -from kombu.tests.utils import mask_modules, module_exists +from .utils import unittest +from .utils import mask_modules, module_exists class test_transport(unittest.TestCase): diff --git a/kombu/tests/test_transport_pyamqplib.py b/kombu/tests/test_transport_amqplib.py index 5cb17c5f..4309c03b 100644 --- a/kombu/tests/test_transport_pyamqplib.py +++ b/kombu/tests/test_transport_amqplib.py @@ -1,8 +1,9 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu.transport import pyamqplib -from kombu.connection import BrokerConnection +from ..transport import amqplib +from ..connection import BrokerConnection +from .utils import unittest class MockConnection(dict): @@ -14,7 +15,7 @@ class test_amqplib(unittest.TestCase): def test_default_port(self): - class Transport(pyamqplib.Transport): + class Transport(amqplib.Transport): Connection = MockConnection c = BrokerConnection(port=None, transport=Transport).connect() @@ -23,7 +24,7 @@ class test_amqplib(unittest.TestCase): def test_custom_port(self): - class Transport(pyamqplib.Transport): + class Transport(amqplib.Transport): Connection = MockConnection c = BrokerConnection(port=1337, transport=Transport).connect() diff --git a/kombu/tests/test_transport_base.py b/kombu/tests/test_transport_base.py index f1828726..f02d150f 100644 --- a/kombu/tests/test_transport_base.py +++ b/kombu/tests/test_transport_base.py @@ -1,6 +1,7 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu.transport.base import Transport +from ..transport.base import Transport +from .utils import unittest class test_interface(unittest.TestCase): diff --git a/kombu/tests/test_transport_memory.py b/kombu/tests/test_transport_memory.py index b1782b23..a8b38471 100644 --- a/kombu/tests/test_transport_memory.py +++ b/kombu/tests/test_transport_memory.py @@ -1,9 +1,12 @@ +from __future__ import absolute_import + import socket -from kombu.tests.utils import unittest -from kombu.connection import BrokerConnection -from kombu.entity import Exchange, Queue -from kombu.messaging import Consumer, Producer +from ..connection import BrokerConnection +from ..entity import Exchange, Queue +from ..messaging import Consumer, Producer + +from .utils import unittest class test_MemoryTransport(unittest.TestCase): diff --git a/kombu/tests/test_transport_pyredis.py b/kombu/tests/test_transport_redis.py index e0b31d42..4c01d0b9 100644 --- a/kombu/tests/test_transport_pyredis.py +++ b/kombu/tests/test_transport_redis.py @@ -1,18 +1,18 @@ +from __future__ import absolute_import + import socket import types from itertools import count from Queue import Empty, Queue as _Queue -from kombu.connection import BrokerConnection -from kombu.entity import Exchange, Queue -from kombu.messaging import Consumer, Producer - -from kombu.tests.utils import unittest -from kombu.tests.utils import module_exists +from ..connection import BrokerConnection +from ..entity import Exchange, Queue +from ..messaging import Consumer, Producer +from ..utils import eventio # patch poll -# patch poll -from kombu.utils import eventio +from .utils import unittest +from .utils import module_exists class _poll(eventio._select): @@ -26,7 +26,7 @@ class _poll(eventio._select): eventio.poll = _poll -from kombu.transport import pyredis # must import after poller patch +from ..transport import redis # must import after poller patch class ResponseError(Exception): @@ -169,7 +169,7 @@ class Pipeline(object): return [fun(*args, **kwargs) for fun, args, kwargs in stack] -class Channel(pyredis.Channel): +class Channel(redis.Channel): def _get_client(self): return Client @@ -181,7 +181,7 @@ class Channel(pyredis.Channel): self.client._new_queue(queue) -class Transport(pyredis.Transport): +class Transport(redis.Transport): Channel = Channel def _get_errors(self): @@ -300,9 +300,9 @@ class test_Redis(unittest.TestCase): def test_get_client(self): - redis, exceptions = _redis_modules() + myredis, exceptions = _redis_modules() - @module_exists(redis, exceptions) + @module_exists(myredis, exceptions) def _do_test(): conn = BrokerConnection(transport=Transport) chan = conn.channel() @@ -341,8 +341,8 @@ def _redis_modules(): class Redis(object): pass - redis = types.ModuleType("redis") - redis.exceptions = exceptions - redis.Redis = Redis + myredis = types.ModuleType("redis") + myredis.exceptions = exceptions + myredis.Redis = Redis - return redis, exceptions + return myredis, exceptions diff --git a/kombu/tests/test_transport_virtual.py b/kombu/tests/test_transport_virtual.py index 46a8f861..ccc8b1c0 100644 --- a/kombu/tests/test_transport_virtual.py +++ b/kombu/tests/test_transport_virtual.py @@ -1,10 +1,11 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu.connection import BrokerConnection -from kombu.transport import virtual -from kombu.utils import uuid +from ..connection import BrokerConnection +from ..transport import virtual +from ..utils import uuid -from kombu.tests.utils import redirect_stdouts +from .utils import unittest +from .utils import redirect_stdouts def client(): diff --git a/kombu/tests/test_utils.py b/kombu/tests/test_utils.py index 5daf75a2..539dbc9c 100644 --- a/kombu/tests/test_utils.py +++ b/kombu/tests/test_utils.py @@ -1,19 +1,19 @@ +from __future__ import absolute_import + import pickle import sys -from kombu.tests.utils import unittest + +from functools import wraps if sys.version_info >= (3, 0): from io import StringIO, BytesIO else: from StringIO import StringIO, StringIO as BytesIO # noqa -from kombu import utils -from kombu.utils.functional import wraps +from .. import utils -from kombu.tests.utils import redirect_stdouts, mask_modules, skip_if_module - -partition = utils._compat_partition -rpartition = utils._compat_rpartition +from .utils import redirect_stdouts, mask_modules, skip_if_module +from .utils import unittest class OldString(object): @@ -38,48 +38,6 @@ class test_utils(unittest.TestCase): self.assertEqual(utils.maybe_list(1), [1]) self.assertEqual(utils.maybe_list([1, 2, 3]), [1, 2, 3]) - def assert_partition(self, p, t=str): - self.assertEqual(p(t("foo.bar.baz"), "."), - ("foo", ".", "bar.baz")) - self.assertEqual(p(t("foo"), "."), - ("foo", "", "")) - self.assertEqual(p(t("foo."), "."), - ("foo", ".", "")) - self.assertEqual(p(t(".bar"), "."), - ("", ".", "bar")) - self.assertEqual(p(t("."), "."), - ('', ".", '')) - - def assert_rpartition(self, p, t=str): - self.assertEqual(p(t("foo.bar.baz"), "."), - ("foo.bar", ".", "baz")) - self.assertEqual(p(t("foo"), "."), - ("", "", "foo")) - self.assertEqual(p(t("foo."), "."), - ("foo", ".", "")) - self.assertEqual(p(t(".bar"), "."), - ("", ".", "bar")) - self.assertEqual(p(t("."), "."), - ('', ".", '')) - - def test_compat_partition(self): - self.assert_partition(partition) - - def test_compat_rpartition(self): - self.assert_rpartition(rpartition) - - def test_partition(self): - self.assert_partition(utils.partition) - - def test_rpartition(self): - self.assert_rpartition(utils.rpartition) - - def test_partition_oldstr(self): - self.assert_partition(utils.partition, OldString) - - def test_rpartition_oldstr(self): - self.assert_rpartition(utils.rpartition, OldString) - class test_UUID(unittest.TestCase): @@ -99,7 +57,7 @@ class test_UUID(unittest.TestCase): @mask_modules("ctypes") def with_ctypes_masked(): - from kombu.utils import ctypes, uuid + from ..utils import ctypes, uuid self.assertIsNone(ctypes) tid = uuid() diff --git a/kombu/tests/test_virtual_exchange.py b/kombu/tests/test_virtual_exchange.py index c7fb28c1..b842d09b 100644 --- a/kombu/tests/test_virtual_exchange.py +++ b/kombu/tests/test_virtual_exchange.py @@ -1,9 +1,10 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu import BrokerConnection -from kombu.transport.virtual import exchange +from .. import BrokerConnection +from ..transport.virtual import exchange -from kombu.tests.mocks import Transport +from .mocks import Transport +from .utils import unittest class ExchangeCase(unittest.TestCase): diff --git a/kombu/tests/test_virtual_scheduling.py b/kombu/tests/test_virtual_scheduling.py index d1e36f94..e5310824 100644 --- a/kombu/tests/test_virtual_scheduling.py +++ b/kombu/tests/test_virtual_scheduling.py @@ -1,6 +1,8 @@ -from kombu.tests.utils import unittest +from __future__ import absolute_import -from kombu.transport.virtual.scheduling import FairCycle +from ..transport.virtual.scheduling import FairCycle + +from .utils import unittest class MyEmpty(Exception): diff --git a/kombu/tests/utils.py b/kombu/tests/utils.py index 8ef4cbd4..ad73f3f8 100644 --- a/kombu/tests/utils.py +++ b/kombu/tests/utils.py @@ -1,14 +1,15 @@ +from __future__ import absolute_import + import __builtin__ import os import sys import types +from functools import wraps from StringIO import StringIO from nose import SkipTest -from kombu.utils.functional import wraps - try: import unittest unittest.skip diff --git a/kombu/transport/SQS.py b/kombu/transport/SQS.py index f9ee2c75..91a517a4 100644 --- a/kombu/transport/SQS.py +++ b/kombu/transport/SQS.py @@ -8,6 +8,8 @@ Amazon SQS transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import socket import string @@ -23,9 +25,9 @@ from boto.sdb.connection import SDBConnection from boto.sqs.connection import SQSConnection from boto.sqs.message import Message -from kombu.transport import virtual -from kombu.utils import cached_property, uuid +from ..utils import cached_property, uuid +from . import virtual # dots are replaced by dash, all other punctuation # replaced by underscore. diff --git a/kombu/transport/__init__.py b/kombu/transport/__init__.py index 0acdce36..22ab0a30 100644 --- a/kombu/transport/__init__.py +++ b/kombu/transport/__init__.py @@ -8,11 +8,11 @@ Built-in transports. :license: BSD, see LICENSE for more details. """ -import sys +from __future__ import absolute_import -from kombu.utils import rpartition +import sys -DEFAULT_TRANSPORT = "kombu.transport.pyamqplib.Transport" +DEFAULT_TRANSPORT = "kombu.transport.amqplib.Transport" MISSING_LIB = """ The %(feature)s requires the %(lib)s module to be @@ -68,21 +68,21 @@ def _ghettoq(name, new, alias=None): TRANSPORT_ALIASES = { - "amqp": "kombu.transport.pyamqplib.Transport", - "amqplib": "kombu.transport.pyamqplib.Transport", + "amqp": "kombu.transport.amqplib.Transport", + "amqplib": "kombu.transport.amqplib.Transport", "librabbitmq": "kombu.transport.librabbitmq.Transport", - "pika": "kombu.transport.pypika.AsyncoreTransport", - "syncpika": "kombu.transport.pypika.SyncTransport", + "pika": "kombu.transport.pika.AsyncoreTransport", + "syncpika": "kombu.transport.pika.SyncTransport", "memory": "kombu.transport.memory.Transport", - "redis": "kombu.transport.pyredis.Transport", + "redis": "kombu.transport.redis.Transport", "SQS": "kombu.transport.SQS.Transport", "beanstalk": "kombu.transport.beanstalk.Transport", "mongodb": "kombu.transport.mongodb.Transport", - "couchdb": "kombu.transport.pycouchdb.Transport", + "couchdb": "kombu.transport.couchdb.Transport", "django": _django_transport, "sqlalchemy": _sqlalchemy_transport, - "ghettoq.taproot.Redis": _ghettoq("Redis", "pyredis", "redis"), + "ghettoq.taproot.Redis": _ghettoq("Redis", "redis", "redis"), "ghettoq.taproot.Database": _ghettoq("Database", _django_transport, "django"), "ghettoq.taproot.MongoDB": _ghettoq("MongoDB", "mongodb"), @@ -97,7 +97,7 @@ def resolve_transport(transport=None): transport = TRANSPORT_ALIASES.get(transport, transport) if callable(transport): transport = transport() - transport_module_name, _, transport_cls_name = rpartition(transport, ".") + transport_module_name, _, transport_cls_name = transport.rpartition(".") if not transport_module_name: raise KeyError("No such transport: %s" % (transport, )) return transport_module_name, transport_cls_name @@ -115,7 +115,7 @@ def get_transport_cls(transport=None): The transport string is the full path to a transport class, e.g.:: - "kombu.transport.pyamqplib.Transport" + "kombu.transport.amqplib.Transport" If the name does not include `"."` (is not fully qualified), the alias table will be consulted. diff --git a/kombu/transport/pyamqplib.py b/kombu/transport/amqplib.py index 12bcd672..7f6de539 100644 --- a/kombu/transport/pyamqplib.py +++ b/kombu/transport/amqplib.py @@ -1,6 +1,6 @@ """ -kombu.transport.pyamqplib -========================= +kombu.transport.amqplib +======================= amqplib transport. @@ -8,6 +8,8 @@ amqplib transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import socket try: @@ -22,7 +24,7 @@ from amqplib.client_0_8.channel import Channel as _Channel from amqplib.client_0_8.exceptions import AMQPConnectionException from amqplib.client_0_8.exceptions import AMQPChannelException -from kombu.transport import base +from . import base DEFAULT_PORT = 5672 diff --git a/kombu/transport/base.py b/kombu/transport/base.py index fa2ddbac..d8faa78c 100644 --- a/kombu/transport/base.py +++ b/kombu/transport/base.py @@ -8,10 +8,11 @@ Base transport interface. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import -from kombu import serialization -from kombu.compression import decompress -from kombu.exceptions import MessageStateError +from .. import serialization +from ..compression import decompress +from ..exceptions import MessageStateError ACKNOWLEDGED_STATES = frozenset(["ACK", "REJECTED", "REQUEUED"]) @@ -20,11 +21,11 @@ class StdChannel(object): no_ack_consumers = None def Consumer(self, *args, **kwargs): - from kombu.messaging import Consumer + from ..messaging import Consumer return Consumer(self, *args, **kwargs) def Producer(self, *args, **kwargs): - from kombu.messaging import Producer + from ..messaging import Producer return Producer(self, *args, **kwargs) def list_bindings(self): diff --git a/kombu/transport/beanstalk.py b/kombu/transport/beanstalk.py index 216a021a..488d641d 100644 --- a/kombu/transport/beanstalk.py +++ b/kombu/transport/beanstalk.py @@ -8,6 +8,8 @@ Beanstalk transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import socket from Queue import Empty @@ -15,7 +17,7 @@ from Queue import Empty from anyjson import serialize, deserialize from beanstalkc import Connection, BeanstalkcException, SocketError -from kombu.transport import virtual +from . import virtual DEFAULT_PORT = 11300 diff --git a/kombu/transport/pycouchdb.py b/kombu/transport/couchdb.py index af50b527..669edd21 100644 --- a/kombu/transport/pycouchdb.py +++ b/kombu/transport/couchdb.py @@ -1,6 +1,6 @@ """ -kombu.transport.pycouchdb -========================= +kombu.transport.couchdb +======================= CouchDB transport. @@ -8,6 +8,8 @@ CouchDB transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + from Queue import Empty import socket @@ -15,8 +17,8 @@ import couchdb from anyjson import serialize, deserialize -from kombu.transport import virtual -from kombu.utils import uuid4 +from ..utils import uuid4 +from . import virtual DEFAULT_PORT = 5984 DEFAULT_DATABASE = "kombu_default" diff --git a/kombu/transport/librabbitmq.py b/kombu/transport/librabbitmq.py index d88c7d74..90e914e2 100644 --- a/kombu/transport/librabbitmq.py +++ b/kombu/transport/librabbitmq.py @@ -8,12 +8,13 @@ pylibrabbitmq transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import import socket import pylibrabbitmq as amqp from pylibrabbitmq import ChannelError, ConnectionError -from kombu.transport import base +from . import base DEFAULT_PORT = 5672 diff --git a/kombu/transport/memory.py b/kombu/transport/memory.py index 4f6d4ff4..af8aecfa 100644 --- a/kombu/transport/memory.py +++ b/kombu/transport/memory.py @@ -8,9 +8,11 @@ In-memory transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + from Queue import Queue -from kombu.transport import virtual +from . import virtual class Channel(virtual.Channel): diff --git a/kombu/transport/mongodb.py b/kombu/transport/mongodb.py index 26017fe8..a0653c76 100644 --- a/kombu/transport/mongodb.py +++ b/kombu/transport/mongodb.py @@ -9,6 +9,8 @@ MongoDB transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + from Queue import Empty import pymongo @@ -16,7 +18,7 @@ from pymongo import errors from anyjson import serialize, deserialize from pymongo.connection import Connection -from kombu.transport import virtual +from . import virtual DEFAULT_HOST = "127.0.0.1" DEFAULT_PORT = 27017 diff --git a/kombu/transport/pypika.py b/kombu/transport/pika.py index 7228ba41..e4a8b16e 100644 --- a/kombu/transport/pypika.py +++ b/kombu/transport/pika.py @@ -1,6 +1,6 @@ """ -kombu.transport.pypika -====================== +kombu.transport.pika +==================== Pika transport. @@ -8,12 +8,14 @@ Pika transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import socket from operator import attrgetter -from kombu.exceptions import VersionMismatch -from kombu.transport import base +from ..exceptions import VersionMismatch +from . import base from pika import channel # must be here to raise importerror for below. try: @@ -25,6 +27,7 @@ from pika import connection from pika import exceptions from pika.spec import Basic, BasicProperties + DEFAULT_PORT = 5672 diff --git a/kombu/transport/pyredis.py b/kombu/transport/redis.py index 9125ee7a..1ebf4643 100644 --- a/kombu/transport/pyredis.py +++ b/kombu/transport/redis.py @@ -1,6 +1,6 @@ """ -kombu.transport.pyredis -======================= +kombu.transport.redis +===================== Redis transport. @@ -8,15 +8,16 @@ Redis transport. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import from Queue import Empty from anyjson import serialize, deserialize -from kombu.exceptions import VersionMismatch -from kombu.transport import virtual -from kombu.utils import eventio -from kombu.utils import cached_property +from ..exceptions import VersionMismatch +from ..utils import eventio, cached_property + +from . import virtual DEFAULT_PORT = 6379 DEFAULT_DB = 0 diff --git a/kombu/transport/virtual/__init__.py b/kombu/transport/virtual/__init__.py index 6320c934..291164ef 100644 --- a/kombu/transport/virtual/__init__.py +++ b/kombu/transport/virtual/__init__.py @@ -10,6 +10,8 @@ Emulates the AMQ API for non-AMQ transports. :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import base64 import socket @@ -17,14 +19,15 @@ from itertools import count from time import sleep, time from Queue import Empty -from kombu.exceptions import StdChannelError -from kombu.transport import base -from kombu.utils import emergency_dump_state, say -from kombu.utils.compat import OrderedDict -from kombu.utils.finalize import Finalize +from ...exceptions import StdChannelError +from ...utils import emergency_dump_state, say +from ...utils.compat import OrderedDict +from ...utils.finalize import Finalize + +from .. import base -from kombu.transport.virtual.scheduling import FairCycle -from kombu.transport.virtual.exchange import STANDARD_EXCHANGE_TYPES +from .scheduling import FairCycle +from .exchange import STANDARD_EXCHANGE_TYPES class Base64(object): diff --git a/kombu/transport/virtual/exchange.py b/kombu/transport/virtual/exchange.py index 86190064..90cadf32 100644 --- a/kombu/transport/virtual/exchange.py +++ b/kombu/transport/virtual/exchange.py @@ -9,6 +9,8 @@ by the AMQ protocol (excluding the `headers` exchange). :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + import re diff --git a/kombu/transport/virtual/scheduling.py b/kombu/transport/virtual/scheduling.py index d25d2117..c361d525 100644 --- a/kombu/transport/virtual/scheduling.py +++ b/kombu/transport/virtual/scheduling.py @@ -8,6 +8,8 @@ :license: BSD, see LICENSE for more details. """ +from __future__ import absolute_import + from itertools import count diff --git a/kombu/utils/__init__.py b/kombu/utils/__init__.py index bbe81c35..374a36ed 100644 --- a/kombu/utils/__init__.py +++ b/kombu/utils/__init__.py @@ -1,9 +1,11 @@ +from __future__ import absolute_import + import sys from time import sleep from uuid import UUID, uuid4 as _uuid4, _uuid_generate_random -from kombu.utils.encoding import safe_repr as _safe_repr +from .encoding import safe_repr as _safe_repr try: import ctypes @@ -145,54 +147,6 @@ def emergency_dump_state(state, open_file=open, dump=None): fh.close() return persist -############## str.partition/str.rpartition ################################# - - -def _compat_rl_partition(S, sep, direction=None, reverse=False): - items = direction(sep, 1) - if len(items) == 1: - if reverse: - return '', '', items[0] - return items[0], '', '' - return items[0], sep, items[1] - - -def _compat_partition(S, sep): - """``partition(S, sep) -> (head, sep, tail)`` - - Search for the separator ``sep`` in ``S``, and return the part before - it, the separator itself, and the part after it. If the separator is not - found, return ``S`` and two empty strings. - - """ - return _compat_rl_partition(S, sep, direction=S.split) - - -def _compat_rpartition(S, sep): - """``rpartition(S, sep) -> (tail, sep, head)`` - - Search for the separator ``sep`` in ``S``, starting at the end of ``S``, - and return the part before it, the separator itself, and the part - after it. If the separator is not found, return two empty - strings and ``S``. - - """ - return _compat_rl_partition(S, sep, direction=S.rsplit, reverse=True) - - -def partition(S, sep): - if hasattr(S, 'partition'): - return S.partition(sep) - else: # Python <= 2.4: - return _compat_partition(S, sep) - - -def rpartition(S, sep): - if hasattr(S, 'rpartition'): - return S.rpartition(sep) - else: # Python <= 2.4: - return _compat_rpartition(S, sep) - class cached_property(object): """Property descriptor that caches the return value diff --git a/kombu/utils/compat.py b/kombu/utils/compat.py index 4bd2386e..e492c4fc 100644 --- a/kombu/utils/compat.py +++ b/kombu/utils/compat.py @@ -1,29 +1,5 @@ import sys -############## __builtin__.all ############################################## - -try: - all([True]) - all = all -except NameError: - def all(iterable): # noqa - for item in iterable: - if not item: - return False - return True - -############## __builtin__.any ############################################## - -try: - any([True]) - any = any -except NameError: - def any(iterable): # noqa - for item in iterable: - if item: - return True - return False - ############## collections.OrderedDict ####################################### import weakref diff --git a/kombu/utils/debug.py b/kombu/utils/debug.py index 09736c8e..3a6f84f7 100644 --- a/kombu/utils/debug.py +++ b/kombu/utils/debug.py @@ -1,7 +1,10 @@ +from __future__ import absolute_import + import logging -from kombu.utils.functional import wraps -from kombu.utils.log import get_logger +from functools import wraps + +from .log import get_logger def setup_logging(loglevel=logging.DEBUG, loggers=["kombu.connection", diff --git a/kombu/utils/encoding.py b/kombu/utils/encoding.py index c9e091ac..a30cbdf4 100644 --- a/kombu/utils/encoding.py +++ b/kombu/utils/encoding.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import sys import traceback diff --git a/kombu/utils/eventio.py b/kombu/utils/eventio.py index e8b41d58..7ed97f6e 100644 --- a/kombu/utils/eventio.py +++ b/kombu/utils/eventio.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import select import socket diff --git a/kombu/utils/finalize.py b/kombu/utils/finalize.py index 46331f53..bc2178ba 100644 --- a/kombu/utils/finalize.py +++ b/kombu/utils/finalize.py @@ -1,4 +1,6 @@ """Taken from multiprocessing.util.Finalize.""" +from __future__ import absolute_import + import weakref from itertools import count diff --git a/kombu/utils/functional.py b/kombu/utils/functional.py deleted file mode 100644 index ad5da24e..00000000 --- a/kombu/utils/functional.py +++ /dev/null @@ -1,137 +0,0 @@ -"""Functional utilities for Python 2.4 compatibility.""" -# License for code in this file that was taken from Python 2.5. - -# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -# -------------------------------------------- -# -# 1. This LICENSE AGREEMENT is between the Python Software Foundation -# ("PSF"), and the Individual or Organization ("Licensee") accessing and -# otherwise using this software ("Python") in source or binary form and -# its associated documentation. -# -# 2. Subject to the terms and conditions of this License Agreement, PSF -# hereby grants Licensee a nonexclusive, royalty-free, world-wide -# license to reproduce, analyze, test, perform and/or display publicly, -# prepare derivative works, distribute, and otherwise use Python -# alone or in any derivative version, provided, however, that PSF's -# License Agreement and PSF's notice of copyright, i.e., "Copyright (c) -# 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; -# All Rights Reserved" are retained in Python alone or in any derivative -# version prepared by Licensee. -# -# 3. In the event Licensee prepares a derivative work that is based on -# or incorporates Python or any part thereof, and wants to make -# the derivative work available to others as provided herein, then -# Licensee hereby agrees to include in any such work a brief summary of -# the changes made to Python. -# -# 4. PSF is making Python available to Licensee on an "AS IS" -# basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR -# IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND -# DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS -# FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT -# INFRINGE ANY THIRD PARTY RIGHTS. -# -# 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON -# FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS -# A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, -# OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. -# -# 6. This License Agreement will automatically terminate upon a material -# breach of its terms and conditions. -# -# 7. Nothing in this License Agreement shall be deemed to create any -# relationship of agency, partnership, or joint venture between PSF and -# Licensee. This License Agreement does not grant permission to use PSF -# trademarks or trade name in a trademark sense to endorse or promote -# products or services of Licensee, or any third party. -# -# 8. By copying, installing or otherwise using Python, Licensee -# agrees to be bound by the terms and conditions of this License -# Agreement. - -### Begin from Python 2.5 functools.py ######################################## - -# Summary of changes made to the Python 2.5 code below: -# * Wrapped the ``setattr`` call in ``update_wrapper`` with a try-except -# block to make it compatible with Python 2.3, which doesn't allow -# assigning to ``__name__``. - -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software -# Foundation. All Rights Reserved. - -############################################################################### - -# update_wrapper() and wraps() are tools to help write -# wrapper functions that can handle naive introspection - - -def _compat_partial(fun, *args, **kwargs): - """New function with partial application of the given arguments - and keywords.""" - - def _curried(*addargs, **addkwargs): - return fun(*(args + addargs), **dict(kwargs, **addkwargs)) - - return _curried - - -try: - from functools import partial -except ImportError: - partial = _compat_partial # noqa - -WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') -WRAPPER_UPDATES = ('__dict__',) - - -def _compat_update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, - updated=WRAPPER_UPDATES): - """Update a wrapper function to look like the wrapped function - - wrapper is the function to be updated - wrapped is the original function - assigned is a tuple naming the attributes assigned directly - from the wrapped function to the wrapper function (defaults to - functools.WRAPPER_ASSIGNMENTS) - updated is a tuple naming the attributes off the wrapper that - are updated with the corresponding attribute from the wrapped - function (defaults to functools.WRAPPER_UPDATES) - - """ - for attr in assigned: - try: - setattr(wrapper, attr, getattr(wrapped, attr)) - except TypeError: # Python 2.3 doesn't allow assigning to __name__. - pass - for attr in updated: - getattr(wrapper, attr).update(getattr(wrapped, attr)) - # Return the wrapper so this can be used as a decorator via partial() - return wrapper - -try: - from functools import update_wrapper -except ImportError: - update_wrapper = _compat_update_wrapper # noqa - - -def _compat_wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, - updated=WRAPPER_UPDATES): - """Decorator factory to apply update_wrapper() to a wrapper function - - Returns a decorator that invokes update_wrapper() with the decorated - function as the wrapper argument and the arguments to wraps() as the - remaining arguments. Default arguments are as for update_wrapper(). - This is a convenience function to simplify applying partial() to - update_wrapper(). - - """ - return partial(update_wrapper, wrapped=wrapped, - assigned=assigned, updated=updated) - -try: - from functools import wraps -except ImportError: - wraps = _compat_wraps # noqa - -### End from Python 2.5 functools.py ########################################## diff --git a/kombu/utils/log.py b/kombu/utils/log.py index 952be9fd..88867b9a 100644 --- a/kombu/utils/log.py +++ b/kombu/utils/log.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import logging |