We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
test_retry_kwargs_can_be_empty fails on pypy3
From https://travis-ci.org/celery/celery/jobs/151613800:

```
======================================================================
ERROR: test_retry_kwargs_can_be_empty (celery.tests.tasks.test_tasks.test_task_retries)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/celery/celery/celery/tests/tasks/test_tasks.py", line 178, in test_retry_kwargs_can_be_empty
    self.retry_task_mockapply.retry(args=[4, 4], kwargs=None)
  File "/home/travis/build/celery/celery/celery/app/task.py", line 611, in retry
    raise_with_context(exc or Retry('Task can be retried', None))
  File "/home/travis/build/celery/celery/celery/utils/serialization.py", line 255, in raise_with_context
    _raise_with_context(exc, exc_info[1])
  File "<string>", line 1, in _raise_with_context
TypeError: exception causes must derive from BaseException, not NoneType
```

https://github.com/celery/celery/blob/5031d6f27862001d3e3bc5a2dacf1185c933f2c9/celery/tests/tasks/test_tasks.py#L169


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `celery/utils/serialization.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """Utilities for safely pickling exceptions."""
3 from __future__ import absolute_import, unicode_literals
4 
5 import datetime
6 import numbers
7 import sys
8 
9 from base64 import b64encode as base64encode, b64decode as base64decode
10 from functools import partial
11 from inspect import getmro
12 from itertools import takewhile
13 
14 from kombu.utils.encoding import bytes_to_str, str_to_bytes
15 
16 from celery.five import (
17     bytes_if_py2, python_2_unicode_compatible, items, reraise, string_t,
18 )
19 
20 from .encoding import safe_repr
21 
22 try:
23     import cPickle as pickle
24 except ImportError:
25     import pickle  # noqa
26 
27 PY3 = sys.version_info[0] >= 3
28 
29 __all__ = [
30     'UnpickleableExceptionWrapper', 'subclass_exception',
31     'find_pickleable_exception', 'create_exception_cls',
32     'get_pickleable_exception', 'get_pickleable_etype',
33     'get_pickled_exception', 'strtobool',
34 ]
35 
36 #: List of base classes we probably don't want to reduce to.
37 try:
38     unwanted_base_classes = (StandardError, Exception, BaseException, object)
39 except NameError:  # pragma: no cover
40     unwanted_base_classes = (Exception, BaseException, object)  # py3k
41 
42 
43 def subclass_exception(name, parent, module):  # noqa
44     return type(bytes_if_py2(name), (parent,), {'__module__': module})
45 
46 
47 def find_pickleable_exception(exc, loads=pickle.loads,
48                               dumps=pickle.dumps):
49     """With an exception instance, iterate over its super classes (by MRO)
50     and find the first super exception that's pickleable.  It does
51     not go below :exc:`Exception` (i.e., it skips :exc:`Exception`,
52     :class:`BaseException` and :class:`object`).  If that happens
53     you should use :exc:`UnpickleableException` instead.
54 
55     Arguments:
56         exc (BaseException): An exception instance.
57 
58     Returns:
59         Exception: Nearest pickleable parent exception class
60             (except :exc:`Exception` and parents), or if the exception is
61             pickleable it will return :const:`None`.
62     """
63     exc_args = getattr(exc, 'args', [])
64     for supercls in itermro(exc.__class__, unwanted_base_classes):
65         try:
66             superexc = supercls(*exc_args)
67             loads(dumps(superexc))
68         except:
69             pass
70         else:
71             return superexc
72 
73 
74 def itermro(cls, stop):
75     return takewhile(lambda sup: sup not in stop, getmro(cls))
76 
77 
78 def create_exception_cls(name, module, parent=None):
79     """Dynamically create an exception class."""
80     if not parent:
81         parent = Exception
82     return subclass_exception(name, parent, module)
83 
84 
85 @python_2_unicode_compatible
86 class UnpickleableExceptionWrapper(Exception):
87     """Wraps unpickleable exceptions.
88 
89     Arguments:
90         exc_module (str): See :attr:`exc_module`.
91         exc_cls_name (str): See :attr:`exc_cls_name`.
92         exc_args (Tuple[Any, ...]): See :attr:`exc_args`.
93 
94     Example:
95         >>> def pickle_it(raising_function):
96         ...     try:
97         ...         raising_function()
98         ...     except Exception as e:
99         ...         exc = UnpickleableExceptionWrapper(
100         ...             e.__class__.__module__,
101         ...             e.__class__.__name__,
102         ...             e.args,
103         ...         )
104         ...         pickle.dumps(exc)  # Works fine.
105     """
106 
107     #: The module of the original exception.
108     exc_module = None
109 
110     #: The name of the original exception class.
111     exc_cls_name = None
112 
113     #: The arguments for the original exception.
114     exc_args = None
115 
116     def __init__(self, exc_module, exc_cls_name, exc_args, text=None):
117         safe_exc_args = []
118         for arg in exc_args:
119             try:
120                 pickle.dumps(arg)
121                 safe_exc_args.append(arg)
122             except Exception:
123                 safe_exc_args.append(safe_repr(arg))
124         self.exc_module = exc_module
125         self.exc_cls_name = exc_cls_name
126         self.exc_args = safe_exc_args
127         self.text = text
128         Exception.__init__(self, exc_module, exc_cls_name, safe_exc_args, text)
129 
130     def restore(self):
131         return create_exception_cls(self.exc_cls_name,
132                                     self.exc_module)(*self.exc_args)
133 
134     def __str__(self):
135         return self.text
136 
137     @classmethod
138     def from_exception(cls, exc):
139         return cls(exc.__class__.__module__,
140                    exc.__class__.__name__,
141                    getattr(exc, 'args', []),
142                    safe_repr(exc))
143 
144 
145 def get_pickleable_exception(exc):
146     """Make sure exception is pickleable."""
147     try:
148         pickle.loads(pickle.dumps(exc))
149     except Exception:
150         pass
151     else:
152         return exc
153     nearest = find_pickleable_exception(exc)
154     if nearest:
155         return nearest
156     return UnpickleableExceptionWrapper.from_exception(exc)
157 
158 
159 def get_pickleable_etype(cls, loads=pickle.loads, dumps=pickle.dumps):
160     try:
161         loads(dumps(cls))
162     except:
163         return Exception
164     else:
165         return cls
166 
167 
168 def get_pickled_exception(exc):
169     """Get original exception from exception pickled using
170     :meth:`get_pickleable_exception`."""
171     if isinstance(exc, UnpickleableExceptionWrapper):
172         return exc.restore()
173     return exc
174 
175 
176 def b64encode(s):
177     return bytes_to_str(base64encode(str_to_bytes(s)))
178 
179 
180 def b64decode(s):
181     return base64decode(str_to_bytes(s))
182 
183 
184 def strtobool(term, table={'false': False, 'no': False, '0': False,
185                            'true': True, 'yes': True, '1': True,
186                            'on': True, 'off': False}):
187     """Convert common terms for true/false to bool
188     (true/false/yes/no/on/off/1/0)."""
189     if isinstance(term, string_t):
190         try:
191             return table[term.lower()]
192         except KeyError:
193             raise TypeError('Cannot coerce {0!r} to type bool'.format(term))
194     return term
195 
196 
197 def jsonify(obj,
198             builtin_types=(numbers.Real, string_t), key=None,
199             keyfilter=None,
200             unknown_type_filter=None):
201     """Transforms object making it suitable for json serialization"""
202     from kombu.abstract import Object as KombuDictType
203     _jsonify = partial(jsonify, builtin_types=builtin_types, key=key,
204                        keyfilter=keyfilter,
205                        unknown_type_filter=unknown_type_filter)
206 
207     if isinstance(obj, KombuDictType):
208         obj = obj.as_dict(recurse=True)
209 
210     if obj is None or isinstance(obj, builtin_types):
211         return obj
212     elif isinstance(obj, (tuple, list)):
213         return [_jsonify(v) for v in obj]
214     elif isinstance(obj, dict):
215         return {
216             k: _jsonify(v, key=k) for k, v in items(obj)
217             if (keyfilter(k) if keyfilter else 1)
218         }
219     elif isinstance(obj, datetime.datetime):
220         # See "Date Time String Format" in the ECMA-262 specification.
221         r = obj.isoformat()
222         if obj.microsecond:
223             r = r[:23] + r[26:]
224         if r.endswith('+00:00'):
225             r = r[:-6] + 'Z'
226         return r
227     elif isinstance(obj, datetime.date):
228         return obj.isoformat()
229     elif isinstance(obj, datetime.time):
230         r = obj.isoformat()
231         if obj.microsecond:
232             r = r[:12]
233         return r
234     elif isinstance(obj, datetime.timedelta):
235         return str(obj)
236     else:
237         if unknown_type_filter is None:
238             raise ValueError(
239                 'Unsupported type: {0!r} {1!r} (parent: {2})'.format(
240                     type(obj), obj, key))
241         return unknown_type_filter(obj)
242 
243 
244 if PY3:
245     from vine.five import exec_
246     _raise_with_context = None  # for flake8
247     exec_("""def _raise_with_context(exc, ctx): raise exc from ctx""")
248 
249     def raise_with_context(exc):
250         exc_info = sys.exc_info()
251         if not exc_info:
252             raise exc
253         elif exc_info[1] is exc:
254             raise
255         _raise_with_context(exc, exc_info[1])
256 else:
257     def raise_with_context(exc):
258         exc_info = sys.exc_info()
259         if not exc_info:
260             raise exc
261         if exc_info[1] is exc:
262             raise
263         elif exc_info[2]:
264             reraise(type(exc), exc, exc_info[2])
265         raise exc
266
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/celery/utils/serialization.py b/celery/utils/serialization.py
--- a/celery/utils/serialization.py
+++ b/celery/utils/serialization.py
@@ -24,7 +24,7 @@
 except ImportError:
     import pickle  # noqa
 
-PY3 = sys.version_info[0] >= 3
+PY33 = sys.version_info >= (3, 3)
 
 __all__ = [
     'UnpickleableExceptionWrapper', 'subclass_exception',
@@ -241,7 +241,9 @@
         return unknown_type_filter(obj)
 
 
-if PY3:
+# Since PyPy 3 targets Python 3.2, 'raise exc from None' will
+# raise a TypeError so we need to look for Python 3.3 or newer
+if PY33:
     from vine.five import exec_
     _raise_with_context = None  # for flake8
     exec_("""def _raise_with_context(exc, ctx): raise exc from ctx""")

{"golden_diff": "diff --git a/celery/utils/serialization.py b/celery/utils/serialization.py\n--- a/celery/utils/serialization.py\n+++ b/celery/utils/serialization.py\n@@ -24,7 +24,7 @@\n except ImportError:\n     import pickle  # noqa\n \n-PY3 = sys.version_info[0] >= 3\n+PY33 = sys.version_info >= (3, 3)\n \n __all__ = [\n     'UnpickleableExceptionWrapper', 'subclass_exception',\n@@ -241,7 +241,9 @@\n         return unknown_type_filter(obj)\n \n \n-if PY3:\n+# Since PyPy 3 targets Python 3.2, 'raise exc from None' will\n+# raise a TypeError so we need to look for Python 3.3 or newer\n+if PY33:\n     from vine.five import exec_\n     _raise_with_context = None  # for flake8\n     exec_(\"\"\"def _raise_with_context(exc, ctx): raise exc from ctx\"\"\")\n", "issue": "test_retry_kwargs_can_be_empty fails on pypy3\nFrom https://travis-ci.org/celery/celery/jobs/151613800:\n\n```\n======================================================================\nERROR: test_retry_kwargs_can_be_empty (celery.tests.tasks.test_tasks.test_task_retries)\n----------------------------------------------------------------------\nTraceback (most recent call last):\n  File \"/home/travis/build/celery/celery/celery/tests/tasks/test_tasks.py\", line 178, in test_retry_kwargs_can_be_empty\n    self.retry_task_mockapply.retry(args=[4, 4], kwargs=None)\n  File \"/home/travis/build/celery/celery/celery/app/task.py\", line 611, in retry\n    raise_with_context(exc or Retry('Task can be retried', None))\n  File \"/home/travis/build/celery/celery/celery/utils/serialization.py\", line 255, in raise_with_context\n    _raise_with_context(exc, exc_info[1])\n  File \"<string>\", line 1, in _raise_with_context\nTypeError: exception causes must derive from BaseException, not NoneType\n```\n\nhttps://github.com/celery/celery/blob/5031d6f27862001d3e3bc5a2dacf1185c933f2c9/celery/tests/tasks/test_tasks.py#L169\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Utilities for safely pickling exceptions.\"\"\"\nfrom __future__ import absolute_import, unicode_literals\n\nimport datetime\nimport numbers\nimport sys\n\nfrom base64 import b64encode as base64encode, b64decode as base64decode\nfrom functools import partial\nfrom inspect import getmro\nfrom itertools import takewhile\n\nfrom kombu.utils.encoding import bytes_to_str, str_to_bytes\n\nfrom celery.five import (\n    bytes_if_py2, python_2_unicode_compatible, items, reraise, string_t,\n)\n\nfrom .encoding import safe_repr\n\ntry:\n    import cPickle as pickle\nexcept ImportError:\n    import pickle  # noqa\n\nPY3 = sys.version_info[0] >= 3\n\n__all__ = [\n    'UnpickleableExceptionWrapper', 'subclass_exception',\n    'find_pickleable_exception', 'create_exception_cls',\n    'get_pickleable_exception', 'get_pickleable_etype',\n    'get_pickled_exception', 'strtobool',\n]\n\n#: List of base classes we probably don't want to reduce to.\ntry:\n    unwanted_base_classes = (StandardError, Exception, BaseException, object)\nexcept NameError:  # pragma: no cover\n    unwanted_base_classes = (Exception, BaseException, object)  # py3k\n\n\ndef subclass_exception(name, parent, module):  # noqa\n    return type(bytes_if_py2(name), (parent,), {'__module__': module})\n\n\ndef find_pickleable_exception(exc, loads=pickle.loads,\n                              dumps=pickle.dumps):\n    \"\"\"With an exception instance, iterate over its super classes (by MRO)\n    and find the first super exception that's pickleable.  It does\n    not go below :exc:`Exception` (i.e., it skips :exc:`Exception`,\n    :class:`BaseException` and :class:`object`).  If that happens\n    you should use :exc:`UnpickleableException` instead.\n\n    Arguments:\n        exc (BaseException): An exception instance.\n\n    Returns:\n        Exception: Nearest pickleable parent exception class\n            (except :exc:`Exception` and parents), or if the exception is\n            pickleable it will return :const:`None`.\n    \"\"\"\n    exc_args = getattr(exc, 'args', [])\n    for supercls in itermro(exc.__class__, unwanted_base_classes):\n        try:\n            superexc = supercls(*exc_args)\n            loads(dumps(superexc))\n        except:\n            pass\n        else:\n            return superexc\n\n\ndef itermro(cls, stop):\n    return takewhile(lambda sup: sup not in stop, getmro(cls))\n\n\ndef create_exception_cls(name, module, parent=None):\n    \"\"\"Dynamically create an exception class.\"\"\"\n    if not parent:\n        parent = Exception\n    return subclass_exception(name, parent, module)\n\n\n@python_2_unicode_compatible\nclass UnpickleableExceptionWrapper(Exception):\n    \"\"\"Wraps unpickleable exceptions.\n\n    Arguments:\n        exc_module (str): See :attr:`exc_module`.\n        exc_cls_name (str): See :attr:`exc_cls_name`.\n        exc_args (Tuple[Any, ...]): See :attr:`exc_args`.\n\n    Example:\n        >>> def pickle_it(raising_function):\n        ...     try:\n        ...         raising_function()\n        ...     except Exception as e:\n        ...         exc = UnpickleableExceptionWrapper(\n        ...             e.__class__.__module__,\n        ...             e.__class__.__name__,\n        ...             e.args,\n        ...         )\n        ...         pickle.dumps(exc)  # Works fine.\n    \"\"\"\n\n    #: The module of the original exception.\n    exc_module = None\n\n    #: The name of the original exception class.\n    exc_cls_name = None\n\n    #: The arguments for the original exception.\n    exc_args = None\n\n    def __init__(self, exc_module, exc_cls_name, exc_args, text=None):\n        safe_exc_args = []\n        for arg in exc_args:\n            try:\n                pickle.dumps(arg)\n                safe_exc_args.append(arg)\n            except Exception:\n                safe_exc_args.append(safe_repr(arg))\n        self.exc_module = exc_module\n        self.exc_cls_name = exc_cls_name\n        self.exc_args = safe_exc_args\n        self.text = text\n        Exception.__init__(self, exc_module, exc_cls_name, safe_exc_args, text)\n\n    def restore(self):\n        return create_exception_cls(self.exc_cls_name,\n                                    self.exc_module)(*self.exc_args)\n\n    def __str__(self):\n        return self.text\n\n    @classmethod\n    def from_exception(cls, exc):\n        return cls(exc.__class__.__module__,\n                   exc.__class__.__name__,\n                   getattr(exc, 'args', []),\n                   safe_repr(exc))\n\n\ndef get_pickleable_exception(exc):\n    \"\"\"Make sure exception is pickleable.\"\"\"\n    try:\n        pickle.loads(pickle.dumps(exc))\n    except Exception:\n        pass\n    else:\n        return exc\n    nearest = find_pickleable_exception(exc)\n    if nearest:\n        return nearest\n    return UnpickleableExceptionWrapper.from_exception(exc)\n\n\ndef get_pickleable_etype(cls, loads=pickle.loads, dumps=pickle.dumps):\n    try:\n        loads(dumps(cls))\n    except:\n        return Exception\n    else:\n        return cls\n\n\ndef get_pickled_exception(exc):\n    \"\"\"Get original exception from exception pickled using\n    :meth:`get_pickleable_exception`.\"\"\"\n    if isinstance(exc, UnpickleableExceptionWrapper):\n        return exc.restore()\n    return exc\n\n\ndef b64encode(s):\n    return bytes_to_str(base64encode(str_to_bytes(s)))\n\n\ndef b64decode(s):\n    return base64decode(str_to_bytes(s))\n\n\ndef strtobool(term, table={'false': False, 'no': False, '0': False,\n                           'true': True, 'yes': True, '1': True,\n                           'on': True, 'off': False}):\n    \"\"\"Convert common terms for true/false to bool\n    (true/false/yes/no/on/off/1/0).\"\"\"\n    if isinstance(term, string_t):\n        try:\n            return table[term.lower()]\n        except KeyError:\n            raise TypeError('Cannot coerce {0!r} to type bool'.format(term))\n    return term\n\n\ndef jsonify(obj,\n            builtin_types=(numbers.Real, string_t), key=None,\n            keyfilter=None,\n            unknown_type_filter=None):\n    \"\"\"Transforms object making it suitable for json serialization\"\"\"\n    from kombu.abstract import Object as KombuDictType\n    _jsonify = partial(jsonify, builtin_types=builtin_types, key=key,\n                       keyfilter=keyfilter,\n                       unknown_type_filter=unknown_type_filter)\n\n    if isinstance(obj, KombuDictType):\n        obj = obj.as_dict(recurse=True)\n\n    if obj is None or isinstance(obj, builtin_types):\n        return obj\n    elif isinstance(obj, (tuple, list)):\n        return [_jsonify(v) for v in obj]\n    elif isinstance(obj, dict):\n        return {\n            k: _jsonify(v, key=k) for k, v in items(obj)\n            if (keyfilter(k) if keyfilter else 1)\n        }\n    elif isinstance(obj, datetime.datetime):\n        # See \"Date Time String Format\" in the ECMA-262 specification.\n        r = obj.isoformat()\n        if obj.microsecond:\n            r = r[:23] + r[26:]\n        if r.endswith('+00:00'):\n            r = r[:-6] + 'Z'\n        return r\n    elif isinstance(obj, datetime.date):\n        return obj.isoformat()\n    elif isinstance(obj, datetime.time):\n        r = obj.isoformat()\n        if obj.microsecond:\n            r = r[:12]\n        return r\n    elif isinstance(obj, datetime.timedelta):\n        return str(obj)\n    else:\n        if unknown_type_filter is None:\n            raise ValueError(\n                'Unsupported type: {0!r} {1!r} (parent: {2})'.format(\n                    type(obj), obj, key))\n        return unknown_type_filter(obj)\n\n\nif PY3:\n    from vine.five import exec_\n    _raise_with_context = None  # for flake8\n    exec_(\"\"\"def _raise_with_context(exc, ctx): raise exc from ctx\"\"\")\n\n    def raise_with_context(exc):\n        exc_info = sys.exc_info()\n        if not exc_info:\n            raise exc\n        elif exc_info[1] is exc:\n            raise\n        _raise_with_context(exc, exc_info[1])\nelse:\n    def raise_with_context(exc):\n        exc_info = sys.exc_info()\n        if not exc_info:\n            raise exc\n        if exc_info[1] is exc:\n            raise\n        elif exc_info[2]:\n            reraise(type(exc), exc, exc_info[2])\n        raise exc\n", "path": "celery/utils/serialization.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"Utilities for safely pickling exceptions.\"\"\"\nfrom __future__ import absolute_import, unicode_literals\n\nimport datetime\nimport numbers\nimport sys\n\nfrom base64 import b64encode as base64encode, b64decode as base64decode\nfrom functools import partial\nfrom inspect import getmro\nfrom itertools import takewhile\n\nfrom kombu.utils.encoding import bytes_to_str, str_to_bytes\n\nfrom celery.five import (\n    bytes_if_py2, python_2_unicode_compatible, items, reraise, string_t,\n)\n\nfrom .encoding import safe_repr\n\ntry:\n    import cPickle as pickle\nexcept ImportError:\n    import pickle  # noqa\n\nPY33 = sys.version_info >= (3, 3)\n\n__all__ = [\n    'UnpickleableExceptionWrapper', 'subclass_exception',\n    'find_pickleable_exception', 'create_exception_cls',\n    'get_pickleable_exception', 'get_pickleable_etype',\n    'get_pickled_exception', 'strtobool',\n]\n\n#: List of base classes we probably don't want to reduce to.\ntry:\n    unwanted_base_classes = (StandardError, Exception, BaseException, object)\nexcept NameError:  # pragma: no cover\n    unwanted_base_classes = (Exception, BaseException, object)  # py3k\n\n\ndef subclass_exception(name, parent, module):  # noqa\n    return type(bytes_if_py2(name), (parent,), {'__module__': module})\n\n\ndef find_pickleable_exception(exc, loads=pickle.loads,\n                              dumps=pickle.dumps):\n    \"\"\"With an exception instance, iterate over its super classes (by MRO)\n    and find the first super exception that's pickleable.  It does\n    not go below :exc:`Exception` (i.e., it skips :exc:`Exception`,\n    :class:`BaseException` and :class:`object`).  If that happens\n    you should use :exc:`UnpickleableException` instead.\n\n    Arguments:\n        exc (BaseException): An exception instance.\n\n    Returns:\n        Exception: Nearest pickleable parent exception class\n            (except :exc:`Exception` and parents), or if the exception is\n            pickleable it will return :const:`None`.\n    \"\"\"\n    exc_args = getattr(exc, 'args', [])\n    for supercls in itermro(exc.__class__, unwanted_base_classes):\n        try:\n            superexc = supercls(*exc_args)\n            loads(dumps(superexc))\n        except:\n            pass\n        else:\n            return superexc\n\n\ndef itermro(cls, stop):\n    return takewhile(lambda sup: sup not in stop, getmro(cls))\n\n\ndef create_exception_cls(name, module, parent=None):\n    \"\"\"Dynamically create an exception class.\"\"\"\n    if not parent:\n        parent = Exception\n    return subclass_exception(name, parent, module)\n\n\n@python_2_unicode_compatible\nclass UnpickleableExceptionWrapper(Exception):\n    \"\"\"Wraps unpickleable exceptions.\n\n    Arguments:\n        exc_module (str): See :attr:`exc_module`.\n        exc_cls_name (str): See :attr:`exc_cls_name`.\n        exc_args (Tuple[Any, ...]): See :attr:`exc_args`.\n\n    Example:\n        >>> def pickle_it(raising_function):\n        ...     try:\n        ...         raising_function()\n        ...     except Exception as e:\n        ...         exc = UnpickleableExceptionWrapper(\n        ...             e.__class__.__module__,\n        ...             e.__class__.__name__,\n        ...             e.args,\n        ...         )\n        ...         pickle.dumps(exc)  # Works fine.\n    \"\"\"\n\n    #: The module of the original exception.\n    exc_module = None\n\n    #: The name of the original exception class.\n    exc_cls_name = None\n\n    #: The arguments for the original exception.\n    exc_args = None\n\n    def __init__(self, exc_module, exc_cls_name, exc_args, text=None):\n        safe_exc_args = []\n        for arg in exc_args:\n            try:\n                pickle.dumps(arg)\n                safe_exc_args.append(arg)\n            except Exception:\n                safe_exc_args.append(safe_repr(arg))\n        self.exc_module = exc_module\n        self.exc_cls_name = exc_cls_name\n        self.exc_args = safe_exc_args\n        self.text = text\n        Exception.__init__(self, exc_module, exc_cls_name, safe_exc_args, text)\n\n    def restore(self):\n        return create_exception_cls(self.exc_cls_name,\n                                    self.exc_module)(*self.exc_args)\n\n    def __str__(self):\n        return self.text\n\n    @classmethod\n    def from_exception(cls, exc):\n        return cls(exc.__class__.__module__,\n                   exc.__class__.__name__,\n                   getattr(exc, 'args', []),\n                   safe_repr(exc))\n\n\ndef get_pickleable_exception(exc):\n    \"\"\"Make sure exception is pickleable.\"\"\"\n    try:\n        pickle.loads(pickle.dumps(exc))\n    except Exception:\n        pass\n    else:\n        return exc\n    nearest = find_pickleable_exception(exc)\n    if nearest:\n        return nearest\n    return UnpickleableExceptionWrapper.from_exception(exc)\n\n\ndef get_pickleable_etype(cls, loads=pickle.loads, dumps=pickle.dumps):\n    try:\n        loads(dumps(cls))\n    except:\n        return Exception\n    else:\n        return cls\n\n\ndef get_pickled_exception(exc):\n    \"\"\"Get original exception from exception pickled using\n    :meth:`get_pickleable_exception`.\"\"\"\n    if isinstance(exc, UnpickleableExceptionWrapper):\n        return exc.restore()\n    return exc\n\n\ndef b64encode(s):\n    return bytes_to_str(base64encode(str_to_bytes(s)))\n\n\ndef b64decode(s):\n    return base64decode(str_to_bytes(s))\n\n\ndef strtobool(term, table={'false': False, 'no': False, '0': False,\n                           'true': True, 'yes': True, '1': True,\n                           'on': True, 'off': False}):\n    \"\"\"Convert common terms for true/false to bool\n    (true/false/yes/no/on/off/1/0).\"\"\"\n    if isinstance(term, string_t):\n        try:\n            return table[term.lower()]\n        except KeyError:\n            raise TypeError('Cannot coerce {0!r} to type bool'.format(term))\n    return term\n\n\ndef jsonify(obj,\n            builtin_types=(numbers.Real, string_t), key=None,\n            keyfilter=None,\n            unknown_type_filter=None):\n    \"\"\"Transforms object making it suitable for json serialization\"\"\"\n    from kombu.abstract import Object as KombuDictType\n    _jsonify = partial(jsonify, builtin_types=builtin_types, key=key,\n                       keyfilter=keyfilter,\n                       unknown_type_filter=unknown_type_filter)\n\n    if isinstance(obj, KombuDictType):\n        obj = obj.as_dict(recurse=True)\n\n    if obj is None or isinstance(obj, builtin_types):\n        return obj\n    elif isinstance(obj, (tuple, list)):\n        return [_jsonify(v) for v in obj]\n    elif isinstance(obj, dict):\n        return {\n            k: _jsonify(v, key=k) for k, v in items(obj)\n            if (keyfilter(k) if keyfilter else 1)\n        }\n    elif isinstance(obj, datetime.datetime):\n        # See \"Date Time String Format\" in the ECMA-262 specification.\n        r = obj.isoformat()\n        if obj.microsecond:\n            r = r[:23] + r[26:]\n        if r.endswith('+00:00'):\n            r = r[:-6] + 'Z'\n        return r\n    elif isinstance(obj, datetime.date):\n        return obj.isoformat()\n    elif isinstance(obj, datetime.time):\n        r = obj.isoformat()\n        if obj.microsecond:\n            r = r[:12]\n        return r\n    elif isinstance(obj, datetime.timedelta):\n        return str(obj)\n    else:\n        if unknown_type_filter is None:\n            raise ValueError(\n                'Unsupported type: {0!r} {1!r} (parent: {2})'.format(\n                    type(obj), obj, key))\n        return unknown_type_filter(obj)\n\n\n# Since PyPy 3 targets Python 3.2, 'raise exc from None' will\n# raise a TypeError so we need to look for Python 3.3 or newer\nif PY33:\n    from vine.five import exec_\n    _raise_with_context = None  # for flake8\n    exec_(\"\"\"def _raise_with_context(exc, ctx): raise exc from ctx\"\"\")\n\n    def raise_with_context(exc):\n        exc_info = sys.exc_info()\n        if not exc_info:\n            raise exc\n        elif exc_info[1] is exc:\n            raise\n        _raise_with_context(exc, exc_info[1])\nelse:\n    def raise_with_context(exc):\n        exc_info = sys.exc_info()\n        if not exc_info:\n            raise exc\n        if exc_info[1] is exc:\n            raise\n        elif exc_info[2]:\n            reraise(type(exc), exc, exc_info[2])\n        raise exc\n", "path": "celery/utils/serialization.py"}]}