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:
parent
90d71e63e0
commit
fd60b1815c
@ -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)
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
|
||||
@ -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.")
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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])
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 />]>"
|
||||
)
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user