blackd: a HTTP server for blackening (#460)
This commit is contained in:
parent
80500748a7
commit
a82f186787
@ -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
|
||||
|
@ -4,12 +4,12 @@ language: python
|
||||
cache: pip
|
||||
install:
|
||||
- pip install coverage coveralls flake8 flake8-bugbear mypy
|
||||
- pip install -e .
|
||||
- pip install -e '.[d]'
|
||||
script:
|
||||
- coverage run tests/test_black.py
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then mypy black.py tests/test_black.py; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then mypy black.py blackd.py tests/test_black.py; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.7' ]]; then black --check --verbose .; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.8-dev' ]]; then flake8 black.py tests/test_black.py; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.8-dev' ]]; then flake8 black.py blackd.py tests/test_black.py; fi
|
||||
after_success:
|
||||
- coveralls
|
||||
notifications:
|
||||
|
2
Pipfile
2
Pipfile
@ -4,10 +4,12 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
aiohttp = ">=3.3.2"
|
||||
attrs = ">=17.4.0"
|
||||
click = ">=6.5"
|
||||
appdirs = "*"
|
||||
toml = ">=0.9.4"
|
||||
black = {editable = true, path = ".", extras = ["d"]}
|
||||
|
||||
[dev-packages]
|
||||
pre-commit = "*"
|
||||
|
164
Pipfile.lock
generated
164
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "83e7921ad3bcb0c1ee6c654ef6c2b737dd72629c2541f387ac186bedc55d33af"
|
||||
"sha256": "1becc24ea9195b4295de408a96a019ad449aaee7da84555b6857bb2125749892"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@ -14,6 +14,34 @@
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"aiohttp": {
|
||||
"hashes": [
|
||||
"sha256:01a2059a0505460828854d218cf090d80db277033b8e6906144ab9bd4677fc82",
|
||||
"sha256:01bcaf83911c5a88f74629f116540a1b80391e6e496e6fb8708bb2987b60da63",
|
||||
"sha256:199ea4a9c424904f04a86563a8e9e2759d49e3a0bf789496714253237f16015f",
|
||||
"sha256:229975cb8ff6056c8ef581383a653e7110480d52c9f46eaf560113f8d5005510",
|
||||
"sha256:2bb4224e3a3d7dd2ee18f6c42c1925c3200cd46fe18ec9f293b9bc88644c4878",
|
||||
"sha256:2ddf47c31048efad5a566d82822194bbb680fc1be852915c2949eb69891b5d5a",
|
||||
"sha256:3bc9c87845962f583d6929f837b02b80d2544920be65daf0d0a1306ad1a2089b",
|
||||
"sha256:3f88a3428f40c788321cf5b8191f9dd9e002145545fa0cefc023b4b11e17aaa7",
|
||||
"sha256:4785935328facee0878c29d46f02b12f1e8e8db1cd3d9ec9af666eb163418a64",
|
||||
"sha256:48e8d1973ba62a952f19a7916e54a7155f4b14505507432fc0559d8b5b0e5cad",
|
||||
"sha256:5cd8662ddd7c95e99010e30cc52e20a092939844e8e8a4f37abf1866231f1880",
|
||||
"sha256:6880406a0c776fbff63c0d9eb8a2d96d8134b17fafeeea01180b58ab8ff0f6f5",
|
||||
"sha256:6a8e447742fc45791ffea0b3ce308f1476a9f4707fb6525a2f23b43d4b26cfb3",
|
||||
"sha256:81456c04c54288928da4e7e1893314c8e74d5e9f33163e39aa47c26c5e5c7911",
|
||||
"sha256:9b15efa7411dcf3b59c1f4766eb16ba1aba4531a33e54d469ee22106eabce460",
|
||||
"sha256:a6132db365def76145084041cede574a0c8ed53aa1a680a3027e41ee8f291bd4",
|
||||
"sha256:ddee38858a9ef52ca33cb5dd1607d07d0fb99e2efe523ecb437b1758c49622a5",
|
||||
"sha256:de703f333381864dce788dbfa1a49ef4551e8f082b607a943b94b239d97965cc",
|
||||
"sha256:e08cacfede41291c05b4668c3178d303d078417c013bc3d5287b2b0d0e6a3aa7",
|
||||
"sha256:e4c37c7ec1e1157ae4af73fd1d7f201accebf6ed2222120bc660fd002c45cbac",
|
||||
"sha256:e4f9fc91d617d2e54bda97bc1db9814918691fe799e037ccf973fda434fd2c18",
|
||||
"sha256:f6f73c812c1830a06de76ccbea10a4ebb1fd46230a80f280362e84578e4932a2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.4.0"
|
||||
},
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
|
||||
@ -22,6 +50,14 @@
|
||||
"index": "pypi",
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"async-timeout": {
|
||||
"hashes": [
|
||||
"sha256:474d4bc64cee20603e225eb1ece15e248962958b45a3648a9f5cc29e827a610c",
|
||||
"sha256:b3c0ddc416736619bd4a95ca31de8da6920c3b9a140c64dbef2b2fa7bf521287"
|
||||
],
|
||||
"markers": "python_version >= '3.5.3'",
|
||||
"version": "==3.0.0"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265",
|
||||
@ -30,6 +66,20 @@
|
||||
"index": "pypi",
|
||||
"version": "==18.1.0"
|
||||
},
|
||||
"black": {
|
||||
"editable": true,
|
||||
"extras": [
|
||||
"d"
|
||||
],
|
||||
"path": "."
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
|
||||
@ -38,12 +88,60 @@
|
||||
"index": "pypi",
|
||||
"version": "==6.7"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
||||
],
|
||||
"version": "==2.7"
|
||||
},
|
||||
"idna-ssl": {
|
||||
"hashes": [
|
||||
"sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"
|
||||
],
|
||||
"markers": "python_version < '3.7'",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"multidict": {
|
||||
"hashes": [
|
||||
"sha256:1a1d76374a1e7fe93acef96b354a03c1d7f83e7512e225a527d283da0d7ba5e0",
|
||||
"sha256:1d6e191965505652f194bc4c40270a842922685918a4f45e6936a6b15cc5816d",
|
||||
"sha256:295961a6a88f1199e19968e15d9b42f3a191c89ec13034dbc212bf9c394c3c82",
|
||||
"sha256:2be5af084de6c3b8e20d6421cb0346378a9c867dcf7c86030d6b0b550f9888e4",
|
||||
"sha256:2eb99617c7a0e9f2b90b64bc1fb742611718618572747d6f3d6532b7b78755ab",
|
||||
"sha256:4ba654c6b5ad1ae4a4d792abeb695b29ce981bb0f157a41d0fd227b385f2bef0",
|
||||
"sha256:5ba766433c30d703f6b2c17eb0b6826c6f898e5f58d89373e235f07764952314",
|
||||
"sha256:a59d58ee85b11f337b54933e8d758b2356fcdcc493248e004c9c5e5d11eedbe4",
|
||||
"sha256:a6e35d28900cf87bcc11e6ca9e474db0099b78f0be0a41d95bef02d49101b5b2",
|
||||
"sha256:b4df7ca9c01018a51e43937eaa41f2f5dce17a6382fda0086403bcb1f5c2cf8e",
|
||||
"sha256:bbd5a6bffd3ba8bfe75b16b5e28af15265538e8be011b0b9fddc7d86a453fd4a",
|
||||
"sha256:d870f399fcd58a1889e93008762a3b9a27cf7ea512818fc6e689f59495648355",
|
||||
"sha256:e9404e2e19e901121c3c5c6cffd5a8ae0d1d67919c970e3b3262231175713068"
|
||||
],
|
||||
"markers": "python_version >= '3.4.1'",
|
||||
"version": "==4.3.1"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:8e86bd6ce8cc11b9620cb637466453d94f5d57ad86f17e98a98d1f73e3baab2d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.9.4"
|
||||
},
|
||||
"yarl": {
|
||||
"hashes": [
|
||||
"sha256:2556b779125621b311844a072e0ed367e8409a18fa12cbd68eb1258d187820f9",
|
||||
"sha256:4aec0769f1799a9d4496827292c02a7b1f75c0bab56ab2b60dd94ebb57cbd5ee",
|
||||
"sha256:55369d95afaacf2fa6b49c84d18b51f1704a6560c432a0f9a1aeb23f7b971308",
|
||||
"sha256:6c098b85442c8fe3303e708bbb775afd0f6b29f77612e8892627bcab4b939357",
|
||||
"sha256:9182cd6f93412d32e009020a44d6d170d2093646464a88aeec2aef50592f8c78",
|
||||
"sha256:c8cbc21bbfa1dd7d5386d48cc814fe3d35b80f60299cdde9279046f399c3b0d8",
|
||||
"sha256:db6f70a4b09cde813a4807843abaaa60f3b15fb4a2a06f9ae9c311472662daa1",
|
||||
"sha256:f17495e6fe3d377e3faac68121caef6f974fcb9e046bc075bcff40d8e5cc69a4",
|
||||
"sha256:f85900b9cca0c67767bb61b2b9bd53208aaa7373dae633dbe25d179b4bf38aa7"
|
||||
],
|
||||
"markers": "python_version >= '3.4.1'",
|
||||
"version": "==1.2.6"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
@ -78,10 +176,10 @@
|
||||
},
|
||||
"bleach": {
|
||||
"hashes": [
|
||||
"sha256:b8fa79e91f96c2c2cd9fd1f9eda906efb1b88b483048978ba62fef680e962b34",
|
||||
"sha256:eb7386f632349d10d9ce9d4a838b134d4731571851149f9cc2c05a9a837a9a44"
|
||||
"sha256:0ee95f6167129859c5dce9b1ca291ebdb5d8cd7e382ca0e237dfd0dad63f63d8",
|
||||
"sha256:24754b9a7d530bf30ce7cbc805bc6cce785660b4a10ff3a43633728438c105ab"
|
||||
],
|
||||
"version": "==2.1.3"
|
||||
"version": "==2.1.4"
|
||||
},
|
||||
"cached-property": {
|
||||
"hashes": [
|
||||
@ -92,10 +190,10 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
|
||||
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
|
||||
"sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638",
|
||||
"sha256:456048c7e371c089d0a77a5212fb37a2c2dce1e24146e3b7e0261736aaeaa22a"
|
||||
],
|
||||
"version": "==2018.4.16"
|
||||
"version": "==2018.8.24"
|
||||
},
|
||||
"cffi": {
|
||||
"hashes": [
|
||||
@ -152,6 +250,7 @@
|
||||
"hashes": [
|
||||
"sha256:0186dccca79483e3405217993b83b914ba4559fe9a8396efc4eea56561b74061",
|
||||
"sha256:1a625afc6f62da428df96ec325dc30866cc5781520cbd904ff4ec44cf018171c",
|
||||
"sha256:207b7673ff4e177374c572feeae0e4ef33be620ec9171c08fd22e2b796e03e3d",
|
||||
"sha256:275905bb371a99285c74931700db3f0c078e7603bed383e8cf1a09f3ee05a3de",
|
||||
"sha256:50098f1c4950722521f0671e54139e0edc1837d63c990cf0f3d2c49607bb51a2",
|
||||
"sha256:50ed116d0b60a07df0dc7b180c28569064b9d37d1578d4c9021cff04d725cb63",
|
||||
@ -163,15 +262,19 @@
|
||||
"sha256:811527e9b7280b136734ed6cb6845e5fbccaeaa132ddf45f0246cbe544016957",
|
||||
"sha256:987b0e157f70c72a84f3c2f9ef2d7ab0f26c08f2bf326c12c087ff9eebcb3ff5",
|
||||
"sha256:9fc6a2183d0a9b0974ec7cdcdad42bd78a3be674cc3e65f87dd694419b3b0ab7",
|
||||
"sha256:a3d17ee4ae739fe16f7501a52255c2e287ac817cfd88565b9859f70520afffea",
|
||||
"sha256:ba5b5488719c0f2ced0aa1986376f7baff1a1653a8eb5fdfcf3f84c7ce46ef8d",
|
||||
"sha256:c573ea89dd95d41b6d8cf36799c34b6d5b1eac4aed0212dee0f0a11fb7b01e8f",
|
||||
"sha256:c5f1b9e8592d2c448c44e6bc0d91224b16ea5f8293908b1561de1f6d2d0658b1",
|
||||
"sha256:cbe581456357d8f0674d6a590b1aaf46c11d01dd0a23af147a51a798c3818034",
|
||||
"sha256:cf219bec69e601fe27e3974b7307d2f06082ab385d42752738ad2eb630a47d65",
|
||||
"sha256:cf5014eb214d814a83a7a47407272d5db10b719dbeaf4d3cfe5969309d0fcf4b",
|
||||
"sha256:d08bad67fa18f7e8ff738c090628ee0cbf0505d74a991c848d6d04abfe67b697",
|
||||
"sha256:d6f716d7b1182bf35862b5065112f933f43dd1aa4f8097c9bcfb246f71528a34",
|
||||
"sha256:e08e479102627641c7cb4ece421c6ed4124820b1758765db32201136762282d9",
|
||||
"sha256:e20ac21418af0298437d29599f7851915497ce9f2866bc8e86b084d8911ee061",
|
||||
"sha256:e25f53c37e319241b9a412382140dffac98ca756ba8f360ac7ab5e30cad9670a",
|
||||
"sha256:e8932bddf159064f04e946fbb64693753488de21586f20e840b3be51745c8c09",
|
||||
"sha256:f20900f16377f2109783ae9348d34bc80530808439591c3d3df73d5c7ef1a00c"
|
||||
],
|
||||
"version": "==0.4.2"
|
||||
@ -186,8 +289,11 @@
|
||||
"hashes": [
|
||||
"sha256:03481e81d558d30d230bc12999e3edffe392d244349a90f4ef9b88425fac74ba",
|
||||
"sha256:0b136648de27201056c1869a6c0d4e23f464750fd9a9ba9750b8336a244429ed",
|
||||
"sha256:10a46017fef60e16694a30627319f38a2b9b52e90182dddb6e37dcdab0f4bf95",
|
||||
"sha256:198626739a79b09fa0a2f06e083ffd12eb55449b5f8bfdbeed1df4910b2ca640",
|
||||
"sha256:23d341cdd4a0371820eb2b0bd6b88f5003a7438bbedb33688cd33b8eae59affd",
|
||||
"sha256:28b2191e7283f4f3568962e373b47ef7f0392993bb6660d079c62bd50fe9d162",
|
||||
"sha256:2a5b73210bad5279ddb558d9a2bfedc7f4bf6ad7f3c988641d83c40293deaec1",
|
||||
"sha256:2eb564bbf7816a9d68dd3369a510be3327f1c618d2357fa6b1216994c2e3d508",
|
||||
"sha256:337ded681dd2ef9ca04ef5d93cfc87e52e09db2594c296b4a0a3662cb1b41249",
|
||||
"sha256:3a2184c6d797a125dca8367878d3b9a178b6fdd05fdc2d35d758c3006a1cd694",
|
||||
@ -234,11 +340,11 @@
|
||||
},
|
||||
"flake8-bugbear": {
|
||||
"hashes": [
|
||||
"sha256:541746f0f3b2f1a8d7278e1d2d218df298996b60b02677708560db7c7e620e3b",
|
||||
"sha256:5f14a99d458e29cb92be9079c970030e0dd398b2decb179d76d39a5266ea1578"
|
||||
"sha256:07b6e769d7f4e168d590f7088eae40f6ddd9fa4952bed31602def65842682c83",
|
||||
"sha256:0ccf56975f4db1d69dc1cf3598c99d768ebf95d0cad27d76087954aa399b515a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==18.2.0"
|
||||
"version": "==18.8.0"
|
||||
},
|
||||
"flake8-mypy": {
|
||||
"hashes": [
|
||||
@ -263,10 +369,10 @@
|
||||
},
|
||||
"identify": {
|
||||
"hashes": [
|
||||
"sha256:0bab212939e3e83caf60788fac9bda5ea4a496f9147ed4746bb04f10ec6c0cbf",
|
||||
"sha256:264f34cbd4002d5b2f4b323ae9e5776a16189363d82627f46570b9c703fea448"
|
||||
"sha256:49845e70fc6b1ec3694ab930a2c558912d7de24548eebcd448f65567dc757c43",
|
||||
"sha256:68daab16a3db364fa204591f97dc40bfffd1a7739f27788a4895b4d8fd3516e5"
|
||||
],
|
||||
"version": "==1.1.3"
|
||||
"version": "==1.1.4"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
@ -312,9 +418,9 @@
|
||||
},
|
||||
"nodeenv": {
|
||||
"hashes": [
|
||||
"sha256:0611c726af1b252908646787f4d49811aa69cd92ec19644ded06ad9d3162f88e"
|
||||
"sha256:aa040ab5189bae17d272175609010be6c5b589ec4b8dbd832cc50c9e9cb7496f"
|
||||
],
|
||||
"version": "==1.3.1"
|
||||
"version": "==1.3.2"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
@ -332,11 +438,11 @@
|
||||
},
|
||||
"pre-commit": {
|
||||
"hashes": [
|
||||
"sha256:2d57dd6b0c117ef8363233f256de8a3f26ee1c6e05ed96f9e2d9135ca5467d90",
|
||||
"sha256:9807f29320547a8a13163c1977f6765e488a9349a01431ff4fbd196ff287b51c"
|
||||
"sha256:c1472b0d73e27a5697a477f77a4973c708da4fc433cc89648e8612c8cd623b87",
|
||||
"sha256:ec206de6fbcbd9381ff3169f9975571fb2efa99794c328518a5f0c06ae0b49c5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.10.3"
|
||||
"version": "==1.10.5"
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
@ -415,7 +521,6 @@
|
||||
"sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1",
|
||||
"sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version != '3.2.*' and python_version < '4' and python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"version": "==2.19.1"
|
||||
},
|
||||
"requests-toolbelt": {
|
||||
@ -423,7 +528,6 @@
|
||||
"sha256:42c9c170abc2cacb78b8ab23ac957945c7716249206f90874651971a4acff237",
|
||||
"sha256:f6a531936c6fa4c6cfce1b9c10d5c4f498d16528d2a54a22ca00011205a187b5"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version != '3.2.*' and python_version < '4' and python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"version": "==0.8.0"
|
||||
},
|
||||
"six": {
|
||||
@ -442,18 +546,18 @@
|
||||
},
|
||||
"sphinx": {
|
||||
"hashes": [
|
||||
"sha256:217ad9ece2156ed9f8af12b5d2c82a499ddf2c70a33c5f81864a08d8c67b9efc",
|
||||
"sha256:a765c6db1e5b62aae857697cd4402a5c1a315a7b0854bbcd0fc8cdc524da5896"
|
||||
"sha256:71531900af3f68625a29c4e00381bee8f85255219a3d500a3e255076a45b735e",
|
||||
"sha256:a3defde5e17b5bc2aa21820674409287acc4d56bf8d009213d275e4b9d0d490d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.7.6"
|
||||
"version": "==1.7.7"
|
||||
},
|
||||
"sphinxcontrib-websupport": {
|
||||
"hashes": [
|
||||
"sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
|
||||
"sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
|
||||
],
|
||||
"markers": "python_version != '3.2.*' and python_version >= '2.7' and python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"markers": "python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.2.*'",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"toml": {
|
||||
@ -465,11 +569,11 @@
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:224291ee0d8c52d91b037fd90806f48c79bcd9994d3b0abc9e44b946a908fccd",
|
||||
"sha256:77b8424d41b31e68f437c6dd9cd567aebc9a860507cb42fbd880a5f822d966fe"
|
||||
"sha256:5ef526702c0d265d5a960a3b27f3971fac13c26cf0fb819294bfa71fc6026c88",
|
||||
"sha256:a3364bd83ce4777320b862e3c8a93d7da91e20a95f06ef79bed7dd71c654cafa"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"version": "==4.23.4"
|
||||
"markers": "python_version != '3.1.*' and python_version != '3.0.*' and python_version >= '2.6'",
|
||||
"version": "==4.25.0"
|
||||
},
|
||||
"twine": {
|
||||
"hashes": [
|
||||
@ -512,7 +616,7 @@
|
||||
"sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf",
|
||||
"sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version != '3.2.*' and python_version < '4' and python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"markers": "python_version != '3.1.*' and python_version >= '2.6' and python_version < '4' and python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.2.*'",
|
||||
"version": "==1.23"
|
||||
},
|
||||
"virtualenv": {
|
||||
@ -520,7 +624,7 @@
|
||||
"sha256:2ce32cd126117ce2c539f0134eb89de91a8413a29baac49cbab3eb50e2026669",
|
||||
"sha256:ca07b4c0b54e14a91af9f34d0919790b016923d157afda5efdde55c96718f752"
|
||||
],
|
||||
"markers": "python_version != '3.0.*' and python_version != '3.2.*' and python_version != '3.1.*' and python_version >= '2.7'",
|
||||
"markers": "python_version != '3.1.*' and python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*'",
|
||||
"version": "==16.0.0"
|
||||
},
|
||||
"webencodings": {
|
||||
|
77
README.md
77
README.md
@ -35,6 +35,7 @@ Try it out now using the [Black Playground](https://black.now.sh).
|
||||
**[Code style](#the-black-code-style)** |
|
||||
**[pyproject.toml](#pyprojecttoml)** |
|
||||
**[Editor integration](#editor-integration)** |
|
||||
**[blackd](#blackd)** |
|
||||
**[Version control integration](#version-control-integration)** |
|
||||
**[Ignoring unmodified files](#ignoring-unmodified-files)** |
|
||||
**[Testimonials](#testimonials)** |
|
||||
@ -745,6 +746,76 @@ affect your use case.
|
||||
|
||||
This can be used for example with PyCharm's [File Watchers](https://www.jetbrains.com/help/pycharm/file-watchers.html).
|
||||
|
||||
## blackd
|
||||
|
||||
`blackd` is a small HTTP server that exposes *Black*'s functionality over
|
||||
a simple protocol. The main benefit of using it is to avoid paying the
|
||||
cost of starting up a new *Black* process every time you want to blacken
|
||||
a file.
|
||||
|
||||
### Usage
|
||||
|
||||
`blackd` is not packaged alongside *Black* by default because it has additional
|
||||
dependencies. You will need to do `pip install black[d]` to install it.
|
||||
|
||||
You can start the server on the default port, binding only to the local interface
|
||||
by running `blackd`. You will see a single line mentioning the server's version,
|
||||
and the host and port it's listening on. `blackd` will then print an access log
|
||||
similar to most web servers on standard output, merged with any exception traces
|
||||
caused by invalid formatting requests.
|
||||
|
||||
`blackd` provides even less options than *Black*. You can see them by running
|
||||
`blackd --help`:
|
||||
|
||||
```text
|
||||
Usage: blackd [OPTIONS]
|
||||
|
||||
Options:
|
||||
--bind-host TEXT Address to bind the server to.
|
||||
--bind-port INTEGER Port to listen on
|
||||
--version Show the version and exit.
|
||||
-h, --help Show this message and exit.
|
||||
```
|
||||
|
||||
### Protocol
|
||||
|
||||
`blackd` only accepts `POST` requests at the `/` path. The body of the request
|
||||
should contain the python source code to be formatted, encoded
|
||||
according to the `charset` field in the `Content-Type` request header. If no
|
||||
`charset` is specified, `blackd` assumes `UTF-8`.
|
||||
|
||||
There are a few HTTP headers that control how the source is formatted. These
|
||||
correspond to command line flags for *Black*. There is one exception to this:
|
||||
`X-Protocol-Version` which if present, should have the value `1`, otherwise the
|
||||
request is rejected with `HTTP 501` (Not Implemented).
|
||||
|
||||
The headers controlling how code is formatted are:
|
||||
|
||||
- `X-Line-Length`: corresponds to the `--line-length` command line flag.
|
||||
- `X-Skip-String-Normalization`: corresponds to the `--skip-string-normalization`
|
||||
command line flag. If present and its value is not the empty string, no string
|
||||
normalization will be performed.
|
||||
- `X-Fast-Or-Safe`: if set to `fast`, `blackd` will act as *Black* does when
|
||||
passed the `--fast` command line flag.
|
||||
- `X-Python-Variant`: if set to `pyi`, `blackd` will act as *Black* does when
|
||||
passed the `--pyi` command line flag. Otherwise, its value must correspond to
|
||||
a Python version. If this value represents at least Python 3.6, `blackd` will
|
||||
act as *Black* does when passed the `--py36` command line flag.
|
||||
|
||||
If any of these headers are set to invalid values, `blackd` returns a `HTTP 400`
|
||||
error response, mentioning the name of the problematic header in the message body.
|
||||
|
||||
Apart from the above, `blackd` can produce the following response codes:
|
||||
|
||||
- `HTTP 204`: If the input is already well-formatted. The response body is
|
||||
empty.
|
||||
- `HTTP 200`: If formatting was needed on the input. The response body
|
||||
contains the blackened Python code, and the `Content-Type` header is set
|
||||
accordingly.
|
||||
- `HTTP 400`: If the input contains a syntax error. Details of the error are
|
||||
returned in the response body.
|
||||
- `HTTP 500`: If there was any kind of error while trying to format the input.
|
||||
The response body contains a textual representation of the error.
|
||||
|
||||
## Version control integration
|
||||
|
||||
@ -850,8 +921,14 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md).
|
||||
|
||||
### 18.8b0
|
||||
|
||||
* added `blackd`, see [its documentation](#blackd) for more info (#349)
|
||||
|
||||
* adjacent string literals are now correctly split into multiple lines (#463)
|
||||
|
||||
* added `blackd`, see [its documentation](#blackd) for more info (#349)
|
||||
|
||||
* code with `_` in numeric literals is recognized as Python 3.6+ (#461)
|
||||
|
||||
* numeric literals are now formatted by *Black* (#452, #461, #464, #469):
|
||||
|
||||
* numeric literals are normalized to include `_` separators on Python 3.6+ code
|
||||
|
12
black.py
12
black.py
@ -79,15 +79,15 @@
|
||||
|
||||
|
||||
class NothingChanged(UserWarning):
|
||||
"""Raised by :func:`format_file` when reformatted code is the same as source."""
|
||||
"""Raised when reformatted code is the same as source."""
|
||||
|
||||
|
||||
class CannotSplit(Exception):
|
||||
"""A readable split that fits the allotted line length is impossible.
|
||||
"""A readable split that fits the allotted line length is impossible."""
|
||||
|
||||
Raised by :func:`left_hand_split`, :func:`right_hand_split`, and
|
||||
:func:`delimiter_split`.
|
||||
"""
|
||||
|
||||
class InvalidInput(ValueError):
|
||||
"""Raised when input source code fails all parse attempts."""
|
||||
|
||||
|
||||
class WriteBack(Enum):
|
||||
@ -676,7 +676,7 @@ def lib2to3_parse(src_txt: str) -> Node:
|
||||
faulty_line = lines[lineno - 1]
|
||||
except IndexError:
|
||||
faulty_line = "<line number missing in source>"
|
||||
exc = ValueError(f"Cannot parse: {lineno}:{column}: {faulty_line}")
|
||||
exc = InvalidInput(f"Cannot parse: {lineno}:{column}: {faulty_line}")
|
||||
else:
|
||||
raise exc from None
|
||||
|
||||
|
106
blackd.py
Normal file
106
blackd.py
Normal file
@ -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()
|
1
docs/blackd.md
Symbolic link
1
docs/blackd.md
Symbolic link
@ -0,0 +1 @@
|
||||
_build/generated/blackd.md
|
@ -52,6 +52,7 @@ Contents
|
||||
the_black_code_style
|
||||
pyproject_toml
|
||||
editor_integration
|
||||
blackd
|
||||
version_control_integration
|
||||
ignoring_unmodified_files
|
||||
contributing
|
||||
|
3
mypy.ini
3
mypy.ini
@ -29,3 +29,6 @@ check_untyped_defs=True
|
||||
|
||||
# No incremental mode
|
||||
cache_dir=/dev/null
|
||||
|
||||
[mypy-aiohttp.*]
|
||||
follow_imports=skip
|
||||
|
@ -62,6 +62,7 @@ attrs = "^17.4"
|
||||
click = "^6.5"
|
||||
toml = "^0.9.4"
|
||||
appdirs = "^1.4"
|
||||
aiohttp = "^3.4"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
Sphinx = "^1.7"
|
||||
|
5
setup.py
5
setup.py
@ -36,12 +36,13 @@ def get_version() -> str:
|
||||
author_email="lukasz@langa.pl",
|
||||
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]"]},
|
||||
)
|
||||
|
@ -2,14 +2,24 @@
|
||||
import asyncio
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from contextlib import contextmanager
|
||||
from functools import partial
|
||||
from functools import partial, wraps
|
||||
from io import BytesIO, TextIOWrapper
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import Any, BinaryIO, Generator, List, Tuple, Iterator
|
||||
from typing import (
|
||||
Any,
|
||||
BinaryIO,
|
||||
Callable,
|
||||
Coroutine,
|
||||
Generator,
|
||||
List,
|
||||
Tuple,
|
||||
Iterator,
|
||||
TypeVar,
|
||||
)
|
||||
import unittest
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
@ -18,6 +28,14 @@
|
||||
|
||||
import black
|
||||
|
||||
try:
|
||||
import blackd
|
||||
from aiohttp.test_utils import TestClient, TestServer
|
||||
except ImportError:
|
||||
has_blackd_deps = False
|
||||
else:
|
||||
has_blackd_deps = True
|
||||
|
||||
|
||||
ll = 88
|
||||
ff = partial(black.format_file_in_place, line_length=ll, fast=True)
|
||||
@ -25,6 +43,8 @@
|
||||
THIS_FILE = Path(__file__)
|
||||
THIS_DIR = THIS_FILE.parent
|
||||
EMPTY_LINE = "# EMPTY LINE WITH WHITESPACE" + " (this comment will be removed)"
|
||||
T = TypeVar("T")
|
||||
R = TypeVar("R")
|
||||
|
||||
|
||||
def dump_to_stderr(*output: str) -> str:
|
||||
@ -79,6 +99,15 @@ def event_loop(close: bool) -> Iterator[None]:
|
||||
loop.close()
|
||||
|
||||
|
||||
def async_test(f: Callable[..., Coroutine[Any, None, R]]) -> Callable[..., None]:
|
||||
@event_loop(close=True)
|
||||
@wraps(f)
|
||||
def wrapper(*args: Any, **kwargs: Any) -> None:
|
||||
asyncio.get_event_loop().run_until_complete(f(*args, **kwargs))
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class BlackRunner(CliRunner):
|
||||
"""Modify CliRunner so that stderr is not merged with stdout.
|
||||
|
||||
@ -824,7 +853,7 @@ def test_format_file_contents(self) -> None:
|
||||
actual = black.format_file_contents(different, line_length=ll, fast=False)
|
||||
self.assertEqual(expected, actual)
|
||||
invalid = "return if you can"
|
||||
with self.assertRaises(ValueError) as e:
|
||||
with self.assertRaises(black.InvalidInput) as e:
|
||||
black.format_file_contents(invalid, line_length=ll, fast=False)
|
||||
self.assertEqual(str(e.exception), "Cannot parse: 1:7: return if you can")
|
||||
|
||||
@ -1289,6 +1318,171 @@ def test_shhh_click(self) -> None:
|
||||
except RuntimeError as re:
|
||||
self.fail(f"`patch_click()` failed, exception still raised: {re}")
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_request_needs_formatting(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post("/", data=b"print('hello world')")
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertEqual(response.charset, "utf8")
|
||||
self.assertEqual(await response.read(), b'print("hello world")\n')
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_request_no_change(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post("/", data=b'print("hello world")\n')
|
||||
self.assertEqual(response.status, 204)
|
||||
self.assertEqual(await response.read(), b"")
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_request_syntax_error(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post("/", data=b"what even ( is")
|
||||
self.assertEqual(response.status, 400)
|
||||
content = await response.text()
|
||||
self.assertTrue(
|
||||
content.startswith("Cannot parse"),
|
||||
msg=f"Expected error to start with 'Cannot parse', got {repr(content)}",
|
||||
)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_unsupported_version(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post(
|
||||
"/", data=b"what", headers={blackd.VERSION_HEADER: "2"}
|
||||
)
|
||||
self.assertEqual(response.status, 501)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_supported_version(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post(
|
||||
"/", data=b"what", headers={blackd.VERSION_HEADER: "1"}
|
||||
)
|
||||
self.assertEqual(response.status, 200)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_invalid_python_variant(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post(
|
||||
"/", data=b"what", headers={blackd.PYTHON_VARIANT_HEADER: "lol"}
|
||||
)
|
||||
self.assertEqual(response.status, 400)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_pyi(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
source, expected = read_data("stub.pyi")
|
||||
response = await client.post(
|
||||
"/", data=source, headers={blackd.PYTHON_VARIANT_HEADER: "pyi"}
|
||||
)
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertEqual(await response.text(), expected)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_py36(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post(
|
||||
"/",
|
||||
data=(
|
||||
"def f(\n"
|
||||
" and_has_a_bunch_of,\n"
|
||||
" very_long_arguments_too,\n"
|
||||
" and_lots_of_them_as_well_lol,\n"
|
||||
" **and_very_long_keyword_arguments\n"
|
||||
"):\n"
|
||||
" pass\n"
|
||||
),
|
||||
headers={blackd.PYTHON_VARIANT_HEADER: "3.6"},
|
||||
)
|
||||
self.assertEqual(response.status, 200)
|
||||
response = await client.post(
|
||||
"/",
|
||||
data=(
|
||||
"def f(\n"
|
||||
" and_has_a_bunch_of,\n"
|
||||
" very_long_arguments_too,\n"
|
||||
" and_lots_of_them_as_well_lol,\n"
|
||||
" **and_very_long_keyword_arguments\n"
|
||||
"):\n"
|
||||
" pass\n"
|
||||
),
|
||||
headers={blackd.PYTHON_VARIANT_HEADER: "3.5"},
|
||||
)
|
||||
self.assertEqual(response.status, 204)
|
||||
response = await client.post(
|
||||
"/",
|
||||
data=(
|
||||
"def f(\n"
|
||||
" and_has_a_bunch_of,\n"
|
||||
" very_long_arguments_too,\n"
|
||||
" and_lots_of_them_as_well_lol,\n"
|
||||
" **and_very_long_keyword_arguments\n"
|
||||
"):\n"
|
||||
" pass\n"
|
||||
),
|
||||
headers={blackd.PYTHON_VARIANT_HEADER: "2"},
|
||||
)
|
||||
self.assertEqual(response.status, 204)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_fast(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post("/", data=b"ur'hello'")
|
||||
self.assertEqual(response.status, 500)
|
||||
self.assertIn("failed to parse source file", await response.text())
|
||||
response = await client.post(
|
||||
"/", data=b"ur'hello'", headers={blackd.FAST_OR_SAFE_HEADER: "fast"}
|
||||
)
|
||||
self.assertEqual(response.status, 200)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_line_length(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post(
|
||||
"/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "7"}
|
||||
)
|
||||
self.assertEqual(response.status, 200)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
@async_test
|
||||
async def test_blackd_invalid_line_length(self) -> None:
|
||||
app = blackd.make_app()
|
||||
async with TestClient(TestServer(app)) as client:
|
||||
response = await client.post(
|
||||
"/",
|
||||
data=b'print("hello")\n',
|
||||
headers={blackd.LINE_LENGTH_HEADER: "NaN"},
|
||||
)
|
||||
self.assertEqual(response.status, 400)
|
||||
|
||||
@unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed")
|
||||
def test_blackd_main(self) -> None:
|
||||
with patch("blackd.web.run_app"):
|
||||
result = CliRunner().invoke(blackd.main, [])
|
||||
if result.exception is not None:
|
||||
raise result.exception
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(module="test_black")
|
||||
|
Loading…
Reference in New Issue
Block a user