Skip to content

Commit 85bfb11

Browse files
authored
Merge pull request #39 from hramezani/linting
Add linting
2 parents 5950014 + f30a095 commit 85bfb11

File tree

14 files changed

+286
-234
lines changed

14 files changed

+286
-234
lines changed

.pre-commit-config.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
repos:
2+
- repo: https://github.com/psf/black
3+
rev: 22.3.0
4+
hooks:
5+
- id: black
6+
args: [--safe, --quiet]
7+
8+
- repo: https://github.com/pre-commit/pre-commit-hooks
9+
rev: v4.2.0
10+
hooks:
11+
- id: trailing-whitespace
12+
- id: end-of-file-fixer
13+
- id: fix-encoding-pragma
14+
args: [--remove]
15+
- id: check-yaml
16+
language_version: python3
17+
18+
- repo: https://github.com/myint/autoflake
19+
rev: v1.4
20+
hooks:
21+
- id: autoflake
22+
name: autoflake
23+
args: ["--in-place", "--remove-unused-variables", "--remove-all-unused-imports"]
24+
language: python
25+
files: \.py$
26+
27+
- repo: https://github.com/PyCQA/flake8
28+
rev: 4.0.1
29+
hooks:
30+
- id: flake8
31+
language_version: python3
32+
33+
- repo: https://github.com/asottile/reorder_python_imports
34+
rev: v3.1.0
35+
hooks:
36+
- id: reorder-python-imports
37+
args: [--py3-plus]
38+
39+
- repo: https://github.com/asottile/pyupgrade
40+
rev: v2.32.1
41+
hooks:
42+
- id: pyupgrade
43+
args: [--py3-plus]

README.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
:alt: Supported Python versions
77
:target: https://pypi.python.org/pypi/pytest-localserver
88

9+
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
10+
:target: https://github.com/psf/black
11+
12+
.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest-localserver/master.svg
13+
:target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest-localserver/master
14+
:alt: pre-commit.ci status
15+
916
==================
1017
pytest-localserver
1118
==================

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[tool.setuptools_scm]
66
write_to = "pytest_localserver/_version.py"
7+
8+
[tool.black]
9+
target-version = ['py35']
10+
line-length = 120

pytest_localserver/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from pytest_localserver._version import version as VERSION
1+
from pytest_localserver._version import version as VERSION # noqa

pytest_localserver/http.py

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#
33
# This program is release under the MIT license. You can find the full text of
44
# the license in the LICENSE file.
5-
65
import enum
76
import itertools
87
import json
@@ -11,7 +10,8 @@
1110

1211
from werkzeug.datastructures import Headers
1312
from werkzeug.serving import make_server
14-
from werkzeug.wrappers import Response, Request
13+
from werkzeug.wrappers import Request
14+
from werkzeug.wrappers import Response
1515

1616

1717
class WSGIServer(threading.Thread):
@@ -20,14 +20,12 @@ class WSGIServer(threading.Thread):
2020
HTTP server running a WSGI application in its own thread.
2121
"""
2222

23-
def __init__(self, host='127.0.0.1', port=0, application=None, **kwargs):
23+
def __init__(self, host="127.0.0.1", port=0, application=None, **kwargs):
2424
self.app = application
2525
self._server = make_server(host, port, self.app, **kwargs)
2626
self.server_address = self._server.server_address
2727

28-
super().__init__(
29-
name=self.__class__,
30-
target=self._server.serve_forever)
28+
super().__init__(name=self.__class__, target=self._server.serve_forever)
3129

3230
def __del__(self):
3331
self.stop()
@@ -38,8 +36,8 @@ def stop(self):
3836
@property
3937
def url(self):
4038
host, port = self.server_address
41-
proto = 'http' if self._server.ssl_context is None else 'https'
42-
return '%s://%s:%i' % (proto, host, port)
39+
proto = "http" if self._server.ssl_context is None else "https"
40+
return "%s://%s:%i" % (proto, host, port)
4341

4442

4543
class Chunked(enum.Enum):
@@ -54,7 +52,7 @@ def __bool__(self):
5452
def _encode_chunk(chunk, charset):
5553
if isinstance(chunk, str):
5654
chunk = chunk.encode(charset)
57-
return '{:x}'.format(len(chunk)).encode(charset) + b'\r\n' + chunk + b'\r\n'
55+
return "{:x}".format(len(chunk)).encode(charset) + b"\r\n" + chunk + b"\r\n"
5856

5957

6058
class ContentServer(WSGIServer):
@@ -78,9 +76,9 @@ class ContentServer(WSGIServer):
7876
7977
"""
8078

81-
def __init__(self, host='127.0.0.1', port=0, ssl_context=None):
79+
def __init__(self, host="127.0.0.1", port=0, ssl_context=None):
8280
super().__init__(host, port, self, ssl_context=ssl_context)
83-
self.content, self.code = ('', 204) # HTTP 204: No Content
81+
self.content, self.code = ("", 204) # HTTP 204: No Content
8482
self.headers = {}
8583
self.show_post_vars = False
8684
self.compress = None
@@ -93,25 +91,27 @@ def __call__(self, environ, start_response):
9391
"""
9492
request = Request(environ)
9593
self.requests.append(request)
96-
if (request.content_type == 'application/x-www-form-urlencoded'
97-
and request.method == 'POST' and self.show_post_vars):
94+
if (
95+
request.content_type == "application/x-www-form-urlencoded"
96+
and request.method == "POST"
97+
and self.show_post_vars
98+
):
9899
content = json.dumps(request.form)
99100
else:
100101
content = self.content
101102

102-
if (
103-
self.chunked == Chunked.YES
104-
or (self.chunked == Chunked.AUTO and 'chunked' in self.headers.get('Transfer-encoding', ''))
103+
if self.chunked == Chunked.YES or (
104+
self.chunked == Chunked.AUTO and "chunked" in self.headers.get("Transfer-encoding", "")
105105
):
106106
# If the code below ever changes to allow setting the charset of
107107
# the Response object, the charset used here should also be changed
108108
# to match. But until that happens, use UTF-8 since it is Werkzeug's
109109
# default.
110-
charset = 'utf-8'
110+
charset = "utf-8"
111111
if isinstance(content, (str, bytes)):
112-
content = (_encode_chunk(content, charset), '0\r\n\r\n')
112+
content = (_encode_chunk(content, charset), "0\r\n\r\n")
113113
else:
114-
content = itertools.chain((_encode_chunk(item, charset) for item in content), ['0\r\n\r\n'])
114+
content = itertools.chain((_encode_chunk(item, charset) for item in content), ["0\r\n\r\n"])
115115

116116
response = Response(response=content, status=self.code)
117117
response.headers.clear()
@@ -152,28 +152,27 @@ def serve_content(self, content, code=200, headers=None, chunked=Chunked.NO):
152152
self.headers = Headers(headers)
153153

154154

155-
if __name__ == '__main__': # pragma: no cover
155+
if __name__ == "__main__": # pragma: no cover
156156
import os.path
157157
import time
158158

159159
app = ContentServer()
160160
server = WSGIServer(application=app)
161161
server.start()
162162

163-
print('HTTP server is running at %s' % server.url)
164-
print('Type <Ctrl-C> to stop')
163+
print("HTTP server is running at %s" % server.url)
164+
print("Type <Ctrl-C> to stop")
165165

166166
try:
167167
path = sys.argv[1]
168168
except IndexError:
169-
path = os.path.join(
170-
os.path.dirname(os.path.abspath(__file__)), '..', 'README.rst')
169+
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "README.rst")
171170

172171
app.serve_content(open(path).read(), 302)
173172

174173
try:
175174
while True:
176175
time.sleep(1)
177176
except KeyboardInterrupt:
178-
print('\rstopping...')
177+
print("\rstopping...")
179178
server.stop()

pytest_localserver/https.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@
22
#
33
# This program is release under the MIT license. You can find the full text of
44
# the license in the LICENSE file.
5-
65
import os.path
76

87
from pytest_localserver.http import ContentServer
98

109
#: default server certificate
11-
DEFAULT_CERTIFICATE = os.path.join(
12-
os.path.abspath(os.path.dirname(__file__)), 'server.pem')
10+
DEFAULT_CERTIFICATE = os.path.join(os.path.abspath(os.path.dirname(__file__)), "server.pem")
1311

1412

15-
class SecureContentServer (ContentServer):
13+
class SecureContentServer(ContentServer):
1614

1715
"""
1816
Small test server which works just like :class:`http.Server` over HTTP::
@@ -109,12 +107,11 @@ class SecureContentServer (ContentServer):
109107
110108
A more advanced tutorial can be found `here`_.
111109
112-
.. _pytest-localserver CA: https://raw.githubusercontent.com/pytest-dev/pytest-localserver/master/pytest_localserver/ca.crt
110+
.. _pytest-localserver CA: https://raw.githubusercontent.com/pytest-dev/pytest-localserver/master/pytest_localserver/ca.crt # noqa: E501
113111
.. _pyOpenSSH: https://launchpad.net/pyopenssl
114112
"""
115113

116-
def __init__(self, host='localhost', port=0,
117-
key=DEFAULT_CERTIFICATE, cert=DEFAULT_CERTIFICATE):
114+
def __init__(self, host="localhost", port=0, key=DEFAULT_CERTIFICATE, cert=DEFAULT_CERTIFICATE):
118115
"""
119116
:param key: location of file containing the server private key.
120117
:param cert: location of file containing server certificate.
@@ -123,31 +120,30 @@ def __init__(self, host='localhost', port=0,
123120
super().__init__(host, port, ssl_context=(key, cert))
124121

125122

126-
if __name__ == '__main__': # pragma: no cover
123+
if __name__ == "__main__": # pragma: no cover
127124

128125
import sys
129126
import time
130127

131-
print('Using certificate %s.' % DEFAULT_CERTIFICATE)
128+
print("Using certificate %s." % DEFAULT_CERTIFICATE)
132129

133130
server = SecureContentServer()
134131
server.start()
135132
server.logging = True
136133

137-
print('HTTPS server is running at %s' % server.url)
138-
print('Type <Ctrl-C> to stop')
134+
print("HTTPS server is running at %s" % server.url)
135+
print("Type <Ctrl-C> to stop")
139136

140137
try:
141138
path = sys.argv[1]
142139
except IndexError:
143-
path = os.path.join(
144-
os.path.dirname(os.path.abspath(__file__)), '..', 'README.rst')
140+
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "README.rst")
145141

146142
server.serve_content(open(path).read(), 302)
147143

148144
try:
149145
while True:
150146
time.sleep(1)
151147
except KeyboardInterrupt:
152-
print('\rstopping...')
148+
print("\rstopping...")
153149
server.stop()

pytest_localserver/plugin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def test_retrieve_some_content(httpserver):
4848
4949
"""
5050
from pytest_localserver import http
51+
5152
server = http.ContentServer()
5253
server.start()
5354
request.addfinalizer(server.stop)
@@ -61,6 +62,7 @@ def httpsserver(request):
6162
SSL encryption.
6263
"""
6364
from pytest_localserver import https
65+
6466
server = https.SecureContentServer()
6567
server.start()
6668
request.addfinalizer(server.stop)
@@ -76,6 +78,7 @@ def smtpserver(request):
7678
* ``addr`` - server address as tuple (host as str, port as int)
7779
"""
7880
from pytest_localserver import smtp
81+
7982
server = smtp.Server()
8083
server.start()
8184
request.addfinalizer(server.stop)

pytest_localserver/smtp.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
# SmtpMailsink Copyright 2005 Aviarc Corporation
66
# Written by Adam Feuer, Matt Branthwaite, and Troy Frever
77
# which is Licensed under the PSF License
8+
import email
89

910
import aiosmtpd.controller
10-
import email
11-
import sys
1211

1312

1413
class MessageDetails:
@@ -30,7 +29,7 @@ async def handle_DATA(self, server, session, envelope):
3029
message = email.message_from_bytes(envelope.content)
3130
message.details = MessageDetails(session.peer, envelope.mail_from, envelope.rcpt_tos)
3231
self.outbox.append(message)
33-
return '250 OK'
32+
return "250 OK"
3433

3534

3635
class Server(aiosmtpd.controller.Controller):
@@ -56,7 +55,7 @@ class Server(aiosmtpd.controller.Controller):
5655
5756
"""
5857

59-
def __init__(self, host='localhost', port=0):
58+
def __init__(self, host="localhost", port=0):
6059
try:
6160
super().__init__(Handler(), hostname=host, port=port, server_hostname=host)
6261
except TypeError:
@@ -79,8 +78,8 @@ def _set_server_socket_attributes(self):
7978
# would fail when calling super()._trigger_server(). In the future, when
8079
# we can safely require aiosmtpd >=1.4, this method can be inlined
8180
# directly into _trigger_server().
82-
if hasattr(self, 'addr'):
83-
assert hasattr(self, 'port')
81+
if hasattr(self, "addr"):
82+
assert hasattr(self, "port")
8483
return
8584

8685
self.addr = self.server.sockets[0].getsockname()[:2]
@@ -111,7 +110,8 @@ def accepting(self):
111110
return self.loop.is_running()
112111

113112
# for aiosmtpd <1.4
114-
if not hasattr(aiosmtpd.controller.Controller, '_trigger_server'):
113+
if not hasattr(aiosmtpd.controller.Controller, "_trigger_server"):
114+
115115
def start(self):
116116
super().start()
117117
self._set_server_socket_attributes()
@@ -149,24 +149,25 @@ def __del__(self):
149149
self.stop()
150150

151151
def __repr__(self): # pragma: no cover
152-
return '<smtp.Server %s:%s>' % self.addr
152+
return "<smtp.Server %s:%s>" % self.addr
153+
153154

154155
if __name__ == "__main__": # pragma: no cover
155156
import time
156157

157158
server = Server()
158159
server.start()
159160

160-
print('SMTP server is running on %s:%i' % server.addr)
161-
print('Type <Ctrl-C> to stop')
161+
print("SMTP server is running on %s:%i" % server.addr)
162+
print("Type <Ctrl-C> to stop")
162163

163164
try:
164165

165166
try:
166167
while True:
167168
time.sleep(1)
168169
finally:
169-
print('\rstopping...')
170+
print("\rstopping...")
170171
server.stop()
171172

172173
except KeyboardInterrupt:

0 commit comments

Comments
 (0)