We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix `safely_reserve_a_username`
This function keeps using a cursor after an `IntegrityError` exception is raised, that's invalid and raises another exception. See https://github.com/gratipay/gratipay.com/pull/2752#issuecomment-65266388.

Fix `safely_reserve_a_username`
This function keeps using a cursor after an `IntegrityError` exception is raised, that's invalid and raises another exception. See https://github.com/gratipay/gratipay.com/pull/2752#issuecomment-65266388.


--- 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/username.py`
Content:
```
1 from psycopg2 import IntegrityError
2 import random
3 
4 
5 class FailedToReserveUsername(Exception): pass
6 class RanOutOfUsernameAttempts(Exception): pass
7 
8 
9 def gen_random_usernames():
10     """Yield random 12-hex-digit unicodes.
11     """
12     while 1:
13         yield hex(int(random.random() * 16**12))[2:].zfill(12).decode('ASCII')
14 
15 
16 def insert_into_participants(cursor, username):
17     return cursor.one( "INSERT INTO participants (username, username_lower) "
18                        "VALUES (%s, %s) RETURNING username"
19                      , (username, username.lower())
20                       )
21 
22 
23 def safely_reserve_a_username(cursor, gen_usernames=gen_random_usernames,
24                                                                  reserve=insert_into_participants):
25     """Safely reserve a username.
26 
27     :param cursor: a :py:class:`psycopg2.cursor` managed as a :py:mod:`postgres`
28         transaction
29     :param gen_usernames: a generator of usernames to try
30     :param reserve: a function that takes the cursor and does the SQL
31         stuff
32     :database: one ``INSERT`` on average
33     :returns: a 12-hex-digit unicode
34     :raises: :py:class:`FailedToReserveUsername` if no acceptable username is found
35         within 100 attempts, or :py:class:`RanOutOfUsernameAttempts` if the username
36         generator runs out first
37 
38     The returned value is guaranteed to have been reserved in the database.
39 
40     """
41     seatbelt = 0
42     for username in gen_usernames():
43         seatbelt += 1
44         if seatbelt > 100:
45             raise FailedToReserveUsername
46 
47         try:
48             check = reserve(cursor, username)
49         except IntegrityError:  # Collision, try again with another value.
50             continue
51         else:
52             assert check == username
53             break
54     else:
55         raise RanOutOfUsernameAttempts
56     return username
57
```
--- 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/username.py b/gratipay/utils/username.py
--- a/gratipay/utils/username.py
+++ b/gratipay/utils/username.py
@@ -38,6 +38,8 @@
     The returned value is guaranteed to have been reserved in the database.
 
     """
+    cursor.execute("SAVEPOINT safely_reserve_a_username")
+
     seatbelt = 0
     for username in gen_usernames():
         seatbelt += 1
@@ -47,10 +49,13 @@
         try:
             check = reserve(cursor, username)
         except IntegrityError:  # Collision, try again with another value.
+            cursor.execute("ROLLBACK TO safely_reserve_a_username")
             continue
         else:
             assert check == username
             break
     else:
         raise RanOutOfUsernameAttempts
+
+    cursor.execute("RELEASE safely_reserve_a_username")
     return username

{"golden_diff": "diff --git a/gratipay/utils/username.py b/gratipay/utils/username.py\n--- a/gratipay/utils/username.py\n+++ b/gratipay/utils/username.py\n@@ -38,6 +38,8 @@\n     The returned value is guaranteed to have been reserved in the database.\n \n     \"\"\"\n+    cursor.execute(\"SAVEPOINT safely_reserve_a_username\")\n+\n     seatbelt = 0\n     for username in gen_usernames():\n         seatbelt += 1\n@@ -47,10 +49,13 @@\n         try:\n             check = reserve(cursor, username)\n         except IntegrityError:  # Collision, try again with another value.\n+            cursor.execute(\"ROLLBACK TO safely_reserve_a_username\")\n             continue\n         else:\n             assert check == username\n             break\n     else:\n         raise RanOutOfUsernameAttempts\n+\n+    cursor.execute(\"RELEASE safely_reserve_a_username\")\n     return username\n", "issue": "Fix `safely_reserve_a_username`\nThis function keeps using a cursor after an `IntegrityError` exception is raised, that's invalid and raises another exception. See https://github.com/gratipay/gratipay.com/pull/2752#issuecomment-65266388.\n\nFix `safely_reserve_a_username`\nThis function keeps using a cursor after an `IntegrityError` exception is raised, that's invalid and raises another exception. See https://github.com/gratipay/gratipay.com/pull/2752#issuecomment-65266388.\n\n", "before_files": [{"content": "from psycopg2 import IntegrityError\nimport random\n\n\nclass FailedToReserveUsername(Exception): pass\nclass RanOutOfUsernameAttempts(Exception): pass\n\n\ndef gen_random_usernames():\n    \"\"\"Yield random 12-hex-digit unicodes.\n    \"\"\"\n    while 1:\n        yield hex(int(random.random() * 16**12))[2:].zfill(12).decode('ASCII')\n\n\ndef insert_into_participants(cursor, username):\n    return cursor.one( \"INSERT INTO participants (username, username_lower) \"\n                       \"VALUES (%s, %s) RETURNING username\"\n                     , (username, username.lower())\n                      )\n\n\ndef safely_reserve_a_username(cursor, gen_usernames=gen_random_usernames,\n                                                                 reserve=insert_into_participants):\n    \"\"\"Safely reserve a username.\n\n    :param cursor: a :py:class:`psycopg2.cursor` managed as a :py:mod:`postgres`\n        transaction\n    :param gen_usernames: a generator of usernames to try\n    :param reserve: a function that takes the cursor and does the SQL\n        stuff\n    :database: one ``INSERT`` on average\n    :returns: a 12-hex-digit unicode\n    :raises: :py:class:`FailedToReserveUsername` if no acceptable username is found\n        within 100 attempts, or :py:class:`RanOutOfUsernameAttempts` if the username\n        generator runs out first\n\n    The returned value is guaranteed to have been reserved in the database.\n\n    \"\"\"\n    seatbelt = 0\n    for username in gen_usernames():\n        seatbelt += 1\n        if seatbelt > 100:\n            raise FailedToReserveUsername\n\n        try:\n            check = reserve(cursor, username)\n        except IntegrityError:  # Collision, try again with another value.\n            continue\n        else:\n            assert check == username\n            break\n    else:\n        raise RanOutOfUsernameAttempts\n    return username\n", "path": "gratipay/utils/username.py"}], "after_files": [{"content": "from psycopg2 import IntegrityError\nimport random\n\n\nclass FailedToReserveUsername(Exception): pass\nclass RanOutOfUsernameAttempts(Exception): pass\n\n\ndef gen_random_usernames():\n    \"\"\"Yield random 12-hex-digit unicodes.\n    \"\"\"\n    while 1:\n        yield hex(int(random.random() * 16**12))[2:].zfill(12).decode('ASCII')\n\n\ndef insert_into_participants(cursor, username):\n    return cursor.one( \"INSERT INTO participants (username, username_lower) \"\n                       \"VALUES (%s, %s) RETURNING username\"\n                     , (username, username.lower())\n                      )\n\n\ndef safely_reserve_a_username(cursor, gen_usernames=gen_random_usernames,\n                                                                 reserve=insert_into_participants):\n    \"\"\"Safely reserve a username.\n\n    :param cursor: a :py:class:`psycopg2.cursor` managed as a :py:mod:`postgres`\n        transaction\n    :param gen_usernames: a generator of usernames to try\n    :param reserve: a function that takes the cursor and does the SQL\n        stuff\n    :database: one ``INSERT`` on average\n    :returns: a 12-hex-digit unicode\n    :raises: :py:class:`FailedToReserveUsername` if no acceptable username is found\n        within 100 attempts, or :py:class:`RanOutOfUsernameAttempts` if the username\n        generator runs out first\n\n    The returned value is guaranteed to have been reserved in the database.\n\n    \"\"\"\n    cursor.execute(\"SAVEPOINT safely_reserve_a_username\")\n\n    seatbelt = 0\n    for username in gen_usernames():\n        seatbelt += 1\n        if seatbelt > 100:\n            raise FailedToReserveUsername\n\n        try:\n            check = reserve(cursor, username)\n        except IntegrityError:  # Collision, try again with another value.\n            cursor.execute(\"ROLLBACK TO safely_reserve_a_username\")\n            continue\n        else:\n            assert check == username\n            break\n    else:\n        raise RanOutOfUsernameAttempts\n\n    cursor.execute(\"RELEASE safely_reserve_a_username\")\n    return username\n", "path": "gratipay/utils/username.py"}]}