Repository: mkdocstrings/griffe

Issue:
bug: two issues with parsing Google-style Deprecated sections
### Description of the bug (1 of 2)

 1. [Griffe claims to specifically support "Deprecated" sections in Google-style docstrings](https://mkdocstrings.github.io/griffe/reference/docstrings/#google-section-deprecated), but actually parses them as general admonitions.  (See the "To Reproduce" section below.)  The parsing code is there, but it isn't being triggered, because "deprecated" is not recognized as a section name: it is missing from the table of known section names.

    https://github.com/mkdocstrings/griffe/blob/a2f320fd4138a0a6697376509d625b9ec6e0797b/src/_griffe/docstrings/google.py#L48-L72

    ~I'm preparing a PR to address this.~ PR #353 addresses this issue.

### To Reproduce (1 of 2)

Using `mkdocstrings-python` 1.13.0 (with MkDocs 1.6.1 and `mkdocs-material` 9.5.49) and `griffe` 1.5.4, the following Python function

```` python
def griffe_bug() -> None:
    """bla bla bla

    Deprecated:
        Since v1.0: Insecure! Do not use!
    """
````

renders as

![(an admonition)](https://github.com/user-attachments/assets/3ac9316d-e765-4186-9780-66abe9312b81)

Changing the section heading to `DeprecatedABC` changes the rendered admonition heading to "DeprecatedABC", confirming that this is indeed parsed as an admonition.

The tests in #353 confirm this suspicion as well.

### Description of the bug (2 of 2)

If point (1) is fixed by adding the "deprecated" entry into the recognized section names table, then Griffe will assume the section contents are of the form `version: text`, and will attempt to partition the contents in this manner.  If this fails, then Griffe will issue a warning, and then **silently drop the entire section**.  This is because the parsing code, upon failing to partition the section text, returns `None` instead of a `DocstringSection` object (L711).

https://github.com/mkdocstrings/griffe/blob/a2f320fd4138a0a6697376509d625b9ec6e0797b/src/_griffe/docstrings/google.py#L706-L719

### To Reproduce (2 of 2)

This is only confirmed via the tests in #353.  No published version of Griffe exhibits this behavior yet.

### Expected behavior

Griffe should parse these sections as Deprecated sections, not as admonitions.  `mkdocstrings-python` should render them not as default admonitions, but as specific ones (perhaps similar to how griffe-deprecations renders them).

Griffe should not drop docstring sections it cannot properly parse, it should *always* pass them on.

### Environment information

Debian Linux "testing", Python 3.12. See reproduction \#1 above for Griffe and `mkdocs*` versions.

### Additional context

(none)

Discussion:
@pawamoy: Awesome report @the-13th-letter, thank you very much 🙂 I agree with everything. I'll review your PR now!

Solution patch:
diff --git a/src/_griffe/docstrings/google.py b/src/_griffe/docstrings/google.py
index f99c0a4..daa10df 100644
--- a/src/_griffe/docstrings/google.py
+++ b/src/_griffe/docstrings/google.py
@@ -69,6 +69,7 @@ _section_kind = {
     "modules": DocstringSectionKind.modules,
     "warns": DocstringSectionKind.warns,
     "warnings": DocstringSectionKind.warns,
+    "deprecated": DocstringSectionKind.deprecated,
 }
 
 _BlockItem = tuple[int, list[str]]
@@ -705,8 +706,7 @@ def _read_deprecated_section(
     try:
         version, text = text.split(":", 1)
     except ValueError:
-        docstring_warning(docstring, new_offset, f"Could not parse version, text at line {offset}")
-        return None, new_offset
+        version = ""
 
     version = version.lstrip()
     description = text.lstrip()


Test patch:
diff --git a/tests/test_docstrings/test_google.py b/tests/test_docstrings/test_google.py
index 15037b2..083acf6 100644
--- a/tests/test_docstrings/test_google.py
+++ b/tests/test_docstrings/test_google.py
@@ -525,6 +525,28 @@ def test_parse_yields_section(parse_google: ParserType) -> None:
     assert "'x'" in warnings[0]
 
 
+def test_parse_deprecated_section(parse_google: ParserType) -> None:
+    """Parse Deprecated section.
+
+    See [`mkdocstrings/griffe#352`](https://github.com/mkdocstrings/griffe/issues/352)
+    for context.
+
+    Parameters:
+        parse_google: Fixture parser.
+    """
+    docstring = """
+        Deprecated:
+            1.0: This function is deprecated.
+    """
+    sections, warnings = parse_google(docstring)
+    assert len(sections) == 1
+    deprecated = sections[0]
+    assert deprecated.kind is DocstringSectionKind.deprecated
+    assert deprecated.value.version == "1.0"
+    assert deprecated.value.description == "This function is deprecated."
+    assert not warnings
+
+
 def test_invalid_sections(parse_google: ParserType) -> None:
     """Warn on invalid sections.
 
@@ -1131,6 +1153,60 @@ def test_parse_returns_tuple_in_generator(parse_google: ParserType) -> None:
     assert returns[1].annotation.name == "float"
 
 
+# =============================================================================================
+# Deprecated sections
+
+
+def test_parse_deprecated_section_missing_version(parse_google: ParserType) -> None:
+    """Parse version numbers in Deprecated sections that aren't numbers.
+
+    See [`mkdocstrings/griffe#352`](https://github.com/mkdocstrings/griffe/issues/352)
+    for context.
+
+    Parameters:
+        parse_google: Fixture parser.
+    """
+    docstring = """
+        Summary.
+
+        Deprecated:
+            Since "Dapper Drake": This function is deprecated.
+    """
+    sections, warnings = parse_google(docstring)
+    assert len(sections) == 2
+    deprecated = sections[1]
+    assert deprecated.kind is DocstringSectionKind.deprecated
+    assert deprecated.value.version == 'Since "Dapper Drake"'
+    assert deprecated.value.description == "This function is deprecated."
+    assert not warnings
+
+
+def test_dont_warn_about_missing_deprecated_version(parse_google: ParserType) -> None:
+    """Don't warn about missing version info in Deprecated sections.
+
+    Also assert that we don't just swallow the section, but actually parse it.
+
+    See [`mkdocstrings/griffe#352`](https://github.com/mkdocstrings/griffe/issues/352)
+    for context.
+
+    Parameters:
+        parse_google: Fixture parser.
+    """
+    docstring = """
+        Summary.
+
+        Deprecated:
+            This function is deprecated since v0.9alpha1.
+    """
+    sections, warnings = parse_google(docstring)
+    assert len(sections) == 2
+    deprecated = sections[1]
+    assert deprecated.kind is DocstringSectionKind.deprecated
+    assert not deprecated.value.version
+    assert deprecated.value.description == "This function is deprecated since v0.9alpha1."
+    assert not warnings
+
+
 # =============================================================================================
 # Parser special features
 def test_parse_admonitions(parse_google: ParserType) -> None: