diff --git a/services/webhook/new_pr_handler.py b/services/webhook/new_pr_handler.py index a3f82549..d6bec313 100644 --- a/services/webhook/new_pr_handler.py +++ b/services/webhook/new_pr_handler.py @@ -32,6 +32,7 @@ get_remote_file_content_by_url, ) from services.github.markdown.render_text import render_text +from services.github.pulls.close_pull_request import close_pull_request from services.github.pulls.get_pull_request_files import get_pull_request_files from services.github.trees.get_local_file_tree import get_local_file_tree from services.github.types.github_types import PrLabeledPayload @@ -62,6 +63,7 @@ from utils.pr_templates.schedule import SCHEDULE_PREFIX_INCREASE from utils.files.find_test_files import find_test_files from utils.files.is_config_file import is_config_file +from utils.files.should_skip_test import should_skip_test from utils.files.read_local_file import read_local_file from utils.files.is_test_file import is_test_file from utils.files.merge_test_file_headers import merge_test_file_headers @@ -325,6 +327,18 @@ async def handle_new_pr( base_args=base_args, ) + # Skip files with no testable code (e.g. __init__.py with only a docstring) + if should_skip_test(impl_file_path, impl_file_content): + msg = f"Closing PR: `{impl_file_path}` has no testable code (only docstrings, imports, constants, or type definitions)." + logger.info(msg) + add_log_message(msg, log_messages) + update_comment( + body=create_progress_bar(p=100, msg="\n".join(log_messages)), + base_args=base_args, + ) + close_pull_request(pr_number=base_args["pr_number"], base_args=base_args) + return + # Check if uncovered code is untestable (for schedule-triggered coverage issues) untestable_code_info: EvaluationResult | None = None coverage_dict = get_coverages(owner_id, repo_id, [impl_file_path]) diff --git a/utils/files/should_skip_python.py b/utils/files/should_skip_python.py index 59e61a89..374a17b7 100644 --- a/utils/files/should_skip_python.py +++ b/utils/files/should_skip_python.py @@ -46,8 +46,21 @@ def should_skip_python(content: str) -> bool: in_triple_quote_string = True continue # Handle module-level docstrings (standalone triple-quoted strings) - if line.strip() in ['"""', "'''"]: - triple_quote_type = line.strip() + # Single-line docstring: """text""" or '''text''' + for tq in ['"""', "'''"]: + if ( + line.startswith(tq) + and line.endswith(tq) + and len(line) > len(tq) + ): + break + else: + tq = None + if tq: + continue + # Multi-line docstring opening: bare """ or ''' + if line in ['"""', "'''"]: + triple_quote_type = line in_triple_quote_string = True continue else: