Ruff linter: Use the default line-length (#2922)

Co-authored-by: Tester <Tester@test.com>
Co-authored-by: Kar Petrosyan <92274156+karpetrosyan@users.noreply.github.com>
This commit is contained in:
T-256 2023-11-29 12:58:31 +03:30 committed by GitHub
parent 90d71e63e0
commit fd60b1815c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 89 additions and 58 deletions

View File

@ -1264,7 +1264,9 @@ class Client(BaseClient):
if self._state != ClientState.UNOPENED:
msg = {
ClientState.OPENED: "Cannot open a client instance more than once.",
ClientState.CLOSED: "Cannot reopen a client instance, once it has been closed.",
ClientState.CLOSED: (
"Cannot reopen a client instance, once it has been closed."
),
}[self._state]
raise RuntimeError(msg)
@ -1980,7 +1982,9 @@ class AsyncClient(BaseClient):
if self._state != ClientState.UNOPENED:
msg = {
ClientState.OPENED: "Cannot open a client instance more than once.",
ClientState.CLOSED: "Cannot reopen a client instance, once it has been closed.",
ClientState.CLOSED: (
"Cannot reopen a client instance, once it has been closed."
),
}[self._state]
raise RuntimeError(msg)

View File

@ -259,7 +259,8 @@ class LineDecoder:
"""
Handles incrementally reading lines from text.
Has the same behaviour as the stdllib splitlines, but handling the input iteratively.
Has the same behaviour as the stdllib splitlines,
but handling the input iteratively.
"""
def __init__(self) -> None:

View File

@ -313,7 +313,10 @@ class ResponseNotRead(StreamError):
"""
def __init__(self) -> None:
message = "Attempted to access streaming response content, without having called `read()`."
message = (
"Attempted to access streaming response content,"
" without having called `read()`."
)
super().__init__(message)
@ -323,7 +326,10 @@ class RequestNotRead(StreamError):
"""
def __init__(self) -> None:
message = "Attempted to access streaming request content, without having called `read()`."
message = (
"Attempted to access streaming request content,"
" without having called `read()`."
)
super().__init__(message)

View File

@ -63,9 +63,10 @@ def print_help() -> None:
)
table.add_row(
"--auth [cyan]<USER PASS>",
"Username and password to include in the request. Specify '-' for the password to use "
"a password prompt. Note that using --verbose/-v will expose the Authorization "
"header, including the password encoding in a trivially reversible format.",
"Username and password to include in the request. Specify '-' for the password"
" to use a password prompt. Note that using --verbose/-v will expose"
" the Authorization header, including the password encoding"
" in a trivially reversible format.",
)
table.add_row(
@ -75,8 +76,8 @@ def print_help() -> None:
table.add_row(
"--timeout [cyan]FLOAT",
"Timeout value to use for network operations, such as establishing the connection, "
"reading some data, etc... [Default: 5.0]",
"Timeout value to use for network operations, such as establishing the"
" connection, reading some data, etc... [Default: 5.0]",
)
table.add_row("--follow-redirects", "Automatically follow redirects.")

View File

@ -358,7 +358,8 @@ class Request:
# Using `content=...` implies automatically populated `Host` and content
# headers, of either `Content-Length: ...` or `Transfer-Encoding: chunked`.
#
# Using `stream=...` will not automatically include *any* auto-populated headers.
# Using `stream=...` will not automatically include *any*
# auto-populated headers.
#
# As an end-user you don't really need `stream=...`. It's only
# useful when:

View File

@ -48,7 +48,8 @@ class DataField:
)
if value is not None and not isinstance(value, (str, bytes, int, float)):
raise TypeError(
f"Invalid type for value. Expected primitive type, got {type(value)}: {value!r}"
"Invalid type for value. Expected primitive type,"
f" got {type(value)}: {value!r}"
)
self.name = name
self.value: typing.Union[str, bytes] = (
@ -96,11 +97,13 @@ class FileField:
content_type: typing.Optional[str] = None
# This large tuple based API largely mirror's requests' API
# It would be good to think of better APIs for this that we could include in httpx 2.0
# since variable length tuples (especially of 4 elements) are quite unwieldly
# It would be good to think of better APIs for this that we could
# include in httpx 2.0 since variable length tuples(especially of 4 elements)
# are quite unwieldly
if isinstance(value, tuple):
if len(value) == 2:
# neither the 3rd parameter (content_type) nor the 4th (headers) was included
# neither the 3rd parameter (content_type) nor the 4th (headers)
# was included
filename, fileobj = value # type: ignore
elif len(value) == 3:
filename, fileobj, content_type = value # type: ignore
@ -116,9 +119,9 @@ class FileField:
has_content_type_header = any("content-type" in key.lower() for key in headers)
if content_type is not None and not has_content_type_header:
# note that unlike requests, we ignore the content_type
# provided in the 3rd tuple element if it is also included in the headers
# requests does the opposite (it overwrites the header with the 3rd tuple element)
# note that unlike requests, we ignore the content_type provided in the 3rd
# tuple element if it is also included in the headers requests does
# the opposite (it overwrites the headerwith the 3rd tuple element)
headers["Content-Type"] = content_type
if isinstance(fileobj, io.StringIO):

View File

@ -190,7 +190,8 @@ class HTTPTransport(BaseTransport):
)
else: # pragma: no cover
raise ValueError(
f"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}."
"Proxy protocol must be either 'http', 'https', or 'socks5',"
f" but got {proxy.url.scheme!r}."
)
def __enter__(self: T) -> T: # Use generics for subclass support.
@ -328,7 +329,8 @@ class AsyncHTTPTransport(AsyncBaseTransport):
)
else: # pragma: no cover
raise ValueError(
f"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}."
"Proxy protocol must be either 'http', 'https', or 'socks5',"
" but got {proxy.url.scheme!r}."
)
async def __aenter__(self: A) -> A: # Use generics for subclass support.

View File

@ -360,24 +360,25 @@ def normalize_port(
def validate_path(path: str, has_scheme: bool, has_authority: bool) -> None:
"""
Path validation rules that depend on if the URL contains a scheme or authority component.
Path validation rules that depend on if the URL contains
a scheme or authority component.
See https://datatracker.ietf.org/doc/html/rfc3986.html#section-3.3
"""
if has_authority:
# > If a URI contains an authority component, then the path component
# > must either be empty or begin with a slash ("/") character."
# If a URI contains an authority component, then the path component
# must either be empty or begin with a slash ("/") character."
if path and not path.startswith("/"):
raise InvalidURL("For absolute URLs, path must be empty or begin with '/'")
else:
# > If a URI does not contain an authority component, then the path cannot begin
# > with two slash characters ("//").
# If a URI does not contain an authority component, then the path cannot begin
# with two slash characters ("//").
if path.startswith("//"):
raise InvalidURL(
"URLs with no authority component cannot have a path starting with '//'"
)
# > In addition, a URI reference (Section 4.1) may be a relative-path reference, in which
# > case the first path segment cannot contain a colon (":") character.
# In addition, a URI reference (Section 4.1) may be a relative-path reference,
# in which case the first path segment cannot contain a colon (":") character.
if path.startswith(":") and not has_scheme:
raise InvalidURL(
"URLs with no scheme component cannot have a path starting with ':'"
@ -449,16 +450,18 @@ def quote(string: str, safe: str = "/") -> str:
def urlencode(items: typing.List[typing.Tuple[str, str]]) -> str:
# We can use a much simpler version of the stdlib urlencode here because
# we don't need to handle a bunch of different typing cases, such as bytes vs str.
#
# https://github.com/python/cpython/blob/b2f7b2ef0b5421e01efb8c7bee2ef95d3bab77eb/Lib/urllib/parse.py#L926
#
# Note that we use '%20' encoding for spaces. and '%2F for '/'.
# This is slightly different than `requests`, but is the behaviour that browsers use.
#
# See
# - https://github.com/encode/httpx/issues/2536
# - https://github.com/encode/httpx/issues/2721
# - https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
"""
We can use a much simpler version of the stdlib urlencode here because
we don't need to handle a bunch of different typing cases, such as bytes vs str.
https://github.com/python/cpython/blob/b2f7b2ef0b5421e01efb8c7bee2ef95d3bab77eb/Lib/urllib/parse.py#L926
Note that we use '%20' encoding for spaces. and '%2F for '/'.
This is slightly different than `requests`, but is the behaviour that browsers use.
See
- https://github.com/encode/httpx/issues/2536
- https://github.com/encode/httpx/issues/2721
- https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode
"""
return "&".join([quote(k, safe="") + "=" + quote(v, safe="") for k, v in items])

View File

@ -51,21 +51,23 @@ class URL:
assert url.raw_host == b"xn--fiqs8s.icom.museum"
* `url.port` is either None or an integer. URLs that include the default port for
"http", "https", "ws", "wss", and "ftp" schemes have their port normalized to `None`.
"http", "https", "ws", "wss", and "ftp" schemes have their port
normalized to `None`.
assert httpx.URL("http://example.com") == httpx.URL("http://example.com:80")
assert httpx.URL("http://example.com").port is None
assert httpx.URL("http://example.com:80").port is None
* `url.userinfo` is raw bytes, without URL escaping. Usually you'll want to work with
`url.username` and `url.password` instead, which handle the URL escaping.
* `url.userinfo` is raw bytes, without URL escaping. Usually you'll want to work
with `url.username` and `url.password` instead, which handle the URL escaping.
* `url.raw_path` is raw bytes of both the path and query, without URL escaping.
This portion is used as the target when constructing HTTP requests. Usually you'll
want to work with `url.path` instead.
* `url.query` is raw bytes, without URL escaping. A URL query string portion can only
be properly URL escaped when decoding the parameter names and values themselves.
* `url.query` is raw bytes, without URL escaping. A URL query string portion can
only be properly URL escaped when decoding the parameter names and values
themselves.
"""
def __init__(
@ -115,7 +117,8 @@ class URL:
self._uri_reference = url._uri_reference.copy_with(**kwargs)
else:
raise TypeError(
f"Invalid type for url. Expected str or httpx.URL, got {type(url)}: {url!r}"
"Invalid type for url. Expected str or httpx.URL,"
f" got {type(url)}: {url!r}"
)
@property
@ -305,7 +308,8 @@ class URL:
Provides the (scheme, host, port, target) for the outgoing request.
In older versions of `httpx` this was used in the low-level transport API.
We no longer use `RawURL`, and this property will be deprecated in a future release.
We no longer use `RawURL`, and this property will be deprecated
in a future release.
"""
return RawURL(
self.raw_scheme,
@ -342,7 +346,9 @@ class URL:
For example:
url = httpx.URL("https://www.example.com").copy_with(username="jo@gmail.com", password="a secret")
url = httpx.URL("https://www.example.com").copy_with(
username="jo@gmail.com", password="a secret"
)
assert url == "https://jo%40email.com:a%20secret@www.example.com"
"""
return URL(self, **kwargs)

View File

@ -97,10 +97,6 @@ replacement = 'src="https://raw.githubusercontent.com/encode/httpx/master/\1"'
[tool.ruff]
select = ["E", "F", "I", "B", "PIE"]
ignore = ["B904", "B028"]
line-length = 88
[tool.ruff.pycodestyle]
max-line-length = 120
[tool.ruff.isort]
combine-as-imports = true

View File

@ -596,7 +596,8 @@ async def test_digest_auth_resets_nonce_count_after_401() -> None:
# with this we now force a 401 on a subsequent (but initial) request
app.send_response_after_attempt = 2
# we expect the client again to try to authenticate, i.e. the history length must be 1
# we expect the client again to try to authenticate,
# i.e. the history length must be 1
response_2 = await client.get(url, auth=auth)
assert response_2.status_code == 200
assert len(response_2.history) == 1

View File

@ -92,7 +92,7 @@ def test_cookies_repr():
cookies.set(name="foo", value="bar", domain="http://blah.com")
cookies.set(name="fizz", value="buzz", domain="http://hello.com")
assert (
repr(cookies)
== "<Cookies[<Cookie foo=bar for http://blah.com />, <Cookie fizz=buzz for http://hello.com />]>"
assert repr(cookies) == (
"<Cookies[<Cookie foo=bar for http://blah.com />,"
" <Cookie fizz=buzz for http://hello.com />]>"
)

View File

@ -101,7 +101,10 @@ def test_create_ssl_context_with_get_request(server, cert_pem_file):
def test_limits_repr():
limits = httpx.Limits(max_connections=100)
expected = "Limits(max_connections=100, max_keepalive_connections=None, keepalive_expiry=5.0)"
expected = (
"Limits(max_connections=100, max_keepalive_connections=None,"
" keepalive_expiry=5.0)"
)
assert repr(limits) == expected

View File

@ -174,7 +174,10 @@ def test_multipart_file_tuple_headers(file_content_type: typing.Optional[str]) -
def test_multipart_headers_include_content_type() -> None:
"""Content-Type from 4th tuple parameter (headers) should override the 3rd parameter (content_type)"""
"""
Content-Type from 4th tuple parameter (headers) should
override the 3rd parameter (content_type)
"""
file_name = "test.txt"
file_content = io.BytesIO(b"<file content>")
file_content_type = "text/plain"

View File

@ -109,7 +109,8 @@ def test_logging_redirect_chain(server, caplog):
(
"httpx",
logging.INFO,
'HTTP Request: GET http://127.0.0.1:8000/redirect_301 "HTTP/1.1 301 Moved Permanently"',
"HTTP Request: GET http://127.0.0.1:8000/redirect_301"
' "HTTP/1.1 301 Moved Permanently"',
),
(
"httpx",