From 11a5df57f4240e4256d9d5a2a76ccc7f4eea1aeb Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Wed, 5 Jan 2022 13:20:35 -0500
Subject: [PATCH] remove six and future dependency, also isort and black

---
 setup.cfg                                     |  4 --
 src/_zkapauthorizer/_json.py                  |  1 +
 src/_zkapauthorizer/_plugin.py                |  2 +-
 src/_zkapauthorizer/_storage_client.py        |  5 ++-
 src/_zkapauthorizer/_storage_server.py        |  3 +-
 src/_zkapauthorizer/config.py                 |  6 +--
 src/_zkapauthorizer/configutil.py             |  1 +
 src/_zkapauthorizer/controller.py             | 18 ++++-----
 src/_zkapauthorizer/foolscap.py               |  5 +--
 src/_zkapauthorizer/lease_maintenance.py      | 14 +------
 src/_zkapauthorizer/model.py                  | 15 ++++----
 src/_zkapauthorizer/resource.py               |  5 +--
 src/_zkapauthorizer/spending.py               | 13 +++++--
 src/_zkapauthorizer/tests/storage_common.py   |  2 +-
 src/_zkapauthorizer/tests/strategies.py       |  3 +-
 .../tests/test_client_resource.py             | 29 +++++++++------
 src/_zkapauthorizer/tests/test_controller.py  | 17 ++++++---
 .../tests/test_lease_maintenance.py           | 10 +----
 src/_zkapauthorizer/tests/test_model.py       |  3 +-
 src/_zkapauthorizer/tests/test_plugin.py      |  4 +-
 .../tests/test_storage_protocol.py            | 37 ++++++++++++-------
 21 files changed, 102 insertions(+), 95 deletions(-)

diff --git a/setup.cfg b/setup.cfg
index fe4b45c..65fd066 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -53,10 +53,6 @@ install_requires =
     # install cross-platform.
     colorama
 
-    # Python 3 transition
-    six
-    future
-
 [options.extras_require]
 test = coverage; fixtures; testtools; hypothesis
 
diff --git a/src/_zkapauthorizer/_json.py b/src/_zkapauthorizer/_json.py
index 898f6b5..cd148c9 100644
--- a/src/_zkapauthorizer/_json.py
+++ b/src/_zkapauthorizer/_json.py
@@ -15,6 +15,7 @@
 from json import dumps as _dumps
 from typing import Any
 
+
 def dumps_utf8(o: Any) -> bytes:
     """
     Serialize an object to a UTF-8-encoded JSON byte string.
diff --git a/src/_zkapauthorizer/_plugin.py b/src/_zkapauthorizer/_plugin.py
index 68a5d19..ba94115 100644
--- a/src/_zkapauthorizer/_plugin.py
+++ b/src/_zkapauthorizer/_plugin.py
@@ -20,8 +20,8 @@ Tahoe-LAFS.
 import random
 from datetime import datetime
 from functools import partial
-from weakref import WeakValueDictionary
 from typing import Callable
+from weakref import WeakValueDictionary
 
 import attr
 from allmydata.client import _Client
diff --git a/src/_zkapauthorizer/_storage_client.py b/src/_zkapauthorizer/_storage_client.py
index 1f9d19a..6ebd3cc 100644
--- a/src/_zkapauthorizer/_storage_client.py
+++ b/src/_zkapauthorizer/_storage_client.py
@@ -21,14 +21,14 @@ implemented in ``_storage_server.py``.
 """
 
 from functools import partial, wraps
-from typing import Any, Tuple, Dict, List, Optional
+from typing import Any, Dict, List, Optional, Tuple
 
 import attr
 from allmydata.interfaces import IStorageServer
 from allmydata.util.eliotutil import log_call_deferred
 from attr.validators import provides
 from eliot.twisted import inline_callbacks
-from twisted.internet.defer import returnValue, Deferred
+from twisted.internet.defer import Deferred, returnValue
 from twisted.internet.interfaces import IReactorTime
 from twisted.python.reflect import namedAny
 from zope.interface import implementer
@@ -60,6 +60,7 @@ TestWriteVectors = Dict[
 ]
 ReadVector = List[Tuple[int, int]]
 
+
 class IncorrectStorageServerReference(Exception):
     """
     A Foolscap remote object which should reference a ZKAPAuthorizer storage
diff --git a/src/_zkapauthorizer/_storage_server.py b/src/_zkapauthorizer/_storage_server.py
index 2aedd90..73e4d55 100644
--- a/src/_zkapauthorizer/_storage_server.py
+++ b/src/_zkapauthorizer/_storage_server.py
@@ -131,7 +131,8 @@ class _ValidationResult(object):
             unblinded_token = signing_key.rederive_unblinded_token(preimage)
             verification_key = unblinded_token.derive_verification_key_sha512()
             invalid_pass = verification_key.invalid_sha512(
-                proposed_signature, message,
+                proposed_signature,
+                message,
             )
             return invalid_pass
         except Exception:
diff --git a/src/_zkapauthorizer/config.py b/src/_zkapauthorizer/config.py
index b30b43f..f13e895 100644
--- a/src/_zkapauthorizer/config.py
+++ b/src/_zkapauthorizer/config.py
@@ -17,11 +17,7 @@ Helpers for reading values from the Tahoe-LAFS configuration.
 """
 
 from datetime import timedelta
-
-try:
-    from typing import Optional
-except ImportError:
-    pass
+from typing import Optional
 
 from allmydata.node import _Config
 
diff --git a/src/_zkapauthorizer/configutil.py b/src/_zkapauthorizer/configutil.py
index 8270936..b9b167e 100644
--- a/src/_zkapauthorizer/configutil.py
+++ b/src/_zkapauthorizer/configutil.py
@@ -16,6 +16,7 @@
 Basic utilities related to the Tahoe configuration file.
 """
 
+
 def _merge_dictionaries(dictionaries):
     """
     Collapse a sequence of dictionaries into one, with collisions resolved by
diff --git a/src/_zkapauthorizer/controller.py b/src/_zkapauthorizer/controller.py
index a1147a7..7078112 100644
--- a/src/_zkapauthorizer/controller.py
+++ b/src/_zkapauthorizer/controller.py
@@ -17,15 +17,14 @@ This module implements controllers (in the MVC sense) for the web interface
 for the client side of the storage plugin.
 """
 
-from typing import List
 from base64 import b64decode, b64encode
 from datetime import timedelta
 from functools import partial
 from hashlib import sha256
 from json import loads
 from operator import delitem, setitem
+from typing import List
 
-from six import ensure_text
 import attr
 import challenge_bypass_ristretto
 from treq import content
@@ -38,8 +37,8 @@ from twisted.python.url import URL
 from twisted.web.client import Agent
 from zope.interface import Interface, implementer
 
-from ._json import dumps_utf8
 from ._base64 import urlsafe_b64decode
+from ._json import dumps_utf8
 from ._stack import less_limited_stack
 from .model import Error as model_Error
 from .model import Pass
@@ -245,10 +244,10 @@ class ErrorRedeemer(object):
 
     @classmethod
     def make(cls, section_name, node_config, announcement, reactor):
-        details = ensure_text(node_config.get_config(
+        details = node_config.get_config(
             section=section_name,
             option="details",
-        ))
+        )
         return cls(details)
 
     def random_tokens_for_voucher(self, voucher, counter, count):
@@ -462,10 +461,10 @@ class RistrettoRedeemer(object):
 
     @classmethod
     def make(cls, section_name, node_config, announcement, reactor):
-        configured_issuer = ensure_text(node_config.get_config(
+        configured_issuer = node_config.get_config(
             section=section_name,
             option="ristretto-issuer-root-url",
-        ))
+        )
         if announcement is not None:
             # Don't let us talk to a storage server that has a different idea
             # about who issues ZKAPs.  We should lift this limitation (that is, we
@@ -507,7 +506,8 @@ class RistrettoRedeemer(object):
                     "redeemVoucher": voucher.number.decode("ascii"),
                     "redeemCounter": counter,
                     "redeemTokens": list(
-                        ensure_text(token.encode_base64()) for token in blinded_tokens
+                        token.encode_base64().decode("utf-8")
+                        for token in blinded_tokens
                     ),
                 }
             ),
@@ -941,7 +941,7 @@ class PaymentController(object):
             )
             self._error[voucher] = model_Error(
                 finished=self.store.now(),
-                details=ensure_text(reason.getErrorMessage()),
+                details=reason.getErrorMessage(),
             )
         return False
 
diff --git a/src/_zkapauthorizer/foolscap.py b/src/_zkapauthorizer/foolscap.py
index efd2e74..5ff7ff9 100644
--- a/src/_zkapauthorizer/foolscap.py
+++ b/src/_zkapauthorizer/foolscap.py
@@ -23,6 +23,7 @@ from foolscap.api import Any, Copyable, DictOf, ListOf, RemoteCopy
 from foolscap.constraint import ByteStringConstraint
 from foolscap.remoteinterface import RemoteInterface, RemoteMethodSchema
 
+
 @attr.s
 class ShareStat(Copyable, RemoteCopy):
     """
@@ -133,9 +134,7 @@ class RIPrivacyPassAuthorizedStorageServer(RemoteInterface):
     validated is service provided.
     """
 
-    __remote_name__ = (
-        "RIPrivacyPassAuthorizedStorageServer.tahoe.privatestorage.io"
-    )
+    __remote_name__ = "RIPrivacyPassAuthorizedStorageServer.tahoe.privatestorage.io"
 
     get_version = RIStorageServer["get_version"]
 
diff --git a/src/_zkapauthorizer/lease_maintenance.py b/src/_zkapauthorizer/lease_maintenance.py
index 48f6ecf..ed7d967 100644
--- a/src/_zkapauthorizer/lease_maintenance.py
+++ b/src/_zkapauthorizer/lease_maintenance.py
@@ -20,13 +20,8 @@ refresh leases on all shares reachable from a root.
 from datetime import datetime, timedelta
 from errno import ENOENT
 from functools import partial
+from typing import Any, Dict, Iterable
 
-try:
-    from typing import Any, Dict
-except ImportError:
-    pass
-
-from six import ensure_binary
 import attr
 from allmydata.interfaces import IDirectoryNode, IFilesystemNode
 from allmydata.util.hashutil import (
@@ -45,11 +40,6 @@ from .controller import bracket
 from .foolscap import ShareStat
 from .model import ILeaseMaintenanceObserver
 
-try:
-    from typing import Iterable
-except ImportError:
-    pass
-
 SERVICE_NAME = u"lease maintenance service"
 
 
@@ -508,7 +498,7 @@ def write_time_to_path(path, when):
 
     :param datetime when: The datetime to write.
     """
-    path.setContent(ensure_binary(when.isoformat()))
+    path.setContent(when.isoformat().encode("utf-8"))
 
 
 def read_time_from_path(path):
diff --git a/src/_zkapauthorizer/model.py b/src/_zkapauthorizer/model.py
index a568ba2..df00eb6 100644
--- a/src/_zkapauthorizer/model.py
+++ b/src/_zkapauthorizer/model.py
@@ -29,10 +29,9 @@ from past.builtins import long
 from twisted.logger import Logger
 from twisted.python.filepath import FilePath
 from zope.interface import Interface, implementer
-from six import ensure_text
 
-from ._json import dumps_utf8
 from ._base64 import urlsafe_b64decode
+from ._json import dumps_utf8
 from .schema import get_schema_upgrades, get_schema_version, run_schema_upgrades
 from .storage_common import (
     get_configured_pass_value,
@@ -936,7 +935,7 @@ class Redeeming(object):
     def to_json_v1(self):
         return {
             "name": "redeeming",
-            "started": ensure_text(self.started.isoformat()),
+            "started": self.started.isoformat(),
             "counter": self.counter,
         }
 
@@ -961,7 +960,7 @@ class Redeemed(object):
     def to_json_v1(self):
         return {
             "name": "redeemed",
-            "finished": ensure_text(self.finished.isoformat()),
+            "finished": self.finished.isoformat(),
             "token-count": self.token_count,
         }
 
@@ -976,7 +975,7 @@ class DoubleSpend(object):
     def to_json_v1(self):
         return {
             "name": "double-spend",
-            "finished": ensure_text(self.finished.isoformat()),
+            "finished": self.finished.isoformat(),
         }
 
 
@@ -996,7 +995,7 @@ class Unpaid(object):
     def to_json_v1(self):
         return {
             "name": "unpaid",
-            "finished": ensure_text(self.finished.isoformat()),
+            "finished": self.finished.isoformat(),
         }
 
 
@@ -1017,7 +1016,7 @@ class Error(object):
     def to_json_v1(self):
         return {
             "name": "error",
-            "finished": ensure_text(self.finished.isoformat()),
+            "finished": self.finished.isoformat(),
             "details": self.details,
         }
 
@@ -1165,7 +1164,7 @@ class Voucher(object):
         return {
             "number": self.number.decode("ascii"),
             "expected-tokens": self.expected_tokens,
-            "created": None if self.created is None else ensure_text(self.created.isoformat()),
+            "created": None if self.created is None else self.created.isoformat(),
             "state": state,
             "version": 1,
         }
diff --git a/src/_zkapauthorizer/resource.py b/src/_zkapauthorizer/resource.py
index 68ef2b7..9399392 100644
--- a/src/_zkapauthorizer/resource.py
+++ b/src/_zkapauthorizer/resource.py
@@ -25,7 +25,6 @@ from itertools import islice
 from json import load, loads
 from sys import maxsize
 
-from six import ensure_binary
 from past.builtins import long
 from twisted.logger import Logger
 from twisted.web.http import BAD_REQUEST
@@ -33,9 +32,9 @@ from twisted.web.resource import ErrorPage, IResource, NoResource, Resource
 from twisted.web.server import NOT_DONE_YET
 from zope.interface import Attribute
 
-from ._json import dumps_utf8
 from . import __version__ as _zkapauthorizer_version
 from ._base64 import urlsafe_b64decode
+from ._json import dumps_utf8
 from .config import get_configured_lease_duration
 from .controller import PaymentController, get_redeemer
 from .pricecalculator import PriceCalculator
@@ -143,7 +142,7 @@ def from_configuration(
     )
 
     root = create_private_tree(
-        lambda: ensure_binary(node_config.get_private_config("api_auth_token")),
+        lambda: node_config.get_private_config("api_auth_token").encode("utf-8"),
         authorizationless_resource_tree(
             store,
             controller,
diff --git a/src/_zkapauthorizer/spending.py b/src/_zkapauthorizer/spending.py
index 0543fac..89625b5 100644
--- a/src/_zkapauthorizer/spending.py
+++ b/src/_zkapauthorizer/spending.py
@@ -22,7 +22,8 @@ import attr
 from zope.interface import Attribute, Interface, implementer
 
 from .eliot import GET_PASSES, INVALID_PASSES, RESET_PASSES, SPENT_PASSES
-from .model import UnblindedToken, Pass
+from .model import Pass, UnblindedToken
+
 
 class IPassGroup(Interface):
     """
@@ -112,8 +113,12 @@ class PassGroup(object):
     """
 
     _message = attr.ib(validator=attr.validators.instance_of(bytes))  # type: bytes
-    _factory = attr.ib(validator=attr.validators.provides(IPassFactory))  # type: IPassFactory
-    _tokens = attr.ib(validator=attr.validators.instance_of(list))  # type: List[Tuple[UnblindedToken, Pass]]
+    _factory = attr.ib(
+        validator=attr.validators.provides(IPassFactory)
+    )  # type: IPassFactory
+    _tokens = attr.ib(
+        validator=attr.validators.instance_of(list)
+    )  # type: List[Tuple[UnblindedToken, Pass]]
 
     @property
     def passes(self):
@@ -172,7 +177,7 @@ class SpendingController(object):
     invalidate_unblinded_tokens = attr.ib()  # type: ([UnblindedToken]) -> None
     reset_unblinded_tokens = attr.ib()  # type: ([UnblindedToken]) -> None
 
-    tokens_to_passes = attr.ib() # type: (bytes, [UnblindedToken]) -> [Pass]
+    tokens_to_passes = attr.ib()  # type: (bytes, [UnblindedToken]) -> [Pass]
 
     @classmethod
     def for_store(cls, tokens_to_passes, store):
diff --git a/src/_zkapauthorizer/tests/storage_common.py b/src/_zkapauthorizer/tests/storage_common.py
index 35d52fa..62bfae3 100644
--- a/src/_zkapauthorizer/tests/storage_common.py
+++ b/src/_zkapauthorizer/tests/storage_common.py
@@ -20,7 +20,7 @@ from functools import partial
 from itertools import islice
 from os import SEEK_CUR
 from struct import pack
-from typing import List, Set, Dict
+from typing import Dict, List, Set
 
 import attr
 from challenge_bypass_ristretto import RandomToken
diff --git a/src/_zkapauthorizer/tests/strategies.py b/src/_zkapauthorizer/tests/strategies.py
index 977362a..d8b48e2 100644
--- a/src/_zkapauthorizer/tests/strategies.py
+++ b/src/_zkapauthorizer/tests/strategies.py
@@ -18,6 +18,7 @@ Hypothesis strategies for property testing.
 
 from base64 import b64encode, urlsafe_b64encode
 from datetime import datetime, timedelta
+from urllib.parse import quote
 
 import attr
 from allmydata.client import config_from_string
@@ -40,7 +41,6 @@ from hypothesis.strategies import (
     text,
     tuples,
 )
-from urllib.parse import quote
 from twisted.internet.defer import succeed
 from twisted.internet.task import Clock
 from twisted.web.test.requesthelper import DummyRequest
@@ -728,6 +728,7 @@ def request_paths():
 
     :see: ``requests``
     """
+
     def quote_segment(seg):
         return quote(seg, safe="").encode("utf-8")
 
diff --git a/src/_zkapauthorizer/tests/test_client_resource.py b/src/_zkapauthorizer/tests/test_client_resource.py
index f206bdd..e72c0b9 100644
--- a/src/_zkapauthorizer/tests/test_client_resource.py
+++ b/src/_zkapauthorizer/tests/test_client_resource.py
@@ -19,9 +19,8 @@ plugin.
 
 from datetime import datetime
 from io import BytesIO
+from typing import Optional, Set
 from urllib.parse import quote
-from six import ensure_text
-from typing import Set, TypeVar, Optional
 
 import attr
 from allmydata.client import config_from_string
@@ -29,6 +28,7 @@ from aniso8601 import parse_datetime
 from fixtures import TempDir
 from hypothesis import given, note
 from hypothesis.strategies import (
+    SearchStrategy,
     binary,
     builds,
     datetimes,
@@ -70,9 +70,9 @@ from twisted.web.http import BAD_REQUEST, NOT_FOUND, NOT_IMPLEMENTED, OK, UNAUTH
 from twisted.web.http_headers import Headers
 from twisted.web.resource import IResource, getChildForRequest
 
-from .. _json import dumps_utf8
 from .. import __version__ as zkapauthorizer_version
 from .._base64 import urlsafe_b64decode
+from .._json import dumps_utf8
 from ..configutil import config_string_from_sections
 from ..model import (
     DoubleSpend,
@@ -110,8 +110,6 @@ from .strategies import (
     vouchers,
 )
 
-Strategy = TypeVar()
-
 TRANSIENT_ERROR = "something went wrong, who knows what"
 
 # Helper to work-around https://github.com/twisted/treq/issues/161
@@ -142,9 +140,11 @@ def not_vouchers():
     Builds byte strings which are not legal vouchers.
     """
     return one_of(
-        text().filter(
+        text()
+        .filter(
             lambda t: (not is_urlsafe_base64(t)),
-        ).map(lambda t: t.encode("utf-8")),
+        )
+        .map(lambda t: t.encode("utf-8")),
         vouchers().map(
             # Turn a valid voucher into a voucher that is invalid only by
             # containing a character from the base64 alphabet in place of one
@@ -176,7 +176,7 @@ def invalid_bodies():
         # The wrong key but the right kind of value.
         fixed_dictionaries(
             {
-                "some-key": vouchers().map(ensure_text),
+                "some-key": vouchers().map(lambda v: v.decode("utf-8")),
             }
         ).map(dumps_utf8),
         # The right key but the wrong kind of value.
@@ -184,7 +184,7 @@ def invalid_bodies():
             {
                 "voucher": one_of(
                     integers(),
-                    not_vouchers().map(ensure_text),
+                    not_vouchers().map(lambda v: v.decode("utf-8")),
                 ),
             }
         ).map(dumps_utf8),
@@ -456,7 +456,7 @@ def maybe_extra_tokens():
     return one_of(
         just(None),
         # If we do, we can't have fewer than the number of redemption groups
-        # which we don't know until we're further inside the test.  So supply
+        # which we don't know until we're further inside the test.  oSo supply
         # an amount to add to that, in the case where we have tokens at all.
         integers(min_value=0, max_value=100),
     )
@@ -520,7 +520,11 @@ class UnblindedTokenTests(TestCase):
 
         self.assertThat(
             stored_tokens,
-            Equals(list(token.unblinded_token.decode("ascii") for token in unblinded_tokens)),
+            Equals(
+                list(
+                    token.unblinded_token.decode("ascii") for token in unblinded_tokens
+                )
+            ),
         )
 
     @given(
@@ -1401,7 +1405,8 @@ class VoucherTests(TestCase):
             ),
         )
 
-def mime_types(blacklist: Optional[Set[str]] = None) -> Strategy[str]:
+
+def mime_types(blacklist: Optional[Set[str]] = None) -> SearchStrategy[str]:
     """
     Build MIME types as b"major/minor" byte strings.
 
diff --git a/src/_zkapauthorizer/tests/test_controller.py b/src/_zkapauthorizer/tests/test_controller.py
index b7efbe8..f48b8e1 100644
--- a/src/_zkapauthorizer/tests/test_controller.py
+++ b/src/_zkapauthorizer/tests/test_controller.py
@@ -21,7 +21,6 @@ from functools import partial
 from json import loads
 
 import attr
-from six import ensure_text
 from challenge_bypass_ristretto import (
     BatchDLEQProof,
     BlindedToken,
@@ -794,7 +793,9 @@ class RistrettoRedeemerTests(TestCase):
                         HasLength(num_tokens),
                     ),
                     public_key=Equals(
-                        ensure_text(PublicKey.from_signing_key(signing_key).encode_base64()),
+                        PublicKey.from_signing_key(signing_key)
+                        .encode_base64()
+                        .decode("utf-8"),
                     ),
                 ),
             ),
@@ -1156,9 +1157,9 @@ class RistrettoRedemption(Resource):
         return dumps_utf8(
             {
                 u"success": True,
-                u"public-key": ensure_text(self.public_key.encode_base64()),
-                u"signatures": list(ensure_text(t) for t in marshaled_signed_tokens),
-                u"proof": ensure_text(marshaled_proof),
+                u"public-key": self.public_key.encode_base64().decode("utf-8"),
+                u"signatures": list(t.decode("utf-8") for t in marshaled_signed_tokens),
+                u"proof": marshaled_proof.decode("utf-8"),
             }
         )
 
@@ -1297,6 +1298,7 @@ class _BracketTestMixin:
     """
     Tests for ``bracket``.
     """
+
     def wrap_success(self, result):
         raise NotImplementedError()
 
@@ -1370,6 +1372,7 @@ class _BracketTestMixin:
 
         actions = []
         first = partial(actions.append, "first")
+
         def between():
             actions.append("between")
             return self.wrap_success(None)
@@ -1461,14 +1464,18 @@ class _BracketTestMixin:
             Equals(["first"]),
         )
 
+
 class BracketTests(_BracketTestMixin, TestCase):
     def wrap_success(self, result):
         return result
+
     def wrap_failure(self, exception):
         raise exception
 
+
 class SynchronousDeferredBracketTests(_BracketTestMixin, TestCase):
     def wrap_success(self, result):
         return succeed(result)
+
     def wrap_failure(self, exception):
         return fail(exception)
diff --git a/src/_zkapauthorizer/tests/test_lease_maintenance.py b/src/_zkapauthorizer/tests/test_lease_maintenance.py
index 2f20fcd..703305b 100644
--- a/src/_zkapauthorizer/tests/test_lease_maintenance.py
+++ b/src/_zkapauthorizer/tests/test_lease_maintenance.py
@@ -17,6 +17,7 @@ Tests for ``_zkapauthorizer.lease_maintenance``.
 """
 
 from datetime import datetime, timedelta
+from typing import Dict, List
 
 import attr
 from allmydata.client import SecretHolder
@@ -35,7 +36,6 @@ from hypothesis.strategies import (
     randoms,
     sets,
 )
-from six import ensure_binary
 from testtools import TestCase
 from testtools.matchers import (
     AfterPreprocessing,
@@ -77,12 +77,6 @@ from .strategies import (
     storage_indexes,
 )
 
-try:
-    from typing import Dict, List
-except ImportError:
-    pass
-
-
 default_lease_maint_config = lease_maintenance_from_tahoe_config(empty_config)
 
 
@@ -312,7 +306,7 @@ class LeaseMaintenanceServiceTests(TestCase):
         # Figure out the absolute last run time.
         last_run = datetime_now - since_last_run
         last_run_path = FilePath(self.useFixture(TempDir()).join("last-run"))
-        last_run_path.setContent(ensure_binary(last_run.isoformat()))
+        last_run_path.setContent(last_run.isoformat().encode("utf-8"))
 
         service = lease_maintenance_service(
             dummy_maintain_leases,
diff --git a/src/_zkapauthorizer/tests/test_model.py b/src/_zkapauthorizer/tests/test_model.py
index 914bb9a..f5d195f 100644
--- a/src/_zkapauthorizer/tests/test_model.py
+++ b/src/_zkapauthorizer/tests/test_model.py
@@ -382,7 +382,8 @@ class VoucherStoreTests(TestCase):
         while tokens_remaining > 0:
             to_spend = data.draw(integers(min_value=1, max_value=tokens_remaining))
             extracted_tokens.extend(
-                token.unblinded_token.decode("ascii") for token in store.get_unblinded_tokens(to_spend)
+                token.unblinded_token.decode("ascii")
+                for token in store.get_unblinded_tokens(to_spend)
             )
             tokens_remaining -= to_spend
 
diff --git a/src/_zkapauthorizer/tests/test_plugin.py b/src/_zkapauthorizer/tests/test_plugin.py
index 80d9813..10cdaf4 100644
--- a/src/_zkapauthorizer/tests/test_plugin.py
+++ b/src/_zkapauthorizer/tests/test_plugin.py
@@ -16,10 +16,11 @@
 Tests for the Tahoe-LAFS plugin.
 """
 
+import os.path
 from datetime import timedelta
 from functools import partial
+from io import StringIO
 from os import makedirs
-import os.path
 
 from allmydata.client import config_from_string, create_client_from_config
 from allmydata.interfaces import (
@@ -38,7 +39,6 @@ from hypothesis import given, settings
 from hypothesis.strategies import datetimes, just, sampled_from, timedeltas
 from prometheus_client import Gauge
 from prometheus_client.parser import text_string_to_metric_families
-from io import StringIO
 from testtools import TestCase
 from testtools.content import text_content
 from testtools.matchers import (
diff --git a/src/_zkapauthorizer/tests/test_storage_protocol.py b/src/_zkapauthorizer/tests/test_storage_protocol.py
index a231c66..3a21804 100644
--- a/src/_zkapauthorizer/tests/test_storage_protocol.py
+++ b/src/_zkapauthorizer/tests/test_storage_protocol.py
@@ -1084,7 +1084,9 @@ class ShareTests(TestCase):
         data_vector=slot_data_vectors(),
         replacement_data_vector=slot_data_vectors(),
     )
-    def test_test_vectors_match(self, storage_index, secrets, sharenum, data_vector, replacement_data_vector):
+    def test_test_vectors_match(
+        self, storage_index, secrets, sharenum, data_vector, replacement_data_vector
+    ):
         """
         If test vectors are given then the write is allowed if they match the
         existing data.
@@ -1105,28 +1107,37 @@ class ShareTests(TestCase):
             return d
 
         def equal_test_vector(data_vector):
-            return list(
-                (offset, len(data), data)
-                for (offset, data)
-                in data_vector
-            )
+            return list((offset, len(data), data) for (offset, data) in data_vector)
 
         # Create the share
-        d = write({
-            sharenum: (empty_test_vector, data_vector, None),
-        })
+        d = write(
+            {
+                sharenum: (empty_test_vector, data_vector, None),
+            }
+        )
         self.assertThat(d, is_successful_write())
 
         # Write some new data to with a correct test vector.  We can only be
         # sure we know data from the last element of the test vector since
         # earlier elements may have been overwritten.
-        d = write({
-            sharenum: (equal_test_vector(data_vector)[-1:], replacement_data_vector, None),
-        })
+        d = write(
+            {
+                sharenum: (
+                    equal_test_vector(data_vector)[-1:],
+                    replacement_data_vector,
+                    None,
+                ),
+            }
+        )
         self.assertThat(d, is_successful_write())
 
         # Check that the new data is present
-        assert_read_back_data(self, storage_index, secrets, {sharenum: TestAndWriteVectors(None, replacement_data_vector, None)})
+        assert_read_back_data(
+            self,
+            storage_index,
+            secrets,
+            {sharenum: TestAndWriteVectors(None, replacement_data_vector, None)},
+        )
 
 
 def assert_read_back_data(
-- 
GitLab