format-docstring 0.1.5__tar.gz → 0.1.7__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 (97) hide show
  1. {format_docstring-0.1.5 → format_docstring-0.1.7}/CHANGELOG.md +16 -0
  2. {format_docstring-0.1.5 → format_docstring-0.1.7}/PKG-INFO +33 -1
  3. {format_docstring-0.1.5 → format_docstring-0.1.7}/README.md +32 -0
  4. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/docstring_rewriter.py +33 -6
  5. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/line_wrap_google.py +1 -0
  6. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/line_wrap_numpy.py +118 -4
  7. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/main_jupyter.py +14 -1
  8. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/main_py.py +14 -1
  9. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring.egg-info/PKG-INFO +33 -1
  10. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring.egg-info/SOURCES.txt +2 -0
  11. {format_docstring-0.1.5 → format_docstring-0.1.7}/pyproject.toml +1 -1
  12. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/examples_section.txt +1 -1
  13. format_docstring-0.1.7/tests/test_data/end_to_end/numpy/fix_rst_backticks.txt +176 -0
  14. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/examples_section.txt +1 -1
  15. format_docstring-0.1.7/tests/test_data/line_wrap/numpy/fix_rst_backticks.txt +93 -0
  16. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_docstring_rewriter.py +25 -0
  17. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_line_wrap_numpy.py +90 -1
  18. {format_docstring-0.1.5 → format_docstring-0.1.7}/.github/workflows/python-package.yml +0 -0
  19. {format_docstring-0.1.5 → format_docstring-0.1.7}/.github/workflows/python-publish.yml +0 -0
  20. {format_docstring-0.1.5 → format_docstring-0.1.7}/.gitignore +0 -0
  21. {format_docstring-0.1.5 → format_docstring-0.1.7}/.pre-commit-config.yaml +0 -0
  22. {format_docstring-0.1.5 → format_docstring-0.1.7}/.pre-commit-hooks.yaml +0 -0
  23. {format_docstring-0.1.5 → format_docstring-0.1.7}/CLAUDE.md +0 -0
  24. {format_docstring-0.1.5 → format_docstring-0.1.7}/LICENSE +0 -0
  25. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/__init__.py +0 -0
  26. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/base_fixer.py +0 -0
  27. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/config.py +0 -0
  28. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring/line_wrap_utils.py +0 -0
  29. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring.egg-info/dependency_links.txt +0 -0
  30. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring.egg-info/entry_points.txt +0 -0
  31. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring.egg-info/requires.txt +0 -0
  32. {format_docstring-0.1.5 → format_docstring-0.1.7}/format_docstring.egg-info/top_level.txt +0 -0
  33. {format_docstring-0.1.5 → format_docstring-0.1.7}/muff.toml +0 -0
  34. {format_docstring-0.1.5 → format_docstring-0.1.7}/requirements.dev +0 -0
  35. {format_docstring-0.1.5 → format_docstring-0.1.7}/setup.cfg +0 -0
  36. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/__init__.py +0 -0
  37. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/helpers.py +0 -0
  38. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_config.py +0 -0
  39. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/README.md +0 -0
  40. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/colon_spacing_fix.txt +0 -0
  41. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/contents_that_are_not_wrapped.txt +0 -0
  42. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/default_value_standardization.txt +0 -0
  43. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/empty_lines_are_respected.txt +0 -0
  44. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
  45. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/four_level_nested_classes.txt +0 -0
  46. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
  47. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/indent_misaligned_all.txt +0 -0
  48. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/indent_two_levels_8_spaces.txt +0 -0
  49. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/line_length_2.txt +0 -0
  50. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/mismatched_underlines.txt +0 -0
  51. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/mismatched_underlines_one_dash.txt +0 -0
  52. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/mismatched_underlines_two_dashes.txt +0 -0
  53. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/module_level_docstring.txt +0 -0
  54. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/new_lines_before_and_after.txt +0 -0
  55. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/param_signature_without_type.txt +0 -0
  56. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/parameters_returns_raises_wrapping.txt +0 -0
  57. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/returns_signature_and_description.txt +0 -0
  58. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/section_title_fixed.txt +0 -0
  59. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/sections_notes_examples.txt +0 -0
  60. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/signature_line_is_not_wrapped.txt +0 -0
  61. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/single_line_docstring.txt +0 -0
  62. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/texts_are_rewrapped.txt +0 -0
  63. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/end_to_end/numpy/very_long_unbreakable_word.txt +0 -0
  64. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/integration_test/numpy/after.ipynb +0 -0
  65. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/integration_test/numpy/after.py +0 -0
  66. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/integration_test/numpy/after_50.ipynb +0 -0
  67. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/integration_test/numpy/after_50.py +0 -0
  68. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/integration_test/numpy/before.ipynb +0 -0
  69. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/integration_test/numpy/before.py +0 -0
  70. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/README.md +0 -0
  71. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/colon_spacing_fix.txt +0 -0
  72. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/contents_that_are_not_wrapped.txt +0 -0
  73. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/default_value_standardization.txt +0 -0
  74. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/empty_lines_are_respected.txt +0 -0
  75. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
  76. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
  77. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/indent_two_levels_8_spaces.txt +0 -0
  78. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/line_length_2.txt +0 -0
  79. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/mismatched_underlines.txt +0 -0
  80. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/mismatched_underlines_one_dash.txt +0 -0
  81. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/mismatched_underlines_two_dashes.txt +0 -0
  82. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/module_level_docstring.txt +0 -0
  83. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/param_signature_without_type.txt +0 -0
  84. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/parameters_returns_raises_wrapping.txt +0 -0
  85. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/returns_signature_and_description.txt +0 -0
  86. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/section_title_fixed.txt +0 -0
  87. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/sections_notes_examples.txt +0 -0
  88. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/signature_line_is_not_wrapped.txt +0 -0
  89. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/texts_are_rewrapped.txt +0 -0
  90. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/line_wrap/numpy/very_long_unbreakable_word.txt +0 -0
  91. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_data/playground.py +0 -0
  92. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_line_wrap_google.py +0 -0
  93. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_line_wrap_utils.py +0 -0
  94. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_main_jupyter.py +0 -0
  95. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_main_py.py +0 -0
  96. {format_docstring-0.1.5 → format_docstring-0.1.7}/tests/test_playground.py +0 -0
  97. {format_docstring-0.1.5 → format_docstring-0.1.7}/tox.ini +0 -0
@@ -6,6 +6,22 @@ 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.1.7] - 2025-10-14
10
+
11
+ - Fixed
12
+ - Backtick fixing logic to properly distinguish between inline literals and
13
+ external links (e.g., `` `Python <https://example.org>`_ ``)
14
+ - Refactored `_fix_rst_backticks()` to use pre-compiled regex pattern for
15
+ better performance
16
+
17
+ ## [0.1.6] - 2025-10-13
18
+
19
+ - Added
20
+ - New `--fix-rst-backticks` option to automatically convert single backticks
21
+ to double backticks per rST syntax
22
+ - Full diff
23
+ - https://github.com/jsh9/format-docstring/compare/0.1.5...0.1.6
24
+
9
25
  ## [0.1.5] - 2025-10-13
10
26
 
11
27
  - Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: format-docstring
3
- Version: 0.1.5
3
+ Version: 0.1.7
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>
@@ -45,6 +45,7 @@ A Python formatter to automatically format numpy-style docstrings.
45
45
  - [2.2. One-line summaries are formatted to fit line length limit](#22-one-line-summaries-are-formatted-to-fit-line-length-limit)
46
46
  - [2.3. Minor typos can be automatically fixed](#23-minor-typos-can-be-automatically-fixed)
47
47
  - [2.4. Default value declarations are standardized](#24-default-value-declarations-are-standardized)
48
+ - [2.5. Single backticks are converted to double backticks (rST syntax)](#25-single-backticks-are-converted-to-double-backticks-rst-syntax)
48
49
  - [3. Installation](#3-installation)
49
50
  - [4. Usage](#4-usage)
50
51
  - [4.1. Command Line Interface](#41-command-line-interface)
@@ -209,6 +210,29 @@ def example_function(arg1, arg2, arg3, arg4):
209
210
  pass
210
211
  ```
211
212
 
213
+ ### 2.5. Single backticks are converted to double backticks (rST syntax)
214
+
215
+ ```diff
216
+ def process_data(data):
217
+ """
218
+ - Process data using the `transform` function.
219
+ + Process data using the ``transform`` function.
220
+
221
+ Parameters
222
+ ----------
223
+ data : dict
224
+ - Input data with keys `id`, `value`, and `timestamp`.
225
+ + Input data with keys ``id``, ``value``, and ``timestamp``.
226
+
227
+ Returns
228
+ -------
229
+ dict
230
+ - Processed data with key `result`.
231
+ + Processed data with key ``result``.
232
+ """
233
+ pass
234
+ ```
235
+
212
236
  ## 3. Installation
213
237
 
214
238
  ```bash
@@ -265,6 +289,8 @@ pre-commit install
265
289
  (default: 79)
266
290
  - `--docstring-style CHOICE`: Docstring style to target (`numpy` or `google`,
267
291
  default: `numpy`). Note: Currently only `numpy` style is fully supported.
292
+ - `--fix-rst-backticks BOOL`: Automatically fix single backticks to double
293
+ backticks per rST syntax (default: True)
268
294
  - `--exclude TEXT`: Regex pattern to exclude files/directories (default:
269
295
  `\.git|\.tox|\.pytest_cache`)
270
296
  - `--config PATH`: Path to a `pyproject.toml` config file. If not specified,
@@ -290,6 +316,9 @@ format-docstring --config path/to/pyproject.toml src/
290
316
 
291
317
  # CLI options override config file settings
292
318
  format-docstring --config pyproject.toml --line-length 100 src/
319
+
320
+ # Disable backtick fixing
321
+ format-docstring --fix-rst-backticks=False my_module.py
293
322
  ```
294
323
 
295
324
  ### 5.3. `pyproject.toml` Configuration
@@ -301,6 +330,7 @@ override these settings:
301
330
  [tool.format_docstring]
302
331
  line_length = 79
303
332
  docstring_style = "numpy"
333
+ fix_rst_backticks = true
304
334
  exclude = "\\.git|\\.venv|__pycache__"
305
335
  ```
306
336
 
@@ -310,6 +340,8 @@ exclude = "\\.git|\\.venv|__pycache__"
310
340
  79\)
311
341
  - `docstring_style` (str): Docstring style, either `"numpy"` or `"google"`
312
342
  (default: `"numpy"`)
343
+ - `fix_rst_backticks` (bool): Automatically fix single backticks to double
344
+ backticks per rST syntax (default: `true`)
313
345
  - `exclude` (str): Regex pattern to exclude files/directories (default:
314
346
  `"\\.git|\\.tox|\\.pytest_cache"`)
315
347
 
@@ -12,6 +12,7 @@ A Python formatter to automatically format numpy-style docstrings.
12
12
  - [2.2. One-line summaries are formatted to fit line length limit](#22-one-line-summaries-are-formatted-to-fit-line-length-limit)
13
13
  - [2.3. Minor typos can be automatically fixed](#23-minor-typos-can-be-automatically-fixed)
14
14
  - [2.4. Default value declarations are standardized](#24-default-value-declarations-are-standardized)
15
+ - [2.5. Single backticks are converted to double backticks (rST syntax)](#25-single-backticks-are-converted-to-double-backticks-rst-syntax)
15
16
  - [3. Installation](#3-installation)
16
17
  - [4. Usage](#4-usage)
17
18
  - [4.1. Command Line Interface](#41-command-line-interface)
@@ -176,6 +177,29 @@ def example_function(arg1, arg2, arg3, arg4):
176
177
  pass
177
178
  ```
178
179
 
180
+ ### 2.5. Single backticks are converted to double backticks (rST syntax)
181
+
182
+ ```diff
183
+ def process_data(data):
184
+ """
185
+ - Process data using the `transform` function.
186
+ + Process data using the ``transform`` function.
187
+
188
+ Parameters
189
+ ----------
190
+ data : dict
191
+ - Input data with keys `id`, `value`, and `timestamp`.
192
+ + Input data with keys ``id``, ``value``, and ``timestamp``.
193
+
194
+ Returns
195
+ -------
196
+ dict
197
+ - Processed data with key `result`.
198
+ + Processed data with key ``result``.
199
+ """
200
+ pass
201
+ ```
202
+
179
203
  ## 3. Installation
180
204
 
181
205
  ```bash
@@ -232,6 +256,8 @@ pre-commit install
232
256
  (default: 79)
233
257
  - `--docstring-style CHOICE`: Docstring style to target (`numpy` or `google`,
234
258
  default: `numpy`). Note: Currently only `numpy` style is fully supported.
259
+ - `--fix-rst-backticks BOOL`: Automatically fix single backticks to double
260
+ backticks per rST syntax (default: True)
235
261
  - `--exclude TEXT`: Regex pattern to exclude files/directories (default:
236
262
  `\.git|\.tox|\.pytest_cache`)
237
263
  - `--config PATH`: Path to a `pyproject.toml` config file. If not specified,
@@ -257,6 +283,9 @@ format-docstring --config path/to/pyproject.toml src/
257
283
 
258
284
  # CLI options override config file settings
259
285
  format-docstring --config pyproject.toml --line-length 100 src/
286
+
287
+ # Disable backtick fixing
288
+ format-docstring --fix-rst-backticks=False my_module.py
260
289
  ```
261
290
 
262
291
  ### 5.3. `pyproject.toml` Configuration
@@ -268,6 +297,7 @@ override these settings:
268
297
  [tool.format_docstring]
269
298
  line_length = 79
270
299
  docstring_style = "numpy"
300
+ fix_rst_backticks = true
271
301
  exclude = "\\.git|\\.venv|__pycache__"
272
302
  ```
273
303
 
@@ -277,6 +307,8 @@ exclude = "\\.git|\\.venv|__pycache__"
277
307
  79\)
278
308
  - `docstring_style` (str): Docstring style, either `"numpy"` or `"google"`
279
309
  (default: `"numpy"`)
310
+ - `fix_rst_backticks` (bool): Automatically fix single backticks to double
311
+ backticks per rST syntax (default: `true`)
280
312
  - `exclude` (str): Regex pattern to exclude files/directories (default:
281
313
  `"\\.git|\\.tox|\\.pytest_cache"`)
282
314
 
@@ -18,6 +18,7 @@ def fix_src(
18
18
  *,
19
19
  line_length: int = 79,
20
20
  docstring_style: str = 'numpy',
21
+ fix_rst_backticks: bool = True,
21
22
  ) -> str:
22
23
  """Return code with only docstrings updated to wrapped content.
23
24
 
@@ -27,9 +28,11 @@ def fix_src(
27
28
  The full Python source code to process.
28
29
  line_length : int, default=79
29
30
  Target maximum line length for wrapping logic.
30
-
31
31
  docstring_style : str, default='numpy'
32
32
  The docstring style to target ('numpy' or 'google').
33
+ fix_rst_backticks : bool, default=True
34
+ If True, automatically fix single backticks to double backticks per
35
+ rST syntax.
33
36
 
34
37
  Returns
35
38
  -------
@@ -51,7 +54,12 @@ def fix_src(
51
54
 
52
55
  # Module-level docstring
53
56
  rep = build_replacement_docstring(
54
- tree, source_code, line_starts, line_length, docstring_style
57
+ tree,
58
+ source_code,
59
+ line_starts,
60
+ line_length,
61
+ docstring_style,
62
+ fix_rst_backticks,
55
63
  )
56
64
  if rep is not None:
57
65
  replacements.append(rep)
@@ -62,7 +70,12 @@ def fix_src(
62
70
  node, ast.ClassDef | ast.FunctionDef | ast.AsyncFunctionDef
63
71
  ):
64
72
  rep = build_replacement_docstring(
65
- node, source_code, line_starts, line_length, docstring_style
73
+ node,
74
+ source_code,
75
+ line_starts,
76
+ line_length,
77
+ docstring_style,
78
+ fix_rst_backticks,
66
79
  )
67
80
  if rep is not None:
68
81
  replacements.append(rep)
@@ -107,6 +120,7 @@ def build_replacement_docstring(
107
120
  line_starts: list[int],
108
121
  line_length: int,
109
122
  docstring_style: str = 'numpy',
123
+ fix_rst_backticks: bool = True,
110
124
  ) -> tuple[int, int, str] | None:
111
125
  """Compute a single docstring replacement for the given node.
112
126
 
@@ -120,9 +134,11 @@ def build_replacement_docstring(
120
134
  Line start offsets from :func:`_line_starts`.
121
135
  line_length : int
122
136
  Target maximum line length for wrapping logic.
123
-
124
137
  docstring_style : str, default='numpy'
125
138
  The docstring style to target ('numpy' or 'google').
139
+ fix_rst_backticks : bool, default=True
140
+ If True, automatically fix single backticks to double backticks per
141
+ rST syntax.
126
142
 
127
143
  Returns
128
144
  -------
@@ -164,6 +180,7 @@ def build_replacement_docstring(
164
180
  line_length=line_length,
165
181
  docstring_style=docstring_style,
166
182
  leading_indent=leading_indent_, # type: ignore[arg-type]
183
+ fix_rst_backticks=fix_rst_backticks,
167
184
  )
168
185
 
169
186
  new_literal: str | None = rebuild_literal(original_literal, wrapped)
@@ -277,6 +294,7 @@ def wrap_docstring(
277
294
  line_length: int = 79,
278
295
  docstring_style: str = 'numpy',
279
296
  leading_indent: int = 0,
297
+ fix_rst_backticks: bool = True,
280
298
  ) -> str:
281
299
  """Wrap a docstring to the given line length (stub).
282
300
 
@@ -290,6 +308,9 @@ def wrap_docstring(
290
308
  The docstring style to target ('numpy' or 'google').
291
309
  leading_indent : int, default=0
292
310
  The number of indentation spaces of this docstring.
311
+ fix_rst_backticks : bool, default=True
312
+ If True, automatically fix single backticks to double backticks per
313
+ rST syntax.
293
314
 
294
315
  Returns
295
316
  -------
@@ -306,9 +327,15 @@ def wrap_docstring(
306
327
  style = (docstring_style or '').strip().lower()
307
328
  if style == 'google':
308
329
  return wrap_docstring_google(
309
- docstring, line_length, leading_indent=leading_indent
330
+ docstring,
331
+ line_length,
332
+ leading_indent=leading_indent,
333
+ fix_rst_backticks=fix_rst_backticks,
310
334
  )
311
335
  # Default to NumPy-style for unknown/unspecified styles to be permissive.
312
336
  return wrap_docstring_numpy(
313
- docstring, line_length, leading_indent=leading_indent
337
+ docstring,
338
+ line_length,
339
+ leading_indent=leading_indent,
340
+ fix_rst_backticks=fix_rst_backticks,
314
341
  )
@@ -2,6 +2,7 @@ def wrap_docstring_google(
2
2
  docstring: str,
3
3
  line_length: int,
4
4
  leading_indent: int | None = None,
5
+ fix_rst_backticks: bool = True,
5
6
  ) -> str:
6
7
  """A placeholder for now.""" # noqa: D401
7
8
  return ''
@@ -15,6 +15,7 @@ def wrap_docstring_numpy(
15
15
  docstring: str,
16
16
  line_length: int,
17
17
  leading_indent: int | None = None,
18
+ fix_rst_backticks: bool = False,
18
19
  ) -> str:
19
20
  """Wrap NumPy-style docstrings with light parsing rules.
20
21
 
@@ -103,7 +104,7 @@ def wrap_docstring_numpy(
103
104
  i += 1
104
105
  continue
105
106
 
106
- # In Examples, skip wrapping for REPL lines
107
+ # In Examples, skip wrapping and backtick fixing for REPL lines
107
108
  if in_examples and (
108
109
  stripped.startswith('>>> ') or stripped.startswith('... ')
109
110
  ):
@@ -131,7 +132,10 @@ def wrap_docstring_numpy(
131
132
  continue
132
133
 
133
134
  # Description lines (typically indented): wrap if too long
134
- collect_to_temp_output(temp_out, line)
135
+ line_to_process = (
136
+ _fix_rst_backticks(line) if fix_rst_backticks else line
137
+ )
138
+ collect_to_temp_output(temp_out, line_to_process)
135
139
  i += 1
136
140
  continue
137
141
 
@@ -148,12 +152,18 @@ def wrap_docstring_numpy(
148
152
  i += 1
149
153
  continue
150
154
 
151
- collect_to_temp_output(temp_out, line)
155
+ line_to_process = (
156
+ _fix_rst_backticks(line) if fix_rst_backticks else line
157
+ )
158
+ collect_to_temp_output(temp_out, line_to_process)
152
159
  i += 1
153
160
  continue
154
161
 
155
162
  # Examples or any other section
156
- collect_to_temp_output(temp_out, line)
163
+ line_to_process = (
164
+ _fix_rst_backticks(line) if fix_rst_backticks else line
165
+ )
166
+ collect_to_temp_output(temp_out, line_to_process)
157
167
  i += 1
158
168
 
159
169
  out: list[str] = process_temp_output(temp_out, width=line_length)
@@ -403,3 +413,107 @@ def handle_single_line_docstring(
403
413
  return f'{prefix}\n{wrapped}\n{indent}{postfix}'
404
414
 
405
415
  return whole_docstring_literal
416
+
417
+
418
+ # Precompiled regex for fixing RST backticks.
419
+ # Pattern matches inline literals while avoiding roles, cross-references, and
420
+ # links. See the documentation of _fix_rst_backticks() for more details.
421
+ # The pattern allows backticks after: start of line, whitespace, parentheses,
422
+ # or certain punctuation (like > and . for `>>> ` and `... ` literals)
423
+ # Note: We match [^`]+ (anything except backticks) and then check in the
424
+ # replacement function whether it's an external link (contains < followed by >)
425
+ _RST_BACKTICK_PATTERN = re.compile(
426
+ r'(?:^|(?<=\s)|(?<=\()|(?<=[>.]))(?::[\w-]+:)?`([^`]+)`(?!`)(?!__)(?!_)'
427
+ )
428
+
429
+
430
+ def _fix_rst_backticks(docstring: str) -> str:
431
+ """
432
+ Fix inline-literal single backticks to double backticks per rST syntax.
433
+
434
+ This function converts pairs of single backticks (`` `...` ``) that
435
+ represent inline *literals* into pairs of double backticks (`` ``...`` ``).
436
+ It deliberately **does not** modify other rST constructs that require
437
+ single backticks.
438
+
439
+ What stays untouched
440
+ --------------------
441
+ - Existing double-backtick literals: ````code````.
442
+ - Roles: ``:role:`text``` (e.g., ``:emphasis:`word```).
443
+ - Cross-references: `` `text`_ `` and anonymous refs `` `text`__ ``.
444
+ - Inline external links: `` `text <https://example.com>`_ ``.
445
+ - Explicit hyperlink targets: ``.. _`Label`: https://example.com``.
446
+
447
+ How it works (regex guards)
448
+ ---------------------------
449
+ The pattern only upgrades a match when **all** these are true:
450
+ - Opening backtick is not part of an existing ````...```` (``(?<!`)``).
451
+ - Opening backtick is not immediately preceded by ``:`` (to avoid roles).
452
+ - Opening backtick is not immediately preceded by ``_`` (to avoid
453
+ explicit targets like ``.. _`Label`: …``).
454
+ - The enclosed text contains **no** backticks and **no** ``<`` (to avoid
455
+ inline-link forms like `` `text <url>`_ ``).
456
+ - Closing backtick is not part of ````...```` (``(?!`)``).
457
+ - Closing backtick is not followed by ``__`` or ``_`` (to avoid
458
+ anonymous/named references).
459
+
460
+ Parameters
461
+ ----------
462
+ docstring : str
463
+ The docstring content to process.
464
+
465
+ Returns
466
+ -------
467
+ str
468
+ The docstring with only inline-literal backticks fixed.
469
+
470
+ Examples
471
+ --------
472
+ >>> _fix_rst_backticks('Use `foo` to do something')
473
+ 'Use ``foo`` to do something'
474
+
475
+ >>> _fix_rst_backticks('Edge punctuation: `x`.')
476
+ 'Edge punctuation: ``x``.'
477
+
478
+ >>> _fix_rst_backticks(':emphasis:`word`')
479
+ ':emphasis:`word`'
480
+
481
+ >>> _fix_rst_backticks('See `Link`_ for details')
482
+ 'See `Link`_ for details'
483
+
484
+ >>> _fix_rst_backticks('`Python <https://www.python.org>`_')
485
+ '`Python <https://www.python.org>`_'
486
+
487
+ >>> _fix_rst_backticks('.. _`Special Target`: https://example.com/special')
488
+ '.. _`Special Target`: https://example.com/special'
489
+
490
+ >>> _fix_rst_backticks('Already has ``foo`` double backticks')
491
+ 'Already has ``foo`` double backticks'
492
+ """
493
+
494
+ def replace_func(match: re.Match[str]) -> str:
495
+ # match.group(0) is the full match
496
+ # match.group(1) is the content between backticks
497
+ full_match: str = match.group(0)
498
+ content: str = match.group(1)
499
+
500
+ # If the match includes a role prefix (like :emphasis:), don't replace
501
+ if ':' in full_match and full_match.index('`') > 0:
502
+ # Check if there's a role prefix before the backtick
503
+ before_backtick = full_match[: full_match.index('`')]
504
+ if ':' in before_backtick:
505
+ return full_match # Keep original (it's a role)
506
+
507
+ # Check if this is an external link (contains <...> pattern)
508
+ # External links look like: `text <url>`_
509
+ if '<' in content and '>' in content:
510
+ # Check if < comes before > (basic validation)
511
+ if content.index('<') < content.rindex('>'):
512
+ return full_match # Keep original (it's an external link)
513
+
514
+ # Otherwise, replace single backticks with double
515
+ # Keep any leading whitespace/parenthesis/punctuation
516
+ prefix = match.group(0)[: match.group(0).index('`')]
517
+ return f'{prefix}``{content}``'
518
+
519
+ return _RST_BACKTICK_PATTERN.sub(replace_func, docstring)
@@ -54,18 +54,28 @@ from format_docstring.config import inject_config_from_file
54
54
  show_default=True,
55
55
  help='Docstring style to target',
56
56
  )
57
+ @click.option(
58
+ '--fix-rst-backticks',
59
+ default=True,
60
+ show_default=True,
61
+ help='Fix single backticks to double backticks per rST syntax',
62
+ )
57
63
  def main(
58
64
  paths: tuple[str, ...],
59
65
  config: str | None, # noqa: ARG001 (used by Click callback)
60
66
  exclude: str,
61
67
  line_length: int,
62
68
  docstring_style: str,
69
+ fix_rst_backticks: bool,
63
70
  ) -> None:
64
71
  """Format .ipynb files."""
65
72
  ret = 0
66
73
  for path in paths:
67
74
  fixer = JupyterNotebookFixer(
68
- path=path, exclude_pattern=exclude, line_length=line_length
75
+ path=path,
76
+ exclude_pattern=exclude,
77
+ line_length=line_length,
78
+ fix_rst_backticks=fix_rst_backticks,
69
79
  )
70
80
  fixer.docstring_style = docstring_style
71
81
  ret |= fixer.fix_one_directory_or_one_file()
@@ -82,9 +92,11 @@ class JupyterNotebookFixer(BaseFixer):
82
92
  path: str,
83
93
  exclude_pattern: str = r'\.git|\.tox|\.pytest_cache',
84
94
  line_length: int = 79,
95
+ fix_rst_backticks: bool = True,
85
96
  ) -> None:
86
97
  super().__init__(path=path, exclude_pattern=exclude_pattern)
87
98
  self.line_length = line_length
99
+ self.fix_rst_backticks = fix_rst_backticks
88
100
  self.docstring_style: str = 'numpy'
89
101
 
90
102
  def fix_one_directory_or_one_file(self) -> int:
@@ -140,6 +152,7 @@ class JupyterNotebookFixer(BaseFixer):
140
152
  source_code=source_without_magic,
141
153
  line_length=self.line_length,
142
154
  docstring_style=self.docstring_style,
155
+ fix_rst_backticks=self.fix_rst_backticks,
143
156
  )
144
157
 
145
158
  if fixed != source_without_magic:
@@ -46,12 +46,19 @@ from format_docstring.config import inject_config_from_file
46
46
  show_default=True,
47
47
  help='Docstring style to target',
48
48
  )
49
+ @click.option(
50
+ '--fix-rst-backticks',
51
+ default=True,
52
+ show_default=True,
53
+ help='Fix single backticks to double backticks per rST syntax',
54
+ )
49
55
  def main(
50
56
  paths: tuple[str, ...],
51
57
  config: str | None, # noqa: ARG001 (used by Click callback)
52
58
  exclude: str,
53
59
  line_length: int,
54
60
  docstring_style: str,
61
+ fix_rst_backticks: bool,
55
62
  ) -> None:
56
63
  """Format .py files."""
57
64
  ret = 0
@@ -61,7 +68,10 @@ def main(
61
68
 
62
69
  for path in paths:
63
70
  fixer = PythonFileFixer(
64
- path=path, exclude_pattern=exclude, line_length=line_length
71
+ path=path,
72
+ exclude_pattern=exclude,
73
+ line_length=line_length,
74
+ fix_rst_backticks=fix_rst_backticks,
65
75
  )
66
76
  fixer.docstring_style = docstring_style
67
77
  ret |= fixer.fix_one_directory_or_one_file()
@@ -78,9 +88,11 @@ class PythonFileFixer(BaseFixer):
78
88
  path: str,
79
89
  exclude_pattern: str = r'\.git|\.tox|\.pytest_cache',
80
90
  line_length: int = 79,
91
+ fix_rst_backticks: bool = True,
81
92
  ) -> None:
82
93
  super().__init__(path=path, exclude_pattern=exclude_pattern)
83
94
  self.line_length = line_length
95
+ self.fix_rst_backticks = fix_rst_backticks
84
96
  self.docstring_style: str = 'numpy'
85
97
 
86
98
  def fix_one_file(self, filename: str) -> int:
@@ -109,6 +121,7 @@ class PythonFileFixer(BaseFixer):
109
121
  source_text,
110
122
  line_length=self.line_length,
111
123
  docstring_style=self.docstring_style,
124
+ fix_rst_backticks=self.fix_rst_backticks,
112
125
  )
113
126
 
114
127
  if filename == '-':
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: format-docstring
3
- Version: 0.1.5
3
+ Version: 0.1.7
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>
@@ -45,6 +45,7 @@ A Python formatter to automatically format numpy-style docstrings.
45
45
  - [2.2. One-line summaries are formatted to fit line length limit](#22-one-line-summaries-are-formatted-to-fit-line-length-limit)
46
46
  - [2.3. Minor typos can be automatically fixed](#23-minor-typos-can-be-automatically-fixed)
47
47
  - [2.4. Default value declarations are standardized](#24-default-value-declarations-are-standardized)
48
+ - [2.5. Single backticks are converted to double backticks (rST syntax)](#25-single-backticks-are-converted-to-double-backticks-rst-syntax)
48
49
  - [3. Installation](#3-installation)
49
50
  - [4. Usage](#4-usage)
50
51
  - [4.1. Command Line Interface](#41-command-line-interface)
@@ -209,6 +210,29 @@ def example_function(arg1, arg2, arg3, arg4):
209
210
  pass
210
211
  ```
211
212
 
213
+ ### 2.5. Single backticks are converted to double backticks (rST syntax)
214
+
215
+ ```diff
216
+ def process_data(data):
217
+ """
218
+ - Process data using the `transform` function.
219
+ + Process data using the ``transform`` function.
220
+
221
+ Parameters
222
+ ----------
223
+ data : dict
224
+ - Input data with keys `id`, `value`, and `timestamp`.
225
+ + Input data with keys ``id``, ``value``, and ``timestamp``.
226
+
227
+ Returns
228
+ -------
229
+ dict
230
+ - Processed data with key `result`.
231
+ + Processed data with key ``result``.
232
+ """
233
+ pass
234
+ ```
235
+
212
236
  ## 3. Installation
213
237
 
214
238
  ```bash
@@ -265,6 +289,8 @@ pre-commit install
265
289
  (default: 79)
266
290
  - `--docstring-style CHOICE`: Docstring style to target (`numpy` or `google`,
267
291
  default: `numpy`). Note: Currently only `numpy` style is fully supported.
292
+ - `--fix-rst-backticks BOOL`: Automatically fix single backticks to double
293
+ backticks per rST syntax (default: True)
268
294
  - `--exclude TEXT`: Regex pattern to exclude files/directories (default:
269
295
  `\.git|\.tox|\.pytest_cache`)
270
296
  - `--config PATH`: Path to a `pyproject.toml` config file. If not specified,
@@ -290,6 +316,9 @@ format-docstring --config path/to/pyproject.toml src/
290
316
 
291
317
  # CLI options override config file settings
292
318
  format-docstring --config pyproject.toml --line-length 100 src/
319
+
320
+ # Disable backtick fixing
321
+ format-docstring --fix-rst-backticks=False my_module.py
293
322
  ```
294
323
 
295
324
  ### 5.3. `pyproject.toml` Configuration
@@ -301,6 +330,7 @@ override these settings:
301
330
  [tool.format_docstring]
302
331
  line_length = 79
303
332
  docstring_style = "numpy"
333
+ fix_rst_backticks = true
304
334
  exclude = "\\.git|\\.venv|__pycache__"
305
335
  ```
306
336
 
@@ -310,6 +340,8 @@ exclude = "\\.git|\\.venv|__pycache__"
310
340
  79\)
311
341
  - `docstring_style` (str): Docstring style, either `"numpy"` or `"google"`
312
342
  (default: `"numpy"`)
343
+ - `fix_rst_backticks` (bool): Automatically fix single backticks to double
344
+ backticks per rST syntax (default: `true`)
313
345
  - `exclude` (str): Regex pattern to exclude files/directories (default:
314
346
  `"\\.git|\\.tox|\\.pytest_cache"`)
315
347
 
@@ -44,6 +44,7 @@ tests/test_data/end_to_end/numpy/default_value_standardization.txt
44
44
  tests/test_data/end_to_end/numpy/empty_lines_are_respected.txt
45
45
  tests/test_data/end_to_end/numpy/examples_section.txt
46
46
  tests/test_data/end_to_end/numpy/existing_linebreaks_should_not_be_respected.txt
47
+ tests/test_data/end_to_end/numpy/fix_rst_backticks.txt
47
48
  tests/test_data/end_to_end/numpy/four_level_nested_classes.txt
48
49
  tests/test_data/end_to_end/numpy/indent_four_levels_16_spaces_width_10.txt
49
50
  tests/test_data/end_to_end/numpy/indent_misaligned_all.txt
@@ -76,6 +77,7 @@ tests/test_data/line_wrap/numpy/default_value_standardization.txt
76
77
  tests/test_data/line_wrap/numpy/empty_lines_are_respected.txt
77
78
  tests/test_data/line_wrap/numpy/examples_section.txt
78
79
  tests/test_data/line_wrap/numpy/existing_linebreaks_should_not_be_respected.txt
80
+ tests/test_data/line_wrap/numpy/fix_rst_backticks.txt
79
81
  tests/test_data/line_wrap/numpy/indent_four_levels_16_spaces_width_10.txt
80
82
  tests/test_data/line_wrap/numpy/indent_two_levels_8_spaces.txt
81
83
  tests/test_data/line_wrap/numpy/line_length_2.txt
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "format-docstring"
7
- version = "0.1.5"
7
+ version = "0.1.7"
8
8
  description = "A Python formatter to wrap/adjust docstring lines"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -97,7 +97,7 @@ class MyClass:
97
97
 
98
98
  Examples
99
99
  --------
100
- Should not be wrapped, because of `>>> ` and `... `
100
+ Should not be wrapped, because of ``>>> `` and ``... ``
101
101
  >>> result = my_function(
102
102
  ... arg1=1,
103
103
  ... arg2=2,