← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/turnip:pre-commit into turnip:master

 

Colin Watson has proposed merging ~cjwatson/turnip:pre-commit into turnip:master.

Commit message:
Add pre-commit configuration

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/turnip/+git/turnip/+merge/410742

I've also fixed up some flake8 and isort issues along the way.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/turnip:pre-commit into turnip:master.
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..77560c4
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,20 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+-   repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v3.2.0
+    hooks:
+    -   id: check-added-large-files
+    -   id: check-ast
+    -   id: check-merge-conflict
+    -   id: check-yaml
+    -   id: debug-statements
+    -   id: no-commit-to-branch
+-   repo: https://github.com/PyCQA/flake8
+    rev: 3.9.2
+    hooks:
+    -   id: flake8
+-   repo: https://github.com/PyCQA/isort
+    rev: 5.9.2
+    hooks:
+    -   id: isort
diff --git a/charm/layer/turnip-base/lib/charms/turnip/base.py b/charm/layer/turnip-base/lib/charms/turnip/base.py
index 552705f..b369a7b 100644
--- a/charm/layer/turnip-base/lib/charms/turnip/base.py
+++ b/charm/layer/turnip-base/lib/charms/turnip/base.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 import errno
 import os.path
diff --git a/charm/layer/turnip-base/reactive/turnip-base.py b/charm/layer/turnip-base/reactive/turnip-base.py
index 37cc033..dc32d9e 100644
--- a/charm/layer/turnip-base/reactive/turnip-base.py
+++ b/charm/layer/turnip-base/reactive/turnip-base.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charms.layer import status
 from charms.reactive import (
diff --git a/charm/layer/turnip-storage/lib/charms/turnip/storage.py b/charm/layer/turnip-storage/lib/charms/turnip/storage.py
index 02a74a4..1f0171e 100644
--- a/charm/layer/turnip-storage/lib/charms/turnip/storage.py
+++ b/charm/layer/turnip-storage/lib/charms/turnip/storage.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 import os
 import subprocess
diff --git a/charm/layer/turnip-storage/reactive/turnip-storage.py b/charm/layer/turnip-storage/reactive/turnip-storage.py
index 9575790..faa95f3 100644
--- a/charm/layer/turnip-storage/reactive/turnip-storage.py
+++ b/charm/layer/turnip-storage/reactive/turnip-storage.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import hookenv
 from charmhelpers.fetch import apt_install
diff --git a/charm/turnip-api/lib/charms/turnip/api.py b/charm/turnip-api/lib/charms/turnip/api.py
index f1e421c..8575717 100644
--- a/charm/turnip-api/lib/charms/turnip/api.py
+++ b/charm/turnip-api/lib/charms/turnip/api.py
@@ -1,10 +1,14 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
-import os.path
 from multiprocessing import cpu_count
+import os.path
 
 from charmhelpers.core import (
     hookenv,
diff --git a/charm/turnip-api/reactive/turnip-api.py b/charm/turnip-api/reactive/turnip-api.py
index 60c156f..e00dc8c 100644
--- a/charm/turnip-api/reactive/turnip-api.py
+++ b/charm/turnip-api/reactive/turnip-api.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import (
     hookenv,
diff --git a/charm/turnip-celery/lib/charms/turnip/celery.py b/charm/turnip-celery/lib/charms/turnip/celery.py
index 5bbfd36..07e0777 100644
--- a/charm/turnip-celery/lib/charms/turnip/celery.py
+++ b/charm/turnip-celery/lib/charms/turnip/celery.py
@@ -1,8 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
-
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import (
     hookenv,
diff --git a/charm/turnip-celery/reactive/turnip-celery.py b/charm/turnip-celery/reactive/turnip-celery.py
index 7604852..92128cb 100644
--- a/charm/turnip-celery/reactive/turnip-celery.py
+++ b/charm/turnip-celery/reactive/turnip-celery.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import (
     hookenv,
@@ -17,12 +21,12 @@ from charms.reactive import (
     when_not_all,
     )
 
-from charms.turnip.celery import configure_celery
 from charms.turnip.base import (
     configure_service,
     deconfigure_service,
     get_rabbitmq_url,
     )
+from charms.turnip.celery import configure_celery
 
 
 @when('turnip.installed', 'turnip.storage.available', 'turnip.amqp.available')
diff --git a/charm/turnip-pack-backend/reactive/turnip-pack-backend.py b/charm/turnip-pack-backend/reactive/turnip-pack-backend.py
index 6998ae5..1bd2be3 100644
--- a/charm/turnip-pack-backend/reactive/turnip-pack-backend.py
+++ b/charm/turnip-pack-backend/reactive/turnip-pack-backend.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import hookenv
 from charms.layer import status
diff --git a/charm/turnip-pack-frontend-git/reactive/turnip-pack-frontend-git.py b/charm/turnip-pack-frontend-git/reactive/turnip-pack-frontend-git.py
index d72b894..d72a4a6 100644
--- a/charm/turnip-pack-frontend-git/reactive/turnip-pack-frontend-git.py
+++ b/charm/turnip-pack-frontend-git/reactive/turnip-pack-frontend-git.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import hookenv
 from charms.layer import status
diff --git a/charm/turnip-pack-frontend-http/lib/charms/turnip/http.py b/charm/turnip-pack-frontend-http/lib/charms/turnip/http.py
index 174b3a4..2e55c9c 100644
--- a/charm/turnip-pack-frontend-http/lib/charms/turnip/http.py
+++ b/charm/turnip-pack-frontend-http/lib/charms/turnip/http.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 import base64
 import os.path
diff --git a/charm/turnip-pack-frontend-http/reactive/turnip-pack-frontend-http.py b/charm/turnip-pack-frontend-http/reactive/turnip-pack-frontend-http.py
index f3e452d..0211a42 100644
--- a/charm/turnip-pack-frontend-http/reactive/turnip-pack-frontend-http.py
+++ b/charm/turnip-pack-frontend-http/reactive/turnip-pack-frontend-http.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import (
     hookenv,
diff --git a/charm/turnip-pack-frontend-ssh/lib/charms/turnip/ssh.py b/charm/turnip-pack-frontend-ssh/lib/charms/turnip/ssh.py
index 796045f..06b32dd 100644
--- a/charm/turnip-pack-frontend-ssh/lib/charms/turnip/ssh.py
+++ b/charm/turnip-pack-frontend-ssh/lib/charms/turnip/ssh.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 import base64
 import os.path
diff --git a/charm/turnip-pack-frontend-ssh/reactive/turnip-pack-frontend-ssh.py b/charm/turnip-pack-frontend-ssh/reactive/turnip-pack-frontend-ssh.py
index 4ac4f03..3d9fe1a 100644
--- a/charm/turnip-pack-frontend-ssh/reactive/turnip-pack-frontend-ssh.py
+++ b/charm/turnip-pack-frontend-ssh/reactive/turnip-pack-frontend-ssh.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import hookenv
 from charms.layer import status
diff --git a/charm/turnip-pack-virt/reactive/turnip-pack-virt.py b/charm/turnip-pack-virt/reactive/turnip-pack-virt.py
index e442d70..8a58cbd 100644
--- a/charm/turnip-pack-virt/reactive/turnip-pack-virt.py
+++ b/charm/turnip-pack-virt/reactive/turnip-pack-virt.py
@@ -1,7 +1,11 @@
 # Copyright 2018 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 from charmhelpers.core import hookenv
 from charms.layer import status
diff --git a/httpserver.tac b/httpserver.tac
index cf1d876..22aa649 100644
--- a/httpserver.tac
+++ b/httpserver.tac
@@ -6,8 +6,8 @@
 from __future__ import unicode_literals
 
 from twisted.application import (
-    service,
     internet,
+    service,
     )
 from twisted.scripts.twistd import ServerOptions
 from twisted.web import server
diff --git a/packbackendserver.tac b/packbackendserver.tac
index fd2205e..a43c1ef 100644
--- a/packbackendserver.tac
+++ b/packbackendserver.tac
@@ -14,16 +14,14 @@ import os.path
 
 import statsd
 from twisted.application import (
-    service,
     internet,
+    service,
     )
 from twisted.scripts.twistd import ServerOptions
 
 from turnip.config import config
 from turnip.log import RotatableFileLogObserver
-from turnip.pack.git import (
-    PackBackendFactory,
-    )
+from turnip.pack.git import PackBackendFactory
 from turnip.pack.hookrpc import (
     HookRPCHandler,
     HookRPCServerFactory,
diff --git a/packfrontendserver.tac b/packfrontendserver.tac
index 1070914..fdc71f0 100644
--- a/packfrontendserver.tac
+++ b/packfrontendserver.tac
@@ -11,8 +11,8 @@ from __future__ import (
     )
 
 from twisted.application import (
-    service,
     internet,
+    service,
     )
 from twisted.scripts.twistd import ServerOptions
 
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..019bc23
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,21 @@
+[flake8]
+hang-closing = true
+ignore =
+    # Skip for now; this will get sorted out automatically when we switch to
+    # black.
+    E133,
+    # Don't enforce either position of line breaks relative to binary
+    # operators, at least for now.
+    W503,
+    W504
+
+[isort]
+combine_as_imports = true
+force_grid_wrap = 2
+force_sort_within_sections = true
+include_trailing_comma = true
+known_first_party = turnip,charms.turnip
+line_length = 78
+lines_after_imports = 2
+multi_line_output = 8
+order_by_type = false
diff --git a/setup.py b/setup.py
index 6e65710..fb7b2ea 100755
--- a/setup.py
+++ b/setup.py
@@ -8,7 +8,8 @@ import os
 from setuptools import (
     find_packages,
     setup,
-)
+    )
+
 
 here = os.path.abspath(os.path.dirname(__file__))
 
diff --git a/turnip/api/store.py b/turnip/api/store.py
index f56962d..8f24a79 100644
--- a/turnip/api/store.py
+++ b/turnip/api/store.py
@@ -2,6 +2,7 @@
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 import base64
+from collections import defaultdict
 import itertools
 import logging
 import os
@@ -9,7 +10,6 @@ import re
 import shutil
 import subprocess
 import uuid
-from collections import defaultdict
 
 from contextlib2 import (
     contextmanager,
@@ -33,8 +33,15 @@ from twisted.web import xmlrpc
 
 from turnip.config import config
 from turnip.helpers import TimeoutServerProxy
-from turnip.pack.helpers import ensure_config, get_repack_data
-from turnip.tasks import app, logger as tasks_logger
+from turnip.pack.helpers import (
+    ensure_config,
+    get_repack_data,
+    )
+from turnip.tasks import (
+    app,
+    logger as tasks_logger,
+    )
+
 
 logger = logging.getLogger(__name__)
 
diff --git a/turnip/api/tests/test_api.py b/turnip/api/tests/test_api.py
index 0863e5e..43a1274 100644
--- a/turnip/api/tests/test_api.py
+++ b/turnip/api/tests/test_api.py
@@ -3,10 +3,16 @@
 # Copyright 2015 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import print_function, unicode_literals
+from __future__ import (
+    print_function,
+    unicode_literals,
+    )
 
 import base64
-from datetime import timedelta, datetime
+from datetime import (
+    datetime,
+    timedelta,
+    )
 import os
 import re
 import subprocess
@@ -14,8 +20,8 @@ from textwrap import dedent
 import time
 import unittest
 from unittest import mock
-import uuid
 from urllib.parse import quote
+import uuid
 
 from fixtures import (
     EnvironmentVariable,
diff --git a/turnip/api/tests/test_helpers.py b/turnip/api/tests/test_helpers.py
index 6c6a4a1..4c3fcb3 100644
--- a/turnip/api/tests/test_helpers.py
+++ b/turnip/api/tests/test_helpers.py
@@ -6,10 +6,15 @@ import fnmatch
 import itertools
 import logging
 import os
-from subprocess import PIPE, Popen, CalledProcessError, STDOUT
-import uuid
+from subprocess import (
+    CalledProcessError,
+    PIPE,
+    Popen,
+    STDOUT,
+    )
 from urllib.parse import urljoin
 from urllib.request import pathname2url
+import uuid
 
 from pygit2 import (
     clone_repository,
@@ -21,6 +26,7 @@ from pygit2 import (
     )
 import six
 
+
 log = logging.getLogger()
 
 
diff --git a/turnip/api/views.py b/turnip/api/views.py
index ce9d716..ff34e31 100644
--- a/turnip/api/views.py
+++ b/turnip/api/views.py
@@ -10,8 +10,8 @@ from pygit2 import GitError
 import pyramid.httpexceptions as exc
 from pyramid.response import Response
 
-from turnip.config import config
 from turnip.api import store
+from turnip.config import config
 
 
 def is_valid_path(repo_store, repo_path):
diff --git a/turnip/config.py b/turnip/config.py
index f57b790..8656588 100644
--- a/turnip/config.py
+++ b/turnip/config.py
@@ -7,6 +7,7 @@ import os
 
 import yaml
 
+
 __all__ = [
     'config',
     ]
diff --git a/turnip/pack/git.py b/turnip/pack/git.py
index 7c43143..a3d77f7 100644
--- a/turnip/pack/git.py
+++ b/turnip/pack/git.py
@@ -15,10 +15,10 @@ import json
 import os
 import re
 import sys
+import traceback
 import uuid
 
 import six
-import traceback
 from twisted.internet import (
     defer,
     error,
@@ -41,8 +41,8 @@ from turnip.pack.helpers import (
     encode_request,
     ensure_config,
     ensure_hooks,
-    INCOMPLETE_PKT,
     get_repack_data,
+    INCOMPLETE_PKT,
     translate_xmlrpc_fault,
     )
 
diff --git a/turnip/pack/git_helper.py b/turnip/pack/git_helper.py
index 72290cc..0673068 100755
--- a/turnip/pack/git_helper.py
+++ b/turnip/pack/git_helper.py
@@ -3,7 +3,11 @@
 # Copyright 2020 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import absolute_import, print_function, unicode_literals
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
 
 import fcntl
 import json
diff --git a/turnip/pack/helpers.py b/turnip/pack/helpers.py
index 561bcb6..9cfcfcf 100644
--- a/turnip/pack/helpers.py
+++ b/turnip/pack/helpers.py
@@ -12,8 +12,8 @@ import enum
 import hashlib
 import os.path
 import re
-import subprocess
 import stat
+import subprocess
 import sys
 from tempfile import (
     mktemp,
@@ -27,6 +27,7 @@ import yaml
 import turnip.pack.hooks
 from turnip.version_info import version_info
 
+
 DELIM_PKT = object()
 PKT_LEN_SIZE = 4
 PKT_PAYLOAD_MAX = 65520
diff --git a/turnip/pack/hooks/hook.py b/turnip/pack/hooks/hook.py
index 38a9c19..634ddd6 100755
--- a/turnip/pack/hooks/hook.py
+++ b/turnip/pack/hooks/hook.py
@@ -20,9 +20,10 @@ import six
 
 from turnip.pack.helpers import get_repack_data
 
+
 # XXX twom 2018-10-23 This should be a pygit2 import, but
 # that currently causes CFFI warnings to be returned to the client.
-GIT_OID_HEX_ZERO = b'0'*40
+GIT_OID_HEX_ZERO = b'0' * 40
 
 
 # Users cannot update references in this list.
diff --git a/turnip/pack/http.py b/turnip/pack/http.py
index 1039b1e..70a2c21 100644
--- a/turnip/pack/http.py
+++ b/turnip/pack/http.py
@@ -13,6 +13,7 @@ import json
 import os.path
 import tempfile
 import textwrap
+import time
 from urllib.parse import urlencode
 import uuid
 import zlib
@@ -29,7 +30,6 @@ from paste.auth.cookie import (
     encode as encode_cookie,
     )
 import six
-import time
 from twisted.internet import (
     defer,
     error,
@@ -61,7 +61,9 @@ from turnip.pack.helpers import (
     get_capabilities_advertisement,
     translate_xmlrpc_fault,
     TurnipFaultCode,
-)
+    )
+
+
 try:
     from turnip.version_info import version_info
 except ImportError:
diff --git a/turnip/pack/ssh.py b/turnip/pack/ssh.py
index 39979ba..1ff91ad 100644
--- a/turnip/pack/ssh.py
+++ b/turnip/pack/ssh.py
@@ -48,6 +48,7 @@ from turnip.pack.helpers import (
     encode_request,
     )
 
+
 __all__ = [
     "SmartSSHSession",
     ]
diff --git a/turnip/pack/tests/fake_servers.py b/turnip/pack/tests/fake_servers.py
index e1be1be..a782575 100644
--- a/turnip/pack/tests/fake_servers.py
+++ b/turnip/pack/tests/fake_servers.py
@@ -15,6 +15,7 @@ from lazr.sshserver.auth import NoSuchPersonWithName
 import six
 from twisted.web import xmlrpc
 
+
 __all__ = [
     "FakeAuthServerService",
     "FakeVirtInfoService",
diff --git a/turnip/pack/tests/test_functional.py b/turnip/pack/tests/test_functional.py
index 163bf0b..eec4db8 100644
--- a/turnip/pack/tests/test_functional.py
+++ b/turnip/pack/tests/test_functional.py
@@ -22,8 +22,6 @@ from urllib.parse import (
     urlunsplit,
     )
 
-from turnip.config import config
-
 from fixtures import (
     EnvironmentVariable,
     TempDir,
@@ -56,6 +54,7 @@ from twisted.web import (
     xmlrpc,
     )
 
+from turnip.config import config
 from turnip.pack import helpers
 from turnip.pack.git import (
     PackBackendFactory,
diff --git a/turnip/pack/tests/test_git.py b/turnip/pack/tests/test_git.py
index c2c38a7..9a1e99e 100644
--- a/turnip/pack/tests/test_git.py
+++ b/turnip/pack/tests/test_git.py
@@ -11,7 +11,10 @@ import hashlib
 import os.path
 from unittest import mock
 
-from fixtures import TempDir, MonkeyPatch
+from fixtures import (
+    MonkeyPatch,
+    TempDir,
+    )
 from pygit2 import init_repository
 import six
 from testtools import TestCase
diff --git a/turnip/pack/tests/test_http.py b/turnip/pack/tests/test_http.py
index 229546b..9624aa2 100644
--- a/turnip/pack/tests/test_http.py
+++ b/turnip/pack/tests/test_http.py
@@ -13,9 +13,9 @@ import os
 from unittest import mock
 
 from fixtures import TempDir
-import six
 from openid.consumer import consumer
 from paste.auth.cookie import encode as encode_cookie
+import six
 from testtools import TestCase
 from testtools.deferredruntest import AsynchronousDeferredRunTest
 from twisted.internet import (
diff --git a/turnip/pack/tests/test_ssh.py b/turnip/pack/tests/test_ssh.py
index d0e7f14..58da206 100644
--- a/turnip/pack/tests/test_ssh.py
+++ b/turnip/pack/tests/test_ssh.py
@@ -8,7 +8,10 @@ from __future__ import (
     )
 
 from testtools import TestCase
-from twisted.conch.interfaces import ISession, ISessionSetEnv
+from twisted.conch.interfaces import (
+    ISession,
+    ISessionSetEnv,
+    )
 
 from turnip.pack.ssh import SmartSSHSession
 
diff --git a/turnip/tasks.py b/turnip/tasks.py
index 1f4131a..ec6c4cc 100644
--- a/turnip/tasks.py
+++ b/turnip/tasks.py
@@ -1,7 +1,12 @@
 # Copyright 2020 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-from __future__ import print_function, unicode_literals, absolute_import
+from __future__ import (
+    absolute_import,
+    print_function,
+    unicode_literals,
+    )
+
 
 __all__ = [
     'app',
diff --git a/turnip/tests/logging.py b/turnip/tests/logging.py
index 28b6ef3..8f61a9a 100644
--- a/turnip/tests/logging.py
+++ b/turnip/tests/logging.py
@@ -7,8 +7,8 @@ from __future__ import (
     unicode_literals,
     )
 
-import sys
 import logging
+import sys
 
 
 def setupLogger():
diff --git a/turnip/tests/tasks.py b/turnip/tests/tasks.py
index 791d522..aa40015 100644
--- a/turnip/tests/tasks.py
+++ b/turnip/tests/tasks.py
@@ -2,7 +2,10 @@
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 import atexit
-from datetime import datetime, timedelta
+from datetime import (
+    datetime,
+    timedelta,
+    )
 import os
 import subprocess
 import sys
@@ -14,6 +17,7 @@ import six
 from turnip.config import config
 from turnip.tasks import app
 
+
 BROKER_URL = 'pyamqp://guest@localhost/turnip-test-vhost'
 
 
diff --git a/turnipserver.py b/turnipserver.py
index d61edec..88fc6e1 100644
--- a/turnipserver.py
+++ b/turnipserver.py
@@ -26,6 +26,7 @@ from turnip.pack.hookrpc import (
 from turnip.pack.http import SmartHTTPFrontendResource
 from turnip.pack.ssh import SmartSSHService
 
+
 data_dir = os.path.join(
     os.path.dirname(__file__), "turnip", "pack", "tests", "data")
 
diff --git a/virtserver.tac b/virtserver.tac
index e6654cd..9815e16 100644
--- a/virtserver.tac
+++ b/virtserver.tac
@@ -8,8 +8,8 @@ from __future__ import (
     )
 
 from twisted.application import (
-    service,
     internet,
+    service,
     )
 from twisted.scripts.twistd import ServerOptions