We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
log spam during test
What's this `TypeError` about? Seems spurious ...

```
pid-13897 thread-4384100352 (Thread-1) Traceback (most recent call last):
pid-13897 thread-4384100352 (Thread-1)   File "/Users/whit537/personal/gratipay/gratipay.com/gratipay/cron.py", line 26, in f
pid-13897 thread-4384100352 (Thread-1)     func()
pid-13897 thread-4384100352 (Thread-1)   File "/Users/whit537/personal/gratipay/gratipay.com/gratipay/main.py", line 82, in <lambda>
pid-13897 thread-4384100352 (Thread-1)     cron(env.update_cta_every, lambda: utils.update_cta(website))
pid-13897 thread-4384100352 (Thread-1)   File "/Users/whit537/personal/gratipay/gratipay.com/gratipay/utils/__init__.py", line 145, in update_cta
pid-13897 thread-4384100352 (Thread-1)     website.support_current = cur = int(round(nreceiving_from / nusers * 100)) if nusers else 0
pid-13897 thread-4384100352 (Thread-1) TypeError: unsupported operand type(s) for /: 'int' and 'tuple'
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gratipay/utils/__init__.py`
Content:
```
1 # encoding: utf8
2 
3 from __future__ import absolute_import, division, print_function, unicode_literals
4 
5 from datetime import datetime, timedelta
6 
7 from aspen import Response, json
8 from aspen.utils import to_rfc822, utcnow
9 from dependency_injection import resolve_dependencies
10 from postgres.cursors import SimpleCursorBase
11 
12 import gratipay
13 
14 
15 BEGINNING_OF_EPOCH = to_rfc822(datetime(1970, 1, 1)).encode('ascii')
16 
17 # Difference between current time and credit card expiring date when
18 # card is considered as expiring
19 EXPIRING_DELTA = timedelta(days = 30)
20 
21 
22 def dict_to_querystring(mapping):
23     if not mapping:
24         return u''
25 
26     arguments = []
27     for key, values in mapping.iteritems():
28         for val in values:
29             arguments.append(u'='.join([key, val]))
30 
31     return u'?' + u'&'.join(arguments)
32 
33 
34 def use_tildes_for_participants(website, request):
35     if request.path.raw.startswith('/~/'):
36         to = '/~' + request.path.raw[3:]
37         if request.qs.raw:
38             to += '?' + request.qs.raw
39         website.redirect(to)
40     elif request.path.raw.startswith('/~'):
41         request.path.__init__('/~/' + request.path.raw[2:])
42 
43 
44 def canonicalize(redirect, path, base, canonical, given, arguments=None):
45     if given != canonical:
46         assert canonical.lower() == given.lower()  # sanity check
47         remainder = path[len(base + given):]
48 
49         if arguments is not None:
50             arguments = dict_to_querystring(arguments)
51 
52         newpath = base + canonical + remainder + arguments or ''
53         redirect(newpath)
54 
55 
56 def get_participant(state, restrict=True, resolve_unclaimed=True):
57     """Given a Request, raise Response or return Participant.
58 
59     If restrict is True then we'll restrict access to owners and admins.
60 
61     """
62     redirect = state['website'].redirect
63     request = state['request']
64     user = state['user']
65     slug = request.line.uri.path['username']
66     qs = request.line.uri.querystring
67     _ = state['_']
68 
69     if restrict:
70         if user.ANON:
71             raise Response(403, _("You need to log in to access this page."))
72 
73     from gratipay.models.participant import Participant  # avoid circular import
74     participant = Participant.from_username(slug)
75 
76     if participant is None:
77         raise Response(404)
78 
79     canonicalize(redirect, request.line.uri.path.raw, '/~/', participant.username, slug, qs)
80 
81     if participant.is_closed:
82         if user.ADMIN:
83             return participant
84         raise Response(410)
85 
86     if participant.claimed_time is None and resolve_unclaimed:
87         to = participant.resolve_unclaimed()
88         if to:
89             # This is a stub account (someone on another platform who hasn't
90             # actually registered with Gratipay yet)
91             redirect(to)
92         else:
93             # This is an archived account (result of take_over)
94             if user.ADMIN:
95                 return participant
96             raise Response(404)
97 
98     if restrict:
99         if participant != user.participant:
100             if not user.ADMIN:
101                 raise Response(403, _("You are not authorized to access this page."))
102 
103     return participant
104 
105 
106 def get_team(state):
107     """Given a Request, raise Response or return Team.
108     """
109     redirect = state['website'].redirect
110     request = state['request']
111     user = state['user']
112     slug = request.line.uri.path['team']
113     qs = request.line.uri.querystring
114 
115     from gratipay.models.team import Team  # avoid circular import
116     team = Team.from_slug(slug)
117 
118     if team is None:
119         # Try to redirect to a Participant.
120         from gratipay.models.participant import Participant # avoid circular import
121         participant = Participant.from_username(slug)
122         if participant is not None:
123             qs = '?' + request.qs.raw if request.qs.raw else ''
124             redirect('/~' + request.path.raw[1:] + qs)
125         raise Response(404)
126 
127     canonicalize(redirect, request.line.uri.path.raw, '/', team.slug, slug, qs)
128 
129     if team.is_closed and not user.ADMIN:
130         raise Response(410)
131 
132     return team
133 
134 
135 def update_cta(website):
136     nusers = website.db.one("""
137         SELECT nusers FROM paydays
138         ORDER BY ts_end DESC LIMIT 1
139     """, default=(0.0, 0))
140     nreceiving_from = website.db.one("""
141         SELECT nreceiving_from
142           FROM teams
143          WHERE slug = 'Gratipay'
144     """, default=0)
145     website.support_current = cur = int(round(nreceiving_from / nusers * 100)) if nusers else 0
146     if cur < 10:    goal = 20
147     elif cur < 15:  goal = 30
148     elif cur < 25:  goal = 40
149     elif cur < 35:  goal = 50
150     elif cur < 45:  goal = 60
151     elif cur < 55:  goal = 70
152     elif cur < 65:  goal = 80
153     elif cur > 70:  goal = None
154     website.support_goal = goal
155 
156 
157 def _execute(this, sql, params=[]):
158     print(sql.strip(), params)
159     super(SimpleCursorBase, this).execute(sql, params)
160 
161 def log_cursor(f):
162     "Prints sql and params to stdout. Works globaly so watch for threaded use."
163     def wrapper(*a, **kw):
164         try:
165             SimpleCursorBase.execute = _execute
166             ret = f(*a, **kw)
167         finally:
168             del SimpleCursorBase.execute
169         return ret
170     return wrapper
171 
172 
173 def format_money(money):
174     format = '%.2f' if money < 1000 else '%.0f'
175     return format % money
176 
177 
178 def excerpt_intro(text, length=175, append=u'…'):
179     if not text:
180         return ''
181     if len(text) > length:
182         return text[:length] + append
183     return text
184 
185 
186 def is_card_expiring(expiration_year, expiration_month):
187     now = datetime.utcnow()
188     expiring_date = datetime(expiration_year, expiration_month, 1)
189     delta = expiring_date - now
190     return delta < EXPIRING_DELTA
191 
192 
193 def set_cookie(cookies, key, value, expires=None, httponly=True, path=b'/'):
194     cookies[key] = value
195     cookie = cookies[key]
196     if expires:
197         if isinstance(expires, timedelta):
198             expires += utcnow()
199         if isinstance(expires, datetime):
200             expires = to_rfc822(expires).encode('ascii')
201         cookie[b'expires'] = expires
202     if httponly:
203         cookie[b'httponly'] = True
204     if path:
205         cookie[b'path'] = path
206     if gratipay.use_secure_cookies:
207         cookie[b'secure'] = True
208 
209 
210 def erase_cookie(cookies, key, **kw):
211     set_cookie(cookies, key, '', BEGINNING_OF_EPOCH, **kw)
212 
213 
214 def filter_profile_nav(user, participant, pages):
215     out = []
216     for foo, bar, show_them, show_others in pages:
217         if (user.participant == participant and show_them) \
218         or (user.participant != participant and show_others) \
219         or user.ADMIN:
220             out.append((foo, bar, show_them, show_others))
221     return out
222 
223 
224 def to_javascript(obj):
225     """For when you want to inject an object into a <script> tag.
226     """
227     return json.dumps(obj).replace('</', '<\\/')
228 
229 
230 class LazyResponse(Response):
231 
232     def __init__(self, code, lazy_body, **kw):
233         Response.__init__(self, code, '', **kw)
234         self.lazy_body = lazy_body
235 
236     def render_body(self, state):
237         f = self.lazy_body
238         self.body = f(*resolve_dependencies(f, state).as_args)
239
```
--- 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/gratipay/utils/__init__.py b/gratipay/utils/__init__.py
--- a/gratipay/utils/__init__.py
+++ b/gratipay/utils/__init__.py
@@ -136,7 +136,7 @@
     nusers = website.db.one("""
         SELECT nusers FROM paydays
         ORDER BY ts_end DESC LIMIT 1
-    """, default=(0.0, 0))
+    """, default=0)
     nreceiving_from = website.db.one("""
         SELECT nreceiving_from
           FROM teams

{"golden_diff": "diff --git a/gratipay/utils/__init__.py b/gratipay/utils/__init__.py\n--- a/gratipay/utils/__init__.py\n+++ b/gratipay/utils/__init__.py\n@@ -136,7 +136,7 @@\n     nusers = website.db.one(\"\"\"\n         SELECT nusers FROM paydays\n         ORDER BY ts_end DESC LIMIT 1\n-    \"\"\", default=(0.0, 0))\n+    \"\"\", default=0)\n     nreceiving_from = website.db.one(\"\"\"\n         SELECT nreceiving_from\n           FROM teams\n", "issue": "log spam during test\nWhat's this `TypeError` about? Seems spurious ...\n\n```\npid-13897 thread-4384100352 (Thread-1) Traceback (most recent call last):\npid-13897 thread-4384100352 (Thread-1)   File \"/Users/whit537/personal/gratipay/gratipay.com/gratipay/cron.py\", line 26, in f\npid-13897 thread-4384100352 (Thread-1)     func()\npid-13897 thread-4384100352 (Thread-1)   File \"/Users/whit537/personal/gratipay/gratipay.com/gratipay/main.py\", line 82, in <lambda>\npid-13897 thread-4384100352 (Thread-1)     cron(env.update_cta_every, lambda: utils.update_cta(website))\npid-13897 thread-4384100352 (Thread-1)   File \"/Users/whit537/personal/gratipay/gratipay.com/gratipay/utils/__init__.py\", line 145, in update_cta\npid-13897 thread-4384100352 (Thread-1)     website.support_current = cur = int(round(nreceiving_from / nusers * 100)) if nusers else 0\npid-13897 thread-4384100352 (Thread-1) TypeError: unsupported operand type(s) for /: 'int' and 'tuple'\n```\n\n", "before_files": [{"content": "# encoding: utf8\n\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom datetime import datetime, timedelta\n\nfrom aspen import Response, json\nfrom aspen.utils import to_rfc822, utcnow\nfrom dependency_injection import resolve_dependencies\nfrom postgres.cursors import SimpleCursorBase\n\nimport gratipay\n\n\nBEGINNING_OF_EPOCH = to_rfc822(datetime(1970, 1, 1)).encode('ascii')\n\n# Difference between current time and credit card expiring date when\n# card is considered as expiring\nEXPIRING_DELTA = timedelta(days = 30)\n\n\ndef dict_to_querystring(mapping):\n    if not mapping:\n        return u''\n\n    arguments = []\n    for key, values in mapping.iteritems():\n        for val in values:\n            arguments.append(u'='.join([key, val]))\n\n    return u'?' + u'&'.join(arguments)\n\n\ndef use_tildes_for_participants(website, request):\n    if request.path.raw.startswith('/~/'):\n        to = '/~' + request.path.raw[3:]\n        if request.qs.raw:\n            to += '?' + request.qs.raw\n        website.redirect(to)\n    elif request.path.raw.startswith('/~'):\n        request.path.__init__('/~/' + request.path.raw[2:])\n\n\ndef canonicalize(redirect, path, base, canonical, given, arguments=None):\n    if given != canonical:\n        assert canonical.lower() == given.lower()  # sanity check\n        remainder = path[len(base + given):]\n\n        if arguments is not None:\n            arguments = dict_to_querystring(arguments)\n\n        newpath = base + canonical + remainder + arguments or ''\n        redirect(newpath)\n\n\ndef get_participant(state, restrict=True, resolve_unclaimed=True):\n    \"\"\"Given a Request, raise Response or return Participant.\n\n    If restrict is True then we'll restrict access to owners and admins.\n\n    \"\"\"\n    redirect = state['website'].redirect\n    request = state['request']\n    user = state['user']\n    slug = request.line.uri.path['username']\n    qs = request.line.uri.querystring\n    _ = state['_']\n\n    if restrict:\n        if user.ANON:\n            raise Response(403, _(\"You need to log in to access this page.\"))\n\n    from gratipay.models.participant import Participant  # avoid circular import\n    participant = Participant.from_username(slug)\n\n    if participant is None:\n        raise Response(404)\n\n    canonicalize(redirect, request.line.uri.path.raw, '/~/', participant.username, slug, qs)\n\n    if participant.is_closed:\n        if user.ADMIN:\n            return participant\n        raise Response(410)\n\n    if participant.claimed_time is None and resolve_unclaimed:\n        to = participant.resolve_unclaimed()\n        if to:\n            # This is a stub account (someone on another platform who hasn't\n            # actually registered with Gratipay yet)\n            redirect(to)\n        else:\n            # This is an archived account (result of take_over)\n            if user.ADMIN:\n                return participant\n            raise Response(404)\n\n    if restrict:\n        if participant != user.participant:\n            if not user.ADMIN:\n                raise Response(403, _(\"You are not authorized to access this page.\"))\n\n    return participant\n\n\ndef get_team(state):\n    \"\"\"Given a Request, raise Response or return Team.\n    \"\"\"\n    redirect = state['website'].redirect\n    request = state['request']\n    user = state['user']\n    slug = request.line.uri.path['team']\n    qs = request.line.uri.querystring\n\n    from gratipay.models.team import Team  # avoid circular import\n    team = Team.from_slug(slug)\n\n    if team is None:\n        # Try to redirect to a Participant.\n        from gratipay.models.participant import Participant # avoid circular import\n        participant = Participant.from_username(slug)\n        if participant is not None:\n            qs = '?' + request.qs.raw if request.qs.raw else ''\n            redirect('/~' + request.path.raw[1:] + qs)\n        raise Response(404)\n\n    canonicalize(redirect, request.line.uri.path.raw, '/', team.slug, slug, qs)\n\n    if team.is_closed and not user.ADMIN:\n        raise Response(410)\n\n    return team\n\n\ndef update_cta(website):\n    nusers = website.db.one(\"\"\"\n        SELECT nusers FROM paydays\n        ORDER BY ts_end DESC LIMIT 1\n    \"\"\", default=(0.0, 0))\n    nreceiving_from = website.db.one(\"\"\"\n        SELECT nreceiving_from\n          FROM teams\n         WHERE slug = 'Gratipay'\n    \"\"\", default=0)\n    website.support_current = cur = int(round(nreceiving_from / nusers * 100)) if nusers else 0\n    if cur < 10:    goal = 20\n    elif cur < 15:  goal = 30\n    elif cur < 25:  goal = 40\n    elif cur < 35:  goal = 50\n    elif cur < 45:  goal = 60\n    elif cur < 55:  goal = 70\n    elif cur < 65:  goal = 80\n    elif cur > 70:  goal = None\n    website.support_goal = goal\n\n\ndef _execute(this, sql, params=[]):\n    print(sql.strip(), params)\n    super(SimpleCursorBase, this).execute(sql, params)\n\ndef log_cursor(f):\n    \"Prints sql and params to stdout. Works globaly so watch for threaded use.\"\n    def wrapper(*a, **kw):\n        try:\n            SimpleCursorBase.execute = _execute\n            ret = f(*a, **kw)\n        finally:\n            del SimpleCursorBase.execute\n        return ret\n    return wrapper\n\n\ndef format_money(money):\n    format = '%.2f' if money < 1000 else '%.0f'\n    return format % money\n\n\ndef excerpt_intro(text, length=175, append=u'\u2026'):\n    if not text:\n        return ''\n    if len(text) > length:\n        return text[:length] + append\n    return text\n\n\ndef is_card_expiring(expiration_year, expiration_month):\n    now = datetime.utcnow()\n    expiring_date = datetime(expiration_year, expiration_month, 1)\n    delta = expiring_date - now\n    return delta < EXPIRING_DELTA\n\n\ndef set_cookie(cookies, key, value, expires=None, httponly=True, path=b'/'):\n    cookies[key] = value\n    cookie = cookies[key]\n    if expires:\n        if isinstance(expires, timedelta):\n            expires += utcnow()\n        if isinstance(expires, datetime):\n            expires = to_rfc822(expires).encode('ascii')\n        cookie[b'expires'] = expires\n    if httponly:\n        cookie[b'httponly'] = True\n    if path:\n        cookie[b'path'] = path\n    if gratipay.use_secure_cookies:\n        cookie[b'secure'] = True\n\n\ndef erase_cookie(cookies, key, **kw):\n    set_cookie(cookies, key, '', BEGINNING_OF_EPOCH, **kw)\n\n\ndef filter_profile_nav(user, participant, pages):\n    out = []\n    for foo, bar, show_them, show_others in pages:\n        if (user.participant == participant and show_them) \\\n        or (user.participant != participant and show_others) \\\n        or user.ADMIN:\n            out.append((foo, bar, show_them, show_others))\n    return out\n\n\ndef to_javascript(obj):\n    \"\"\"For when you want to inject an object into a <script> tag.\n    \"\"\"\n    return json.dumps(obj).replace('</', '<\\\\/')\n\n\nclass LazyResponse(Response):\n\n    def __init__(self, code, lazy_body, **kw):\n        Response.__init__(self, code, '', **kw)\n        self.lazy_body = lazy_body\n\n    def render_body(self, state):\n        f = self.lazy_body\n        self.body = f(*resolve_dependencies(f, state).as_args)\n", "path": "gratipay/utils/__init__.py"}], "after_files": [{"content": "# encoding: utf8\n\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom datetime import datetime, timedelta\n\nfrom aspen import Response, json\nfrom aspen.utils import to_rfc822, utcnow\nfrom dependency_injection import resolve_dependencies\nfrom postgres.cursors import SimpleCursorBase\n\nimport gratipay\n\n\nBEGINNING_OF_EPOCH = to_rfc822(datetime(1970, 1, 1)).encode('ascii')\n\n# Difference between current time and credit card expiring date when\n# card is considered as expiring\nEXPIRING_DELTA = timedelta(days = 30)\n\n\ndef dict_to_querystring(mapping):\n    if not mapping:\n        return u''\n\n    arguments = []\n    for key, values in mapping.iteritems():\n        for val in values:\n            arguments.append(u'='.join([key, val]))\n\n    return u'?' + u'&'.join(arguments)\n\n\ndef use_tildes_for_participants(website, request):\n    if request.path.raw.startswith('/~/'):\n        to = '/~' + request.path.raw[3:]\n        if request.qs.raw:\n            to += '?' + request.qs.raw\n        website.redirect(to)\n    elif request.path.raw.startswith('/~'):\n        request.path.__init__('/~/' + request.path.raw[2:])\n\n\ndef canonicalize(redirect, path, base, canonical, given, arguments=None):\n    if given != canonical:\n        assert canonical.lower() == given.lower()  # sanity check\n        remainder = path[len(base + given):]\n\n        if arguments is not None:\n            arguments = dict_to_querystring(arguments)\n\n        newpath = base + canonical + remainder + arguments or ''\n        redirect(newpath)\n\n\ndef get_participant(state, restrict=True, resolve_unclaimed=True):\n    \"\"\"Given a Request, raise Response or return Participant.\n\n    If restrict is True then we'll restrict access to owners and admins.\n\n    \"\"\"\n    redirect = state['website'].redirect\n    request = state['request']\n    user = state['user']\n    slug = request.line.uri.path['username']\n    qs = request.line.uri.querystring\n    _ = state['_']\n\n    if restrict:\n        if user.ANON:\n            raise Response(403, _(\"You need to log in to access this page.\"))\n\n    from gratipay.models.participant import Participant  # avoid circular import\n    participant = Participant.from_username(slug)\n\n    if participant is None:\n        raise Response(404)\n\n    canonicalize(redirect, request.line.uri.path.raw, '/~/', participant.username, slug, qs)\n\n    if participant.is_closed:\n        if user.ADMIN:\n            return participant\n        raise Response(410)\n\n    if participant.claimed_time is None and resolve_unclaimed:\n        to = participant.resolve_unclaimed()\n        if to:\n            # This is a stub account (someone on another platform who hasn't\n            # actually registered with Gratipay yet)\n            redirect(to)\n        else:\n            # This is an archived account (result of take_over)\n            if user.ADMIN:\n                return participant\n            raise Response(404)\n\n    if restrict:\n        if participant != user.participant:\n            if not user.ADMIN:\n                raise Response(403, _(\"You are not authorized to access this page.\"))\n\n    return participant\n\n\ndef get_team(state):\n    \"\"\"Given a Request, raise Response or return Team.\n    \"\"\"\n    redirect = state['website'].redirect\n    request = state['request']\n    user = state['user']\n    slug = request.line.uri.path['team']\n    qs = request.line.uri.querystring\n\n    from gratipay.models.team import Team  # avoid circular import\n    team = Team.from_slug(slug)\n\n    if team is None:\n        # Try to redirect to a Participant.\n        from gratipay.models.participant import Participant # avoid circular import\n        participant = Participant.from_username(slug)\n        if participant is not None:\n            qs = '?' + request.qs.raw if request.qs.raw else ''\n            redirect('/~' + request.path.raw[1:] + qs)\n        raise Response(404)\n\n    canonicalize(redirect, request.line.uri.path.raw, '/', team.slug, slug, qs)\n\n    if team.is_closed and not user.ADMIN:\n        raise Response(410)\n\n    return team\n\n\ndef update_cta(website):\n    nusers = website.db.one(\"\"\"\n        SELECT nusers FROM paydays\n        ORDER BY ts_end DESC LIMIT 1\n    \"\"\", default=0)\n    nreceiving_from = website.db.one(\"\"\"\n        SELECT nreceiving_from\n          FROM teams\n         WHERE slug = 'Gratipay'\n    \"\"\", default=0)\n    website.support_current = cur = int(round(nreceiving_from / nusers * 100)) if nusers else 0\n    if cur < 10:    goal = 20\n    elif cur < 15:  goal = 30\n    elif cur < 25:  goal = 40\n    elif cur < 35:  goal = 50\n    elif cur < 45:  goal = 60\n    elif cur < 55:  goal = 70\n    elif cur < 65:  goal = 80\n    elif cur > 70:  goal = None\n    website.support_goal = goal\n\n\ndef _execute(this, sql, params=[]):\n    print(sql.strip(), params)\n    super(SimpleCursorBase, this).execute(sql, params)\n\ndef log_cursor(f):\n    \"Prints sql and params to stdout. Works globaly so watch for threaded use.\"\n    def wrapper(*a, **kw):\n        try:\n            SimpleCursorBase.execute = _execute\n            ret = f(*a, **kw)\n        finally:\n            del SimpleCursorBase.execute\n        return ret\n    return wrapper\n\n\ndef format_money(money):\n    format = '%.2f' if money < 1000 else '%.0f'\n    return format % money\n\n\ndef excerpt_intro(text, length=175, append=u'\u2026'):\n    if not text:\n        return ''\n    if len(text) > length:\n        return text[:length] + append\n    return text\n\n\ndef is_card_expiring(expiration_year, expiration_month):\n    now = datetime.utcnow()\n    expiring_date = datetime(expiration_year, expiration_month, 1)\n    delta = expiring_date - now\n    return delta < EXPIRING_DELTA\n\n\ndef set_cookie(cookies, key, value, expires=None, httponly=True, path=b'/'):\n    cookies[key] = value\n    cookie = cookies[key]\n    if expires:\n        if isinstance(expires, timedelta):\n            expires += utcnow()\n        if isinstance(expires, datetime):\n            expires = to_rfc822(expires).encode('ascii')\n        cookie[b'expires'] = expires\n    if httponly:\n        cookie[b'httponly'] = True\n    if path:\n        cookie[b'path'] = path\n    if gratipay.use_secure_cookies:\n        cookie[b'secure'] = True\n\n\ndef erase_cookie(cookies, key, **kw):\n    set_cookie(cookies, key, '', BEGINNING_OF_EPOCH, **kw)\n\n\ndef filter_profile_nav(user, participant, pages):\n    out = []\n    for foo, bar, show_them, show_others in pages:\n        if (user.participant == participant and show_them) \\\n        or (user.participant != participant and show_others) \\\n        or user.ADMIN:\n            out.append((foo, bar, show_them, show_others))\n    return out\n\n\ndef to_javascript(obj):\n    \"\"\"For when you want to inject an object into a <script> tag.\n    \"\"\"\n    return json.dumps(obj).replace('</', '<\\\\/')\n\n\nclass LazyResponse(Response):\n\n    def __init__(self, code, lazy_body, **kw):\n        Response.__init__(self, code, '', **kw)\n        self.lazy_body = lazy_body\n\n    def render_body(self, state):\n        f = self.lazy_body\n        self.body = f(*resolve_dependencies(f, state).as_args)\n", "path": "gratipay/utils/__init__.py"}]}