Skip to content

Commit f969041

Browse files
authored
Define valid types for all configuration values (sphinx-doc#13324)
1 parent b59d1b7 commit f969041

33 files changed

+418
-231
lines changed

sphinx/builders/epub3.py

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -287,33 +287,65 @@ def setup(app: Sphinx) -> ExtensionMetadata:
287287
app.add_builder(Epub3Builder)
288288

289289
# config values
290-
app.add_config_value('epub_basename', lambda self: make_filename(self.project), '')
291-
app.add_config_value('epub_version', 3.0, 'epub') # experimental
292-
app.add_config_value('epub_theme', 'epub', 'epub')
293-
app.add_config_value('epub_theme_options', {}, 'epub')
294-
app.add_config_value('epub_title', lambda self: self.project, 'epub')
295-
app.add_config_value('epub_author', lambda self: self.author, 'epub')
296-
app.add_config_value('epub_language', lambda self: self.language or 'en', 'epub')
297-
app.add_config_value('epub_publisher', lambda self: self.author, 'epub')
298-
app.add_config_value('epub_copyright', lambda self: self.copyright, 'epub')
299-
app.add_config_value('epub_identifier', 'unknown', 'epub')
300-
app.add_config_value('epub_scheme', 'unknown', 'epub')
301-
app.add_config_value('epub_uid', 'unknown', 'env')
302-
app.add_config_value('epub_cover', (), 'env')
303-
app.add_config_value('epub_guide', (), 'env')
304-
app.add_config_value('epub_pre_files', [], 'env')
305-
app.add_config_value('epub_post_files', [], 'env')
306-
app.add_config_value('epub_css_files', lambda config: config.html_css_files, 'epub')
307-
app.add_config_value('epub_exclude_files', [], 'env')
308-
app.add_config_value('epub_tocdepth', 3, 'env')
309-
app.add_config_value('epub_tocdup', True, 'env')
310-
app.add_config_value('epub_tocscope', 'default', 'env')
311-
app.add_config_value('epub_fix_images', False, 'env')
312-
app.add_config_value('epub_max_image_width', 0, 'env')
313-
app.add_config_value('epub_show_urls', 'inline', 'epub')
314-
app.add_config_value('epub_use_index', lambda self: self.html_use_index, 'epub')
315-
app.add_config_value('epub_description', 'unknown', 'epub')
316-
app.add_config_value('epub_contributor', 'unknown', 'epub')
290+
app.add_config_value(
291+
'epub_basename',
292+
lambda self: make_filename(self.project),
293+
'',
294+
types=frozenset({str}),
295+
)
296+
app.add_config_value(
297+
'epub_version', 3.0, 'epub', types=frozenset({float})
298+
) # experimental
299+
app.add_config_value('epub_theme', 'epub', 'epub', types=frozenset({str}))
300+
app.add_config_value('epub_theme_options', {}, 'epub', types=frozenset({dict}))
301+
app.add_config_value(
302+
'epub_title', lambda self: self.project, 'epub', types=frozenset({str})
303+
)
304+
app.add_config_value(
305+
'epub_author', lambda self: self.author, 'epub', types=frozenset({str})
306+
)
307+
app.add_config_value(
308+
'epub_language',
309+
lambda self: self.language or 'en',
310+
'epub',
311+
types=frozenset({str}),
312+
)
313+
app.add_config_value(
314+
'epub_publisher', lambda self: self.author, 'epub', types=frozenset({str})
315+
)
316+
app.add_config_value(
317+
'epub_copyright', lambda self: self.copyright, 'epub', types=frozenset({str})
318+
)
319+
app.add_config_value('epub_identifier', 'unknown', 'epub', types=frozenset({str}))
320+
app.add_config_value('epub_scheme', 'unknown', 'epub', types=frozenset({str}))
321+
app.add_config_value('epub_uid', 'unknown', 'env', types=frozenset({str}))
322+
app.add_config_value('epub_cover', (), 'env', types=frozenset({list, tuple}))
323+
app.add_config_value('epub_guide', (), 'env', types=frozenset({list, tuple}))
324+
app.add_config_value('epub_pre_files', [], 'env', types=frozenset({list, tuple}))
325+
app.add_config_value('epub_post_files', [], 'env', types=frozenset({list, tuple}))
326+
app.add_config_value(
327+
'epub_css_files',
328+
lambda config: config.html_css_files,
329+
'epub',
330+
types=frozenset({list, tuple}),
331+
)
332+
app.add_config_value(
333+
'epub_exclude_files', [], 'env', types=frozenset({list, tuple})
334+
)
335+
app.add_config_value('epub_tocdepth', 3, 'env', types=frozenset({int}))
336+
app.add_config_value('epub_tocdup', True, 'env', types=frozenset({bool}))
337+
app.add_config_value('epub_tocscope', 'default', 'env', types=frozenset({str}))
338+
app.add_config_value('epub_fix_images', False, 'env', types=frozenset({bool}))
339+
app.add_config_value('epub_max_image_width', 0, 'env', types=frozenset({int}))
340+
app.add_config_value('epub_show_urls', 'inline', 'epub', types=frozenset({str}))
341+
app.add_config_value(
342+
'epub_use_index',
343+
lambda self: self.html_use_index,
344+
'epub',
345+
types=frozenset({bool}),
346+
)
347+
app.add_config_value('epub_description', 'unknown', 'epub', types=frozenset({str}))
348+
app.add_config_value('epub_contributor', 'unknown', 'epub', types=frozenset({str}))
317349
app.add_config_value(
318350
'epub_writing_mode', 'horizontal', 'epub', types=ENUM('horizontal', 'vertical')
319351
)

sphinx/builders/gettext.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -332,16 +332,27 @@ def setup(app: Sphinx) -> ExtensionMetadata:
332332
app.add_config_value(
333333
'gettext_compact', True, 'gettext', types=frozenset({bool, str})
334334
)
335-
app.add_config_value('gettext_location', True, 'gettext')
336-
app.add_config_value('gettext_uuid', False, 'gettext')
337-
app.add_config_value('gettext_auto_build', True, 'env')
335+
app.add_config_value('gettext_location', True, 'gettext', types=frozenset({bool}))
336+
app.add_config_value('gettext_uuid', False, 'gettext', types=frozenset({bool}))
337+
app.add_config_value('gettext_auto_build', True, 'env', types=frozenset({bool}))
338338
app.add_config_value(
339-
'gettext_additional_targets', [], 'env', types=frozenset({set, list})
339+
'gettext_additional_targets',
340+
[],
341+
'env',
342+
types=frozenset({frozenset, list, set, tuple}),
340343
)
341344
app.add_config_value(
342-
'gettext_last_translator', 'FULL NAME <EMAIL@ADDRESS>', 'gettext'
345+
'gettext_last_translator',
346+
'FULL NAME <EMAIL@ADDRESS>',
347+
'gettext',
348+
types=frozenset({str}),
349+
)
350+
app.add_config_value(
351+
'gettext_language_team',
352+
'LANGUAGE <[email protected]>',
353+
'gettext',
354+
types=frozenset({str}),
343355
)
344-
app.add_config_value('gettext_language_team', 'LANGUAGE <[email protected]>', 'gettext')
345356

346357
return {
347358
'version': 'builtin',

sphinx/builders/html/__init__.py

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import sys
1313
import warnings
1414
from pathlib import Path
15+
from types import NoneType
1516
from typing import TYPE_CHECKING
1617
from urllib.parse import quote
1718

@@ -1439,60 +1440,77 @@ def setup(app: Sphinx) -> ExtensionMetadata:
14391440
app.add_builder(StandaloneHTMLBuilder)
14401441

14411442
# config values
1442-
app.add_config_value('html_theme', 'alabaster', 'html')
1443-
app.add_config_value('html_theme_path', [], 'html')
1444-
app.add_config_value('html_theme_options', {}, 'html')
1443+
app.add_config_value('html_theme', 'alabaster', 'html', types=frozenset({str}))
1444+
app.add_config_value('html_theme_path', [], 'html', types=frozenset({list, tuple}))
1445+
app.add_config_value('html_theme_options', {}, 'html', types=frozenset({dict}))
14451446
app.add_config_value(
14461447
'html_title',
14471448
lambda c: _('%s %s documentation') % (c.project, c.release),
14481449
'html',
14491450
types=frozenset({str}),
14501451
)
1451-
app.add_config_value('html_short_title', lambda self: self.html_title, 'html')
1452-
app.add_config_value('html_style', None, 'html', types=frozenset({list, str}))
1452+
app.add_config_value(
1453+
'html_short_title', lambda self: self.html_title, 'html', types=frozenset({str})
1454+
)
1455+
app.add_config_value(
1456+
'html_style', None, 'html', types=frozenset({list, str, tuple})
1457+
)
14531458
app.add_config_value('html_logo', None, 'html', types=frozenset({str}))
14541459
app.add_config_value('html_favicon', None, 'html', types=frozenset({str}))
1455-
app.add_config_value('html_css_files', [], 'html')
1456-
app.add_config_value('html_js_files', [], 'html')
1457-
app.add_config_value('html_static_path', [], 'html')
1458-
app.add_config_value('html_extra_path', [], 'html')
1460+
app.add_config_value('html_css_files', [], 'html', types=frozenset({list, tuple}))
1461+
app.add_config_value('html_js_files', [], 'html', types=frozenset({list, tuple}))
1462+
app.add_config_value('html_static_path', [], 'html', types=frozenset({list, tuple}))
1463+
app.add_config_value('html_extra_path', [], 'html', types=frozenset({list, tuple}))
14591464
app.add_config_value('html_last_updated_fmt', None, 'html', types=frozenset({str}))
14601465
app.add_config_value(
14611466
'html_last_updated_use_utc', False, 'html', types=frozenset({bool})
14621467
)
1463-
app.add_config_value('html_sidebars', {}, 'html')
1464-
app.add_config_value('html_additional_pages', {}, 'html')
1468+
app.add_config_value('html_sidebars', {}, 'html', types=frozenset({dict}))
1469+
app.add_config_value('html_additional_pages', {}, 'html', types=frozenset({dict}))
14651470
app.add_config_value(
1466-
'html_domain_indices', True, 'html', types=frozenset({set, list})
1471+
'html_domain_indices',
1472+
True,
1473+
'html',
1474+
types=frozenset({frozenset, list, set, tuple}),
1475+
)
1476+
app.add_config_value('html_permalinks', True, 'html', types=frozenset({bool}))
1477+
app.add_config_value('html_permalinks_icon', '¶', 'html', types=frozenset({str}))
1478+
app.add_config_value('html_use_index', True, 'html', types=frozenset({bool}))
1479+
app.add_config_value('html_split_index', False, 'html', types=frozenset({bool}))
1480+
app.add_config_value('html_copy_source', True, 'html', types=frozenset({bool}))
1481+
app.add_config_value('html_show_sourcelink', True, 'html', types=frozenset({bool}))
1482+
app.add_config_value(
1483+
'html_sourcelink_suffix', '.txt', 'html', types=frozenset({str})
14671484
)
1468-
app.add_config_value('html_permalinks', True, 'html')
1469-
app.add_config_value('html_permalinks_icon', '¶', 'html')
1470-
app.add_config_value('html_use_index', True, 'html')
1471-
app.add_config_value('html_split_index', False, 'html')
1472-
app.add_config_value('html_copy_source', True, 'html')
1473-
app.add_config_value('html_show_sourcelink', True, 'html')
1474-
app.add_config_value('html_sourcelink_suffix', '.txt', 'html')
1475-
app.add_config_value('html_use_opensearch', '', 'html')
1485+
app.add_config_value('html_use_opensearch', '', 'html', types=frozenset({str}))
14761486
app.add_config_value('html_file_suffix', None, 'html', types=frozenset({str}))
14771487
app.add_config_value('html_link_suffix', None, 'html', types=frozenset({str}))
1478-
app.add_config_value('html_show_copyright', True, 'html')
1479-
app.add_config_value('html_show_search_summary', True, 'html')
1480-
app.add_config_value('html_show_sphinx', True, 'html')
1481-
app.add_config_value('html_context', {}, 'html')
1482-
app.add_config_value('html_output_encoding', 'utf-8', 'html')
1483-
app.add_config_value('html_compact_lists', True, 'html')
1484-
app.add_config_value('html_secnumber_suffix', '. ', 'html')
1488+
app.add_config_value('html_show_copyright', True, 'html', types=frozenset({bool}))
1489+
app.add_config_value(
1490+
'html_show_search_summary', True, 'html', types=frozenset({bool})
1491+
)
1492+
app.add_config_value('html_show_sphinx', True, 'html', types=frozenset({bool}))
1493+
app.add_config_value('html_context', {}, 'html', types=frozenset({dict}))
1494+
app.add_config_value(
1495+
'html_output_encoding', 'utf-8', 'html', types=frozenset({str})
1496+
)
1497+
app.add_config_value('html_compact_lists', True, 'html', types=frozenset({bool}))
1498+
app.add_config_value('html_secnumber_suffix', '. ', 'html', types=frozenset({str}))
14851499
app.add_config_value('html_search_language', None, 'html', types=frozenset({str}))
1486-
app.add_config_value('html_search_options', {}, 'html')
1487-
app.add_config_value('html_search_scorer', '', '')
1488-
app.add_config_value('html_scaled_image_link', True, 'html')
1489-
app.add_config_value('html_baseurl', '', 'html')
1500+
app.add_config_value('html_search_options', {}, 'html', types=frozenset({dict}))
1501+
app.add_config_value('html_search_scorer', '', '', types=frozenset({str}))
1502+
app.add_config_value(
1503+
'html_scaled_image_link', True, 'html', types=frozenset({bool})
1504+
)
1505+
app.add_config_value('html_baseurl', '', 'html', types=frozenset({str}))
14901506
# removal is indefinitely on hold (ref: https://github.com/sphinx-doc/sphinx/issues/10265)
14911507
app.add_config_value(
14921508
'html_codeblock_linenos_style', 'inline', 'html', types=ENUM('table', 'inline')
14931509
)
1494-
app.add_config_value('html_math_renderer', None, 'env')
1495-
app.add_config_value('html4_writer', False, 'html')
1510+
app.add_config_value(
1511+
'html_math_renderer', None, 'env', types=frozenset({str, NoneType})
1512+
)
1513+
app.add_config_value('html4_writer', False, 'html', types=frozenset({bool}))
14961514

14971515
# events
14981516
app.add_event('html-collect-pages')

sphinx/builders/latex/__init__.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,14 @@ def setup(app: Sphinx) -> ExtensionMetadata:
608608
'',
609609
types=ENUM('pdflatex', 'xelatex', 'lualatex', 'platex', 'uplatex'),
610610
)
611-
app.add_config_value('latex_documents', default_latex_documents, '')
611+
app.add_config_value(
612+
'latex_documents', default_latex_documents, '', types=frozenset({list, tuple})
613+
)
612614
app.add_config_value('latex_logo', None, '', types=frozenset({str}))
613-
app.add_config_value('latex_appendices', [], '')
614-
app.add_config_value('latex_use_latex_multicolumn', False, '')
615+
app.add_config_value('latex_appendices', [], '', types=frozenset({list, tuple}))
616+
app.add_config_value(
617+
'latex_use_latex_multicolumn', False, '', types=frozenset({bool})
618+
)
615619
app.add_config_value(
616620
'latex_use_xindy', default_latex_use_xindy, '', types=frozenset({bool})
617621
)
@@ -621,19 +625,25 @@ def setup(app: Sphinx) -> ExtensionMetadata:
621625
'',
622626
types=ENUM(None, 'part', 'chapter', 'section'),
623627
)
624-
app.add_config_value('latex_domain_indices', True, '', types=frozenset({set, list}))
625-
app.add_config_value('latex_show_urls', 'no', '')
626-
app.add_config_value('latex_show_pagerefs', False, '')
627-
app.add_config_value('latex_elements', {}, '')
628-
app.add_config_value('latex_additional_files', [], '')
628+
app.add_config_value(
629+
'latex_domain_indices', True, '', types=frozenset({frozenset, list, set, tuple})
630+
)
631+
app.add_config_value('latex_show_urls', 'no', '', types=frozenset({str}))
632+
app.add_config_value('latex_show_pagerefs', False, '', types=frozenset({bool}))
633+
app.add_config_value('latex_elements', {}, '', types=frozenset({dict}))
634+
app.add_config_value(
635+
'latex_additional_files', [], '', types=frozenset({list, tuple})
636+
)
629637
app.add_config_value(
630638
'latex_table_style', ['booktabs', 'colorrows'], '', types=frozenset({list})
631639
)
632640
app.add_config_value('latex_theme', 'manual', '', types=frozenset({str}))
633-
app.add_config_value('latex_theme_options', {}, '')
641+
app.add_config_value('latex_theme_options', {}, '', types=frozenset({dict}))
634642
app.add_config_value('latex_theme_path', [], '', types=frozenset({list}))
635643

636-
app.add_config_value('latex_docclass', default_latex_docclass, '')
644+
app.add_config_value(
645+
'latex_docclass', default_latex_docclass, '', types=frozenset({dict})
646+
)
637647

638648
return {
639649
'version': 'builtin',

sphinx/builders/linkcheck.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -768,25 +768,31 @@ def setup(app: Sphinx) -> ExtensionMetadata:
768768
app.add_builder(CheckExternalLinksBuilder)
769769
app.add_post_transform(HyperlinkCollector)
770770

771-
app.add_config_value('linkcheck_ignore', [], '')
772-
app.add_config_value('linkcheck_exclude_documents', [], '')
773-
app.add_config_value('linkcheck_allowed_redirects', {}, '')
774-
app.add_config_value('linkcheck_auth', [], '')
775-
app.add_config_value('linkcheck_request_headers', {}, '')
776-
app.add_config_value('linkcheck_retries', 1, '')
777-
app.add_config_value('linkcheck_timeout', 30, '', types=frozenset({int, float}))
778-
app.add_config_value('linkcheck_workers', 5, '')
779-
app.add_config_value('linkcheck_anchors', True, '')
771+
app.add_config_value('linkcheck_ignore', [], '', types=frozenset({list, tuple}))
772+
app.add_config_value(
773+
'linkcheck_exclude_documents', [], '', types=frozenset({list, tuple})
774+
)
775+
app.add_config_value('linkcheck_allowed_redirects', {}, '', types=frozenset({dict}))
776+
app.add_config_value('linkcheck_auth', [], '', types=frozenset({list, tuple}))
777+
app.add_config_value('linkcheck_request_headers', {}, '', types=frozenset({dict}))
778+
app.add_config_value('linkcheck_retries', 1, '', types=frozenset({int}))
779+
app.add_config_value('linkcheck_timeout', 30, '', types=frozenset({float, int}))
780+
app.add_config_value('linkcheck_workers', 5, '', types=frozenset({int}))
781+
app.add_config_value('linkcheck_anchors', True, '', types=frozenset({bool}))
780782
# Anchors starting with ! are ignored since they are
781783
# commonly used for dynamic pages
782-
app.add_config_value('linkcheck_anchors_ignore', ['^!'], '')
783784
app.add_config_value(
784-
'linkcheck_anchors_ignore_for_url', (), '', types=frozenset({tuple, list})
785+
'linkcheck_anchors_ignore', ['^!'], '', types=frozenset({list, tuple})
786+
)
787+
app.add_config_value(
788+
'linkcheck_anchors_ignore_for_url', (), '', types=frozenset({list, tuple})
789+
)
790+
app.add_config_value(
791+
'linkcheck_rate_limit_timeout', 300.0, '', types=frozenset({float, int})
785792
)
786793
app.add_config_value(
787-
'linkcheck_rate_limit_timeout', 300.0, '', types=frozenset({int, float})
794+
'linkcheck_allow_unauthorized', False, '', types=frozenset({bool})
788795
)
789-
app.add_config_value('linkcheck_allow_unauthorized', False, '')
790796
app.add_config_value(
791797
'linkcheck_report_timeouts_as_broken', False, '', types=frozenset({bool})
792798
)

sphinx/builders/manpage.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,13 @@ def default_man_pages(config: Config) -> list[tuple[str, str, str, list[str], in
131131
def setup(app: Sphinx) -> ExtensionMetadata:
132132
app.add_builder(ManualPageBuilder)
133133

134-
app.add_config_value('man_pages', default_man_pages, '')
135-
app.add_config_value('man_show_urls', False, '')
136-
app.add_config_value('man_make_section_directory', False, '')
134+
app.add_config_value(
135+
'man_pages', default_man_pages, '', types=frozenset({list, tuple})
136+
)
137+
app.add_config_value('man_show_urls', False, '', types=frozenset({bool}))
138+
app.add_config_value(
139+
'man_make_section_directory', False, '', types=frozenset({bool})
140+
)
137141

138142
return {
139143
'version': 'builtin',

sphinx/builders/singlehtml.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,12 @@ def setup(app: Sphinx) -> ExtensionMetadata:
209209
app.setup_extension('sphinx.builders.html')
210210

211211
app.add_builder(SingleFileHTMLBuilder)
212-
app.add_config_value('singlehtml_sidebars', lambda self: self.html_sidebars, 'html')
212+
app.add_config_value(
213+
'singlehtml_sidebars',
214+
lambda self: self.html_sidebars,
215+
'html',
216+
types=frozenset({dict}),
217+
)
213218

214219
return {
215220
'version': 'builtin',

0 commit comments

Comments
 (0)