Browse Source

Make sure __repr__ and __str__ returns bytes on Python 2

Ask Solem 9 years ago
parent
commit
9b68e8f9df

+ 5 - 2
celery/app/base.py

@@ -32,7 +32,9 @@ from celery._state import (
 )
 )
 from celery.datastructures import AttributeDictMixin
 from celery.datastructures import AttributeDictMixin
 from celery.exceptions import AlwaysEagerIgnored, ImproperlyConfigured
 from celery.exceptions import AlwaysEagerIgnored, ImproperlyConfigured
-from celery.five import UserDict, module_name_t, values
+from celery.five import (
+    UserDict, bytes_if_py2, python_2_unicode_compatible, values,
+)
 from celery.loaders import get_loader_cls
 from celery.loaders import get_loader_cls
 from celery.local import PromiseProxy, maybe_evaluate
 from celery.local import PromiseProxy, maybe_evaluate
 from celery.utils import abstract
 from celery.utils import abstract
@@ -108,6 +110,7 @@ class PendingConfiguration(UserDict, AttributeDictMixin):
         return self.callback(key)
         return self.callback(key)
 
 
 
 
+@python_2_unicode_compatible
 class Celery(object):
 class Celery(object):
     """Celery application.
     """Celery application.
 
 
@@ -950,7 +953,7 @@ class Celery(object):
         if not keep_reduce:
         if not keep_reduce:
             attrs['__reduce__'] = __reduce__
             attrs['__reduce__'] = __reduce__
 
 
-        return type(module_name_t(name or Class.__name__), (Class,), attrs)
+        return type(bytes_if_py2(name or Class.__name__), (Class,), attrs)
 
 
     def _rgetattr(self, path):
     def _rgetattr(self, path):
         return attrgetter(path)(self)
         return attrgetter(path)(self)

+ 2 - 1
celery/app/defaults.py

@@ -13,7 +13,7 @@ import sys
 from collections import deque, namedtuple
 from collections import deque, namedtuple
 from datetime import timedelta
 from datetime import timedelta
 
 
-from celery.five import items, keys, values
+from celery.five import items, keys, python_2_unicode_compatible, values
 from celery.utils import strtobool
 from celery.utils import strtobool
 from celery.utils.functional import memoize
 from celery.utils.functional import memoize
 
 
@@ -58,6 +58,7 @@ def old_ns(ns):
     return {'{0}_{{0}}'.format(ns)}
     return {'{0}_{{0}}'.format(ns)}
 
 
 
 
+@python_2_unicode_compatible
 class Option(object):
 class Option(object):
     alt = None
     alt = None
     deprecate_by = None
     deprecate_by = None

+ 3 - 1
celery/app/task.py

@@ -17,7 +17,7 @@ from celery import states
 from celery._state import _task_stack
 from celery._state import _task_stack
 from celery.canvas import signature
 from celery.canvas import signature
 from celery.exceptions import Ignore, MaxRetriesExceededError, Reject, Retry
 from celery.exceptions import Ignore, MaxRetriesExceededError, Reject, Retry
-from celery.five import class_property, items
+from celery.five import class_property, items, python_2_unicode_compatible
 from celery.result import EagerResult
 from celery.result import EagerResult
 from celery.utils import abstract
 from celery.utils import abstract
 from celery.utils import uuid, maybe_reraise
 from celery.utils import uuid, maybe_reraise
@@ -65,6 +65,7 @@ def _reprtask(task, fmt=None, flags=None):
     )
     )
 
 
 
 
+@python_2_unicode_compatible
 class Context(object):
 class Context(object):
     # Default context
     # Default context
     logfile = None
     logfile = None
@@ -119,6 +120,7 @@ class Context(object):
         return self._children
         return self._children
 
 
 
 
+@python_2_unicode_compatible
 class Task(object):
 class Task(object):
     """Task base class.
     """Task base class.
 
 

+ 3 - 0
celery/backends/database/models.py

@@ -14,12 +14,14 @@ import sqlalchemy as sa
 from sqlalchemy.types import PickleType
 from sqlalchemy.types import PickleType
 
 
 from celery import states
 from celery import states
+from celery.five import python_2_unicode_compatible
 
 
 from .session import ResultModelBase
 from .session import ResultModelBase
 
 
 __all__ = ['Task', 'TaskSet']
 __all__ = ['Task', 'TaskSet']
 
 
 
 
+@python_2_unicode_compatible
 class Task(ResultModelBase):
 class Task(ResultModelBase):
     """Task result/status."""
     """Task result/status."""
     __tablename__ = 'celery_taskmeta'
     __tablename__ = 'celery_taskmeta'
@@ -49,6 +51,7 @@ class Task(ResultModelBase):
         return '<Task {0.task_id} state: {0.status}>'.format(self)
         return '<Task {0.task_id} state: {0.status}>'.format(self)
 
 
 
 
+@python_2_unicode_compatible
 class TaskSet(ResultModelBase):
 class TaskSet(ResultModelBase):
     """TaskSet result"""
     """TaskSet result"""
     __tablename__ = 'celery_tasksetmeta'
     __tablename__ = 'celery_tasksetmeta'

+ 8 - 3
celery/beat.py

@@ -29,14 +29,18 @@ from kombu.utils.functional import maybe_evaluate
 from . import __version__
 from . import __version__
 from . import platforms
 from . import platforms
 from . import signals
 from . import signals
-from .five import items, reraise, values, monotonic
+from .five import (
+    items, monotonic, python_2_unicode_compatible, reraise, values,
+)
 from .schedules import maybe_schedule, crontab
 from .schedules import maybe_schedule, crontab
 from .utils.imports import instantiate
 from .utils.imports import instantiate
 from .utils.timeutils import humanize_seconds
 from .utils.timeutils import humanize_seconds
 from .utils.log import get_logger, iter_open_logger_fds
 from .utils.log import get_logger, iter_open_logger_fds
 
 
-__all__ = ['SchedulingError', 'ScheduleEntry', 'Scheduler',
-           'PersistentScheduler', 'Service', 'EmbeddedService']
+__all__ = [
+    'SchedulingError', 'ScheduleEntry', 'Scheduler',
+    'PersistentScheduler', 'Service', 'EmbeddedService',
+]
 
 
 event_t = namedtuple('event_t', ('time', 'priority', 'entry'))
 event_t = namedtuple('event_t', ('time', 'priority', 'entry'))
 
 
@@ -52,6 +56,7 @@ class SchedulingError(Exception):
 
 
 
 
 @total_ordering
 @total_ordering
+@python_2_unicode_compatible
 class ScheduleEntry(object):
 class ScheduleEntry(object):
     """An entry in the scheduler.
     """An entry in the scheduler.
 
 

+ 9 - 5
celery/bin/base.py

@@ -18,7 +18,9 @@ from pprint import pformat
 from celery import VERSION_BANNER, Celery, maybe_patch_concurrency
 from celery import VERSION_BANNER, Celery, maybe_patch_concurrency
 from celery import signals
 from celery import signals
 from celery.exceptions import CDeprecationWarning, CPendingDeprecationWarning
 from celery.exceptions import CDeprecationWarning, CPendingDeprecationWarning
-from celery.five import getfullargspec, items, string, string_t
+from celery.five import (
+    getfullargspec, items, python_2_unicode_compatible, string, string_t,
+)
 from celery.platforms import EX_FAILURE, EX_OK, EX_USAGE
 from celery.platforms import EX_FAILURE, EX_OK, EX_USAGE
 from celery.utils import term
 from celery.utils import term
 from celery.utils import text
 from celery.utils import text
@@ -30,6 +32,11 @@ try:
 except NameError:  # pragma: no cover
 except NameError:  # pragma: no cover
     pass
     pass
 
 
+__all__ = [
+    'Error', 'UsageError', 'Extensions',
+    'HelpFormatter', 'Command', 'Option', 'daemon_options',
+]
+
 # always enable DeprecationWarnings, so our users can see them.
 # always enable DeprecationWarnings, so our users can see them.
 for warning in (CDeprecationWarning, CPendingDeprecationWarning):
 for warning in (CDeprecationWarning, CPendingDeprecationWarning):
     warnings.simplefilter('once', warning, 0)
     warnings.simplefilter('once', warning, 0)
@@ -43,10 +50,8 @@ Try --help?
 find_long_opt = re.compile(r'.+?(--.+?)(?:\s|,|$)')
 find_long_opt = re.compile(r'.+?(--.+?)(?:\s|,|$)')
 find_rst_ref = re.compile(r':\w+:`(.+?)`')
 find_rst_ref = re.compile(r':\w+:`(.+?)`')
 
 
-__all__ = ['Error', 'UsageError', 'Extensions', 'HelpFormatter',
-           'Command', 'Option', 'daemon_options']
-
 
 
+@python_2_unicode_compatible
 class Error(Exception):
 class Error(Exception):
     status = EX_FAILURE
     status = EX_FAILURE
 
 
@@ -57,7 +62,6 @@ class Error(Exception):
 
 
     def __str__(self):
     def __str__(self):
         return self.reason
         return self.reason
-    __unicode__ = __str__
 
 
 
 
 class UsageError(Error):
 class UsageError(Error):

+ 2 - 1
celery/bin/graph.py

@@ -11,7 +11,7 @@ from __future__ import absolute_import, unicode_literals
 from operator import itemgetter
 from operator import itemgetter
 
 
 from celery.datastructures import DependencyGraph, GraphFormatter
 from celery.datastructures import DependencyGraph, GraphFormatter
-from celery.five import items
+from celery.five import items, python_2_unicode_compatible
 
 
 from .base import Command
 from .base import Command
 
 
@@ -58,6 +58,7 @@ class graph(Command):
             return '{0} ({1}://)'.format(type(node).__name__,
             return '{0} ({1}://)'.format(type(node).__name__,
                                          node._label.split('://')[0])
                                          node._label.split('://')[0])
 
 
+        @python_2_unicode_compatible
         class Node(object):
         class Node(object):
             force_label = None
             force_label = None
             scheme = {}
             scheme = {}

+ 4 - 4
celery/bootsteps.py

@@ -16,7 +16,7 @@ from kombu.utils import symbol_by_name
 from kombu.utils.encoding import bytes_to_str
 from kombu.utils.encoding import bytes_to_str
 
 
 from .datastructures import DependencyGraph, GraphFormatter
 from .datastructures import DependencyGraph, GraphFormatter
-from .five import values, with_metaclass
+from .five import bytes_if_py2, values, with_metaclass
 from .utils.imports import instantiate, qualname
 from .utils.imports import instantiate, qualname
 from .utils.log import get_logger
 from .utils.log import get_logger
 
 
@@ -291,10 +291,10 @@ class StepType(type):
         return super(StepType, cls).__new__(cls, name, bases, attrs)
         return super(StepType, cls).__new__(cls, name, bases, attrs)
 
 
     def __str__(self):
     def __str__(self):
-        return self.name
+        return bytes_if_py2(self.name)
 
 
     def __repr__(self):
     def __repr__(self):
-        return 'step:{0.name}{{{0.requires!r}}}'.format(self)
+        return bytes_if_py2('step:{0.name}{{{0.requires!r}}}'.format(self))
 
 
 
 
 @with_metaclass(StepType)
 @with_metaclass(StepType)
@@ -354,7 +354,7 @@ class Step(object):
         pass
         pass
 
 
     def __repr__(self):
     def __repr__(self):
-        return '<step: {0.alias}>'.format(self)
+        return bytes_if_py2('<step: {0.alias}>'.format(self))
 
 
     @property
     @property
     def alias(self):
     def alias(self):

+ 7 - 0
celery/canvas.py

@@ -24,6 +24,7 @@ from kombu.utils import cached_property, fxrange, reprcall, uuid
 from vine import barrier
 from vine import barrier
 
 
 from celery._state import current_app
 from celery._state import current_app
+from celery.five import python_2_unicode_compatible
 from celery.local import try_import
 from celery.local import try_import
 from celery.result import GroupResult
 from celery.result import GroupResult
 from celery.utils import abstract
 from celery.utils import abstract
@@ -119,6 +120,7 @@ def _upgrade(fields, sig):
     return sig
     return sig
 
 
 
 
+@python_2_unicode_compatible
 class Signature(dict):
 class Signature(dict):
     """Class that wraps the arguments and execution options
     """Class that wraps the arguments and execution options
     for a single task invocation.
     for a single task invocation.
@@ -397,6 +399,7 @@ abstract.CallableSignature.register(Signature)
 
 
 
 
 @Signature.register_type
 @Signature.register_type
+@python_2_unicode_compatible
 class chain(Signature):
 class chain(Signature):
     tasks = _getitem_property('kwargs.tasks')
     tasks = _getitem_property('kwargs.tasks')
 
 
@@ -617,6 +620,7 @@ class _basemap(Signature):
 
 
 
 
 @Signature.register_type
 @Signature.register_type
+@python_2_unicode_compatible
 class xmap(_basemap):
 class xmap(_basemap):
     _task_name = 'celery.map'
     _task_name = 'celery.map'
 
 
@@ -627,6 +631,7 @@ class xmap(_basemap):
 
 
 
 
 @Signature.register_type
 @Signature.register_type
+@python_2_unicode_compatible
 class xstarmap(_basemap):
 class xstarmap(_basemap):
     _task_name = 'celery.starmap'
     _task_name = 'celery.starmap'
 
 
@@ -689,6 +694,7 @@ def _maybe_group(tasks, app):
 
 
 
 
 @Signature.register_type
 @Signature.register_type
+@python_2_unicode_compatible
 class group(Signature):
 class group(Signature):
     tasks = _getitem_property('kwargs.tasks')
     tasks = _getitem_property('kwargs.tasks')
 
 
@@ -879,6 +885,7 @@ class group(Signature):
 
 
 
 
 @Signature.register_type
 @Signature.register_type
+@python_2_unicode_compatible
 class chord(Signature):
 class chord(Signature):
 
 
     def __init__(self, header, body=None, task='celery.chord',
     def __init__(self, header, body=None, task='celery.chord',

+ 2 - 1
celery/contrib/migrate.py

@@ -18,7 +18,7 @@ from kombu.common import maybe_declare
 from kombu.utils.encoding import ensure_bytes
 from kombu.utils.encoding import ensure_bytes
 
 
 from celery.app import app_or_default
 from celery.app import app_or_default
-from celery.five import string, string_t
+from celery.five import python_2_unicode_compatible, string, string_t
 from celery.utils import worker_direct
 from celery.utils import worker_direct
 
 
 __all__ = [
 __all__ = [
@@ -38,6 +38,7 @@ class StopFiltering(Exception):
     pass
     pass
 
 
 
 
+@python_2_unicode_compatible
 class State(object):
 class State(object):
     count = 0
     count = 0
     filtered = 0
     filtered = 0

+ 4 - 1
celery/datastructures.py

@@ -21,7 +21,7 @@ from billiard.einfo import ExceptionInfo  # noqa
 from kombu.utils.encoding import safe_str, bytes_to_str
 from kombu.utils.encoding import safe_str, bytes_to_str
 from kombu.utils.limits import TokenBucket  # noqa
 from kombu.utils.limits import TokenBucket  # noqa
 
 
-from celery.five import items, values
+from celery.five import items, python_2_unicode_compatible, values
 from celery.utils.functional import LRUCache, first, uniq  # noqa
 from celery.utils.functional import LRUCache, first, uniq  # noqa
 from celery.utils.text import match_case
 from celery.utils.text import match_case
 
 
@@ -148,6 +148,7 @@ class CycleError(Exception):
     """A cycle was detected in an acyclic graph."""
     """A cycle was detected in an acyclic graph."""
 
 
 
 
+@python_2_unicode_compatible
 class DependencyGraph(object):
 class DependencyGraph(object):
     """A directed acyclic graph of objects and their dependencies.
     """A directed acyclic graph of objects and their dependencies.
 
 
@@ -444,6 +445,7 @@ class DictAttribute(object):
 MutableMapping.register(DictAttribute)
 MutableMapping.register(DictAttribute)
 
 
 
 
+@python_2_unicode_compatible
 class ConfigurationView(AttributeDictMixin):
 class ConfigurationView(AttributeDictMixin):
     """A view over an applications configuration dicts.
     """A view over an applications configuration dicts.
 
 
@@ -587,6 +589,7 @@ class ConfigurationView(AttributeDictMixin):
 MutableMapping.register(ConfigurationView)
 MutableMapping.register(ConfigurationView)
 
 
 
 
+@python_2_unicode_compatible
 class LimitedSet(object):
 class LimitedSet(object):
     """Kind-of Set (or priority queue) with limitations.
     """Kind-of Set (or priority queue) with limitations.
 
 

+ 3 - 1
celery/events/state.py

@@ -33,7 +33,7 @@ from kombu.clocks import timetuple
 from kombu.utils import cached_property
 from kombu.utils import cached_property
 
 
 from celery import states
 from celery import states
-from celery.five import items, values
+from celery.five import items, python_2_unicode_compatible, values
 from celery.utils.functional import LRUCache, memoize
 from celery.utils.functional import LRUCache, memoize
 from celery.utils.log import get_logger
 from celery.utils.log import get_logger
 
 
@@ -110,6 +110,7 @@ def with_unique_field(attr):
 
 
 
 
 @with_unique_field('hostname')
 @with_unique_field('hostname')
+@python_2_unicode_compatible
 class Worker(object):
 class Worker(object):
     """Worker State."""
     """Worker State."""
     heartbeat_max = 4
     heartbeat_max = 4
@@ -202,6 +203,7 @@ class Worker(object):
 
 
 
 
 @with_unique_field('uuid')
 @with_unique_field('uuid')
+@python_2_unicode_compatible
 class Task(object):
 class Task(object):
     """Task State."""
     """Task State."""
     name = received = sent = started = succeeded = failed = retried = \
     name = received = sent = started = succeeded = failed = retried = \

+ 4 - 1
celery/exceptions.py

@@ -10,7 +10,7 @@ from __future__ import absolute_import, unicode_literals
 
 
 import numbers
 import numbers
 
 
-from .five import string_t
+from .five import python_2_unicode_compatible, string_t
 
 
 from billiard.exceptions import (  # noqa
 from billiard.exceptions import (  # noqa
     SoftTimeLimitExceeded, TimeLimitExceeded, WorkerLostError, Terminated,
     SoftTimeLimitExceeded, TimeLimitExceeded, WorkerLostError, Terminated,
@@ -54,6 +54,7 @@ class TaskPredicate(CeleryError):
     pass
     pass
 
 
 
 
+@python_2_unicode_compatible
 class Retry(TaskPredicate):
 class Retry(TaskPredicate):
     """The task is to be retried later."""
     """The task is to be retried later."""
 
 
@@ -98,6 +99,7 @@ class Ignore(TaskPredicate):
     """A task can raise this to ignore doing state updates."""
     """A task can raise this to ignore doing state updates."""
 
 
 
 
+@python_2_unicode_compatible
 class Reject(TaskPredicate):
 class Reject(TaskPredicate):
     """A task can raise this if it wants to reject/requeue the message."""
     """A task can raise this if it wants to reject/requeue the message."""
 
 
@@ -127,6 +129,7 @@ class ImproperlyConfigured(ImportError):
     """Celery is somehow improperly configured."""
     """Celery is somehow improperly configured."""
 
 
 
 
+@python_2_unicode_compatible
 class NotRegistered(KeyError, CeleryError):
 class NotRegistered(KeyError, CeleryError):
     """The task is not registered."""
     """The task is not registered."""
 
 

+ 1 - 1
celery/five.py

@@ -191,7 +191,7 @@ def create_module(name, attrs, cls_attrs=None, pkg=None,
         for attr_name, attr in items(attrs)
         for attr_name, attr in items(attrs)
     }
     }
     module = sys.modules[fqdn] = type(
     module = sys.modules[fqdn] = type(
-        module_name_t(modname), (base,), cls_attrs)(module_name_t(name))
+        bytes_if_py2(modname), (base,), cls_attrs)(bytes_if_py2(name))
     module.__dict__.update(attrs)
     module.__dict__.update(attrs)
     return module
     return module
 
 

+ 8 - 8
celery/local.py

@@ -15,7 +15,7 @@ from __future__ import absolute_import, unicode_literals
 import importlib
 import importlib
 import sys
 import sys
 
 
-from .five import module_name_t, string
+from .five import bytes_if_py2, string
 
 
 __all__ = ['Proxy', 'PromiseProxy', 'try_import', 'maybe_evaluate']
 __all__ = ['Proxy', 'PromiseProxy', 'try_import', 'maybe_evaluate']
 
 
@@ -39,7 +39,7 @@ def _default_cls_attr(name, type_, cls_value):
     def __get__(self, obj, cls=None):
     def __get__(self, obj, cls=None):
         return self.__getter(obj) if obj is not None else self
         return self.__getter(obj) if obj is not None else self
 
 
-    return type(module_name_t(name), (type_,), {
+    return type(bytes_if_py2(name), (type_,), {
         '__new__': __new__, '__get__': __get__,
         '__new__': __new__, '__get__': __get__,
     })
     })
 
 
@@ -126,12 +126,6 @@ class Proxy(object):
             return False
             return False
     __nonzero__ = __bool__  # Py2
     __nonzero__ = __bool__  # Py2
 
 
-    def __unicode__(self):
-        try:
-            return string(self._get_current_object())
-        except RuntimeError:  # pragma: no cover
-            return repr(self)
-
     def __dir__(self):
     def __dir__(self):
         try:
         try:
             return dir(self._get_current_object())
             return dir(self._get_current_object())
@@ -294,6 +288,12 @@ class Proxy(object):
         def __long__(self):
         def __long__(self):
             return long(self._get_current_object())  # noqa
             return long(self._get_current_object())  # noqa
 
 
+        def __unicode__(self):
+            try:
+                return string(self._get_current_object())
+            except RuntimeError:  # pragma: no cover
+                return repr(self)
+
 
 
 class PromiseProxy(Proxy):
 class PromiseProxy(Proxy):
     """This is a proxy to an object that has not yet been evaulated.
     """This is a proxy to an object that has not yet been evaulated.

+ 7 - 1
celery/result.py

@@ -23,7 +23,9 @@ from ._state import _set_task_join_will_block, task_join_will_block
 from .app import app_or_default
 from .app import app_or_default
 from .datastructures import DependencyGraph, GraphFormatter
 from .datastructures import DependencyGraph, GraphFormatter
 from .exceptions import ImproperlyConfigured, IncompleteStream, TimeoutError
 from .exceptions import ImproperlyConfigured, IncompleteStream, TimeoutError
-from .five import items, range, string_t, monotonic
+from .five import (
+    items, python_2_unicode_compatible, range, string_t, monotonic,
+)
 from .utils import deprecated
 from .utils import deprecated
 
 
 __all__ = ['ResultBase', 'AsyncResult', 'ResultSet', 'GroupResult',
 __all__ = ['ResultBase', 'AsyncResult', 'ResultSet', 'GroupResult',
@@ -58,6 +60,7 @@ class ResultBase(object):
     parent = None
     parent = None
 
 
 
 
+@python_2_unicode_compatible
 class AsyncResult(ResultBase):
 class AsyncResult(ResultBase):
     """Query task state.
     """Query task state.
 
 
@@ -425,6 +428,7 @@ class AsyncResult(ResultBase):
 Thenable.register(AsyncResult)
 Thenable.register(AsyncResult)
 
 
 
 
+@python_2_unicode_compatible
 class ResultSet(ResultBase):
 class ResultSet(ResultBase):
     """Working with more than one result.
     """Working with more than one result.
 
 
@@ -790,6 +794,7 @@ class ResultSet(ResultBase):
 Thenable.register(ResultSet)
 Thenable.register(ResultSet)
 
 
 
 
+@python_2_unicode_compatible
 class GroupResult(ResultSet):
 class GroupResult(ResultSet):
     """Like :class:`ResultSet`, but with an associated id.
     """Like :class:`ResultSet`, but with an associated id.
 
 
@@ -864,6 +869,7 @@ class GroupResult(ResultSet):
 Thenable.register(ResultSet)
 Thenable.register(ResultSet)
 
 
 
 
+@python_2_unicode_compatible
 class EagerResult(AsyncResult):
 class EagerResult(AsyncResult):
     """Result that we know has already been executed."""
     """Result that we know has already been executed."""
 
 

+ 4 - 1
celery/schedules.py

@@ -19,7 +19,7 @@ from datetime import datetime, timedelta
 from kombu.utils import cached_property
 from kombu.utils import cached_property
 
 
 from . import current_app
 from . import current_app
-from .five import range, string_t
+from .five import python_2_unicode_compatible, range, string_t
 from .utils import is_iterable
 from .utils import is_iterable
 from .utils.timeutils import (
 from .utils.timeutils import (
     weekday, maybe_timedelta, remaining, humanize_seconds,
     weekday, maybe_timedelta, remaining, humanize_seconds,
@@ -69,6 +69,7 @@ class ParseException(Exception):
     """Raised by crontab_parser when the input can't be parsed."""
     """Raised by crontab_parser when the input can't be parsed."""
 
 
 
 
+@python_2_unicode_compatible
 class schedule(object):
 class schedule(object):
     """Schedule for periodic task.
     """Schedule for periodic task.
 
 
@@ -303,6 +304,7 @@ class crontab_parser(object):
         return i
         return i
 
 
 
 
+@python_2_unicode_compatible
 class crontab(schedule):
 class crontab(schedule):
     """A crontab can be used as the `run_every` value of a
     """A crontab can be used as the `run_every` value of a
     :class:`PeriodicTask` to add cron-like scheduling.
     :class:`PeriodicTask` to add cron-like scheduling.
@@ -622,6 +624,7 @@ def maybe_schedule(s, relative=False, app=None):
     return s
     return s
 
 
 
 
+@python_2_unicode_compatible
 class solar(schedule):
 class solar(schedule):
     """A solar event can be used as the `run_every` value of a
     """A solar event can be used as the `run_every` value of a
     :class:`PeriodicTask` to schedule based on certain solar events.
     :class:`PeriodicTask` to schedule based on certain solar events.

+ 6 - 1
celery/task/base.py

@@ -15,7 +15,10 @@ from kombu import Exchange
 
 
 from celery import current_app
 from celery import current_app
 from celery.app.task import Context, Task as BaseTask, _reprtask
 from celery.app.task import Context, Task as BaseTask, _reprtask
-from celery.five import class_property, reclassmethod, with_metaclass
+from celery.five import (
+    class_property, reclassmethod,
+    python_2_unicode_compatible, with_metaclass,
+)
 from celery.local import Proxy
 from celery.local import Proxy
 from celery.schedules import maybe_schedule
 from celery.schedules import maybe_schedule
 from celery.utils.log import get_task_logger
 from celery.utils.log import get_task_logger
@@ -30,6 +33,7 @@ _COMPAT_CLASSMETHODS = (
 )
 )
 
 
 
 
+@python_2_unicode_compatible
 class _CompatShared(object):
 class _CompatShared(object):
 
 
     def __init__(self, name, cons):
     def __init__(self, name, cons):
@@ -124,6 +128,7 @@ class TaskType(type):
 
 
 
 
 @with_metaclass(TaskType)
 @with_metaclass(TaskType)
+@python_2_unicode_compatible
 class Task(BaseTask):
 class Task(BaseTask):
     """Deprecated Task base class.
     """Deprecated Task base class.
 
 

+ 2 - 1
celery/task/http.py

@@ -20,7 +20,7 @@ from kombu.utils import json
 from kombu.utils.encoding import bytes_to_str, str_to_bytes
 from kombu.utils.encoding import bytes_to_str, str_to_bytes
 
 
 from celery import shared_task, __version__ as celery_version
 from celery import shared_task, __version__ as celery_version
-from celery.five import items, reraise
+from celery.five import items, python_2_unicode_compatible, reraise
 from celery.utils.log import get_task_logger
 from celery.utils.log import get_task_logger
 
 
 __all__ = ['InvalidResponseError', 'RemoteExecuteError', 'UnknownStatusError',
 __all__ = ['InvalidResponseError', 'RemoteExecuteError', 'UnknownStatusError',
@@ -83,6 +83,7 @@ def extract_response(raw_response, loads=json.loads):
         raise UnknownStatusError(str(status))
         raise UnknownStatusError(str(status))
 
 
 
 
+@python_2_unicode_compatible
 class MutableURL(object):
 class MutableURL(object):
     """Object wrapping a Uniform Resource Locator.
     """Object wrapping a Uniform Resource Locator.
 
 

+ 2 - 2
celery/tests/app/test_loaders.py

@@ -6,7 +6,7 @@ import warnings
 
 
 from celery import loaders
 from celery import loaders
 from celery.exceptions import NotConfigured
 from celery.exceptions import NotConfigured
-from celery.five import module_name_t
+from celery.five import bytes_if_py2
 from celery.loaders import base
 from celery.loaders import base
 from celery.loaders import default
 from celery.loaders import default
 from celery.loaders.app import AppLoader
 from celery.loaders.app import AppLoader
@@ -164,7 +164,7 @@ class test_DefaultLoader(AppCase):
             pass
             pass
 
 
         configname = os.environ.get('CELERY_CONFIG_MODULE') or 'celeryconfig'
         configname = os.environ.get('CELERY_CONFIG_MODULE') or 'celeryconfig'
-        celeryconfig = ConfigModule(module_name_t(configname))
+        celeryconfig = ConfigModule(bytes_if_py2(configname))
         celeryconfig.imports = ('os', 'sys')
         celeryconfig.imports = ('os', 'sys')
 
 
         prevconfig = sys.modules.get(configname)
         prevconfig = sys.modules.get(configname)

+ 2 - 0
celery/tests/app/test_log.py

@@ -9,6 +9,7 @@ from tempfile import mktemp
 
 
 from celery import signals
 from celery import signals
 from celery.app.log import TaskFormatter
 from celery.app.log import TaskFormatter
+from celery.five import python_2_unicode_compatible
 from celery.utils.log import LoggingProxy
 from celery.utils.log import LoggingProxy
 from celery.utils import uuid
 from celery.utils import uuid
 from celery.utils.log import (
 from celery.utils.log import (
@@ -134,6 +135,7 @@ class test_ColorFormatter(AppCase):
                 safe_str.side_effect = None
                 safe_str.side_effect = None
         safe_str.side_effect = on_safe_str
         safe_str.side_effect = on_safe_str
 
 
+        @python_2_unicode_compatible
         class Record(object):
         class Record(object):
             levelname = 'ERROR'
             levelname = 'ERROR'
             msg = 'HELLO'
             msg = 'HELLO'

+ 5 - 5
celery/tests/backends/test_base.py

@@ -6,7 +6,7 @@ import types
 from contextlib import contextmanager
 from contextlib import contextmanager
 
 
 from celery.exceptions import ChordError, TimeoutError
 from celery.exceptions import ChordError, TimeoutError
-from celery.five import items, module_name_t, range
+from celery.five import items, bytes_if_py2, range
 from celery.utils import serialization
 from celery.utils import serialization
 from celery.utils.serialization import subclass_exception
 from celery.utils.serialization import subclass_exception
 from celery.utils.serialization import find_pickleable_exception as fnpe
 from celery.utils.serialization import find_pickleable_exception as fnpe
@@ -36,15 +36,15 @@ class wrapobject(object):
 if sys.version_info[0] == 3 or getattr(sys, 'pypy_version_info', None):
 if sys.version_info[0] == 3 or getattr(sys, 'pypy_version_info', None):
     Oldstyle = None
     Oldstyle = None
 else:
 else:
-    Oldstyle = types.ClassType(module_name_t('Oldstyle'), (), {})
+    Oldstyle = types.ClassType(bytes_if_py2('Oldstyle'), (), {})
 Unpickleable = subclass_exception(
 Unpickleable = subclass_exception(
-    module_name_t('Unpickleable'), KeyError, 'foo.module',
+    bytes_if_py2('Unpickleable'), KeyError, 'foo.module',
 )
 )
 Impossible = subclass_exception(
 Impossible = subclass_exception(
-    module_name_t('Impossible'), object, 'foo.module',
+    bytes_if_py2('Impossible'), object, 'foo.module',
 )
 )
 Lookalike = subclass_exception(
 Lookalike = subclass_exception(
-    module_name_t('Lookalike'), wrapobject, 'foo.module',
+    bytes_if_py2('Lookalike'), wrapobject, 'foo.module',
 )
 )
 
 
 
 

+ 3 - 3
celery/tests/backends/test_cache.py

@@ -12,7 +12,7 @@ from celery import states
 from celery import group
 from celery import group
 from celery.backends.cache import CacheBackend, DummyClient, backends
 from celery.backends.cache import CacheBackend, DummyClient, backends
 from celery.exceptions import ImproperlyConfigured
 from celery.exceptions import ImproperlyConfigured
-from celery.five import items, module_name_t, string, text_t
+from celery.five import items, bytes_if_py2, string, text_t
 from celery.utils import uuid
 from celery.utils import uuid
 
 
 from celery.tests.case import AppCase, Mock, mock, patch, skip
 from celery.tests.case import AppCase, Mock, mock, patch, skip
@@ -168,7 +168,7 @@ class MockCacheMixin(object):
 
 
     @contextmanager
     @contextmanager
     def mock_memcache(self):
     def mock_memcache(self):
-        memcache = types.ModuleType(module_name_t('memcache'))
+        memcache = types.ModuleType(bytes_if_py2('memcache'))
         memcache.Client = MemcachedClient
         memcache.Client = MemcachedClient
         memcache.Client.__module__ = memcache.__name__
         memcache.Client.__module__ = memcache.__name__
         prev, sys.modules['memcache'] = sys.modules.get('memcache'), memcache
         prev, sys.modules['memcache'] = sys.modules.get('memcache'), memcache
@@ -180,7 +180,7 @@ class MockCacheMixin(object):
 
 
     @contextmanager
     @contextmanager
     def mock_pylibmc(self):
     def mock_pylibmc(self):
-        pylibmc = types.ModuleType(module_name_t('pylibmc'))
+        pylibmc = types.ModuleType(bytes_if_py2('pylibmc'))
         pylibmc.Client = MemcachedClient
         pylibmc.Client = MemcachedClient
         pylibmc.Client.__module__ = pylibmc.__name__
         pylibmc.Client.__module__ = pylibmc.__name__
         prev = sys.modules.get('pylibmc')
         prev = sys.modules.get('pylibmc')

+ 2 - 2
celery/tests/bin/test_base.py

@@ -8,7 +8,7 @@ from celery.bin.base import (
     Extensions,
     Extensions,
     HelpFormatter,
     HelpFormatter,
 )
 )
-from celery.five import module_name_t
+from celery.five import bytes_if_py2
 from celery.utils.objects import Bunch
 from celery.utils.objects import Bunch
 
 
 from celery.tests.case import (
 from celery.tests.case import (
@@ -353,7 +353,7 @@ class test_Command(AppCase):
         cmd = MockCommand(app=self.app)
         cmd = MockCommand(app=self.app)
         with patch('celery.bin.base.symbol_by_name') as sbn:
         with patch('celery.bin.base.symbol_by_name') as sbn:
             from types import ModuleType
             from types import ModuleType
-            x = ModuleType(module_name_t('proj'))
+            x = ModuleType(bytes_if_py2('proj'))
 
 
             def on_sbn(*args, **kwargs):
             def on_sbn(*args, **kwargs):
 
 

+ 2 - 2
celery/tests/utils/test_imports.py

@@ -1,6 +1,6 @@
 from __future__ import absolute_import, unicode_literals
 from __future__ import absolute_import, unicode_literals
 
 
-from celery.five import module_name_t
+from celery.five import bytes_if_py2
 
 
 from celery.utils.imports import (
 from celery.utils.imports import (
     qualname,
     qualname,
@@ -24,7 +24,7 @@ class test_import_utils(Case):
         self.assertTrue(find_module('celery.worker.request'))
         self.assertTrue(find_module('celery.worker.request'))
 
 
     def test_qualname(self):
     def test_qualname(self):
-        Class = type(module_name_t('Fox'), (object,), {
+        Class = type(bytes_if_py2('Fox'), (object,), {
             '__module__': 'quick.brown',
             '__module__': 'quick.brown',
         })
         })
         self.assertEqual(qualname(Class), 'quick.brown.Fox')
         self.assertEqual(qualname(Class), 'quick.brown.Fox')

+ 4 - 2
celery/tests/utils/test_local.py

@@ -2,14 +2,14 @@ from __future__ import absolute_import, unicode_literals
 
 
 import sys
 import sys
 
 
-from celery.five import string, long_t
+from celery.five import python_2_unicode_compatible, string, long_t
 from celery.local import (
 from celery.local import (
     Proxy,
     Proxy,
     PromiseProxy,
     PromiseProxy,
     maybe_evaluate,
     maybe_evaluate,
     try_import,
     try_import,
 )
 )
-from celery.tests.case import Case, Mock
+from celery.tests.case import Case, Mock, skip
 
 
 PY3 = sys.version_info[0] == 3
 PY3 = sys.version_info[0] == 3
 
 
@@ -81,8 +81,10 @@ class test_Proxy(Case):
         with self.assertRaises(AttributeError):
         with self.assertRaises(AttributeError):
             x.__dict__
             x.__dict__
 
 
+    @skip.if_python3()
     def test_unicode(self):
     def test_unicode(self):
 
 
+        @python_2_unicode_compatible
         class X(object):
         class X(object):
 
 
             def __unicode__(self):
             def __unicode__(self):

+ 9 - 1
celery/tests/utils/test_saferepr.py

@@ -5,7 +5,9 @@ import re
 from decimal import Decimal
 from decimal import Decimal
 from pprint import pprint
 from pprint import pprint
 
 
-from celery.five import items, long_t, text_t, values
+from celery.five import (
+    items, long_t, python_2_unicode_compatible, text_t, values,
+)
 
 
 from celery.utils.saferepr import saferepr
 from celery.utils.saferepr import saferepr
 
 
@@ -73,6 +75,7 @@ class list2(list):
     pass
     pass
 
 
 
 
+@python_2_unicode_compatible
 class list3(list):
 class list3(list):
 
 
     def __repr__(self):
     def __repr__(self):
@@ -83,6 +86,7 @@ class tuple2(tuple):
     pass
     pass
 
 
 
 
+@python_2_unicode_compatible
 class tuple3(tuple):
 class tuple3(tuple):
 
 
     def __repr__(self):
     def __repr__(self):
@@ -93,6 +97,7 @@ class set2(set):
     pass
     pass
 
 
 
 
+@python_2_unicode_compatible
 class set3(set):
 class set3(set):
 
 
     def __repr__(self):
     def __repr__(self):
@@ -103,6 +108,7 @@ class frozenset2(frozenset):
     pass
     pass
 
 
 
 
+@python_2_unicode_compatible
 class frozenset3(frozenset):
 class frozenset3(frozenset):
 
 
     def __repr__(self):
     def __repr__(self):
@@ -113,12 +119,14 @@ class dict2(dict):
     pass
     pass
 
 
 
 
+@python_2_unicode_compatible
 class dict3(dict):
 class dict3(dict):
 
 
     def __repr__(self):
     def __repr__(self):
         return dict.__repr__(self)
         return dict.__repr__(self)
 
 
 
 
+@python_2_unicode_compatible
 class Unorderable:
 class Unorderable:
 
 
     def __repr__(self):
     def __repr__(self):

+ 2 - 1
celery/tests/worker/test_loops.py

@@ -9,7 +9,7 @@ from celery.bootsteps import CLOSE, RUN
 from celery.exceptions import (
 from celery.exceptions import (
     InvalidTaskError, WorkerLostError, WorkerShutdown, WorkerTerminate,
     InvalidTaskError, WorkerLostError, WorkerShutdown, WorkerTerminate,
 )
 )
-from celery.five import Empty
+from celery.five import Empty, python_2_unicode_compatible
 from celery.platforms import EX_FAILURE
 from celery.platforms import EX_FAILURE
 from celery.worker import state
 from celery.worker import state
 from celery.worker.consumer import Consumer
 from celery.worker.consumer import Consumer
@@ -18,6 +18,7 @@ from celery.worker.loops import _quick_drain, asynloop, synloop
 from celery.tests.case import AppCase, Mock, task_message_from_sig
 from celery.tests.case import AppCase, Mock, task_message_from_sig
 
 
 
 
+@python_2_unicode_compatible
 class PromiseEqual(object):
 class PromiseEqual(object):
 
 
     def __init__(self, fun, *args, **kwargs):
     def __init__(self, fun, *args, **kwargs):

+ 5 - 2
celery/utils/dispatch/saferef.py

@@ -11,6 +11,8 @@ import sys
 import traceback
 import traceback
 import weakref
 import weakref
 
 
+from celery.five import python_2_unicode_compatible
+
 __all__ = ['safe_ref']
 __all__ = ['safe_ref']
 
 
 PY3 = sys.version_info[0] == 3
 PY3 = sys.version_info[0] == 3
@@ -42,6 +44,7 @@ def safe_ref(target, on_delete=None):  # pragma: no cover
         return weakref.ref(target)
         return weakref.ref(target)
 
 
 
 
+@python_2_unicode_compatible
 class BoundMethodWeakref(object):  # pragma: no cover
 class BoundMethodWeakref(object):  # pragma: no cover
     """'Safe' and reusable weak references to instance methods.
     """'Safe' and reusable weak references to instance methods.
 
 
@@ -167,14 +170,14 @@ class BoundMethodWeakref(object):  # pragma: no cover
     calculate_key = classmethod(calculate_key)
     calculate_key = classmethod(calculate_key)
 
 
     def __str__(self):
     def __str__(self):
-        """Give a friendly representation of the object"""
         return '{0}( {1}.{2} )'.format(
         return '{0}( {1}.{2} )'.format(
             type(self).__name__,
             type(self).__name__,
             self.self_name,
             self.self_name,
             self.fun_name,
             self.fun_name,
         )
         )
 
 
-    __repr__ = __str__
+    def __repr__(self):
+        return str(self)
 
 
     def __bool__(self):
     def __bool__(self):
         """Whether we are still a valid reference"""
         """Whether we are still a valid reference"""

+ 13 - 14
celery/utils/dispatch/signal.py

@@ -3,12 +3,13 @@
 from __future__ import absolute_import, unicode_literals
 from __future__ import absolute_import, unicode_literals
 
 
 import weakref
 import weakref
-from . import saferef
 
 
-from celery.five import range, text_t
+from celery.five import python_2_unicode_compatible, range, text_t
 from celery.local import PromiseProxy, Proxy
 from celery.local import PromiseProxy, Proxy
 from celery.utils.log import get_logger
 from celery.utils.log import get_logger
 
 
+from . import saferef
+
 __all__ = ['Signal']
 __all__ = ['Signal']
 
 
 logger = get_logger(__name__)
 logger = get_logger(__name__)
@@ -27,23 +28,20 @@ def _make_id(target):  # pragma: no cover
     return id(target)
     return id(target)
 
 
 
 
+@python_2_unicode_compatible
 class Signal(object):  # pragma: no cover
 class Signal(object):  # pragma: no cover
-    """Base class for all signals
-
+    """Observer pattern implementation.
 
 
-    .. attribute:: receivers
-        Internal attribute, holds a dictionary of
-        `{receiverkey (id): weakref(receiver)}` mappings.
+    :param providing_args: A list of the arguments this signal can pass
+        along in a :meth:`send` call.
 
 
     """
     """
 
 
-    def __init__(self, providing_args=None):
-        """Create a new signal.
-
-        :param providing_args: A list of the arguments this signal can pass
-            along in a :meth:`send` call.
+    #: Holds a dictionary of
+    #: ``{receiverkey (id): weakref(receiver)}`` mappings.
+    receivers = None
 
 
-        """
+    def __init__(self, providing_args=None):
         self.receivers = []
         self.receivers = []
         if providing_args is None:
         if providing_args is None:
             providing_args = []
             providing_args = []
@@ -214,4 +212,5 @@ class Signal(object):  # pragma: no cover
     def __repr__(self):
     def __repr__(self):
         return '<Signal: {0}>'.format(type(self).__name__)
         return '<Signal: {0}>'.format(type(self).__name__)
 
 
-    __str__ = __repr__
+    def __str__(self):
+        return repr(self)

+ 3 - 0
celery/utils/mail.py

@@ -15,6 +15,8 @@ import warnings
 
 
 from email.mime.text import MIMEText
 from email.mime.text import MIMEText
 
 
+from celery.five import python_2_unicode_compatible
+
 from .functional import maybe_list
 from .functional import maybe_list
 
 
 try:
 try:
@@ -39,6 +41,7 @@ class SendmailWarning(UserWarning):
     """Problem happened while sending the email message."""
     """Problem happened while sending the email message."""
 
 
 
 
+@python_2_unicode_compatible
 class Message(object):
 class Message(object):
 
 
     def __init__(self, to=None, sender=None, subject=None,
     def __init__(self, to=None, sender=None, subject=None,

+ 3 - 2
celery/utils/serialization.py

@@ -8,7 +8,7 @@
 """
 """
 from __future__ import absolute_import, unicode_literals
 from __future__ import absolute_import, unicode_literals
 
 
-from celery.five import module_name_t
+from celery.five import bytes_if_py2, python_2_unicode_compatible
 
 
 from base64 import b64encode as base64encode, b64decode as base64decode
 from base64 import b64encode as base64encode, b64decode as base64decode
 from inspect import getmro
 from inspect import getmro
@@ -36,7 +36,7 @@ except NameError:  # pragma: no cover
 
 
 
 
 def subclass_exception(name, parent, module):  # noqa
 def subclass_exception(name, parent, module):  # noqa
-    return type(module_name_t(name), (parent,), {'__module__': module})
+    return type(bytes_if_py2(name), (parent,), {'__module__': module})
 
 
 
 
 def find_pickleable_exception(exc, loads=pickle.loads,
 def find_pickleable_exception(exc, loads=pickle.loads,
@@ -79,6 +79,7 @@ def create_exception_cls(name, module, parent=None):
     return subclass_exception(name, parent, module)
     return subclass_exception(name, parent, module)
 
 
 
 
+@python_2_unicode_compatible
 class UnpickleableExceptionWrapper(Exception):
 class UnpickleableExceptionWrapper(Exception):
     """Wraps unpickleable exceptions.
     """Wraps unpickleable exceptions.
 
 

+ 4 - 5
celery/utils/term.py

@@ -13,7 +13,8 @@ import platform
 from functools import reduce
 from functools import reduce
 
 
 from kombu.utils.encoding import safe_str
 from kombu.utils.encoding import safe_str
-from celery.five import string
+
+from celery.five import python_2_unicode_compatible, string
 
 
 __all__ = ['colored']
 __all__ = ['colored']
 
 
@@ -29,6 +30,7 @@ def fg(s):
     return COLOR_SEQ % s
     return COLOR_SEQ % s
 
 
 
 
+@python_2_unicode_compatible
 class colored(object):
 class colored(object):
     """Terminal colored text.
     """Terminal colored text.
 
 
@@ -80,15 +82,12 @@ class colored(object):
             prefix = self.op
             prefix = self.op
         return ''.join((string(prefix), string(reduce(self._add, self.s))))
         return ''.join((string(prefix), string(reduce(self._add, self.s))))
 
 
-    def __unicode__(self):
+    def __str__(self):
         suffix = ''
         suffix = ''
         if self.enabled:
         if self.enabled:
             suffix = RESET_SEQ
             suffix = RESET_SEQ
         return string(''.join((self.embed(), string(suffix))))
         return string(''.join((self.embed(), string(suffix))))
 
 
-    def __str__(self):
-        return safe_str(self.__unicode__())
-
     def node(self, s, op):
     def node(self, s, op):
         return self.__class__(enabled=self.enabled, op=op, *s)
         return self.__class__(enabled=self.enabled, op=op, *s)
 
 

+ 6 - 3
celery/utils/threads.py

@@ -17,10 +17,12 @@ import traceback
 from contextlib import contextmanager
 from contextlib import contextmanager
 
 
 from celery.local import Proxy
 from celery.local import Proxy
-from celery.five import THREAD_TIMEOUT_MAX, items
+from celery.five import THREAD_TIMEOUT_MAX, items, python_2_unicode_compatible
 
 
-__all__ = ['bgThread', 'Local', 'LocalStack', 'LocalManager',
-           'get_ident', 'default_socket_timeout']
+__all__ = [
+    'bgThread', 'Local', 'LocalStack', 'LocalManager',
+    'get_ident', 'default_socket_timeout',
+]
 
 
 USE_FAST_LOCALS = os.environ.get('USE_FAST_LOCALS')
 USE_FAST_LOCALS = os.environ.get('USE_FAST_LOCALS')
 PY3 = sys.version_info[0] == 3
 PY3 = sys.version_info[0] == 3
@@ -255,6 +257,7 @@ class _LocalStack(object):
             return None
             return None
 
 
 
 
+@python_2_unicode_compatible
 class LocalManager(object):
 class LocalManager(object):
     """Local objects cannot manage themselves. For that you need a local
     """Local objects cannot manage themselves. For that you need a local
     manager.  You can pass a local manager multiple locals or add them
     manager.  You can pass a local manager multiple locals or add them

+ 10 - 6
celery/utils/timeutils.py

@@ -20,17 +20,19 @@ from kombu.utils import cached_property, reprcall
 
 
 from pytz import timezone as _timezone, AmbiguousTimeError, FixedOffset
 from pytz import timezone as _timezone, AmbiguousTimeError, FixedOffset
 
 
-from celery.five import string_t
+from celery.five import python_2_unicode_compatible, string_t
 
 
 from .functional import dictfilter
 from .functional import dictfilter
 from .iso8601 import parse_iso8601
 from .iso8601 import parse_iso8601
 from .text import pluralize
 from .text import pluralize
 
 
-__all__ = ['LocalTimezone', 'timezone', 'maybe_timedelta',
-           'delta_resolution', 'remaining', 'rate', 'weekday',
-           'humanize_seconds', 'maybe_iso8601', 'is_naive', 'make_aware',
-           'localize', 'to_utc', 'maybe_make_aware', 'ffwd', 'utcoffset',
-           'adjust_timestamp', 'maybe_s_to_ms']
+__all__ = [
+    'LocalTimezone', 'timezone', 'maybe_timedelta',
+    'delta_resolution', 'remaining', 'rate', 'weekday',
+    'humanize_seconds', 'maybe_iso8601', 'is_naive', 'make_aware',
+    'localize', 'to_utc', 'maybe_make_aware', 'ffwd', 'utcoffset',
+    'adjust_timestamp', 'maybe_s_to_ms',
+]
 
 
 PY3 = sys.version_info[0] == 3
 PY3 = sys.version_info[0] == 3
 PY33 = sys.version_info >= (3, 3)
 PY33 = sys.version_info >= (3, 3)
@@ -54,6 +56,7 @@ ZERO = timedelta(0)
 _local_timezone = None
 _local_timezone = None
 
 
 
 
+@python_2_unicode_compatible
 class LocalTimezone(tzinfo):
 class LocalTimezone(tzinfo):
     """Local time implementation taken from Python's docs.
     """Local time implementation taken from Python's docs.
 
 
@@ -313,6 +316,7 @@ def maybe_make_aware(dt, tz=None):
     )
     )
 
 
 
 
+@python_2_unicode_compatible
 class ffwd(object):
 class ffwd(object):
     """Version of relativedelta that only supports addition."""
     """Version of relativedelta that only supports addition."""
 
 

+ 2 - 1
celery/worker/__init__.py

@@ -30,7 +30,7 @@ from celery import signals
 from celery.exceptions import (
 from celery.exceptions import (
     ImproperlyConfigured, WorkerTerminate, TaskRevokedError,
     ImproperlyConfigured, WorkerTerminate, TaskRevokedError,
 )
 )
-from celery.five import string_t, values
+from celery.five import python_2_unicode_compatible, string_t, values
 from celery.platforms import EX_FAILURE, create_pidlock
 from celery.platforms import EX_FAILURE, create_pidlock
 from celery.utils import default_nodename, worker_direct
 from celery.utils import default_nodename, worker_direct
 from celery.utils.imports import reload_from_cwd
 from celery.utils.imports import reload_from_cwd
@@ -64,6 +64,7 @@ def str_to_list(s):
     return s
     return s
 
 
 
 
+@python_2_unicode_compatible
 class WorkController(object):
 class WorkController(object):
     """Unmanaged worker instance."""
     """Unmanaged worker instance."""
     app = None
     app = None

+ 2 - 1
celery/worker/consumer/consumer.py

@@ -20,7 +20,6 @@ from time import sleep
 from billiard.common import restart_state
 from billiard.common import restart_state
 from billiard.exceptions import RestartFreqExceeded
 from billiard.exceptions import RestartFreqExceeded
 from kombu.async.semaphore import DummyLock
 from kombu.async.semaphore import DummyLock
-from kombu.five import buffer_t, items
 from kombu.syn import _detect_environment
 from kombu.syn import _detect_environment
 from kombu.utils.encoding import safe_repr, bytes_t
 from kombu.utils.encoding import safe_repr, bytes_t
 from kombu.utils.limits import TokenBucket
 from kombu.utils.limits import TokenBucket
@@ -30,6 +29,7 @@ from celery import bootsteps
 from celery import signals
 from celery import signals
 from celery.app.trace import build_tracer
 from celery.app.trace import build_tracer
 from celery.exceptions import InvalidTaskError, NotRegistered
 from celery.exceptions import InvalidTaskError, NotRegistered
+from celery.five import buffer_t, items, python_2_unicode_compatible
 from celery.utils import gethostname
 from celery.utils import gethostname
 from celery.utils.functional import noop
 from celery.utils.functional import noop
 from celery.utils.log import get_logger
 from celery.utils.log import get_logger
@@ -120,6 +120,7 @@ def dump_body(m, body):
                                len(m.body))
                                len(m.body))
 
 
 
 
+@python_2_unicode_compatible
 class Consumer(object):
 class Consumer(object):
 
 
     Strategies = dict
     Strategies = dict

+ 2 - 1
celery/worker/request.py

@@ -25,7 +25,7 @@ from celery.exceptions import (
     SoftTimeLimitExceeded, TimeLimitExceeded,
     SoftTimeLimitExceeded, TimeLimitExceeded,
     WorkerLostError, Terminated, Retry, Reject,
     WorkerLostError, Terminated, Retry, Reject,
 )
 )
-from celery.five import string
+from celery.five import python_2_unicode_compatible, string
 from celery.platforms import signals as _signals
 from celery.platforms import signals as _signals
 from celery.utils import cached_property, gethostname
 from celery.utils import cached_property, gethostname
 from celery.utils.functional import noop
 from celery.utils.functional import noop
@@ -64,6 +64,7 @@ task_ready = state.task_ready
 revoked_tasks = state.revoked
 revoked_tasks = state.revoked
 
 
 
 
+@python_2_unicode_compatible
 class Request(object):
 class Request(object):
     """A request for task execution."""
     """A request for task execution."""
     acknowledged = False
     acknowledged = False

+ 6 - 1
funtests/stress/stress/data.py

@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 from __future__ import absolute_import, unicode_literals
 from __future__ import absolute_import, unicode_literals
 
 
+from celery.five import python_2_unicode_compatible
+
 try:
 try:
     import simplejson as json
     import simplejson as json
 except ImportError:
 except ImportError:
@@ -50,6 +52,7 @@ def jsonable(cls):
 
 
 
 
 @jsonable
 @jsonable
+@python_2_unicode_compatible
 class Data(object):
 class Data(object):
 
 
     def __init__(self, label, data):
     def __init__(self, label, data):
@@ -61,6 +64,9 @@ class Data(object):
             self.label, humanbytes(len(self.data)),
             self.label, humanbytes(len(self.data)),
         )
         )
 
 
+    def __repr__(self):
+        return str(self)
+
     def __to_json__(self):
     def __to_json__(self):
         return json_reduce(self, {'label': self.label, 'data': self.data})
         return json_reduce(self, {'label': self.label, 'data': self.data})
 
 
@@ -70,7 +76,6 @@ class Data(object):
 
 
     def __reduce__(self):
     def __reduce__(self):
         return Data, (self.label, self.data)
         return Data, (self.label, self.data)
-    __unicode__ = __repr__ = __str__
 
 
 BIG = Data('BIG', 'x' * 2 ** 20 * 8)
 BIG = Data('BIG', 'x' * 2 ** 20 * 8)
 SMALL = Data('SMALL', 'e' * 1024)
 SMALL = Data('SMALL', 'e' * 1024)