Skip to content

Commit 8dda983

Browse files
HamzaSardarHamza Sardar
andauthored
Enable DOC201 check and fix existing violations (#203)
* Add docstring check for DOC201 Added check to pyproject.toml, and fixed 46 docstrings where DOC201 was flagged. Implements: #159 * Update pyproject to pass pre-commit. Previous change for #159 added `preview = true` to pyproject.toml, which added unstable preview rules. Fixed this by adding `explicit-preview-rules = true`. * Update pyproject.toml to move explicit-preview-rules to ruff.lint. --------- Co-authored-by: Hamza Sardar <[email protected]>
1 parent af7a6a2 commit 8dda983

File tree

26 files changed

+243
-61
lines changed

26 files changed

+243
-61
lines changed

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ indent-width = 4
7979

8080
target-version = "py312"
8181
force-exclude = true
82+
preview = true
8283

8384
[tool.ruff.lint]
8485
select = [
@@ -96,15 +97,17 @@ select = [
9697
"PLE", # ruff currently implements only a subset of pylint's rules
9798
"PLW", # pylint warning
9899
"PLR", # pylint refactor
99-
"UP", # pyupgrade
100-
"C", # Complexity (mccabe+) & comprehensions
100+
"UP", # pyupgrade
101+
"C", # Complexity (mccabe+) & comprehensions
102+
"DOC201", # pydoclint: return value must be documented
101103
]
102104
ignore = [
103105
"UP006", # See https://github.com/bokeh/bokeh/issues/13143
104106
"UP007", # See https://github.com/bokeh/bokeh/pull/13144
105107
"PLC0415", # Allow imports inside functions (useful for optional deps)
106108
"PLR2004", # Allow magic values in comparisons (array indices etc.)
107109
]
110+
explicit-preview-rules = true
108111

109112
[tool.ruff.format]
110113
# Like Black, use double quotes for strings.

src/sre_agent/cli/configuration/wizard.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ def _configure_model_provider(
189189
updates: dict[str, str],
190190
allow_back: bool = False,
191191
) -> str:
192-
"""Prompt for model provider and required credentials."""
192+
"""Prompt for model provider and required credentials.
193+
194+
Returns:
195+
The selected model provider name.
196+
"""
193197
model_provider = _prompt_choice(
194198
"Model provider:",
195199
config.integrations.model_provider,
@@ -215,7 +219,11 @@ def _configure_notification_platform(
215219
updates: dict[str, str],
216220
allow_back: bool = False,
217221
) -> tuple[str, str | None]:
218-
"""Prompt for notification platform and required credentials."""
222+
"""Prompt for notification platform and required credentials.
223+
224+
Returns:
225+
A tuple of (notification_platform, slack_channel_id).
226+
"""
219227
notification_platform = _prompt_choice(
220228
"Messaging/notification platform:",
221229
config.integrations.notification_platform,
@@ -248,7 +256,11 @@ def _configure_code_repository_provider(
248256
updates: dict[str, str],
249257
allow_back: bool = False,
250258
) -> tuple[str, str | None, str | None, str | None]:
251-
"""Prompt for code repository provider and required credentials."""
259+
"""Prompt for code repository provider and required credentials.
260+
261+
Returns:
262+
A tuple of (code_repository_provider, github_owner, github_repo, github_ref).
263+
"""
252264
code_repository_provider = _prompt_choice(
253265
"Remote code repository:",
254266
config.integrations.code_repository_provider,
@@ -299,7 +311,11 @@ def _configure_deployment_platform(
299311
updates: dict[str, str],
300312
allow_back: bool = False,
301313
) -> tuple[str, str]:
302-
"""Prompt for deployment platform, logging platform, and AWS credentials."""
314+
"""Prompt for deployment platform, logging platform, and AWS credentials.
315+
316+
Returns:
317+
A tuple of (deployment_platform, logging_platform).
318+
"""
303319
deployment_platform = _prompt_choice(
304320
"Which platform is your application deployed on?",
305321
config.integrations.deployment_platform,

src/sre_agent/cli/presentation/banner.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ def _print_animated_banner() -> None:
3939

4040

4141
def _build_banner(colour_offset: int) -> Panel:
42-
"""Build the banner panel with a shifted colour palette."""
42+
"""Build the banner panel with a shifted colour palette.
43+
44+
Returns:
45+
A Rich Panel containing the styled ASCII art banner.
46+
"""
4347
ascii_art = get_ascii_art().strip("\n")
4448
# spellchecker:ignore-next-line
4549
banner_text = Text(justify="center")

src/sre_agent/cli/presentation/styles.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,20 @@
44
import questionary.constants as questionary_constants
55
import questionary.styles as questionary_styles
66

7-
QUESTIONARY_STYLE = questionary.Style(
8-
[
9-
("qmark", "fg:#7C3AED"),
10-
("question", "fg:#e0e0e0 bold"),
11-
("answer", "fg:#5EEAD4 bold"),
12-
("search_success", "noinherit fg:#00FF00 bold"),
13-
("search_none", "noinherit fg:#FF0000 bold"),
14-
("pointer", "fg:#e0e0e0"),
15-
("highlighted", "fg:#f2f2f2"),
16-
("selected", "fg:#e0e0e0"),
17-
("separator", "fg:#e0e0e0"),
18-
("instruction", "fg:#e0e0e0"),
19-
("text", "fg:#e0e0e0"),
20-
("disabled", "fg:#bdbdbd italic"),
21-
]
22-
)
7+
QUESTIONARY_STYLE = questionary.Style([
8+
("qmark", "fg:#7C3AED"),
9+
("question", "fg:#e0e0e0 bold"),
10+
("answer", "fg:#5EEAD4 bold"),
11+
("search_success", "noinherit fg:#00FF00 bold"),
12+
("search_none", "noinherit fg:#FF0000 bold"),
13+
("pointer", "fg:#e0e0e0"),
14+
("highlighted", "fg:#f2f2f2"),
15+
("selected", "fg:#e0e0e0"),
16+
("separator", "fg:#e0e0e0"),
17+
("instruction", "fg:#e0e0e0"),
18+
("text", "fg:#e0e0e0"),
19+
("disabled", "fg:#bdbdbd italic"),
20+
])
2321

2422

2523
def apply_questionary_style() -> None:

src/sre_agent/core/deployments/aws_ecs/cleanup.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,11 @@ def _wait_for_nat_gateways(ec2: Any, nat_ids: list[str], reporter: Callable[[str
278278

279279

280280
def _list_internet_gateways(ec2: Any, vpc_id: str) -> list[str]:
281-
"""List internet gateways attached to a VPC."""
281+
"""List internet gateways attached to a VPC.
282+
283+
Returns:
284+
A list of internet gateway IDs attached to the VPC.
285+
"""
282286
response = ec2.describe_internet_gateways(
283287
Filters=[{"Name": "attachment.vpc-id", "Values": [vpc_id]}]
284288
)

src/sre_agent/core/deployments/aws_ecs/ecr.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77

88

99
def ensure_repository(session: Session, name: str) -> str:
10-
"""Ensure an ECR repository exists and return its URI."""
10+
"""Ensure an ECR repository exists and return its URI.
11+
12+
Returns:
13+
The URI of the ECR repository.
14+
"""
1115
ecr = session.client("ecr")
1216
try:
1317
response = ecr.describe_repositories(repositoryNames=[name])

src/sre_agent/core/deployments/aws_ecs/ecs_tasks.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ def register_task_definition(
2929
config: EcsDeploymentConfig,
3030
reporter: Callable[[str], None],
3131
) -> str:
32-
"""Register the ECS task definition."""
32+
"""Register the ECS task definition.
33+
34+
Returns:
35+
The ARN of the registered task definition.
36+
"""
3337
cpu_architecture = _normalise_cpu_architecture(config.task_cpu_architecture)
3438
if not config.exec_role_arn or not config.task_role_arn:
3539
raise RuntimeError("Task roles must be created before registering the task definition.")
@@ -134,7 +138,11 @@ def _normalise_cpu_architecture(value: str) -> str:
134138

135139

136140
def ensure_cluster(session: Session, cluster_name: str) -> str:
137-
"""Ensure an ECS cluster exists."""
141+
"""Ensure an ECS cluster exists.
142+
143+
Returns:
144+
The ARN of the ECS cluster.
145+
"""
138146
ecs = session.client("ecs")
139147
response = ecs.describe_clusters(clusters=[cluster_name])
140148
clusters = response.get("clusters", [])
@@ -159,7 +167,11 @@ def run_task(
159167
config: EcsDeploymentConfig,
160168
container_overrides: list[dict[str, Any]] | None = None,
161169
) -> str:
162-
"""Run a one-off ECS task."""
170+
"""Run a one-off ECS task.
171+
172+
Returns:
173+
The ARN of the launched ECS task.
174+
"""
163175
if not config.task_definition_arn:
164176
raise RuntimeError("Task definition is missing. Register it before running tasks.")
165177
if not config.security_group_id or not config.private_subnet_ids:
@@ -209,7 +221,11 @@ def wait_for_task_completion(
209221
timeout_seconds: int = 1800,
210222
poll_interval_seconds: int = 5,
211223
) -> tuple[bool, str]:
212-
"""Wait for a task to stop and report container exit status."""
224+
"""Wait for a task to stop and report container exit status.
225+
226+
Returns:
227+
A tuple of (success, message) indicating the task outcome.
228+
"""
213229
ecs = session.client("ecs")
214230
deadline = time.time() + timeout_seconds
215231

@@ -232,7 +248,11 @@ def wait_for_task_completion(
232248

233249

234250
def _task_completion_result(task: dict[str, Any]) -> tuple[bool, str]:
235-
"""Convert ECS task details into a completion result."""
251+
"""Convert ECS task details into a completion result.
252+
253+
Returns:
254+
A tuple of (success, message) indicating the task outcome.
255+
"""
236256
target = _find_container(task.get("containers", []), SRE_AGENT_CONTAINER_NAME)
237257
if target is None:
238258
stopped_reason = str(task.get("stoppedReason", "task stopped"))

src/sre_agent/core/deployments/aws_ecs/iam.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ def ensure_roles(
1515
secret_arns: list[str],
1616
reporter: Callable[[str], None],
1717
) -> tuple[str, str]:
18-
"""Ensure execution and task roles exist."""
18+
"""Ensure execution and task roles exist.
19+
20+
Returns:
21+
A tuple of (exec_role_arn, task_role_arn).
22+
"""
1923
if not secret_arns:
2024
raise RuntimeError("Secret ARNs are required before creating roles.")
2125

@@ -71,7 +75,11 @@ def ensure_service_linked_role(session: Session, reporter: Callable[[str], None]
7175

7276

7377
def _ensure_role(iam: Any, role_name: str, trust_policy: dict[str, Any]) -> str:
74-
"""Create a role if needed and return its ARN."""
78+
"""Create a role if needed and return its ARN.
79+
80+
Returns:
81+
The ARN of the IAM role.
82+
"""
7583
try:
7684
response = iam.get_role(RoleName=role_name)
7785
return cast(str, response["Role"]["Arn"])
@@ -125,7 +133,11 @@ def _ecs_trust_policy() -> dict[str, Any]:
125133

126134

127135
def _secrets_policy(secret_arns: list[str]) -> dict[str, Any]:
128-
"""Allow read access to Secrets Manager."""
136+
"""Allow read access to Secrets Manager.
137+
138+
Returns:
139+
An IAM policy document granting read access to the given secrets.
140+
"""
129141
return {
130142
"Version": "2012-10-17",
131143
"Statement": [
@@ -139,7 +151,11 @@ def _secrets_policy(secret_arns: list[str]) -> dict[str, Any]:
139151

140152

141153
def _logs_policy(region: str, account_id: str) -> dict[str, Any]:
142-
"""Allow CloudWatch Logs queries."""
154+
"""Allow CloudWatch Logs queries.
155+
156+
Returns:
157+
An IAM policy document granting CloudWatch Logs query access.
158+
"""
143159
return {
144160
"Version": "2012-10-17",
145161
"Statement": [

src/sre_agent/core/deployments/aws_ecs/images.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ def build_and_push_images(
2828
image_config: ImageBuildConfig,
2929
reporter: Callable[[str], None],
3030
) -> str:
31-
"""Build and push container images to ECR."""
31+
"""Build and push container images to ECR.
32+
33+
Returns:
34+
The ECS runtime CPU architecture used for the build.
35+
"""
3236
_require_docker()
3337

3438
reporter("Authenticating Docker with ECR")

src/sre_agent/core/deployments/aws_ecs/network.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ def create_basic_vpc(
1313
project_name: str,
1414
reporter: Callable[[str], None],
1515
) -> NetworkSelection:
16-
"""Create a simple VPC with one public and one private subnet."""
16+
"""Create a simple VPC with one public and one private subnet.
17+
18+
Returns:
19+
A NetworkSelection containing the VPC ID and private subnet IDs.
20+
"""
1721
ec2 = session.client("ec2")
1822

1923
reporter("Creating VPC (private networking foundation)")
@@ -91,7 +95,11 @@ def _tag_resource(ec2: Any, resource_id: str, name: str) -> None:
9195

9296

9397
def _first_availability_zone(ec2: Any) -> str:
94-
"""Fetch the first availability zone."""
98+
"""Fetch the first availability zone.
99+
100+
Returns:
101+
The name of the first available availability zone.
102+
"""
95103
response = ec2.describe_availability_zones()
96104
zones = response.get("AvailabilityZones", [])
97105
if not zones:

0 commit comments

Comments
 (0)