Sphinx 7.3.7__py3-none-any.whl → 7.4.0__py3-none-any.whl

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.

Potentially problematic release.


This version of Sphinx might be problematic. Click here for more details.

Files changed (357) hide show
  1. sphinx/__init__.py +5 -6
  2. sphinx/_cli/__init__.py +296 -0
  3. sphinx/_cli/util/__init__.py +0 -0
  4. sphinx/_cli/util/colour.py +103 -0
  5. sphinx/_cli/util/errors.py +165 -0
  6. sphinx/application.py +78 -43
  7. sphinx/builders/__init__.py +59 -15
  8. sphinx/builders/_epub_base.py +11 -5
  9. sphinx/builders/changes.py +2 -2
  10. sphinx/builders/epub3.py +2 -2
  11. sphinx/builders/gettext.py +10 -10
  12. sphinx/builders/html/__init__.py +56 -54
  13. sphinx/builders/latex/__init__.py +5 -5
  14. sphinx/builders/latex/constants.py +5 -0
  15. sphinx/builders/linkcheck.py +73 -38
  16. sphinx/builders/texinfo.py +1 -1
  17. sphinx/cmd/build.py +1 -1
  18. sphinx/cmd/quickstart.py +11 -11
  19. sphinx/config.py +57 -38
  20. sphinx/directives/__init__.py +7 -9
  21. sphinx/directives/code.py +12 -15
  22. sphinx/directives/other.py +12 -15
  23. sphinx/directives/patches.py +26 -0
  24. sphinx/domains/__init__.py +1 -1
  25. sphinx/domains/c/__init__.py +5 -5
  26. sphinx/domains/c/_ast.py +436 -12
  27. sphinx/domains/c/_symbol.py +89 -134
  28. sphinx/domains/changeset.py +3 -4
  29. sphinx/domains/cpp/__init__.py +5 -6
  30. sphinx/domains/cpp/_ast.py +822 -25
  31. sphinx/domains/cpp/_symbol.py +3 -0
  32. sphinx/domains/javascript.py +3 -6
  33. sphinx/domains/math.py +3 -2
  34. sphinx/domains/python/__init__.py +44 -6
  35. sphinx/domains/python/_object.py +7 -5
  36. sphinx/domains/rst.py +2 -2
  37. sphinx/domains/std/__init__.py +95 -14
  38. sphinx/environment/__init__.py +35 -15
  39. sphinx/environment/adapters/indexentries.py +71 -24
  40. sphinx/environment/adapters/toctree.py +1 -1
  41. sphinx/environment/collectors/__init__.py +18 -4
  42. sphinx/environment/collectors/asset.py +4 -4
  43. sphinx/environment/collectors/toctree.py +27 -14
  44. sphinx/events.py +7 -6
  45. sphinx/ext/apidoc.py +377 -170
  46. sphinx/ext/autodoc/__init__.py +13 -13
  47. sphinx/ext/autodoc/directive.py +10 -13
  48. sphinx/ext/autodoc/mock.py +10 -7
  49. sphinx/ext/autodoc/preserve_defaults.py +1 -1
  50. sphinx/ext/autodoc/typehints.py +2 -2
  51. sphinx/ext/autosummary/__init__.py +15 -9
  52. sphinx/ext/autosummary/generate.py +270 -154
  53. sphinx/ext/coverage.py +108 -18
  54. sphinx/ext/duration.py +10 -3
  55. sphinx/ext/extlinks.py +3 -2
  56. sphinx/ext/graphviz.py +3 -3
  57. sphinx/ext/ifconfig.py +1 -2
  58. sphinx/ext/imgconverter.py +1 -0
  59. sphinx/ext/imgmath.py +7 -6
  60. sphinx/ext/inheritance_diagram.py +3 -3
  61. sphinx/ext/intersphinx/__init__.py +81 -0
  62. sphinx/ext/intersphinx/__main__.py +10 -0
  63. sphinx/ext/intersphinx/_cli.py +44 -0
  64. sphinx/ext/intersphinx/_load.py +253 -0
  65. sphinx/ext/{intersphinx.py → intersphinx/_resolve.py} +17 -368
  66. sphinx/ext/intersphinx/_shared.py +53 -0
  67. sphinx/ext/mathjax.py +1 -1
  68. sphinx/ext/todo.py +2 -2
  69. sphinx/io.py +2 -6
  70. sphinx/locale/__init__.py +1 -5
  71. sphinx/locale/ar/LC_MESSAGES/sphinx.js +1 -1
  72. sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
  73. sphinx/locale/ar/LC_MESSAGES/sphinx.po +678 -471
  74. sphinx/locale/bg/LC_MESSAGES/sphinx.js +1 -1
  75. sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
  76. sphinx/locale/bg/LC_MESSAGES/sphinx.po +684 -476
  77. sphinx/locale/bn/LC_MESSAGES/sphinx.js +1 -1
  78. sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
  79. sphinx/locale/bn/LC_MESSAGES/sphinx.po +679 -472
  80. sphinx/locale/ca/LC_MESSAGES/sphinx.js +1 -1
  81. sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
  82. sphinx/locale/ca/LC_MESSAGES/sphinx.po +681 -474
  83. sphinx/locale/cak/LC_MESSAGES/sphinx.js +1 -1
  84. sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
  85. sphinx/locale/cak/LC_MESSAGES/sphinx.po +678 -471
  86. sphinx/locale/cs/LC_MESSAGES/sphinx.js +1 -1
  87. sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
  88. sphinx/locale/cs/LC_MESSAGES/sphinx.po +679 -472
  89. sphinx/locale/cy/LC_MESSAGES/sphinx.js +1 -1
  90. sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
  91. sphinx/locale/cy/LC_MESSAGES/sphinx.po +679 -472
  92. sphinx/locale/da/LC_MESSAGES/sphinx.js +1 -1
  93. sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
  94. sphinx/locale/da/LC_MESSAGES/sphinx.po +679 -472
  95. sphinx/locale/de/LC_MESSAGES/sphinx.js +1 -1
  96. sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
  97. sphinx/locale/de/LC_MESSAGES/sphinx.po +679 -472
  98. sphinx/locale/de_DE/LC_MESSAGES/sphinx.js +1 -1
  99. sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
  100. sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +678 -471
  101. sphinx/locale/el/LC_MESSAGES/sphinx.js +1 -1
  102. sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
  103. sphinx/locale/el/LC_MESSAGES/sphinx.po +701 -494
  104. sphinx/locale/en_DE/LC_MESSAGES/sphinx.js +1 -1
  105. sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
  106. sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +700 -493
  107. sphinx/locale/en_FR/LC_MESSAGES/sphinx.js +1 -1
  108. sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
  109. sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +700 -493
  110. sphinx/locale/en_GB/LC_MESSAGES/sphinx.js +1 -1
  111. sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
  112. sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +701 -494
  113. sphinx/locale/en_HK/LC_MESSAGES/sphinx.js +1 -1
  114. sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
  115. sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +700 -493
  116. sphinx/locale/eo/LC_MESSAGES/sphinx.js +1 -1
  117. sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
  118. sphinx/locale/eo/LC_MESSAGES/sphinx.po +701 -494
  119. sphinx/locale/es/LC_MESSAGES/sphinx.js +1 -1
  120. sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
  121. sphinx/locale/es/LC_MESSAGES/sphinx.po +701 -494
  122. sphinx/locale/es_CO/LC_MESSAGES/sphinx.js +1 -1
  123. sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
  124. sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +700 -493
  125. sphinx/locale/et/LC_MESSAGES/sphinx.js +1 -1
  126. sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
  127. sphinx/locale/et/LC_MESSAGES/sphinx.po +701 -494
  128. sphinx/locale/eu/LC_MESSAGES/sphinx.js +1 -1
  129. sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
  130. sphinx/locale/eu/LC_MESSAGES/sphinx.po +701 -494
  131. sphinx/locale/fa/LC_MESSAGES/sphinx.js +1 -1
  132. sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
  133. sphinx/locale/fa/LC_MESSAGES/sphinx.po +701 -494
  134. sphinx/locale/fi/LC_MESSAGES/sphinx.js +1 -1
  135. sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
  136. sphinx/locale/fi/LC_MESSAGES/sphinx.po +700 -493
  137. sphinx/locale/fr/LC_MESSAGES/sphinx.js +1 -1
  138. sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
  139. sphinx/locale/fr/LC_MESSAGES/sphinx.po +725 -518
  140. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.js +1 -1
  141. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
  142. sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +700 -493
  143. sphinx/locale/gl/LC_MESSAGES/sphinx.js +1 -1
  144. sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
  145. sphinx/locale/gl/LC_MESSAGES/sphinx.po +701 -494
  146. sphinx/locale/he/LC_MESSAGES/sphinx.js +1 -1
  147. sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
  148. sphinx/locale/he/LC_MESSAGES/sphinx.po +700 -493
  149. sphinx/locale/hi/LC_MESSAGES/sphinx.js +1 -1
  150. sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
  151. sphinx/locale/hi/LC_MESSAGES/sphinx.po +701 -494
  152. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.js +1 -1
  153. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
  154. sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +700 -493
  155. sphinx/locale/hr/LC_MESSAGES/sphinx.js +1 -1
  156. sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
  157. sphinx/locale/hr/LC_MESSAGES/sphinx.po +701 -494
  158. sphinx/locale/hu/LC_MESSAGES/sphinx.js +1 -1
  159. sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
  160. sphinx/locale/hu/LC_MESSAGES/sphinx.po +701 -494
  161. sphinx/locale/id/LC_MESSAGES/sphinx.js +1 -1
  162. sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
  163. sphinx/locale/id/LC_MESSAGES/sphinx.po +701 -494
  164. sphinx/locale/is/LC_MESSAGES/sphinx.js +1 -1
  165. sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
  166. sphinx/locale/is/LC_MESSAGES/sphinx.po +700 -493
  167. sphinx/locale/it/LC_MESSAGES/sphinx.js +1 -1
  168. sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
  169. sphinx/locale/it/LC_MESSAGES/sphinx.po +708 -500
  170. sphinx/locale/ja/LC_MESSAGES/sphinx.js +1 -1
  171. sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
  172. sphinx/locale/ja/LC_MESSAGES/sphinx.po +701 -494
  173. sphinx/locale/ka/LC_MESSAGES/sphinx.js +1 -1
  174. sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
  175. sphinx/locale/ka/LC_MESSAGES/sphinx.po +700 -493
  176. sphinx/locale/ko/LC_MESSAGES/sphinx.js +1 -1
  177. sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
  178. sphinx/locale/ko/LC_MESSAGES/sphinx.po +701 -494
  179. sphinx/locale/lt/LC_MESSAGES/sphinx.js +1 -1
  180. sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
  181. sphinx/locale/lt/LC_MESSAGES/sphinx.po +701 -494
  182. sphinx/locale/lv/LC_MESSAGES/sphinx.js +1 -1
  183. sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
  184. sphinx/locale/lv/LC_MESSAGES/sphinx.po +701 -494
  185. sphinx/locale/mk/LC_MESSAGES/sphinx.js +1 -1
  186. sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
  187. sphinx/locale/mk/LC_MESSAGES/sphinx.po +700 -493
  188. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +1 -1
  189. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
  190. sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +701 -494
  191. sphinx/locale/ne/LC_MESSAGES/sphinx.js +1 -1
  192. sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
  193. sphinx/locale/ne/LC_MESSAGES/sphinx.po +701 -494
  194. sphinx/locale/nl/LC_MESSAGES/sphinx.js +1 -1
  195. sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
  196. sphinx/locale/nl/LC_MESSAGES/sphinx.po +701 -494
  197. sphinx/locale/pl/LC_MESSAGES/sphinx.js +1 -1
  198. sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
  199. sphinx/locale/pl/LC_MESSAGES/sphinx.po +701 -494
  200. sphinx/locale/pt/LC_MESSAGES/sphinx.js +1 -1
  201. sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
  202. sphinx/locale/pt/LC_MESSAGES/sphinx.po +700 -493
  203. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.js +1 -1
  204. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
  205. sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +705 -498
  206. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.js +1 -1
  207. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
  208. sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +701 -494
  209. sphinx/locale/ro/LC_MESSAGES/sphinx.js +1 -1
  210. sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
  211. sphinx/locale/ro/LC_MESSAGES/sphinx.po +701 -494
  212. sphinx/locale/ru/LC_MESSAGES/sphinx.js +1 -1
  213. sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
  214. sphinx/locale/ru/LC_MESSAGES/sphinx.po +890 -680
  215. sphinx/locale/si/LC_MESSAGES/sphinx.js +1 -1
  216. sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
  217. sphinx/locale/si/LC_MESSAGES/sphinx.po +700 -493
  218. sphinx/locale/sk/LC_MESSAGES/sphinx.js +1 -1
  219. sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
  220. sphinx/locale/sk/LC_MESSAGES/sphinx.po +701 -494
  221. sphinx/locale/sl/LC_MESSAGES/sphinx.js +1 -1
  222. sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
  223. sphinx/locale/sl/LC_MESSAGES/sphinx.po +701 -494
  224. sphinx/locale/sphinx.pot +702 -494
  225. sphinx/locale/sq/LC_MESSAGES/sphinx.js +1 -1
  226. sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
  227. sphinx/locale/sq/LC_MESSAGES/sphinx.po +704 -497
  228. sphinx/locale/sr/LC_MESSAGES/sphinx.js +1 -1
  229. sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
  230. sphinx/locale/sr/LC_MESSAGES/sphinx.po +700 -493
  231. sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
  232. sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
  233. sphinx/locale/sv/LC_MESSAGES/sphinx.js +1 -1
  234. sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
  235. sphinx/locale/sv/LC_MESSAGES/sphinx.po +701 -494
  236. sphinx/locale/ta/LC_MESSAGES/sphinx.po +1016 -808
  237. sphinx/locale/te/LC_MESSAGES/sphinx.js +1 -1
  238. sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
  239. sphinx/locale/te/LC_MESSAGES/sphinx.po +700 -493
  240. sphinx/locale/tr/LC_MESSAGES/sphinx.js +1 -1
  241. sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
  242. sphinx/locale/tr/LC_MESSAGES/sphinx.po +701 -494
  243. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.js +1 -1
  244. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
  245. sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +701 -494
  246. sphinx/locale/ur/LC_MESSAGES/sphinx.js +1 -1
  247. sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
  248. sphinx/locale/ur/LC_MESSAGES/sphinx.po +700 -493
  249. sphinx/locale/vi/LC_MESSAGES/sphinx.js +1 -1
  250. sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
  251. sphinx/locale/vi/LC_MESSAGES/sphinx.po +701 -494
  252. sphinx/locale/yue/LC_MESSAGES/sphinx.js +1 -1
  253. sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
  254. sphinx/locale/yue/LC_MESSAGES/sphinx.po +700 -493
  255. sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +704 -496
  256. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.js +1 -1
  257. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
  258. sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +700 -493
  259. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +1 -1
  260. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
  261. sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +729 -522
  262. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.js +1 -1
  263. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
  264. sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +700 -493
  265. sphinx/roles.py +1 -1
  266. sphinx/search/__init__.py +17 -9
  267. sphinx/templates/quickstart/{root_doc.rst_t → root_doc.rst.jinja} +7 -10
  268. sphinx/testing/fixtures.py +22 -20
  269. sphinx/testing/path.py +6 -2
  270. sphinx/testing/util.py +8 -13
  271. sphinx/texinputs/sphinx.sty +449 -332
  272. sphinx/texinputs/sphinxlatexadmonitions.sty +209 -66
  273. sphinx/texinputs/sphinxlatexliterals.sty +9 -16
  274. sphinx/texinputs/sphinxlatexstyletext.sty +4 -38
  275. sphinx/texinputs/sphinxlatextables.sty +6 -14
  276. sphinx/texinputs/sphinxpackageboxes.sty +15 -42
  277. sphinx/texinputs/sphinxpackagefootnote.sty +4 -3
  278. sphinx/themes/agogo/layout.html +3 -3
  279. sphinx/themes/basic/genindex-single.html +2 -1
  280. sphinx/themes/basic/layout.html +3 -6
  281. sphinx/themes/basic/static/searchtools.js +4 -3
  282. sphinx/themes/haiku/layout.html +4 -4
  283. sphinx/themes/pyramid/layout.html +1 -1
  284. sphinx/themes/scrolls/layout.html +2 -2
  285. sphinx/theming.py +3 -3
  286. sphinx/transforms/__init__.py +34 -20
  287. sphinx/transforms/i18n.py +8 -7
  288. sphinx/transforms/post_transforms/__init__.py +1 -1
  289. sphinx/transforms/post_transforms/images.py +7 -10
  290. sphinx/util/_pathlib.py +2 -2
  291. sphinx/util/cfamily.py +52 -30
  292. sphinx/util/console.py +1 -1
  293. sphinx/util/display.py +16 -11
  294. sphinx/util/docutils.py +88 -40
  295. sphinx/util/fileutil.py +15 -3
  296. sphinx/util/images.py +1 -0
  297. sphinx/util/inspect.py +66 -22
  298. sphinx/util/inventory.py +15 -0
  299. sphinx/util/logging.py +14 -21
  300. sphinx/util/math.py +3 -1
  301. sphinx/util/nodes.py +9 -12
  302. sphinx/util/osutil.py +5 -5
  303. sphinx/util/parsing.py +93 -0
  304. sphinx/util/tags.py +71 -47
  305. sphinx/util/typing.py +261 -143
  306. sphinx/versioning.py +17 -17
  307. sphinx/writers/html5.py +26 -19
  308. sphinx/writers/latex.py +58 -28
  309. sphinx/writers/manpage.py +4 -3
  310. sphinx/writers/texinfo.py +19 -14
  311. {sphinx-7.3.7.dist-info → sphinx-7.4.0.dist-info}/METADATA +21 -20
  312. sphinx-7.4.0.dist-info/RECORD +591 -0
  313. sphinx-7.3.7.dist-info/RECORD +0 -581
  314. /sphinx/templates/apidoc/{module.rst_t → module.rst.jinja} +0 -0
  315. /sphinx/templates/apidoc/{package.rst_t → package.rst.jinja} +0 -0
  316. /sphinx/templates/apidoc/{toc.rst_t → toc.rst.jinja} +0 -0
  317. /sphinx/templates/epub3/{content.opf_t → content.opf.jinja} +0 -0
  318. /sphinx/templates/epub3/{nav.xhtml_t → nav.xhtml.jinja} +0 -0
  319. /sphinx/templates/epub3/{toc.ncx_t → toc.ncx.jinja} +0 -0
  320. /sphinx/templates/gettext/{message.pot_t → message.pot.jinja} +0 -0
  321. /sphinx/templates/imgmath/{preview.tex_t → preview.tex.jinja} +0 -0
  322. /sphinx/templates/imgmath/{template.tex_t → template.tex.jinja} +0 -0
  323. /sphinx/templates/latex/{latex.tex_t → latex.tex.jinja} +0 -0
  324. /sphinx/templates/latex/{longtable.tex_t → longtable.tex.jinja} +0 -0
  325. /sphinx/templates/latex/{sphinxmessages.sty_t → sphinxmessages.sty.jinja} +0 -0
  326. /sphinx/templates/latex/{tabular.tex_t → tabular.tex.jinja} +0 -0
  327. /sphinx/templates/latex/{tabulary.tex_t → tabulary.tex.jinja} +0 -0
  328. /sphinx/templates/quickstart/{Makefile_t → Makefile.jinja} +0 -0
  329. /sphinx/templates/quickstart/{Makefile.new_t → Makefile.new.jinja} +0 -0
  330. /sphinx/templates/quickstart/{conf.py_t → conf.py.jinja} +0 -0
  331. /sphinx/templates/quickstart/{make.bat_t → make.bat.jinja} +0 -0
  332. /sphinx/templates/quickstart/{make.bat.new_t → make.bat.new.jinja} +0 -0
  333. /sphinx/texinputs/{Makefile_t → Makefile.jinja} +0 -0
  334. /sphinx/texinputs/{latexmkjarc_t → latexmkjarc.jinja} +0 -0
  335. /sphinx/texinputs/{latexmkrc_t → latexmkrc.jinja} +0 -0
  336. /sphinx/texinputs/{make.bat_t → make.bat.jinja} +0 -0
  337. /sphinx/texinputs_win/{Makefile_t → Makefile.jinja} +0 -0
  338. /sphinx/themes/agogo/static/{agogo.css_t → agogo.css.jinja} +0 -0
  339. /sphinx/themes/basic/static/{basic.css_t → basic.css.jinja} +0 -0
  340. /sphinx/themes/basic/static/{documentation_options.js_t → documentation_options.js.jinja} +0 -0
  341. /sphinx/themes/basic/static/{language_data.js_t → language_data.js.jinja} +0 -0
  342. /sphinx/themes/bizstyle/static/{bizstyle.css_t → bizstyle.css.jinja} +0 -0
  343. /sphinx/themes/bizstyle/static/{bizstyle.js_t → bizstyle.js.jinja} +0 -0
  344. /sphinx/themes/classic/static/{classic.css_t → classic.css.jinja} +0 -0
  345. /sphinx/themes/classic/static/{sidebar.js_t → sidebar.js.jinja} +0 -0
  346. /sphinx/themes/epub/static/{epub.css_t → epub.css.jinja} +0 -0
  347. /sphinx/themes/haiku/static/{haiku.css_t → haiku.css.jinja} +0 -0
  348. /sphinx/themes/nature/static/{nature.css_t → nature.css.jinja} +0 -0
  349. /sphinx/themes/nonav/static/{nonav.css_t → nonav.css.jinja} +0 -0
  350. /sphinx/themes/pyramid/static/{epub.css_t → epub.css.jinja} +0 -0
  351. /sphinx/themes/pyramid/static/{pyramid.css_t → pyramid.css.jinja} +0 -0
  352. /sphinx/themes/scrolls/static/{scrolls.css_t → scrolls.css.jinja} +0 -0
  353. /sphinx/themes/sphinxdoc/static/{sphinxdoc.css_t → sphinxdoc.css.jinja} +0 -0
  354. /sphinx/themes/traditional/static/{traditional.css_t → traditional.css.jinja} +0 -0
  355. {sphinx-7.3.7.dist-info → sphinx-7.4.0.dist-info}/LICENSE.rst +0 -0
  356. {sphinx-7.3.7.dist-info → sphinx-7.4.0.dist-info}/WHEEL +0 -0
  357. {sphinx-7.3.7.dist-info → sphinx-7.4.0.dist-info}/entry_points.txt +0 -0
@@ -24,6 +24,7 @@ import pydoc
24
24
  import re
25
25
  import sys
26
26
  from os import path
27
+ from pathlib import Path
27
28
  from typing import TYPE_CHECKING, Any, NamedTuple
28
29
 
29
30
  from jinja2 import TemplateNotFound
@@ -65,7 +66,7 @@ class DummyApplication:
65
66
  self.config = Config()
66
67
  self.registry = SphinxComponentRegistry()
67
68
  self.messagelog: list[str] = []
68
- self.srcdir = "/"
69
+ self.srcdir = '/'
69
70
  self.translator = translator
70
71
  self.verbosity = 0
71
72
  self._warncount = 0
@@ -98,10 +99,17 @@ def setup_documenters(app: Any) -> None:
98
99
  ModuleDocumenter,
99
100
  PropertyDocumenter,
100
101
  )
102
+
101
103
  documenters: list[type[Documenter]] = [
102
- ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
103
- FunctionDocumenter, MethodDocumenter,
104
- AttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
104
+ ModuleDocumenter,
105
+ ClassDocumenter,
106
+ ExceptionDocumenter,
107
+ DataDocumenter,
108
+ FunctionDocumenter,
109
+ MethodDocumenter,
110
+ AttributeDocumenter,
111
+ DecoratorDocumenter,
112
+ PropertyDocumenter,
105
113
  ]
106
114
  for documenter in documenters:
107
115
  app.registry.add_documenter(documenter.objtype, documenter)
@@ -123,8 +131,9 @@ class AutosummaryRenderer:
123
131
  raise ValueError(msg)
124
132
 
125
133
  system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
126
- loader = SphinxTemplateLoader(app.srcdir, app.config.templates_path,
127
- system_templates_path)
134
+ loader = SphinxTemplateLoader(
135
+ app.srcdir, app.config.templates_path, system_templates_path
136
+ )
128
137
 
129
138
  self.env = SandboxedEnvironment(loader=loader)
130
139
  self.env.filters['escape'] = rst.escape
@@ -132,7 +141,7 @@ class AutosummaryRenderer:
132
141
  self.env.filters['underline'] = _underline
133
142
 
134
143
  if app.translator:
135
- self.env.add_extension("jinja2.ext.i18n")
144
+ self.env.add_extension('jinja2.ext.i18n')
136
145
  # ``install_gettext_translations`` is injected by the ``jinja2.ext.i18n`` extension
137
146
  self.env.install_gettext_translations(app.translator) # type: ignore[attr-defined]
138
147
 
@@ -168,17 +177,17 @@ def _split_full_qualified_name(name: str) -> tuple[str | None, str]:
168
177
  parts = name.split('.')
169
178
  for i, _part in enumerate(parts, 1):
170
179
  try:
171
- modname = ".".join(parts[:i])
180
+ modname = '.'.join(parts[:i])
172
181
  importlib.import_module(modname)
173
182
  except ImportError:
174
- if parts[:i - 1]:
175
- return ".".join(parts[:i - 1]), ".".join(parts[i - 1:])
183
+ if parts[: i - 1]:
184
+ return '.'.join(parts[: i - 1]), '.'.join(parts[i - 1 :])
176
185
  else:
177
- return None, ".".join(parts)
186
+ return None, '.'.join(parts)
178
187
  except IndexError:
179
188
  pass
180
189
 
181
- return name, ""
190
+ return name, ''
182
191
 
183
192
 
184
193
  # -- Generating output ---------------------------------------------------------
@@ -194,12 +203,19 @@ class ModuleScanner:
194
203
 
195
204
  def is_skipped(self, name: str, value: Any, objtype: str) -> bool:
196
205
  try:
197
- return self.app.emit_firstresult('autodoc-skip-member', objtype,
198
- name, value, False, {})
206
+ return self.app.emit_firstresult(
207
+ 'autodoc-skip-member', objtype, name, value, False, {}
208
+ )
199
209
  except Exception as exc:
200
- logger.warning(__('autosummary: failed to determine %r to be documented, '
201
- 'the following exception was raised:\n%s'),
202
- name, exc, type='autosummary')
210
+ logger.warning(
211
+ __(
212
+ 'autosummary: failed to determine %r to be documented, '
213
+ 'the following exception was raised:\n%s'
214
+ ),
215
+ name,
216
+ exc,
217
+ type='autosummary',
218
+ )
203
219
  return False
204
220
 
205
221
  def scan(self, imported_members: bool) -> list[str]:
@@ -257,12 +273,19 @@ def members_of(obj: Any, conf: Config) -> Sequence[str]:
257
273
  return getall(obj) or dir(obj)
258
274
 
259
275
 
260
- def generate_autosummary_content(name: str, obj: Any, parent: Any,
261
- template: AutosummaryRenderer, template_name: str,
262
- imported_members: bool, app: Any,
263
- recursive: bool, context: dict,
264
- modname: str | None = None,
265
- qualname: str | None = None) -> str:
276
+ def generate_autosummary_content(
277
+ name: str,
278
+ obj: Any,
279
+ parent: Any,
280
+ template: AutosummaryRenderer,
281
+ template_name: str,
282
+ imported_members: bool,
283
+ app: Any,
284
+ recursive: bool,
285
+ context: dict,
286
+ modname: str | None = None,
287
+ qualname: str | None = None,
288
+ ) -> str:
266
289
  doc = get_documenter(app, obj, parent)
267
290
 
268
291
  ns: dict[str, Any] = {}
@@ -275,23 +298,25 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
275
298
  respect_module_all = not app.config.autosummary_ignore_module_all
276
299
  imported_members = imported_members or ('__all__' in dir(obj) and respect_module_all)
277
300
 
278
- ns['functions'], ns['all_functions'] = \
279
- _get_members(doc, app, obj, {'function'}, imported=imported_members)
280
- ns['classes'], ns['all_classes'] = \
281
- _get_members(doc, app, obj, {'class'}, imported=imported_members)
282
- ns['exceptions'], ns['all_exceptions'] = \
283
- _get_members(doc, app, obj, {'exception'}, imported=imported_members)
284
- ns['attributes'], ns['all_attributes'] = \
285
- _get_module_attrs(name, ns['members'])
301
+ ns['functions'], ns['all_functions'] = _get_members(
302
+ doc, app, obj, {'function'}, imported=imported_members
303
+ )
304
+ ns['classes'], ns['all_classes'] = _get_members(
305
+ doc, app, obj, {'class'}, imported=imported_members
306
+ )
307
+ ns['exceptions'], ns['all_exceptions'] = _get_members(
308
+ doc, app, obj, {'exception'}, imported=imported_members
309
+ )
310
+ ns['attributes'], ns['all_attributes'] = _get_module_attrs(name, ns['members'])
286
311
  ispackage = hasattr(obj, '__path__')
287
312
  if ispackage and recursive:
288
313
  # Use members that are not modules as skip list, because it would then mean
289
314
  # that module was overwritten in the package namespace
290
315
  skip = (
291
- ns["all_functions"]
292
- + ns["all_classes"]
293
- + ns["all_exceptions"]
294
- + ns["all_attributes"]
316
+ ns['all_functions']
317
+ + ns['all_classes']
318
+ + ns['all_exceptions']
319
+ + ns['all_attributes']
295
320
  )
296
321
 
297
322
  # If respect_module_all and module has a __all__ attribute, first get
@@ -301,40 +326,44 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
301
326
  #
302
327
  # Otherwise, use get_modules method normally
303
328
  if respect_module_all and '__all__' in dir(obj):
304
- imported_modules, all_imported_modules = \
305
- _get_members(doc, app, obj, {'module'}, imported=True)
329
+ imported_modules, all_imported_modules = _get_members(
330
+ doc, app, obj, {'module'}, imported=True
331
+ )
306
332
  skip += all_imported_modules
307
333
  imported_modules = [name + '.' + modname for modname in imported_modules]
308
- all_imported_modules = \
309
- [name + '.' + modname for modname in all_imported_modules]
334
+ all_imported_modules = [
335
+ name + '.' + modname for modname in all_imported_modules
336
+ ]
310
337
  public_members = getall(obj)
311
338
  else:
312
339
  imported_modules, all_imported_modules = [], []
313
340
  public_members = None
314
341
 
315
- modules, all_modules = _get_modules(obj, skip=skip, name=name,
316
- public_members=public_members)
342
+ modules, all_modules = _get_modules(
343
+ obj, skip=skip, name=name, public_members=public_members
344
+ )
317
345
  ns['modules'] = imported_modules + modules
318
- ns["all_modules"] = all_imported_modules + all_modules
346
+ ns['all_modules'] = all_imported_modules + all_modules
319
347
  elif doc.objtype == 'class':
320
348
  ns['members'] = dir(obj)
321
- ns['inherited_members'] = \
322
- set(dir(obj)) - set(obj.__dict__.keys())
323
- ns['methods'], ns['all_methods'] = \
324
- _get_members(doc, app, obj, {'method'}, include_public={'__init__'})
325
- ns['attributes'], ns['all_attributes'] = \
326
- _get_members(doc, app, obj, {'attribute', 'property'})
349
+ ns['inherited_members'] = set(dir(obj)) - set(obj.__dict__.keys())
350
+ ns['methods'], ns['all_methods'] = _get_members(
351
+ doc, app, obj, {'method'}, include_public={'__init__'}
352
+ )
353
+ ns['attributes'], ns['all_attributes'] = _get_members(
354
+ doc, app, obj, {'attribute', 'property'}
355
+ )
327
356
 
328
357
  if modname is None or qualname is None:
329
358
  modname, qualname = _split_full_qualified_name(name)
330
359
 
331
360
  if doc.objtype in ('method', 'attribute', 'property'):
332
- ns['class'] = qualname.rsplit(".", 1)[0]
361
+ ns['class'] = qualname.rsplit('.', 1)[0]
333
362
 
334
363
  if doc.objtype == 'class':
335
364
  shortname = qualname
336
365
  else:
337
- shortname = qualname.rsplit(".", 1)[-1]
366
+ shortname = qualname.rsplit('.', 1)[-1]
338
367
 
339
368
  ns['fullname'] = name
340
369
  ns['module'] = modname
@@ -352,12 +381,17 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
352
381
 
353
382
  def _skip_member(app: Sphinx, obj: Any, name: str, objtype: str) -> bool:
354
383
  try:
355
- return app.emit_firstresult('autodoc-skip-member', objtype, name,
356
- obj, False, {})
384
+ return app.emit_firstresult('autodoc-skip-member', objtype, name, obj, False, {})
357
385
  except Exception as exc:
358
- logger.warning(__('autosummary: failed to determine %r to be documented, '
359
- 'the following exception was raised:\n%s'),
360
- name, exc, type='autosummary')
386
+ logger.warning(
387
+ __(
388
+ 'autosummary: failed to determine %r to be documented, '
389
+ 'the following exception was raised:\n%s'
390
+ ),
391
+ name,
392
+ exc,
393
+ type='autosummary',
394
+ )
361
395
  return False
362
396
 
363
397
 
@@ -384,9 +418,15 @@ def _get_all_members(doc: type[Documenter], app: Sphinx, obj: Any) -> dict[str,
384
418
  return {}
385
419
 
386
420
 
387
- def _get_members(doc: type[Documenter], app: Sphinx, obj: Any, types: set[str], *,
388
- include_public: Set[str] = frozenset(),
389
- imported: bool = True) -> tuple[list[str], list[str]]:
421
+ def _get_members(
422
+ doc: type[Documenter],
423
+ app: Sphinx,
424
+ obj: Any,
425
+ types: set[str],
426
+ *,
427
+ include_public: Set[str] = frozenset(),
428
+ imported: bool = True,
429
+ ) -> tuple[list[str], list[str]]:
390
430
  items: list[str] = []
391
431
  public: list[str] = []
392
432
 
@@ -423,20 +463,16 @@ def _get_module_attrs(name: str, members: Any) -> tuple[list[str], list[str]]:
423
463
  if not attr_name.startswith('_'):
424
464
  public.append(attr_name)
425
465
  except PycodeError:
426
- pass # give up if ModuleAnalyzer fails to parse code
466
+ pass # give up if ModuleAnalyzer fails to parse code
427
467
  return public, attrs
428
468
 
429
469
 
430
470
  def _get_modules(
431
- obj: Any,
432
- *,
433
- skip: Sequence[str],
434
- name: str,
435
- public_members: Sequence[str] | None = None) -> tuple[list[str], list[str]]:
471
+ obj: Any, *, skip: Sequence[str], name: str, public_members: Sequence[str] | None = None
472
+ ) -> tuple[list[str], list[str]]:
436
473
  items: list[str] = []
437
474
  public: list[str] = []
438
475
  for _, modname, _ispkg in pkgutil.iter_modules(obj.__path__):
439
-
440
476
  if modname in skip:
441
477
  # module was overwritten in __init__.py, so not accessible
442
478
  continue
@@ -458,20 +494,29 @@ def _get_modules(
458
494
  return public, items
459
495
 
460
496
 
461
- def generate_autosummary_docs(sources: list[str],
462
- output_dir: str | os.PathLike[str] | None = None,
463
- suffix: str = '.rst',
464
- base_path: str | os.PathLike[str] | None = None,
465
- imported_members: bool = False, app: Any = None,
466
- overwrite: bool = True, encoding: str = 'utf-8') -> None:
497
+ def generate_autosummary_docs(
498
+ sources: list[str],
499
+ output_dir: str | os.PathLike[str] | None = None,
500
+ suffix: str = '.rst',
501
+ base_path: str | os.PathLike[str] | None = None,
502
+ imported_members: bool = False,
503
+ app: Sphinx | None = None,
504
+ overwrite: bool = True,
505
+ encoding: str = 'utf-8',
506
+ ) -> list[Path]:
507
+ """Generate autosummary documentation for the given sources.
508
+
509
+ :returns: list of generated files (both new and existing ones)
510
+ """
511
+ assert app is not None, 'app is required'
512
+
467
513
  showed_sources = sorted(sources)
468
514
  if len(showed_sources) > 20:
469
515
  showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
470
- logger.info(__('[autosummary] generating autosummary for: %s') %
471
- ', '.join(showed_sources))
516
+ logger.info(__('[autosummary] generating autosummary for: %s'), ', '.join(showed_sources))
472
517
 
473
518
  if output_dir:
474
- logger.info(__('[autosummary] writing to %s') % output_dir)
519
+ logger.info(__('[autosummary] writing to %s'), output_dir)
475
520
 
476
521
  if base_path is not None:
477
522
  sources = [os.path.join(base_path, filename) for filename in sources]
@@ -482,12 +527,10 @@ def generate_autosummary_docs(sources: list[str],
482
527
  items = find_autosummary_in_files(sources)
483
528
 
484
529
  # keep track of new files
485
- new_files = []
530
+ new_files: list[Path] = []
531
+ all_files: list[Path] = []
486
532
 
487
- if app:
488
- filename_map = app.config.autosummary_filename_map
489
- else:
490
- filename_map = {}
533
+ filename_map = app.config.autosummary_filename_map
491
534
 
492
535
  # write
493
536
  for entry in sorted(set(items), key=str):
@@ -501,57 +544,79 @@ def generate_autosummary_docs(sources: list[str],
501
544
 
502
545
  try:
503
546
  name, obj, parent, modname = import_by_name(entry.name)
504
- qualname = name.replace(modname + ".", "")
547
+ qualname = name.replace(modname + '.', '')
505
548
  except ImportExceptionGroup as exc:
506
549
  try:
507
550
  # try to import as an instance attribute
508
551
  name, obj, parent, modname = import_ivar_by_name(entry.name)
509
- qualname = name.replace(modname + ".", "")
552
+ qualname = name.replace(modname + '.', '')
510
553
  except ImportError as exc2:
511
554
  if exc2.__cause__:
512
555
  exceptions: list[BaseException] = [*exc.exceptions, exc2.__cause__]
513
556
  else:
514
557
  exceptions = [*exc.exceptions, exc2]
515
558
 
516
- errors = list({f"* {type(e).__name__}: {e}" for e in exceptions})
517
- logger.warning(__('[autosummary] failed to import %s.\nPossible hints:\n%s'),
518
- entry.name, '\n'.join(errors))
559
+ errors = list({f'* {type(e).__name__}: {e}' for e in exceptions})
560
+ logger.warning(
561
+ __('[autosummary] failed to import %s.\nPossible hints:\n%s'),
562
+ entry.name,
563
+ '\n'.join(errors),
564
+ )
519
565
  continue
520
566
 
521
- context: dict[str, Any] = {}
522
- if app:
523
- context.update(app.config.autosummary_context)
524
-
525
- content = generate_autosummary_content(name, obj, parent, template, entry.template,
526
- imported_members, app, entry.recursive, context,
527
- modname, qualname)
528
-
529
- filename = os.path.join(path, filename_map.get(name, name) + suffix)
530
- if os.path.isfile(filename):
531
- with open(filename, encoding=encoding) as f:
567
+ context: dict[str, Any] = {**app.config.autosummary_context}
568
+
569
+ content = generate_autosummary_content(
570
+ name,
571
+ obj,
572
+ parent,
573
+ template,
574
+ entry.template,
575
+ imported_members,
576
+ app,
577
+ entry.recursive,
578
+ context,
579
+ modname,
580
+ qualname,
581
+ )
582
+
583
+ file_path = Path(path, filename_map.get(name, name) + suffix)
584
+ all_files.append(file_path)
585
+ if file_path.is_file():
586
+ with file_path.open(encoding=encoding) as f:
532
587
  old_content = f.read()
533
588
 
534
589
  if content == old_content:
535
590
  continue
536
591
  if overwrite: # content has changed
537
- with open(filename, 'w', encoding=encoding) as f:
592
+ with file_path.open('w', encoding=encoding) as f:
538
593
  f.write(content)
539
- new_files.append(filename)
594
+ new_files.append(file_path)
540
595
  else:
541
- with open(filename, 'w', encoding=encoding) as f:
596
+ with open(file_path, 'w', encoding=encoding) as f:
542
597
  f.write(content)
543
- new_files.append(filename)
598
+ new_files.append(file_path)
544
599
 
545
600
  # descend recursively to new files
546
601
  if new_files:
547
- generate_autosummary_docs(new_files, output_dir=output_dir,
548
- suffix=suffix, base_path=base_path,
549
- imported_members=imported_members, app=app,
550
- overwrite=overwrite)
602
+ all_files.extend(
603
+ generate_autosummary_docs(
604
+ [str(f) for f in new_files],
605
+ output_dir=output_dir,
606
+ suffix=suffix,
607
+ base_path=base_path,
608
+ imported_members=imported_members,
609
+ app=app,
610
+ overwrite=overwrite,
611
+ )
612
+ )
613
+
614
+ return all_files
551
615
 
552
616
 
553
617
  # -- Finding documented entries in files ---------------------------------------
554
618
 
619
+
555
620
  def find_autosummary_in_files(filenames: list[str]) -> list[AutosummaryEntry]:
556
621
  """Find out what items are documented in source/*.rst.
557
622
 
@@ -566,7 +631,8 @@ def find_autosummary_in_files(filenames: list[str]) -> list[AutosummaryEntry]:
566
631
 
567
632
 
568
633
  def find_autosummary_in_docstring(
569
- name: str, filename: str | None = None,
634
+ name: str,
635
+ filename: str | None = None,
570
636
  ) -> list[AutosummaryEntry]:
571
637
  """Find out what items are documented in the given object's docstring.
572
638
 
@@ -579,16 +645,21 @@ def find_autosummary_in_docstring(
579
645
  except AttributeError:
580
646
  pass
581
647
  except ImportExceptionGroup as exc:
582
- errors = '\n'.join({f"* {type(e).__name__}: {e}" for e in exc.exceptions})
648
+ errors = '\n'.join({f'* {type(e).__name__}: {e}' for e in exc.exceptions})
583
649
  logger.warning(f'Failed to import {name}.\nPossible hints:\n{errors}') # NoQA: G004
584
650
  except SystemExit:
585
- logger.warning("Failed to import '%s'; the module executes module level "
586
- 'statement and it might call sys.exit().', name)
651
+ logger.warning(
652
+ "Failed to import '%s'; the module executes module level "
653
+ 'statement and it might call sys.exit().',
654
+ name,
655
+ )
587
656
  return []
588
657
 
589
658
 
590
659
  def find_autosummary_in_lines(
591
- lines: list[str], module: str | None = None, filename: str | None = None,
660
+ lines: list[str],
661
+ module: str | None = None,
662
+ filename: str | None = None,
592
663
  ) -> list[AutosummaryEntry]:
593
664
  """Find out what items appear in autosummary:: directives in the
594
665
  given lines.
@@ -601,10 +672,8 @@ def find_autosummary_in_lines(
601
672
  corresponding options set.
602
673
  """
603
674
  autosummary_re = re.compile(r'^(\s*)\.\.\s+autosummary::\s*')
604
- automodule_re = re.compile(
605
- r'^\s*\.\.\s+automodule::\s*([A-Za-z0-9_.]+)\s*$')
606
- module_re = re.compile(
607
- r'^\s*\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
675
+ automodule_re = re.compile(r'^\s*\.\.\s+automodule::\s*([A-Za-z0-9_.]+)\s*$')
676
+ module_re = re.compile(r'^\s*\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
608
677
  autosummary_item_re = re.compile(r'^\s+(~?[_a-zA-Z][a-zA-Z0-9_.]*)\s*.*?')
609
678
  recursive_arg_re = re.compile(r'^\s+:recursive:\s*$')
610
679
  toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
@@ -617,7 +686,7 @@ def find_autosummary_in_lines(
617
686
  template = ''
618
687
  current_module = module
619
688
  in_autosummary = False
620
- base_indent = ""
689
+ base_indent = ''
621
690
 
622
691
  for line in lines:
623
692
  if in_autosummary:
@@ -630,8 +699,7 @@ def find_autosummary_in_lines(
630
699
  if m:
631
700
  toctree = m.group(1)
632
701
  if filename:
633
- toctree = os.path.join(os.path.dirname(filename),
634
- toctree)
702
+ toctree = os.path.join(os.path.dirname(filename), toctree)
635
703
  continue
636
704
 
637
705
  m = template_arg_re.match(line)
@@ -647,13 +715,12 @@ def find_autosummary_in_lines(
647
715
  name = m.group(1).strip()
648
716
  if name.startswith('~'):
649
717
  name = name[1:]
650
- if current_module and \
651
- not name.startswith(current_module + '.'):
652
- name = f"{current_module}.{name}"
718
+ if current_module and not name.startswith(current_module + '.'):
719
+ name = f'{current_module}.{name}'
653
720
  documented.append(AutosummaryEntry(name, toctree, template, recursive))
654
721
  continue
655
722
 
656
- if not line.strip() or line.startswith(base_indent + " "):
723
+ if not line.strip() or line.startswith(base_indent + ' '):
657
724
  continue
658
725
 
659
726
  in_autosummary = False
@@ -671,8 +738,7 @@ def find_autosummary_in_lines(
671
738
  if m:
672
739
  current_module = m.group(1).strip()
673
740
  # recurse into the automodule docstring
674
- documented.extend(find_autosummary_in_docstring(
675
- current_module, filename=filename))
741
+ documented.extend(find_autosummary_in_docstring(current_module, filename=filename))
676
742
  continue
677
743
 
678
744
  m = module_re.match(line)
@@ -698,33 +764,69 @@ The format of the autosummary directive is documented in the
698
764
  ``sphinx.ext.autosummary`` Python module and can be read using::
699
765
 
700
766
  pydoc sphinx.ext.autosummary
701
- """))
702
-
703
- parser.add_argument('--version', action='version', dest='show_version',
704
- version='%%(prog)s %s' % __display_version__)
705
-
706
- parser.add_argument('source_file', nargs='+',
707
- help=__('source files to generate rST files for'))
708
-
709
- parser.add_argument('-o', '--output-dir', action='store',
710
- dest='output_dir',
711
- help=__('directory to place all output in'))
712
- parser.add_argument('-s', '--suffix', action='store', dest='suffix',
713
- default='rst',
714
- help=__('default suffix for files (default: '
715
- '%(default)s)'))
716
- parser.add_argument('-t', '--templates', action='store', dest='templates',
717
- default=None,
718
- help=__('custom template directory (default: '
719
- '%(default)s)'))
720
- parser.add_argument('-i', '--imported-members', action='store_true',
721
- dest='imported_members', default=False,
722
- help=__('document imported members (default: '
723
- '%(default)s)'))
724
- parser.add_argument('-a', '--respect-module-all', action='store_true',
725
- dest='respect_module_all', default=False,
726
- help=__('document exactly the members in module __all__ attribute. '
727
- '(default: %(default)s)'))
767
+ """),
768
+ )
769
+
770
+ parser.add_argument(
771
+ '--version',
772
+ action='version',
773
+ dest='show_version',
774
+ version='%%(prog)s %s' % __display_version__,
775
+ )
776
+
777
+ parser.add_argument(
778
+ 'source_file', nargs='+', help=__('source files to generate rST files for')
779
+ )
780
+
781
+ parser.add_argument(
782
+ '-o',
783
+ '--output-dir',
784
+ action='store',
785
+ dest='output_dir',
786
+ help=__('directory to place all output in'),
787
+ )
788
+ parser.add_argument(
789
+ '-s',
790
+ '--suffix',
791
+ action='store',
792
+ dest='suffix',
793
+ default='rst',
794
+ help=__('default suffix for files (default: ' '%(default)s)'),
795
+ )
796
+ parser.add_argument(
797
+ '-t',
798
+ '--templates',
799
+ action='store',
800
+ dest='templates',
801
+ default=None,
802
+ help=__('custom template directory (default: ' '%(default)s)'),
803
+ )
804
+ parser.add_argument(
805
+ '-i',
806
+ '--imported-members',
807
+ action='store_true',
808
+ dest='imported_members',
809
+ default=False,
810
+ help=__('document imported members (default: ' '%(default)s)'),
811
+ )
812
+ parser.add_argument(
813
+ '-a',
814
+ '--respect-module-all',
815
+ action='store_true',
816
+ dest='respect_module_all',
817
+ default=False,
818
+ help=__(
819
+ 'document exactly the members in module __all__ attribute. '
820
+ '(default: %(default)s)'
821
+ ),
822
+ )
823
+ parser.add_argument(
824
+ '--remove-old',
825
+ action='store_true',
826
+ dest='remove_old',
827
+ default=False,
828
+ help=__('Remove existing files in the output directory that were not generated'),
829
+ )
728
830
 
729
831
  return parser
730
832
 
@@ -740,14 +842,28 @@ def main(argv: Sequence[str] = (), /) -> None:
740
842
 
741
843
  if args.templates:
742
844
  app.config.templates_path.append(path.abspath(args.templates))
743
- app.config.autosummary_ignore_module_all = ( # type: ignore[attr-defined]
744
- not args.respect_module_all
845
+ app.config.autosummary_ignore_module_all = not args.respect_module_all
846
+
847
+ written_files = generate_autosummary_docs(
848
+ args.source_file,
849
+ args.output_dir,
850
+ '.' + args.suffix,
851
+ imported_members=args.imported_members,
852
+ app=app, # type: ignore[arg-type]
745
853
  )
746
854
 
747
- generate_autosummary_docs(args.source_file, args.output_dir,
748
- '.' + args.suffix,
749
- imported_members=args.imported_members,
750
- app=app)
855
+ if args.remove_old:
856
+ for existing in Path(args.output_dir).glob(f'**/*.{args.suffix}'):
857
+ if existing not in written_files:
858
+ try:
859
+ existing.unlink()
860
+ except OSError as exc:
861
+ logger.warning(
862
+ __('Failed to remove %s: %s'),
863
+ existing,
864
+ exc.strerror,
865
+ type='autosummary',
866
+ )
751
867
 
752
868
 
753
869
  if __name__ == '__main__':