Skip to content

Commit

Permalink
Add flake8-no-implicit-concat (#7731)
Browse files Browse the repository at this point in the history
  • Loading branch information
booniepepper authored Aug 31, 2024
1 parent cc6d763 commit 1d170d3
Show file tree
Hide file tree
Showing 36 changed files with 111 additions and 123 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ repos:
- id: flake8
additional_dependencies:
- flake8-docstrings==1.6.0
- flake8-no-implicit-concat==0.3.4
- flake8-requirements==1.7.8
exclude: "^docs/"
- repo: https://github.com/Lucas-C/pre-commit-hooks-markup
Expand Down
1 change: 1 addition & 0 deletions CHANGES/7731.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added flake8 settings to avoid some forms of implicit concatenation. -- by :user:`booniepepper`.
8 changes: 3 additions & 5 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,7 @@ def __init__(self, fingerprint: bytes) -> None:
if not hashfunc:
raise ValueError("fingerprint has invalid length")
elif hashfunc is md5 or hashfunc is sha1:
raise ValueError(
"md5 and sha1 are insecure and " "not supported. Use sha256."
)
raise ValueError("md5 and sha1 are insecure and not supported. Use sha256.")
self._hashfunc = hashfunc
self._fingerprint = fingerprint

Expand Down Expand Up @@ -435,7 +433,7 @@ def update_content_encoding(self, data: Any) -> None:
if enc:
if self.compress:
raise ValueError(
"compress can not be set " "if Content-Encoding header is set"
"compress can not be set if Content-Encoding header is set"
)
elif self.compress:
if not isinstance(self.compress, str):
Expand All @@ -457,7 +455,7 @@ def update_transfer_encoding(self) -> None:
elif self.chunked:
if hdrs.CONTENT_LENGTH in self.headers:
raise ValueError(
"chunked can not be set " "if Content-Length header is set"
"chunked can not be set if Content-Length header is set"
)

self.headers[hdrs.TRANSFER_ENCODING] = "chunked"
Expand Down
6 changes: 3 additions & 3 deletions aiohttp/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def __init__(
if force_close:
if keepalive_timeout is not None and keepalive_timeout is not sentinel:
raise ValueError(
"keepalive_timeout cannot " "be set if force_close is True"
"keepalive_timeout cannot be set if force_close is True"
)
else:
if keepalive_timeout is sentinel:
Expand Down Expand Up @@ -828,7 +828,7 @@ def clear_dns_cache(
if host is not None and port is not None:
self._cached_hosts.remove((host, port))
elif host is not None or port is not None:
raise ValueError("either both host and port " "or none of them are allowed")
raise ValueError("either both host and port or none of them are allowed")
else:
self._cached_hosts.clear()

Expand Down Expand Up @@ -1449,7 +1449,7 @@ def __init__(
self._loop, asyncio.ProactorEventLoop # type: ignore[attr-defined]
):
raise RuntimeError(
"Named Pipes only available in proactor " "loop under windows"
"Named Pipes only available in proactor loop under windows"
)
self._path = path

Expand Down
2 changes: 1 addition & 1 deletion aiohttp/cookiejar.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class CookieJar(AbstractCookieJar):
DATE_DAY_OF_MONTH_RE = re.compile(r"(\d{1,2})")

DATE_MONTH_RE = re.compile(
"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|" "(aug)|(sep)|(oct)|(nov)|(dec)",
"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|(aug)|(sep)|(oct)|(nov)|(dec)",
re.I,
)

Expand Down
8 changes: 3 additions & 5 deletions aiohttp/formdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ def add_field(

type_options: MultiDict[str] = MultiDict({"name": name})
if filename is not None and not isinstance(filename, str):
raise TypeError(
"filename must be an instance of str. " "Got: %s" % filename
)
raise TypeError("filename must be an instance of str. Got: %s" % filename)
if filename is None and isinstance(value, io.IOBase):
filename = guess_filename(value, name)
if filename is not None:
Expand All @@ -68,7 +66,7 @@ def add_field(
if content_type is not None:
if not isinstance(content_type, str):
raise TypeError(
"content_type must be an instance of str. " "Got: %s" % content_type
"content_type must be an instance of str. Got: %s" % content_type
)
headers[hdrs.CONTENT_TYPE] = content_type
self._is_multipart = True
Expand Down Expand Up @@ -110,7 +108,7 @@ def _gen_form_urlencoded(self) -> payload.BytesPayload:
if charset == "utf-8":
content_type = "application/x-www-form-urlencoded"
else:
content_type = "application/x-www-form-urlencoded; " "charset=%s" % charset
content_type = "application/x-www-form-urlencoded; charset=%s" % charset

return payload.BytesPayload(
urlencode(data, doseq=True, encoding=charset).encode(),
Expand Down
10 changes: 3 additions & 7 deletions aiohttp/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,16 +396,14 @@ def content_disposition_header(
params is a dict with disposition params.
"""
if not disptype or not (TOKEN > set(disptype)):
raise ValueError("bad content disposition type {!r}" "".format(disptype))
raise ValueError(f"bad content disposition type {disptype!r}")

value = disptype
if params:
lparams = []
for key, val in params.items():
if not key or not (TOKEN > set(key)):
raise ValueError(
"bad content disposition parameter" " {!r}={!r}".format(key, val)
)
raise ValueError(f"bad content disposition parameter {key!r}={val!r}")
if quote_fields:
if key.lower() == "filename":
qval = quote(val, "", encoding=_charset)
Expand Down Expand Up @@ -705,9 +703,7 @@ def __enter__(self) -> BaseTimerContext:
task = asyncio.current_task(loop=self._loop)

if task is None:
raise RuntimeError(
"Timeout context manager should be used " "inside a task"
)
raise RuntimeError("Timeout context manager should be used inside a task")

if self._cancelled:
raise asyncio.TimeoutError from None
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/http_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def ws_ext_gen(
# compress wbit 8 does not support in zlib
if compress < 9 or compress > 15:
raise ValueError(
"Compress wbits must between 9 and 15, " "zlib does not support wbits=8"
"Compress wbits must between 9 and 15, zlib does not support wbits=8"
)
enabledext = ["permessage-deflate"]
if not isserver:
Expand Down Expand Up @@ -496,7 +496,7 @@ def parse_frame(
if opcode > 0x7 and length > 125:
raise WebSocketError(
WSCloseCode.PROTOCOL_ERROR,
"Control frame payload cannot be " "larger than 125 bytes",
"Control frame payload cannot be larger than 125 bytes",
)

# Set compress status if last package is FIN
Expand Down
4 changes: 1 addition & 3 deletions aiohttp/multipart.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,9 +530,7 @@ def _decode_content_transfer(self, data: bytes) -> bytes:
elif encoding in ("binary", "8bit", "7bit"):
return data
else:
raise RuntimeError(
"unknown content transfer encoding: {}" "".format(encoding)
)
raise RuntimeError(f"unknown content transfer encoding: {encoding}")

def get_charset(self, default: str) -> str:
"""Returns charset parameter from Content-Type header or default."""
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def begin_http_chunk_receiving(self) -> None:
if self._http_chunk_splits is None:
if self.total_bytes:
raise RuntimeError(
"Called begin_http_chunk_receiving when" "some data was already fed"
"Called begin_http_chunk_receiving when some data was already fed"
)
self._http_chunk_splits = []

Expand Down
2 changes: 1 addition & 1 deletion aiohttp/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def __init__(
) -> None:
if not isinstance(server, BaseTestServer):
raise TypeError(
"server must be TestServer " "instance, found type: %r" % type(server)
"server must be TestServer instance, found type: %r" % type(server)
)
self._server = server
if cookie_jar is None:
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ def main(argv: List[str]) -> None:
# Compatibility logic
if args.path is not None and not hasattr(socket, "AF_UNIX"):
arg_parser.error(
"file system paths not supported by your operating" " environment"
"file system paths not supported by your operating environment"
)

logging.basicConfig(level=logging.DEBUG)
Expand Down
8 changes: 4 additions & 4 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def __init__(
) -> None:
if debug is not ...:
warnings.warn(
"debug argument is no-op since 4.0 " "and scheduled for removal in 5.0",
"debug argument is no-op since 4.0 and scheduled for removal in 5.0",
DeprecationWarning,
stacklevel=2,
)
Expand Down Expand Up @@ -155,7 +155,7 @@ def __getitem__(self, key: Union[str, AppKey[_T]]) -> Any:
def _check_frozen(self) -> None:
if self._frozen:
raise RuntimeError(
"Changing state of started or joined " "application is forbidden"
"Changing state of started or joined application is forbidden"
)

@overload # type: ignore[override]
Expand Down Expand Up @@ -201,7 +201,7 @@ def get(self, key: Union[str, AppKey[_T]], default: Any = None) -> Any:
########
def _set_loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None:
warnings.warn(
"_set_loop() is no-op since 4.0 " "and scheduled for removal in 5.0",
"_set_loop() is no-op since 4.0 and scheduled for removal in 5.0",
DeprecationWarning,
stacklevel=2,
)
Expand Down Expand Up @@ -251,7 +251,7 @@ def freeze(self) -> None:
@property
def debug(self) -> bool:
warnings.warn(
"debug property is deprecated since 4.0" "and scheduled for removal in 5.0",
"debug property is deprecated since 4.0 and scheduled for removal in 5.0",
DeprecationWarning,
stacklevel=2,
)
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/web_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def clone(
will reuse the one from the current request object.
"""
if self._read_bytes:
raise RuntimeError("Cannot clone request " "after reading its content")
raise RuntimeError("Cannot clone request after reading its content")

dct: Dict[str, Any] = {}
if method is not sentinel:
Expand Down Expand Up @@ -768,7 +768,7 @@ async def post(self) -> "MultiDictProxy[Union[str, bytes, FileField]]":
)
else:
raise ValueError(
"To decode nested multipart you need " "to use custom reader",
"To decode nested multipart you need to use custom reader",
)

field = await multipart.next()
Expand Down
12 changes: 6 additions & 6 deletions aiohttp/web_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ def set_status(
status: int,
reason: Optional[str] = None,
) -> None:
assert not self.prepared, (
"Cannot change the response status code after " "the headers have been sent"
)
assert (
not self.prepared
), "Cannot change the response status code after the headers have been sent"
self._status = int(status)
if reason is None:
try:
Expand All @@ -181,7 +181,7 @@ def enable_chunked_encoding(self) -> None:

if hdrs.CONTENT_LENGTH in self._headers:
raise RuntimeError(
"You can't enable chunked encoding when " "a content length is set"
"You can't enable chunked encoding when a content length is set"
)

def enable_compression(self, force: Optional[ContentCoding] = None) -> None:
Expand All @@ -204,7 +204,7 @@ def content_length(self, value: Optional[int]) -> None:
value = int(value)
if self._chunked:
raise RuntimeError(
"You can't set content length when " "chunked encoding is enable"
"You can't set content length when chunked encoding is enable"
)
self._headers[hdrs.CONTENT_LENGTH] = str(value)
else:
Expand Down Expand Up @@ -530,7 +530,7 @@ def __init__(
real_headers = headers # = cast('CIMultiDict[str]', headers)

if content_type is not None and "charset" in content_type:
raise ValueError("charset must not be in content_type " "argument")
raise ValueError("charset must not be in content_type argument")

if text is not None:
if hdrs.CONTENT_TYPE in real_headers:
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/web_routedef.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __repr__(self) -> str:
info = []
for name, value in sorted(self.kwargs.items()):
info.append(f", {name}={value!r}")
return "<RouteDef {method} {path} -> {handler.__name__!r}" "{info}>".format(
return "<RouteDef {method} {path} -> {handler.__name__!r}{info}>".format(
method=self.method, path=self.path, handler=self.handler, info="".join(info)
)

Expand All @@ -89,7 +89,7 @@ def __repr__(self) -> str:
info = []
for name, value in sorted(self.kwargs.items()):
info.append(f", {name}={value!r}")
return "<StaticDef {prefix} -> {path}" "{info}>".format(
return "<StaticDef {prefix} -> {path}{info}>".format(
prefix=self.prefix, path=self.path, info="".join(info)
)

Expand Down
2 changes: 1 addition & 1 deletion aiohttp/web_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def __init__(self, runner: "BaseRunner[Any]", path: str) -> None:
loop, asyncio.ProactorEventLoop # type: ignore[attr-defined]
):
raise RuntimeError(
"Named Pipes only available in proactor" "loop under windows"
"Named Pipes only available in proactor loop under windows"
)
super().__init__(runner)
self._path = path
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def __init__(
) -> None:
if debug is not None:
warnings.warn(
"debug argument is no-op since 4.0 " "and scheduled for removal in 5.0",
"debug argument is no-op since 4.0 and scheduled for removal in 5.0",
DeprecationWarning,
stacklevel=2,
)
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ def _add_prefix_to_resources(self, prefix: str) -> None:
router.index_resource(resource)

def url_for(self, *args: str, **kwargs: str) -> URL:
raise RuntimeError(".url_for() is not supported " "by sub-application root")
raise RuntimeError(".url_for() is not supported by sub-application root")

def get_info(self) -> _InfoDict:
return {"app": self._app, "prefix": self._prefix}
Expand Down Expand Up @@ -873,7 +873,7 @@ async def resolve(self, request: Request) -> _Resolve:
return match_info, methods

def __repr__(self) -> str:
return "<MatchedSubAppResource -> {app!r}>" "".format(app=self._app)
return f"<MatchedSubAppResource -> {self._app!r}>"


class ResourceRoute(AbstractRoute):
Expand Down
9 changes: 7 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,14 @@ max-line-length=79
zip_ok = false

[flake8]
extend-select = B950
extend-select =
B950,
# NIC001 -- "Implicitly concatenated str literals on one line"
NIC001,
# NIC101 -- "Implicitly concatenated bytes literals on one line"
NIC101,
# TODO: don't disable D*, fix up issues instead
ignore = N801,N802,N803,E203,E226,E305,W504,E252,E301,E302,E501,E704,W503,W504,D1,D4
ignore = N801,N802,N803,NIC002,NIC102,E203,E226,E305,W504,E252,E301,E302,E501,E704,W503,W504,D1,D4
max-line-length = 88
per-file-ignores =
# I900: Shouldn't appear in requirements for examples.
Expand Down
2 changes: 1 addition & 1 deletion tests/test_client_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def test_pickle(self) -> None:

def test_repr(self) -> None:
err = client.ServerDisconnectedError()
assert repr(err) == ("ServerDisconnectedError" "('Server disconnected')")
assert repr(err) == ("ServerDisconnectedError('Server disconnected')")

err = client.ServerDisconnectedError(message="No connection")
assert repr(err) == "ServerDisconnectedError('No connection')"
Expand Down
Loading

0 comments on commit 1d170d3

Please sign in to comment.