Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ repos:
- id: no_optional

- repo: https://github.com/astral-sh/ruff-pre-commit.git
rev: v0.13.3
rev: v0.15.18
hooks:
- id: ruff
args:
# Ref: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
- --fix # NOTE: When `--fix` is used, linting should be before ruff-format

- repo: https://github.com/astral-sh/ruff-pre-commit.git
rev: v0.13.3
rev: v0.15.18
hooks:
- id: ruff-format
alias: ruff-format-first-pass
Expand All @@ -80,7 +80,7 @@ repos:
- id: add-trailing-comma

- repo: https://github.com/astral-sh/ruff-pre-commit.git
rev: v0.13.3
rev: v0.15.18
hooks:
- id: ruff-format
alias: ruff-format-second-pass
Expand Down
4 changes: 4 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ ignore = [
"PLR6104", # non-augmented-assignment # FIXME
"PLR6301", # no-self-use # FIXME / noqa

"PLW0717", # too-many-statements-in-try-clause # FIXME

"PLW1514", # unspecified-encoding # FIXME

"PTH100", # os-path-abspath # FIXME
Expand All @@ -115,6 +117,7 @@ ignore = [
"PYI024", # collections-named-tuple # FIXME

"RUF005", # collection-literal-concatenation # FIXME
"RUF067", # non-empty-init-module # FIXME
"RUF012", # mutable-class-default # FIXME
"RUF043", # pytest-raises-ambiguous-pattern # FIXME
"RUF048", # map-int-version-parsing # FIXME
Expand Down Expand Up @@ -215,6 +218,7 @@ testing = [
"S101", # Allow use of `assert` in test files
"S404", # Allow importing 'subprocess' module to testing call external tools needed by these hooks
"S603", # subprocess-without-shell-equals-true
"S607", # start-process-with-partial-path # FIXME
"SLF001", # Private member accessed
]

Expand Down
4 changes: 2 additions & 2 deletions cheroot/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def __len__(self):

@property
def connections(self):
"""Retrieve connections registered with the selector."""
"""Connections registered with the selector."""
with self._lock:
mapping = self._selector.get_map() or {}
for _, (_, sock_fd, _, conn) in mapping.items():
Expand Down Expand Up @@ -386,7 +386,7 @@ def close(self):

@property
def _num_connections(self):
"""Return the current number of connections.
"""The current number of connections.

Includes all connections registered with the selector,
minus one for the server socket, which is always registered
Expand Down
14 changes: 7 additions & 7 deletions cheroot/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1453,19 +1453,19 @@ def get_peer_creds(self): # LRU cached on per-instance basis, see __init__

@property
def peer_pid(self):
"""Return the id of the connected peer process."""
"""The id of the connected peer process."""
pid, _, _ = self.get_peer_creds()
return pid

@property
def peer_uid(self):
"""Return the user id of the connected peer process."""
"""The user id of the connected peer process."""
_, uid, _ = self.get_peer_creds()
return uid

@property
def peer_gid(self):
"""Return the group id of the connected peer process."""
"""The group id of the connected peer process."""
_, _, gid = self.get_peer_creds()
return gid

Expand Down Expand Up @@ -1495,13 +1495,13 @@ def resolve_peer_creds(self): # LRU cached on per-instance basis

@property
def peer_user(self):
"""Return the username of the connected peer process."""
"""The username of the connected peer process."""
user, _ = self.resolve_peer_creds()
return user

@property
def peer_group(self):
"""Return the group of the connected peer process."""
"""The group of the connected peer process."""
_, group = self.resolve_peer_creds()
return group

Expand Down Expand Up @@ -1750,7 +1750,7 @@ def __str__(self):

@property
def bind_addr(self):
"""Return the interface on which to listen for connections.
"""The interface on which to listen for connections.

For TCP sockets, a (host, port) tuple. Host values may be any
:term:`IPv4` or :term:`IPv6` address, or any valid hostname.
Expand Down Expand Up @@ -2234,7 +2234,7 @@ def interrupt(self):

@property
def _stopping_for_interrupt(self):
"""Return whether the server is responding to an interrupt."""
"""Whether the server is responding to an interrupt."""
return self._interrupt is _STOPPING_FOR_INTERRUPT

@interrupt.setter
Expand Down
26 changes: 6 additions & 20 deletions cheroot/test/_pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,11 @@ def pytest_load_initial_conftests(early_config, parser, args):
# * https://github.com/pytest-dev/pytest/issues/5299
early_config._inicache['filterwarnings'].extend(
(
'ignore:Exception in thread CP Server Thread-:'
'pytest.PytestUnhandledThreadExceptionWarning:_pytest.threadexception',
'ignore:Exception in thread Thread-:'
'pytest.PytestUnhandledThreadExceptionWarning:_pytest.threadexception',
'ignore:Exception ignored in. '
'<socket.socket fd=-1, family=AddressFamily.AF_INET, '
'type=SocketKind.SOCK_STREAM, proto=.:'
'pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception',
'ignore:Exception ignored in. '
'<socket.socket fd=-1, family=AddressFamily.AF_INET6, '
'type=SocketKind.SOCK_STREAM, proto=.:'
'pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception',
'ignore:Exception ignored in. '
'<socket.socket fd=-1, family=AF_INET, '
'type=SocketKind.SOCK_STREAM, proto=.:'
'pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception',
'ignore:Exception ignored in. '
'<socket.socket fd=-1, family=AF_INET6, '
'type=SocketKind.SOCK_STREAM, proto=.:'
'pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception',
'ignore:Exception in thread CP Server Thread-:pytest.PytestUnhandledThreadExceptionWarning:_pytest.threadexception', # noqa: LN001
'ignore:Exception in thread Thread-:pytest.PytestUnhandledThreadExceptionWarning:_pytest.threadexception', # noqa: LN001
'ignore:Exception ignored in. <socket.socket fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=.:pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception', # noqa: LN001
'ignore:Exception ignored in. <socket.socket fd=-1, family=AddressFamily.AF_INET6, type=SocketKind.SOCK_STREAM, proto=.:pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception', # noqa: LN001
'ignore:Exception ignored in. <socket.socket fd=-1, family=AF_INET, type=SocketKind.SOCK_STREAM, proto=.:pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception', # noqa: LN001
'ignore:Exception ignored in. <socket.socket fd=-1, family=AF_INET6, type=SocketKind.SOCK_STREAM, proto=.:pytest.PytestUnraisableExceptionWarning:_pytest.unraisableexception', # noqa: LN001
),
)
27 changes: 7 additions & 20 deletions cheroot/test/test_conn.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ def testing_server(raw_testing_server, monkeypatch):
continue

assert c_msg in raw_testing_server.error_log.ignored_msgs, (
'Found error in the error log: '
f"message = '{c_msg}', level = '{c_level}'\n"
f'{c_traceback}',
f"Found error in the error log: message = '{c_msg}', level = '{c_level}'\n{c_traceback}" # noqa: LN001
)


Expand Down Expand Up @@ -790,17 +788,11 @@ def _read_request_line(self):
(logging.WARNING, r'^socket\.error 666$'),
(
logging.INFO,
'^Got a connection error while handling a connection '
r'from .*:\d{1,5} \(666\)',
r'^Got a connection error while handling a connection from .*:\d{1,5} \(666\)', # noqa: LN001
),
(
logging.CRITICAL,
r'A fatal exception happened\. Setting the server interrupt flag '
r'to ConnectionResetError\(666,?\) and giving up\.\n\nPlease, '
'report this on the Cheroot tracker at '
r'<https://github\.com/cherrypy/cheroot/issues/new/choose>, '
'providing a full reproducer with as much context and details '
r'as possible\.$',
r'A fatal exception happened\. Setting the server interrupt flag to ConnectionResetError\(666,?\) and giving up\.\n\nPlease, report this on the Cheroot tracker at <https://github\.com/cherrypy/cheroot/issues/new/choose>, providing a full reproducer with as much context and details as possible\.$', # noqa: LN001
),
)

Expand Down Expand Up @@ -840,13 +832,11 @@ def _trigger_kb_intr(_req, _resp):
expected_log_entries = (
(
logging.DEBUG,
'^Got a server shutdown request while handling a connection '
r'from .*:\d{1,5} \(simulated test handler keyboard interrupt\)$',
r'^Got a server shutdown request while handling a connection from .*:\d{1,5} \(simulated test handler keyboard interrupt\)$', # noqa: LN001
),
(
logging.DEBUG,
'^Setting the server interrupt flag to KeyboardInterrupt'
r"\('simulated test handler keyboard interrupt',?\)$",
r"^Setting the server interrupt flag to KeyboardInterrupt\('simulated test handler keyboard interrupt',?\)$", # noqa: LN001
),
(
logging.INFO,
Expand Down Expand Up @@ -913,9 +903,7 @@ def _trigger_scary_exc(_req, _resp):
expected_log_entries = (
(
logging.ERROR,
'^Unhandled error while processing an incoming connection '
'SillyMistake'
r"\('simulated unhandled exception πŸ’£ in test handler',?\)$",
r"^Unhandled error while processing an incoming connection SillyMistake\('simulated unhandled exception πŸ’£ in test handler',?\)$", # noqa: LN001
),
(
logging.INFO,
Expand Down Expand Up @@ -997,8 +985,7 @@ def _read_request_line(self):
expected_log_entries = (
(
logging.ERROR,
'^Unhandled error while processing an incoming connection '
r'ScaryCrash\(666,?\)$',
r'^Unhandled error while processing an incoming connection ScaryCrash\(666,?\)$', # noqa: LN001
),
(
logging.INFO,
Expand Down
88 changes: 57 additions & 31 deletions cheroot/test/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,51 +480,75 @@ def test_tls_client_auth( # noqa: C901, WPS213 # FIXME
expected_substrings += (
(
"bad handshake: SysCallError(10054, 'WSAECONNRESET')",
"('Connection aborted.', "
'OSError("(10054, \'WSAECONNRESET\')"))',
"('Connection aborted.', "
'OSError("(10054, \'WSAECONNRESET\')",))',
"('Connection aborted.', "
'error("(10054, \'WSAECONNRESET\')",))',
"('Connection aborted.', "
'ConnectionResetError(10054, '
"'An existing connection was forcibly closed "
"by the remote host', None, 10054, None))",
"('Connection aborted.', "
'error(10054, '
"'An existing connection was forcibly closed "
"by the remote host'))",
(
"('Connection aborted.', "
'OSError("(10054, \'WSAECONNRESET\')"))'
),
(
"('Connection aborted.', "
'OSError("(10054, \'WSAECONNRESET\')",))'
),
(
"('Connection aborted.', "
'error("(10054, \'WSAECONNRESET\')",))'
),
(
"('Connection aborted.', "
'ConnectionResetError(10054, '
"'An existing connection was forcibly closed "
"by the remote host', None, 10054, None))"
),
(
"('Connection aborted.', "
'error(10054, '
"'An existing connection was forcibly closed "
"by the remote host'))"
),
)
if IS_WINDOWS
else (
"('Connection aborted.', "
'OSError("(104, \'ECONNRESET\')"))',
"('Connection aborted.', "
'OSError("(104, \'ECONNRESET\')",))',
(
"('Connection aborted.', "
'OSError("(104, \'ECONNRESET\')"))'
),
(
"('Connection aborted.', "
'OSError("(104, \'ECONNRESET\')",))'
),
"('Connection aborted.', error(\"(104, 'ECONNRESET')\",))",
"('Connection aborted.', "
"ConnectionResetError(104, 'Connection reset by peer'))",
"('Connection aborted.', "
"error(104, 'Connection reset by peer'))",
(
"('Connection aborted.', "
"ConnectionResetError(104, 'Connection reset by peer'))"
),
(
"('Connection aborted.', "
"error(104, 'Connection reset by peer'))"
),
)
if (IS_GITHUB_ACTIONS_WORKFLOW and IS_LINUX)
else (
"('Connection aborted.', "
"BrokenPipeError(32, 'Broken pipe'))",
(
"('Connection aborted.', "
"BrokenPipeError(32, 'Broken pipe'))"
),
)
)

if PY310_PLUS:
# FIXME: Figure out what's happening and correct the problem
expected_substrings += (
'SSLError(SSLEOFError(8, '
"'EOF occurred in violation of protocol (_ssl.c:",
(
'SSLError(SSLEOFError(8, '
"'EOF occurred in violation of protocol (_ssl.c:"
),
)
if IS_GITHUB_ACTIONS_WORKFLOW and IS_WINDOWS and PY310_PLUS:
expected_substrings += (
"('Connection aborted.', "
'RemoteDisconnected('
"'Remote end closed connection without response'))",
(
"('Connection aborted.', "
'RemoteDisconnected('
"'Remote end closed connection without response'))"
),
)

assert any(e in err_text for e in expected_substrings)
Expand Down Expand Up @@ -662,8 +686,10 @@ def test_ssl_env( # noqa: C901 # FIXME
pytest.xfail(
'\n'.join(
(
'Sometimes this test fails due to '
'a socket.socket ResourceWarning:',
(
'Sometimes this test fails due to '
'a socket.socket ResourceWarning:'
),
msg,
),
),
Expand Down
4 changes: 2 additions & 2 deletions cheroot/test/webtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class WebCase(unittest.TestCase):

@property
def _Conn(self):
"""Return HTTPConnection or HTTPSConnection based on self.scheme.
"""HTTPConnection or HTTPSConnection based on self.scheme.

* from :py:mod:`python:http.client`.
"""
Expand Down Expand Up @@ -305,7 +305,7 @@ def _handlewebError(self, msg): # noqa: C901 # FIXME
sys.stdout.flush()

@property
def status_code(self): # noqa: D401; irrelevant for properties
def status_code(self):
"""Integer HTTP status code."""
return int(self.status[:3])

Expand Down
6 changes: 3 additions & 3 deletions cheroot/workers/threadpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ def start(self):
self.grow(self.min)

@property
def idle(self): # noqa: D401; irrelevant for properties
"""Number of worker threads which are idle. Read-only.""" # noqa: D401
def idle(self):
"""Number of worker threads which are idle. Read-only."""
idles = len([t for t in self._threads if t.conn is None])
return max(idles - len(self._pending_shutdowns), 0)

Expand Down Expand Up @@ -432,5 +432,5 @@ def _clear_threads(self):

@property
def qsize(self):
"""Return the queue size."""
"""The queue size."""
return self._queue.qsize()
9 changes: 9 additions & 0 deletions docs/changelog-fragments.d/826.contrib.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Bumped Ruff to v0.15.18, which introduces new rules:
1. Property docstrings must now use noun phrases rather than verb phrases
(D421, e.g. "The queue size." not "Return the queue size."),
2. Implicit string concatenation inside collection literals must be
parenthesized (ISC004).
Three further new rules are suppressed pending fixes: too many statements
in a try clause (PLW0717), non-empty ``__init__`` modules (RUF067), and
starting a process with a partial executable path (S607)
-- by :user:`julianz-`.
Loading
Loading