diff --git a/actions/__init__.py b/actions/__init__.py index 8eac7d9..4d208ea 100644 --- a/actions/__init__.py +++ b/actions/__init__.py @@ -28,4 +28,4 @@ # ├── test_summarize_pr.py # └── ... -__version__ = "0.2.19" +__version__ = "0.2.20" diff --git a/actions/format_python_docstrings.py b/actions/format_python_docstrings.py index 0568a51..96f8071 100644 --- a/actions/format_python_docstrings.py +++ b/actions/format_python_docstrings.py @@ -380,7 +380,8 @@ def format_docstring( single_ok = ("\n" not in text) and not has_section and not has_list if single_ok: words = text.split() - if words and not words[0].startswith(("http://", "https://")) and not words[0][0].isupper(): + core = words[0].rstrip(".") if words else "" # ignore terminal dots so only interior ones mark identifiers + if core.islower() and not any(c in core for c in "_./`("): words[0] = words[0][0].upper() + words[0][1:] out = " ".join(words) if out and out[-1] not in ".!?": diff --git a/tests/test_cli_commands.py b/tests/test_cli_commands.py index 529f1c4..b7478e8 100644 --- a/tests/test_cli_commands.py +++ b/tests/test_cli_commands.py @@ -26,3 +26,15 @@ def test_docstring_formatter_keeps_simple_docstrings_single_line(): text = "Make the live fp32 EMA genuinely non-finite while the model stays finite (sticky-NaN on a finite-loss run)." assert format_python_docstrings.format_docstring(text, 8, 120, '"""', "") == f'"""{text}"""' + + +def test_docstring_formatter_preserves_identifier_first_words(): + """Test that code identifiers, dotted names, and URLs are not capitalized as first words.""" + for text in ( + "process_mask/process_mask_native/scale_masks must handle 0 detections without crashing.", + "np.array inputs are converted to tensors.", + "https://ultralytics.com hosts the docs.", + "iOS builds are not supported.", + ): + assert format_python_docstrings.format_docstring(text, 8, 120, '"""', "") == f'"""{text}"""' + assert format_python_docstrings.format_docstring("done.", 8, 120, '"""', "") == '"""Done."""'