3
3
4
4
from sphinx .util import logging
5
5
from sphinx .application import Sphinx
6
- from sphinx .config import Config
6
+ from sphinx .config import Config , ENUM
7
7
from sphinx .util .docutils import SphinxDirective
8
8
9
9
from docutils .parsers .rst import directives
@@ -24,43 +24,59 @@ def __getitem__(self, _):
24
24
return directives .unchanged
25
25
26
26
27
- class MockDirective (SphinxDirective ):
28
- optional_arguments = 1
29
- final_argument_whitespace = True
30
- option_spec = MockOptionSpec ()
31
- has_content = True
27
+ def _make_mock_directive (mode : str ):
28
+ """Factory function to create a MockDirective class with pre-configured mode."""
32
29
33
- def run (self ) -> List [nodes .Node ]:
34
- mode = None
35
- for d in self .config .mock_directives :
36
- name = d if isinstance (d , str ) else d [0 ]
37
- if self .name != name :
38
- continue
39
- mode = self .config .mock_default_mode if isinstance (d , str ) else d [1 ]
40
- break
30
+ class MockDirective (SphinxDirective ):
31
+ optional_arguments = 1
32
+ final_argument_whitespace = True
33
+ option_spec = MockOptionSpec ()
34
+ has_content = True
41
35
42
- if mode == 'literal' :
43
- literal = nodes .literal_block (self .block_text , self .block_text )
44
- literal ['language' ] = 'rst'
45
- return [literal ]
46
- elif mode == 'hide' :
47
- return []
48
- else :
49
- raise ValueError ('unsupported mock mode' )
36
+ def run (self ) -> List [nodes .Node ]:
37
+ if mode == 'literal' :
38
+ literal = nodes .literal_block (self .block_text , self .block_text )
39
+ literal ['language' ] = 'rst'
40
+ return [literal ]
41
+ else : # mode == 'hide' (validated in _config_inited)
42
+ return []
50
43
44
+ return MockDirective
51
45
52
46
53
47
def _config_inited (app :Sphinx , config :Config ) -> None :
54
48
for d in config .mock_directives :
55
49
name = d if isinstance (d , str ) else d [0 ]
56
- app .add_directive (name , MockDirective , override = True )
50
+ mode = config .mock_default_mode if isinstance (d , str ) else d [1 ]
51
+
52
+ if mode not in ('literal' , 'hide' ):
53
+ raise ValueError (
54
+ f'Invalid mock mode for directive "{ name } ": { mode !r} . '
55
+ f'Must be "literal" or "hide"'
56
+ )
57
+
58
+ directive_class = _make_mock_directive (mode )
59
+ app .add_directive (name , directive_class , override = True )
57
60
58
61
59
62
def setup (app :Sphinx ) -> Dict :
60
63
"""Sphinx extension entrypoint."""
61
64
62
- app .add_config_value ('mock_directives' , [], 'env' )
63
- app .add_config_value ('mock_default_mode' , 'hide' , 'env' )
65
+ app .add_config_value (
66
+ 'mock_directives' ,
67
+ default = [],
68
+ rebuild = 'env' ,
69
+ types = [list ],
70
+ description = 'List of directive names to mock. Each item can be a string (directive name) '
71
+ 'or a tuple (directive name, mode).'
72
+ )
73
+ app .add_config_value (
74
+ 'mock_default_mode' ,
75
+ default = 'hide' ,
76
+ rebuild = 'env' ,
77
+ types = ENUM ('hide' , 'literal' ),
78
+ description = 'Default mode for mocking directives. Valid values: "hide", "literal".'
79
+ )
64
80
app .connect ('config-inited' , _config_inited )
65
81
66
82
return {'version' : __version__ }
0 commit comments