Lint with pre-commit (#365)

* Lint with pre-commit

* Move existing tox qa hooks into pre-commit.
* Set up GitHub Action based on https://github.com/pre-commit/action/ (we could also use https://pre-commit.ci ).
* Add `pyupgrade` to drop old Python syntax.
* Add `flake8-bugbear` plugin to prevent flake8 errors.

* Drop custom GHA
This commit is contained in:
Adam Johnson 2021-04-07 19:11:21 +01:00 committed by GitHub
parent aac4708a61
commit ca61162129
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 55 additions and 45 deletions

24
.github/workflows/pre-commit.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: pre-commit
on:
push:
branches:
- main
pull_request:
jobs:
pre-commit:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-python@v2
with:
python-version: 3.9
- uses: pre-commit/action@v2.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -31,17 +31,3 @@ jobs:
run: | run: |
ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}") ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}")
TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') python -m tox TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') python -m tox
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip tox
- name: Run lint
run: tox -e qa

21
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,21 @@
repos:
- repo: https://github.com/asottile/pyupgrade
rev: v2.11.0
hooks:
- id: pyupgrade
args: [--py36-plus]
- repo: https://github.com/psf/black
rev: 20.8b1
hooks:
- id: black
language_version: python3
- repo: https://github.com/pycqa/isort
rev: 5.8.0
hooks:
- id: isort
- repo: https://github.com/PyCQA/flake8
rev: 3.9.0
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear

View File

@ -1,7 +1,7 @@
import datetime import datetime
class AccessLogGenerator(object): class AccessLogGenerator:
""" """
Object that implements the Daphne "action logger" internal interface in Object that implements the Daphne "action logger" internal interface in
order to provide an access log in something resembling NCSA format. order to provide an access log in something resembling NCSA format.

View File

@ -16,7 +16,7 @@ DEFAULT_HOST = "127.0.0.1"
DEFAULT_PORT = 8000 DEFAULT_PORT = 8000
class CommandLineInterface(object): class CommandLineInterface:
""" """
Acts as the main CLI entry point for running the server. Acts as the main CLI entry point for running the server.
""" """
@ -258,7 +258,7 @@ class CommandLineInterface(object):
) )
endpoints = sorted(args.socket_strings + endpoints) endpoints = sorted(args.socket_strings + endpoints)
# Start the server # Start the server
logger.info("Starting server at %s" % (", ".join(endpoints),)) logger.info("Starting server at {}".format(", ".join(endpoints)))
self.server = self.server_class( self.server = self.server_class(
application=application, application=application,
endpoints=endpoints, endpoints=endpoints,

View File

@ -34,7 +34,7 @@ from .ws_protocol import WebSocketFactory
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Server(object): class Server:
def __init__( def __init__(
self, self,
application, application,

View File

@ -7,7 +7,7 @@ from zope.interface import implementer
@implementer(IPlugin, IStreamServerEndpointStringParser) @implementer(IPlugin, IStreamServerEndpointStringParser)
class _FDParser(object): class _FDParser:
prefix = "fd" prefix = "fd"
def _parseServer(self, reactor, fileno, domain=socket.AF_INET): def _parseServer(self, reactor, fileno, domain=socket.AF_INET):

View File

@ -297,7 +297,7 @@ class WebSocketProtocol(WebSocketServerProtocol):
return id(self) == id(other) return id(self) == id(other)
def __repr__(self): def __repr__(self):
return "<WebSocketProtocol client=%r path=%r>" % (self.client_addr, self.path) return f"<WebSocketProtocol client={self.client_addr!r} path={self.path!r}>"
class WebSocketFactory(WebSocketServerFactory): class WebSocketFactory(WebSocketServerFactory):
@ -318,7 +318,7 @@ class WebSocketFactory(WebSocketServerFactory):
Builds protocol instances. We use this to inject the factory object into the protocol. Builds protocol instances. We use this to inject the factory object into the protocol.
""" """
try: try:
protocol = super(WebSocketFactory, self).buildProtocol(addr) protocol = super().buildProtocol(addr)
protocol.factory = self protocol.factory = self
return protocol return protocol
except Exception: except Exception:

View File

@ -23,7 +23,7 @@ setup(
packages=find_packages() + ["twisted.plugins"], packages=find_packages() + ["twisted.plugins"],
include_package_data=True, include_package_data=True,
install_requires=["twisted[tls]>=18.7", "autobahn>=0.18", "asgiref>=3.2.10,<4"], install_requires=["twisted[tls]>=18.7", "autobahn>=0.18", "asgiref>=3.2.10,<4"],
python_requires='>=3.6', python_requires=">=3.6",
setup_requires=["pytest-runner"], setup_requires=["pytest-runner"],
extras_require={ extras_require={
"tests": ["hypothesis==4.23", "pytest~=3.10", "pytest-asyncio~=0.8"] "tests": ["hypothesis==4.23", "pytest~=3.10", "pytest-asyncio~=0.8"]

View File

@ -182,7 +182,7 @@ class DaphneTestCase(unittest.TestCase):
if response.status != 101: if response.status != 101:
raise RuntimeError("WebSocket upgrade did not result in status code 101") raise RuntimeError("WebSocket upgrade did not result in status code 101")
# Prepare headers for subprotocol searching # Prepare headers for subprotocol searching
response_headers = dict((n.lower(), v) for n, v in response.getheaders()) response_headers = {n.lower(): v for n, v in response.getheaders()}
response.read() response.read()
assert not response.closed assert not response.closed
# Return the raw socket and any subprotocol # Return the raw socket and any subprotocol
@ -252,7 +252,7 @@ class DaphneTestCase(unittest.TestCase):
""" """
try: try:
socket.inet_aton(address) socket.inet_aton(address)
except socket.error: except OSError:
self.fail("'%s' is not a valid IP address." % address) self.fail("'%s' is not a valid IP address." % address)
def assert_key_sets(self, required_keys, optional_keys, actual_keys): def assert_key_sets(self, required_keys, optional_keys, actual_keys):

View File

@ -1,5 +1,3 @@
# coding: utf8
import logging import logging
from argparse import ArgumentError from argparse import ArgumentError
from unittest import TestCase from unittest import TestCase

View File

@ -1,5 +1,3 @@
# coding: utf8
import collections import collections
from urllib import parse from urllib import parse

View File

@ -1,5 +1,3 @@
# coding: utf8
import http_strategies import http_strategies
from http_base import DaphneTestCase from http_base import DaphneTestCase
from hypothesis import given, settings from hypothesis import given, settings

View File

@ -1,5 +1,3 @@
# coding: utf8
from unittest import TestCase from unittest import TestCase
from twisted.web.http_headers import Headers from twisted.web.http_headers import Headers

View File

@ -1,5 +1,3 @@
# coding: utf8
import collections import collections
import time import time
from urllib import parse from urllib import parse

11
tox.ini
View File

@ -1,7 +1,6 @@
[tox] [tox]
envlist = envlist =
py{36,37,38,39}-twisted{187,latest} py{36,37,38,39}-twisted{187,latest}
qa
[testenv] [testenv]
usedevelop = true usedevelop = true
@ -11,13 +10,3 @@ commands =
deps = deps =
twisted187: twisted==18.7.0 twisted187: twisted==18.7.0
twistedlatest: twisted>=20.3.0 twistedlatest: twisted>=20.3.0
[testenv:qa]
deps =
black
flake8
isort
commands =
flake8 daphne tests
black --check daphne tests
isort --check-only --diff daphne tests