Skip to content

docs: add summary lines to 8 missing-value operation docstrings#4130

Open
TaiSakuma wants to merge 3 commits into
scikit-hep:mainfrom
TaiSakuma:docs-missing-value-docstrings
Open

docs: add summary lines to 8 missing-value operation docstrings#4130
TaiSakuma wants to merge 3 commits into
scikit-hep:mainfrom
TaiSakuma:docs-missing-value-docstrings

Conversation

@TaiSakuma

Copy link
Copy Markdown
Member

Summary

Rolls the pilot from #3946 out to the 8 operations in the Missing-value batch of #3980:

fill_none, drop_none, is_none, firsts, singletons, mask, nan_to_none, nan_to_num.

Each docstring now has:

  • A one-line summary on the opening """.
  • Returns: and Examples: section headers (the latter only where examples exist).

Original body text is preserved; only structural edits are applied. The summary lines were reviewed against the checklist posted in #3980.

Summary lines

Operation Summary
ak.fill_none Replaces missing values (None) with a given value.
ak.drop_none Removes missing values (None) from a given array.
ak.is_none Returns True where an element is None at a given axis depth, False otherwise.
ak.firsts Returns the first element of each list, or None for each empty list.
ak.singletons Wraps each value in a length-1 list, or an empty list for each missing value.
ak.mask Returns an array with elements replaced by None where a mask condition fails.
ak.nan_to_none Converts NaN values in floating-point arrays to None.
ak.nan_to_num Replaces NaN and infinite values with finite numbers in floating-point arrays.

Notes for reviewers

  • ak.mask's summary compresses the valid_when semantics to "where a mask condition fails"; the exact output[i] = array[i] if mask[i] == valid_when else None formula is preserved verbatim in the body.
  • ak.nan_to_none's summary adds "in floating-point arrays" — the implementation only converts floating-point data, which the original text did not state.
  • ak.firsts/ak.singletons are phrased as a near-inverse pair.

Test plan

  • pre-commit passes locally on the modified files (ruff check, ruff format, codespell, mypy).
  • Mechanical validation: code outside docstrings byte-identical; Args: blocks and doctests byte-identical; no original narrative text lost.
  • Sphinx docs build cleanly on CI.
  • Rendered docstrings spot-checked in the docs preview.

Part of #3980. Draft for initial review; will mark ready once CI passes and the preview is checked.

AI assistance disclosure

Drafted with Claude Code: summaries drafted by Claude Sonnet 4.6, adversarially verified against the implementations by independent Claude Opus 4.8 agents, mechanically validated (docstring-only changes, original text preserved), and reviewed by a human before submission.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

@github-actions github-actions Bot added the type/docs PR title type: docs (set automatically) label Jun 12, 2026
Comment thread src/awkward/operations/ak_drop_none.py Outdated
Comment on lines +45 to +46
Returns:
Removes missing values (None) from a given array.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should describe the object it returns. Like "Returns: an array....". This type of docstring where under "Returns:" is a sentence that describes the operation and not the object it returns is not nice and it already exists in a number of docstrings from #3986

@ikrommyd ikrommyd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Returns:" statement should always describe the object it returns and not be be a statement that describes the operation which is often identical or very similar to the summary line. You need to make sure that this is the case in all such open docs PRs and there a couple of cases where this needs fixing already in main.

@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.74%. Comparing base (722a1b9) to head (3ea099d).
⚠️ Report is 17 commits behind head on main.

Additional details and impacted files
Files with missing lines Coverage Δ
src/awkward/operations/ak_drop_none.py 100.00% <ø> (ø)
src/awkward/operations/ak_fill_none.py 97.56% <ø> (ø)
src/awkward/operations/ak_firsts.py 97.72% <ø> (ø)
src/awkward/operations/ak_is_none.py 100.00% <ø> (ø)
src/awkward/operations/ak_mask.py 96.77% <ø> (ø)
src/awkward/operations/ak_nan_to_none.py 95.83% <ø> (ø)
src/awkward/operations/ak_nan_to_num.py 98.38% <ø> (ø)
src/awkward/operations/ak_singletons.py 97.29% <ø> (ø)

@TaiSakuma

Copy link
Copy Markdown
Member Author

Follow-up per @ikrommyd's review on #4130: the Returns: sections now describe the returned object (a noun phrase) rather than restating the operation. Final Returns: lines for this batch:

Returns

Operation Returns
ak.fill_none An array with each missing value (None) replaced by value.
ak.drop_none An array with missing values (None) removed.
ak.is_none An array whose value is True where an element of array is None; False otherwise (at a given axis depth).
ak.firsts An array of the first element of each non-empty list, with None for each empty list.
ak.singletons A singleton list (length 1) wrapping each non-missing value and an empty list (length 0) in place of each missing value.
ak.mask An array for which output[i] = array[i] if mask[i] == valid_when else None.
ak.nan_to_none An array with NaN ("not a number") converted to None, i.e. missing values with option-type.
ak.nan_to_num An array with NaN ("not a number") or infinity replaced by the specified finite values, following np.nan_to_num for Awkward Arrays.

@ikrommyd ikrommyd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll keep commenting here but it applies to all similar PRs. I think what we want for "Returns" is a similar to "Args" right above. A very short description that also includes the type of the output.
The longer description of what it actually does and returns can go below in the longer description with examples and not in the "Returns" block.

@TaiSakuma

Copy link
Copy Markdown
Member Author

@ikrommyd, thank you for your comments.

  • I don't think "Returns" needs to be short. At least the Google-style docstring doesn't seem to require a short description.
  • The return type should be optional when the function signature has a type hint on the return type. But since Add typing to all public API #3849 is still open, the "Returns" field should probably specify a type.

I'll have Claude Code research on these two points.

@ikrommyd

Copy link
Copy Markdown
Member

The style definitely does not require it to be short. I’m just commenting on what’s actually happening in packages out there and what people generally want. The return statement in the docstring has the same purpose as the args statements. It has to be concise. And in the same way args specify types, returns needs to say “ak.Array” or “tuple of arrays” or whatever.

@TaiSakuma

Copy link
Copy Markdown
Member Author

Researched and written by Claude Code (Claude Opus 4.8), at @TaiSakuma's request.

Research on the two points, with citations.

1. Returns: does not need to be short. No major Python docstring convention imposes a length limit on the return description.

  • Sphinx Napoleon — which this repo renders with (docs/conf.py: sphinx.ext.napoleon, napoleon_google_docstring = True) — states: "The Returns section may span multiple lines and paragraphs." Its canonical Google example even puts a literal block inside Returns:. (example_google.py)
  • Google Python Style Guide §3.8.3: the Returns: section should "Describe the semantics of the return value…" — a completeness criterion, with no requirement to be short. (pyguide §3.8.3)
  • PEP 257: "The docstring for a function or method should summarize its behavior and document its arguments, return value(s), side effects…" — no brevity rule. (PEP 257)

2. The return type in Returns: is redundant only once a type annotation provides it — but until then it should be stated. Google §3.8.3:

Args: "The description should include required type(s) if the code does not contain a corresponding type annotation."
Returns: "Describe the semantics of the return value, including any type information that the type annotation does not provide."

So the rule cuts both ways: with a -> T annotation, repeating the type in the docstring is redundant; without one, the docstring is where the type should live. Today only ~9 of the 124 operations/ modules carry a return annotation, and adding them across the public API is the separate, still-open effort in #3849. So specifying the type in Returns: is the right call for now, and can be dropped per the Google rule once #3849 lands. (One wrinkle #3849 will have to resolve: these high-level functions are polymorphic — highlevel=Trueak.Array/ak.Record, highlevel=Falseak.contents.Content, reducers → a scalar.)


🤖 Researched and written with Claude Code

@ikrommyd

Copy link
Copy Markdown
Member

Whether the code contains type annotations does not matter at all. When one is reading a documentation page, they don't have to be in an IDE at the same time nor do they even need to have an IDE that shows the annotations in general. Take every function in the numpy docs. All the inputs and outputs of a function show the types and they are described concisely. Of course there is no hard requirement on the length of docstrings that is enforced. But nobody wants to read paragraphs to understand an argument or the return value of a function.

@TaiSakuma

Copy link
Copy Markdown
Member Author

@ikrommyd - Issue comment #3980 (comment) has a checklist for Returns fields. AI generates Returns based on this checklist and also reviews them against it. Any comments on the checklist?

@ianna

ianna commented Jun 22, 2026

Copy link
Copy Markdown
Member

Whether the code contains type annotations does not matter at all. When one is reading a documentation page, they don't have to be in an IDE at the same time nor do they even need to have an IDE that shows the annotations in general. Take every function in the numpy docs. All the inputs and outputs of a function show the types and they are described concisely. Of course there is no hard requirement on the length of docstrings that is enforced. But nobody wants to read paragraphs to understand an argument or the return value of a function.

We have to keep in mind that we are annotating it for AI as well. We need as detailed and as precise description.

TaiSakuma and others added 3 commits June 30, 2026 18:38
Add a Google-style one-line summary and `Returns:`/`Examples:` section
headers to the 8 missing-value operations in `src/awkward/operations/`:
fill_none, drop_none, is_none, firsts, singletons, mask, nan_to_none,
nan_to_num.

Follows the pilot in scikit-hep#3946 on `ak.flatten`. Original body text is
preserved; only structural edits are applied.

Refs scikit-hep#3980.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…#3980.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion. Refs scikit-hep#3980.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@TaiSakuma TaiSakuma force-pushed the docs-missing-value-docstrings branch from 5cd2feb to 3ea099d Compare June 30, 2026 22:41
@TaiSakuma TaiSakuma marked this pull request as ready for review June 30, 2026 22:54
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

The documentation preview is ready to be viewed at http://preview.awkward-array.org.s3-website.us-east-1.amazonaws.com/PR4130

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/docs PR title type: docs (set automatically)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants