This repository has been archived by the owner on Jul 11, 2022. It is now read-only.
forked from pytest-dev/pytest
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
blackd: a HTTP server for blackening (pytest-dev#460)
- Loading branch information
Showing
13 changed files
with
536 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
install: | ||
- C:\Python36\python.exe -m pip install mypy | ||
- C:\Python36\python.exe -m pip install -e . | ||
- C:\Python36\python.exe -m pip install -e .[d] | ||
|
||
# Not a C# project | ||
build: off | ||
|
||
test_script: | ||
- C:\Python36\python.exe tests/test_black.py | ||
- C:\Python36\python.exe -m mypy black.py tests/test_black.py | ||
- C:\Python36\python.exe -m mypy black.py blackd.py tests/test_black.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import asyncio | ||
from concurrent.futures import Executor, ProcessPoolExecutor | ||
from functools import partial | ||
import logging | ||
|
||
from aiohttp import web | ||
import black | ||
import click | ||
|
||
# This is used internally by tests to shut down the server prematurely | ||
_stop_signal = asyncio.Event() | ||
|
||
VERSION_HEADER = "X-Protocol-Version" | ||
LINE_LENGTH_HEADER = "X-Line-Length" | ||
PYTHON_VARIANT_HEADER = "X-Python-Variant" | ||
SKIP_STRING_NORMALIZATION_HEADER = "X-Skip-String-Normalization" | ||
FAST_OR_SAFE_HEADER = "X-Fast-Or-Safe" | ||
|
||
|
||
@click.command(context_settings={"help_option_names": ["-h", "--help"]}) | ||
@click.option( | ||
"--bind-host", type=str, help="Address to bind the server to.", default="localhost" | ||
) | ||
@click.option("--bind-port", type=int, help="Port to listen on", default=45484) | ||
@click.version_option(version=black.__version__) | ||
def main(bind_host: str, bind_port: int) -> None: | ||
logging.basicConfig(level=logging.INFO) | ||
app = make_app() | ||
ver = black.__version__ | ||
black.out(f"blackd version {ver} listening on {bind_host} port {bind_port}") | ||
web.run_app(app, host=bind_host, port=bind_port, handle_signals=True, print=None) | ||
|
||
|
||
def make_app() -> web.Application: | ||
app = web.Application() | ||
executor = ProcessPoolExecutor() | ||
app.add_routes([web.post("/", partial(handle, executor=executor))]) | ||
return app | ||
|
||
|
||
async def handle(request: web.Request, executor: Executor) -> web.Response: | ||
try: | ||
if request.headers.get(VERSION_HEADER, "1") != "1": | ||
return web.Response( | ||
status=501, text="This server only supports protocol version 1" | ||
) | ||
try: | ||
line_length = int( | ||
request.headers.get(LINE_LENGTH_HEADER, black.DEFAULT_LINE_LENGTH) | ||
) | ||
except ValueError: | ||
return web.Response(status=400, text="Invalid line length header value") | ||
py36 = False | ||
pyi = False | ||
if PYTHON_VARIANT_HEADER in request.headers: | ||
value = request.headers[PYTHON_VARIANT_HEADER] | ||
if value == "pyi": | ||
pyi = True | ||
else: | ||
try: | ||
major, *rest = value.split(".") | ||
if int(major) == 3 and len(rest) > 0: | ||
if int(rest[0]) >= 6: | ||
py36 = True | ||
except ValueError: | ||
return web.Response( | ||
status=400, text=f"Invalid value for {PYTHON_VARIANT_HEADER}" | ||
) | ||
skip_string_normalization = bool( | ||
request.headers.get(SKIP_STRING_NORMALIZATION_HEADER, False) | ||
) | ||
fast = False | ||
if request.headers.get(FAST_OR_SAFE_HEADER, "safe") == "fast": | ||
fast = True | ||
mode = black.FileMode.from_configuration( | ||
py36=py36, pyi=pyi, skip_string_normalization=skip_string_normalization | ||
) | ||
req_bytes = await request.content.read() | ||
charset = request.charset if request.charset is not None else "utf8" | ||
req_str = req_bytes.decode(charset) | ||
loop = asyncio.get_event_loop() | ||
formatted_str = await loop.run_in_executor( | ||
executor, | ||
partial( | ||
black.format_file_contents, | ||
req_str, | ||
line_length=line_length, | ||
fast=fast, | ||
mode=mode, | ||
), | ||
) | ||
return web.Response( | ||
content_type=request.content_type, charset=charset, text=formatted_str | ||
) | ||
except black.NothingChanged: | ||
return web.Response(status=204) | ||
except black.InvalidInput as e: | ||
return web.Response(status=400, text=str(e)) | ||
except Exception as e: | ||
logging.exception("Exception during handling a request") | ||
return web.Response(status=500, text=str(e)) | ||
|
||
|
||
if __name__ == "__main__": | ||
black.patch_click() | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
_build/generated/blackd.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,3 +29,6 @@ check_untyped_defs=True | |
|
||
# No incremental mode | ||
cache_dir=/dev/null | ||
|
||
[mypy-aiohttp.*] | ||
follow_imports=skip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,12 +36,13 @@ def get_version() -> str: | |
author_email="[email protected]", | ||
url="https://github.com/ambv/black", | ||
license="MIT", | ||
py_modules=["black"], | ||
py_modules=["black", "blackd"], | ||
packages=["blib2to3", "blib2to3.pgen2"], | ||
package_data={"blib2to3": ["*.txt"]}, | ||
python_requires=">=3.6", | ||
zip_safe=False, | ||
install_requires=["click>=6.5", "attrs>=17.4.0", "appdirs", "toml>=0.9.4"], | ||
extras_require={"d": ["aiohttp>=3.3.2"]}, | ||
test_suite="tests.test_black", | ||
classifiers=[ | ||
"Development Status :: 4 - Beta", | ||
|
@@ -56,5 +57,5 @@ def get_version() -> str: | |
"Topic :: Software Development :: Libraries :: Python Modules", | ||
"Topic :: Software Development :: Quality Assurance", | ||
], | ||
entry_points={"console_scripts": ["black=black:main"]}, | ||
entry_points={"console_scripts": ["black=black:main", "blackd=blackd:main [d]"]}, | ||
) |
Oops, something went wrong.