format-docstring 0.2.5__tar.gz → 0.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. {format_docstring-0.2.5 → format_docstring-0.2.6}/CHANGELOG.md +13 -0
  2. {format_docstring-0.2.5 → format_docstring-0.2.6}/PKG-INFO +1 -1
  3. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/docstring_rewriter.py +9 -2
  4. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/line_wrap_numpy.py +39 -12
  5. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring.egg-info/PKG-INFO +1 -1
  6. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring.egg-info/SOURCES.txt +3 -0
  7. {format_docstring-0.2.5 → format_docstring-0.2.6}/pyproject.toml +1 -1
  8. format_docstring-0.2.6/tests/test_data/end_to_end/numpy/rST_cross_reference.txt +72 -0
  9. format_docstring-0.2.6/tests/test_data/end_to_end/numpy/variadic_signature_without_colon.txt +58 -0
  10. format_docstring-0.2.6/tests/test_data/line_wrap/numpy/variadic_signature_without_colon.txt +38 -0
  11. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_docstring_rewriter.py +52 -4
  12. {format_docstring-0.2.5 → format_docstring-0.2.6}/.github/workflows/python-package.yml +0 -0
  13. {format_docstring-0.2.5 → format_docstring-0.2.6}/.github/workflows/python-publish.yml +0 -0
  14. {format_docstring-0.2.5 → format_docstring-0.2.6}/.gitignore +0 -0
  15. {format_docstring-0.2.5 → format_docstring-0.2.6}/.pre-commit-config.yaml +0 -0
  16. {format_docstring-0.2.5 → format_docstring-0.2.6}/.pre-commit-hooks.yaml +0 -0
  17. {format_docstring-0.2.5 → format_docstring-0.2.6}/AGENTS.md +0 -0
  18. {format_docstring-0.2.5 → format_docstring-0.2.6}/LICENSE +0 -0
  19. {format_docstring-0.2.5 → format_docstring-0.2.6}/README.md +0 -0
  20. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/__init__.py +0 -0
  21. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/base_fixer.py +0 -0
  22. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/config.py +0 -0
  23. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/line_wrap_google.py +0 -0
  24. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/line_wrap_utils.py +0 -0
  25. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/main_jupyter.py +0 -0
  26. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring/main_py.py +0 -0
  27. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring.egg-info/dependency_links.txt +0 -0
  28. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring.egg-info/entry_points.txt +0 -0
  29. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring.egg-info/requires.txt +0 -0
  30. {format_docstring-0.2.5 → format_docstring-0.2.6}/format_docstring.egg-info/top_level.txt +0 -0
  31. {format_docstring-0.2.5 → format_docstring-0.2.6}/muff.toml +0 -0
  32. {format_docstring-0.2.5 → format_docstring-0.2.6}/requirements.dev +0 -0
  33. {format_docstring-0.2.5 → format_docstring-0.2.6}/setup.cfg +0 -0
  34. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/__init__.py +0 -0
  35. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/helpers.py +0 -0
  36. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_base_fixer.py +0 -0
  37. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_config.py +0 -0
  38. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/README.md +0 -0
  39. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/arg_name_is_default.txt +0 -0
  40. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/colon_spacing_fix.txt +0 -0
  41. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/contents_that_are_not_wrapped.txt +0 -0
  42. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/default_value_standardization.txt +0 -0
  43. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/empty_lines_are_respected.txt +0 -0
  44. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/examples_section.txt +0 -0
  45. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
  46. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/fix_rst_backticks.txt +0 -0
  47. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/four_level_nested_classes.txt +0 -0
  48. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
  49. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/indent_misaligned_all.txt +0 -0
  50. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/indent_two_levels_8_spaces.txt +0 -0
  51. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/line_length_2.txt +0 -0
  52. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/mismatched_underlines.txt +0 -0
  53. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/mismatched_underlines_one_dash.txt +0 -0
  54. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/mismatched_underlines_two_dashes.txt +0 -0
  55. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/module_level_docstring.txt +0 -0
  56. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/new_lines_before_and_after.txt +0 -0
  57. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/no_format_docstring_comment.txt +0 -0
  58. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/param_signature_without_type.txt +0 -0
  59. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/parameters_returns_raises_wrapping.txt +0 -0
  60. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/returns_signature_and_description.txt +0 -0
  61. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/section_headings_with_colons.txt +0 -0
  62. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/section_title_fixed.txt +0 -0
  63. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/sections_notes_examples.txt +0 -0
  64. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/signature_dont_sync_raises.txt +0 -0
  65. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/signature_line_is_not_wrapped.txt +0 -0
  66. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/signature_sync_class_docstrings.txt +0 -0
  67. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/signature_sync_parameters.txt +0 -0
  68. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/signature_sync_returns.txt +0 -0
  69. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/signature_sync_yields.txt +0 -0
  70. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/single_line_docstring.txt +0 -0
  71. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/texts_are_rewrapped.txt +0 -0
  72. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/end_to_end/numpy/very_long_unbreakable_word.txt +0 -0
  73. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/integration_test/numpy/after.ipynb +0 -0
  74. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/integration_test/numpy/after.py +0 -0
  75. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/integration_test/numpy/after_50.ipynb +0 -0
  76. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/integration_test/numpy/after_50.py +0 -0
  77. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/integration_test/numpy/before.ipynb +0 -0
  78. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/integration_test/numpy/before.py +0 -0
  79. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/jupyter/before.ipynb +0 -0
  80. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/jupyter/verbose_before.ipynb +0 -0
  81. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/README.md +0 -0
  82. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/colon_spacing_fix.txt +0 -0
  83. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/contents_that_are_not_wrapped.txt +0 -0
  84. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/default_value_standardization.txt +0 -0
  85. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/empty_lines_are_respected.txt +0 -0
  86. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/examples_section.txt +0 -0
  87. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
  88. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/fix_rst_backticks.txt +0 -0
  89. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
  90. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/indent_two_levels_8_spaces.txt +0 -0
  91. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/line_length_2.txt +0 -0
  92. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/mismatched_underlines.txt +0 -0
  93. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/mismatched_underlines_one_dash.txt +0 -0
  94. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/mismatched_underlines_two_dashes.txt +0 -0
  95. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/module_level_docstring.txt +0 -0
  96. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/param_signature_without_type.txt +0 -0
  97. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/parameters_returns_raises_wrapping.txt +0 -0
  98. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/returns_signature_and_description.txt +0 -0
  99. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/section_headings_with_colons.txt +0 -0
  100. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/section_title_fixed.txt +0 -0
  101. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/sections_notes_examples.txt +0 -0
  102. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/signature_line_is_not_wrapped.txt +0 -0
  103. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/texts_are_rewrapped.txt +0 -0
  104. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/line_wrap/numpy/very_long_unbreakable_word.txt +0 -0
  105. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_data/playground.py +0 -0
  106. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_line_wrap_google.py +0 -0
  107. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_line_wrap_numpy.py +0 -0
  108. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_line_wrap_utils.py +0 -0
  109. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_main_jupyter.py +0 -0
  110. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_main_py.py +0 -0
  111. {format_docstring-0.2.5 → format_docstring-0.2.6}/tests/test_playground.py +0 -0
  112. {format_docstring-0.2.5 → format_docstring-0.2.6}/tox.ini +0 -0
@@ -6,6 +6,19 @@ The format is based on
6
6
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
7
7
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [0.2.6] - 2025-11-21
10
+
11
+ - Fixed
12
+ - Multiline annotations now normalize without inserting spaces inside
13
+ `Literal[...]` or other bracketed signatures, even when they span several
14
+ lines.
15
+ - A bug where bare `*args`/`**kwargs` signature lines (typed or untyped)
16
+ would be merged into previous descriptions
17
+ - NumPy signature syncing left the `:class:` / `:meth:` role prefixes behind,
18
+ producing mismatched annotations like ` : MyClass`
19
+ - Full diff
20
+ - https://github.com/jsh9/format-docstring/compare/0.2.5...0.2.6
21
+
9
22
  ## [0.2.5] - 2025-11-20
10
23
 
11
24
  - Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: format-docstring
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: A Python formatter to wrap/adjust docstring lines
5
5
  Author-email: jsh9 <25124332+jsh9@users.noreply.github.com>
6
6
  Maintainer-email: jsh9 <25124332+jsh9@users.noreply.github.com>
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import ast
4
4
  import io
5
5
  import operator
6
+ import textwrap
6
7
  import tokenize
7
8
  from typing import TYPE_CHECKING
8
9
 
@@ -83,12 +84,18 @@ def _normalize_signature_segment(segment: str | None) -> str | None:
83
84
 
84
85
  normalized: str = segment.strip()
85
86
  if '\n' in normalized or '\r' in normalized or '\t' in normalized:
87
+ dedented: str = textwrap.dedent(normalized)
88
+ # Wrap in parentheses so unions split across lines
89
+ # (e.g. ``Literal[...] | None``)
90
+ # remain valid ``eval`` expressions even when indentation is uneven.
91
+ wrapped_for_parse = f'({dedented})'
92
+
86
93
  # `ast.unparse(ast.parse(...))` neatly flattens whitespace but it also
87
94
  # canonicalises string quotes to single quotes. We still rely on it for
88
95
  # whitespace normalization, so capture its output first.
89
96
  try:
90
- canonical = ast.unparse(ast.parse(normalized))
91
- except (SyntaxError, ValueError):
97
+ canonical = ast.unparse(ast.parse(wrapped_for_parse, mode='eval'))
98
+ except (SyntaxError, ValueError, IndentationError):
92
99
  return ' '.join(normalized.split())
93
100
 
94
101
  # Remember the exact string literal tokens from the original text. The
@@ -170,18 +170,22 @@ def wrap_docstring_numpy( # noqa: C901, PLR0915, TODO: https://github.com/jsh9/
170
170
  # section (indentation < 4). This prevents mis-detecting
171
171
  # description lines that happen to contain a colon (e.g., tables,
172
172
  # examples, notes) as new parameter signatures.
173
- if _is_param_signature(line) and (
174
- leading_indent is None or indent_length <= leading_indent
175
- ):
176
- fixed_line = _fix_colon_spacing(line)
177
- fixed_line = _standardize_default_value(fixed_line)
178
- fixed_line = _rewrite_parameter_signature(
179
- fixed_line, metadata_for_section
180
- )
181
- fixed_line = _standardize_default_value(fixed_line)
182
- temp_out.append(fixed_line)
183
- i += 1
184
- continue
173
+ if leading_indent is None or indent_length <= leading_indent:
174
+ if _is_param_signature(line):
175
+ fixed_line = _fix_colon_spacing(line)
176
+ fixed_line = _standardize_default_value(fixed_line)
177
+ fixed_line = _rewrite_parameter_signature(
178
+ fixed_line, metadata_for_section
179
+ )
180
+ fixed_line = _standardize_default_value(fixed_line)
181
+ temp_out.append(fixed_line)
182
+ i += 1
183
+ continue
184
+
185
+ if _is_bare_variadic_signature(line):
186
+ temp_out.append(line)
187
+ i += 1
188
+ continue
185
189
 
186
190
  # Description lines (typically indented): wrap if too long
187
191
  collect_to_temp_output(temp_out, line)
@@ -341,6 +345,13 @@ _PARAM_SIGNATURE_RE = re.compile(
341
345
  rf'^\s*\*{{0,2}}{START}{CONT}*(?:\s*,\s*\*{{0,2}}{START}{CONT}*)*\s*:\s*.*$'
342
346
  )
343
347
 
348
+ # Matches bare variadic signatures without a colon, e.g. ``**kwargs`` or
349
+ # ``*args, **kwargs``. These should be treated like signatures so description
350
+ # text doesn't get collapsed into the preceding entry.
351
+ _BARE_VARIADIC_SIGNATURE_RE = re.compile(
352
+ rf'^\s*\*{{1,2}}{START}{CONT}*(?:\s*,\s*\*{{1,2}}{START}{CONT}*)*\s*$'
353
+ )
354
+
344
355
 
345
356
  def _is_param_signature(text: str) -> bool:
346
357
  r"""
@@ -371,6 +382,16 @@ def _is_param_signature(text: str) -> bool:
371
382
  return bool(_PARAM_SIGNATURE_RE.match(text))
372
383
 
373
384
 
385
+ def _is_bare_variadic_signature(text: str) -> bool:
386
+ """
387
+ Return True for variadic parameter lines lacking ``:`` annotations.
388
+
389
+ Handles stripped signatures such as ``**kwargs`` so they are preserved as
390
+ their own logical entries inside ``Parameters`` sections.
391
+ """
392
+ return bool(_BARE_VARIADIC_SIGNATURE_RE.match(text))
393
+
394
+
374
395
  def _fix_colon_spacing(line: str) -> str:
375
396
  """
376
397
  Fix spacing around colons in parameter signature lines.
@@ -748,6 +769,12 @@ def _rewrite_return_signature(line: str, annotation: str) -> str:
748
769
  colon_idx = stripped.find(':')
749
770
  if colon_idx != -1:
750
771
  name = stripped[:colon_idx].rstrip()
772
+ # Only treat the colon as a signature separator if something precedes
773
+ # it. rST cross references such as ``:class:`Foo``` start with a colon,
774
+ # in which case we just want to output the synced annotation.
775
+ if not name:
776
+ return f'{indent}{annotation}'
777
+
751
778
  return f'{indent}{name} : {annotation}'
752
779
 
753
780
  return f'{indent}{annotation}'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: format-docstring
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: A Python formatter to wrap/adjust docstring lines
5
5
  Author-email: jsh9 <25124332+jsh9@users.noreply.github.com>
6
6
  Maintainer-email: jsh9 <25124332+jsh9@users.noreply.github.com>
@@ -60,6 +60,7 @@ tests/test_data/end_to_end/numpy/new_lines_before_and_after.txt
60
60
  tests/test_data/end_to_end/numpy/no_format_docstring_comment.txt
61
61
  tests/test_data/end_to_end/numpy/param_signature_without_type.txt
62
62
  tests/test_data/end_to_end/numpy/parameters_returns_raises_wrapping.txt
63
+ tests/test_data/end_to_end/numpy/rST_cross_reference.txt
63
64
  tests/test_data/end_to_end/numpy/returns_signature_and_description.txt
64
65
  tests/test_data/end_to_end/numpy/section_headings_with_colons.txt
65
66
  tests/test_data/end_to_end/numpy/section_title_fixed.txt
@@ -72,6 +73,7 @@ tests/test_data/end_to_end/numpy/signature_sync_returns.txt
72
73
  tests/test_data/end_to_end/numpy/signature_sync_yields.txt
73
74
  tests/test_data/end_to_end/numpy/single_line_docstring.txt
74
75
  tests/test_data/end_to_end/numpy/texts_are_rewrapped.txt
76
+ tests/test_data/end_to_end/numpy/variadic_signature_without_colon.txt
75
77
  tests/test_data/end_to_end/numpy/very_long_unbreakable_word.txt
76
78
  tests/test_data/integration_test/numpy/after.ipynb
77
79
  tests/test_data/integration_test/numpy/after.py
@@ -104,4 +106,5 @@ tests/test_data/line_wrap/numpy/section_title_fixed.txt
104
106
  tests/test_data/line_wrap/numpy/sections_notes_examples.txt
105
107
  tests/test_data/line_wrap/numpy/signature_line_is_not_wrapped.txt
106
108
  tests/test_data/line_wrap/numpy/texts_are_rewrapped.txt
109
+ tests/test_data/line_wrap/numpy/variadic_signature_without_colon.txt
107
110
  tests/test_data/line_wrap/numpy/very_long_unbreakable_word.txt
@@ -4,7 +4,7 @@ requires = ["setuptools-scm[toml]>=6.2", "setuptools>=45"]
4
4
 
5
5
  [project]
6
6
  name = "format-docstring"
7
- version = "0.2.5"
7
+ version = "0.2.6"
8
8
  dependencies = [
9
9
  "click>=8.0",
10
10
  "jupyter-notebook-parser>=0.1.4",
@@ -0,0 +1,72 @@
1
+ LINE_LENGTH: 79
2
+
3
+ **********
4
+
5
+ def myfunc() -> MyClass:
6
+ """
7
+ Do something
8
+
9
+ Returns
10
+ -------
11
+ :class:`MyClass`
12
+ An instance of MyClass
13
+ """
14
+ pass
15
+
16
+
17
+ def uses_cross_refs(
18
+ thing: MyClass,
19
+ creator: Callable[[MyClass], MyClass],
20
+ ) -> MyClass:
21
+ """
22
+ Uses parameters and returns that reference rST roles.
23
+
24
+ Parameters
25
+ ----------
26
+ thing : :class:`MyClass`
27
+ Object to transform.
28
+ creator : :meth:`MyClass.build`
29
+ Callback that builds a new instance.
30
+
31
+ Returns
32
+ -------
33
+ :meth:`MyClass.build`
34
+ A created instance.
35
+ """
36
+ return creator(thing)
37
+
38
+
39
+ **********
40
+
41
+ def myfunc() -> MyClass:
42
+ """
43
+ Do something
44
+
45
+ Returns
46
+ -------
47
+ MyClass
48
+ An instance of MyClass
49
+ """
50
+ pass
51
+
52
+
53
+ def uses_cross_refs(
54
+ thing: MyClass,
55
+ creator: Callable[[MyClass], MyClass],
56
+ ) -> MyClass:
57
+ """
58
+ Uses parameters and returns that reference rST roles.
59
+
60
+ Parameters
61
+ ----------
62
+ thing : MyClass
63
+ Object to transform.
64
+ creator : Callable[[MyClass], MyClass]
65
+ Callback that builds a new instance.
66
+
67
+ Returns
68
+ -------
69
+ MyClass
70
+ A created instance.
71
+ """
72
+ return creator(thing)
@@ -0,0 +1,58 @@
1
+ LINE_LENGTH: 75
2
+
3
+ **********
4
+ def function_with_variadics():
5
+ """
6
+ Parameters
7
+ ----------
8
+ arg1 : str
9
+ Something short
10
+ **kwargs
11
+ Keyword args that should remain on their own entry.
12
+ *custom_args
13
+ Positional extras that should wrap to their own block even without a colon.
14
+ **some_other_strange_name
15
+ Keyword extras that likewise need wrapping to stay with their entry.
16
+ *explicit_typed_args : tuple[int, ...]
17
+ Shows a variadic entry that still provides a type annotation.
18
+ **typed_kwargs : dict[str, int]
19
+ Another variadic keyword argument that uses a type hint.
20
+ """
21
+ return (
22
+ arg1,
23
+ kwargs,
24
+ custom_args,
25
+ some_other_strange_name,
26
+ explicit_typed_args,
27
+ typed_kwargs,
28
+ )
29
+
30
+ **********
31
+
32
+ def function_with_variadics():
33
+ """
34
+ Parameters
35
+ ----------
36
+ arg1 : str
37
+ Something short
38
+ **kwargs
39
+ Keyword args that should remain on their own entry.
40
+ *custom_args
41
+ Positional extras that should wrap to their own block even without
42
+ a colon.
43
+ **some_other_strange_name
44
+ Keyword extras that likewise need wrapping to stay with their
45
+ entry.
46
+ *explicit_typed_args : tuple[int, ...]
47
+ Shows a variadic entry that still provides a type annotation.
48
+ **typed_kwargs : dict[str, int]
49
+ Another variadic keyword argument that uses a type hint.
50
+ """
51
+ return (
52
+ arg1,
53
+ kwargs,
54
+ custom_args,
55
+ some_other_strange_name,
56
+ explicit_typed_args,
57
+ typed_kwargs,
58
+ )
@@ -0,0 +1,38 @@
1
+ LINE_LENGTH: 55
2
+
3
+ **********
4
+ Parameters
5
+ ----------
6
+ arg1 : str
7
+ Something short
8
+ **kwargs
9
+ Keyword args that should remain on their own entry.
10
+ *custom_args
11
+ Positional extras that should wrap to their own block even without a colon.
12
+ **some_other_strange_name
13
+ Keyword extras that likewise need wrapping to stay with their entry.
14
+ *explicit_typed_args : tuple[int, ...]
15
+ Shows a variadic entry that still provides a type annotation.
16
+ **typed_kwargs : dict[str, int]
17
+ Another variadic keyword argument that uses a type hint.
18
+
19
+ **********
20
+
21
+ Parameters
22
+ ----------
23
+ arg1 : str
24
+ Something short
25
+ **kwargs
26
+ Keyword args that should remain on their own entry.
27
+ *custom_args
28
+ Positional extras that should wrap to their own
29
+ block even without a colon.
30
+ **some_other_strange_name
31
+ Keyword extras that likewise need wrapping to stay
32
+ with their entry.
33
+ *explicit_typed_args : tuple[int, ...]
34
+ Shows a variadic entry that still provides a type
35
+ annotation.
36
+ **typed_kwargs : dict[str, int]
37
+ Another variadic keyword argument that uses a type
38
+ hint.
@@ -4,7 +4,6 @@ from textwrap import dedent
4
4
 
5
5
  import pytest
6
6
 
7
- import format_docstring.docstring_rewriter
8
7
  from format_docstring import docstring_rewriter
9
8
 
10
9
 
@@ -57,6 +56,57 @@ def test_rebuild_literal(literal: str, content: str, expected: str) -> None:
57
56
  assert docstring_rewriter.rebuild_literal(literal, content) == expected
58
57
 
59
58
 
59
+ @pytest.mark.parametrize(
60
+ ('segment', 'expected'),
61
+ [
62
+ (
63
+ dedent(
64
+ """
65
+ Literal[
66
+ 'auto', 'default', 'flex', 'scale', 'priority'
67
+ ]
68
+ | None
69
+ | NotGiven
70
+ """
71
+ ),
72
+ "Literal['auto', 'default', 'flex', 'scale', 'priority'] | None | NotGiven", # noqa: E501
73
+ ),
74
+ (
75
+ dedent(
76
+ """
77
+ Optional[
78
+ 'Widget'
79
+ ]
80
+ | None
81
+ """
82
+ ),
83
+ "Optional['Widget'] | None",
84
+ ),
85
+ (
86
+ dedent(
87
+ """
88
+ tuple[
89
+ dict[str, int],
90
+ list[
91
+ tuple[str, float]
92
+ ]
93
+ ]
94
+ """
95
+ ),
96
+ 'tuple[dict[str, int], list[tuple[str, float]]]',
97
+ ),
98
+ ],
99
+ )
100
+ def test_normalize_signature_segment_multiline_cases(
101
+ segment: str, expected: str
102
+ ) -> None:
103
+ """
104
+ Multiline annotations should normalize without inserting bracket gaps.
105
+ """
106
+ normalized = docstring_rewriter._normalize_signature_segment(segment) # noqa: SLF001
107
+ assert normalized == expected
108
+
109
+
60
110
  @pytest.mark.parametrize(
61
111
  ('src', 'selector', 'has_doc'),
62
112
  [
@@ -232,9 +282,7 @@ def test_wrap_docstring_numpy_parameters_and_examples() -> None:
232
282
  """ # noqa: E501
233
283
  ).strip('\n')
234
284
 
235
- wrapped = format_docstring.docstring_rewriter.wrap_docstring(
236
- doc, line_length=79
237
- )
285
+ wrapped = docstring_rewriter.wrap_docstring(doc, line_length=79)
238
286
 
239
287
  temp: str = 'very very very very very very very very very very'
240
288