##// END OF EJS Templates
Include command line aliases in config docs
Thomas Kluyver -
Show More
@@ -1,91 +1,125 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2
2
3 from os.path import join, dirname, abspath
3 from os.path import join, dirname, abspath
4
4
5 from IPython.terminal.ipapp import TerminalIPythonApp
5 from IPython.terminal.ipapp import TerminalIPythonApp
6 from ipykernel.kernelapp import IPKernelApp
6 from ipykernel.kernelapp import IPKernelApp
7 from traitlets import Undefined
7 from traitlets import Undefined
8 from collections import defaultdict
8
9
9 here = abspath(dirname(__file__))
10 here = abspath(dirname(__file__))
10 options = join(here, 'source', 'config', 'options')
11 options = join(here, 'source', 'config', 'options')
11 generated = join(options, 'config-generated.txt')
12 generated = join(options, 'config-generated.txt')
12
13
13 from ipython_genutils.text import indent, dedent
14 from ipython_genutils.text import indent, dedent
14
15
15 def interesting_default_value(dv):
16 def interesting_default_value(dv):
16 if (dv is None) or (dv is Undefined):
17 if (dv is None) or (dv is Undefined):
17 return False
18 return False
18 if isinstance(dv, (str, list, tuple, dict, set)):
19 if isinstance(dv, (str, list, tuple, dict, set)):
19 return bool(dv)
20 return bool(dv)
20 return True
21 return True
21
22
22 def class_config_rst_doc(cls):
23 def format_aliases(aliases):
24 fmted = []
25 for a in aliases:
26 dashes = '-' if len(a) == 1 else '--'
27 fmted.append('``%s%s``' % (dashes, a))
28 return ', '.join(fmted)
29
30 def class_config_rst_doc(cls, trait_aliases):
23 """Generate rST documentation for this class' config options.
31 """Generate rST documentation for this class' config options.
24
32
25 Excludes traits defined on parent classes.
33 Excludes traits defined on parent classes.
26 """
34 """
27 lines = []
35 lines = []
28 classname = cls.__name__
36 classname = cls.__name__
29 for k, trait in sorted(cls.class_traits(config=True).items()):
37 for k, trait in sorted(cls.class_traits(config=True).items()):
30 ttype = trait.__class__.__name__
38 ttype = trait.__class__.__name__
31
39
32 lines += ['.. configtrait:: ' + classname + '.' + trait.name,
40 fullname = classname + '.' + trait.name
41 lines += ['.. configtrait:: ' + fullname,
33 ''
42 ''
34 ]
43 ]
35
44
36 help = trait.help.rstrip() or 'No description'
45 help = trait.help.rstrip() or 'No description'
37 lines.append(indent(dedent(help), 4) + '\n')
46 lines.append(indent(dedent(help), 4) + '\n')
38
47
39 # Choices or type
48 # Choices or type
40 if 'Enum' in ttype:
49 if 'Enum' in ttype:
41 # include Enum choices
50 # include Enum choices
42 lines.append(indent(
51 lines.append(indent(
43 ':options: ' + ', '.join('``%r``' % x for x in trait.values), 4))
52 ':options: ' + ', '.join('``%r``' % x for x in trait.values), 4))
44 else:
53 else:
45 lines.append(indent(':trait type: ' + ttype, 4))
54 lines.append(indent(':trait type: ' + ttype, 4))
46
55
47 # Default value
56 # Default value
48 # Ignore boring default values like None, [] or ''
57 # Ignore boring default values like None, [] or ''
49 if interesting_default_value(trait.default_value):
58 if interesting_default_value(trait.default_value):
50 try:
59 try:
51 dvr = trait.default_value_repr()
60 dvr = trait.default_value_repr()
52 except Exception:
61 except Exception:
53 dvr = None # ignore defaults we can't construct
62 dvr = None # ignore defaults we can't construct
54 if dvr is not None:
63 if dvr is not None:
55 if len(dvr) > 64:
64 if len(dvr) > 64:
56 dvr = dvr[:61] + '...'
65 dvr = dvr[:61] + '...'
57 # Double up backslashes, so they get to the rendered docs
66 # Double up backslashes, so they get to the rendered docs
58 dvr = dvr.replace('\\n', '\\\\n')
67 dvr = dvr.replace('\\n', '\\\\n')
59 lines.append(indent(':default: ``%s``' % dvr, 4))
68 lines.append(indent(':default: ``%s``' % dvr, 4))
60
69
70 # Command line aliases
71 if trait_aliases[fullname]:
72 fmt_aliases = format_aliases(trait_aliases[fullname])
73 lines.append(indent(':CLI option: ' + fmt_aliases, 4))
74
61 # Blank line
75 # Blank line
62 lines.append('')
76 lines.append('')
63
77
64 return '\n'.join(lines)
78 return '\n'.join(lines)
65
79
80 def reverse_aliases(app):
81 """Produce a mapping of trait names to lists of command line aliases.
82 """
83 res = defaultdict(list)
84 for alias, trait in app.aliases.items():
85 res[trait].append(alias)
86
87 # Flags also often act as aliases for a boolean trait.
88 # Treat flags which set one trait to True as aliases.
89 for flag, (cfg, _) in app.flags.items():
90 if len(cfg) == 1:
91 classname = list(cfg)[0]
92 cls_cfg = cfg[classname]
93 if len(cls_cfg) == 1:
94 traitname = list(cls_cfg)[0]
95 if cls_cfg[traitname] is True:
96 res[classname+'.'+traitname].append(flag)
97
98 return res
66
99
67 def write_doc(name, title, app, preamble=None):
100 def write_doc(name, title, app, preamble=None):
101 trait_aliases = reverse_aliases(app)
68 filename = join(options, name+'.rst')
102 filename = join(options, name+'.rst')
69 with open(filename, 'w') as f:
103 with open(filename, 'w') as f:
70 f.write(title + '\n')
104 f.write(title + '\n')
71 f.write(('=' * len(title)) + '\n')
105 f.write(('=' * len(title)) + '\n')
72 f.write('\n')
106 f.write('\n')
73 if preamble is not None:
107 if preamble is not None:
74 f.write(preamble + '\n\n')
108 f.write(preamble + '\n\n')
75 #f.write(app.document_config_options())
109 #f.write(app.document_config_options())
76
110
77 for c in app._classes_inc_parents():
111 for c in app._classes_inc_parents():
78 f.write(class_config_rst_doc(c))
112 f.write(class_config_rst_doc(c, trait_aliases))
79 f.write('\n')
113 f.write('\n')
80
114
81
115
82 if __name__ == '__main__':
116 if __name__ == '__main__':
83 # Touch this file for the make target
117 # Touch this file for the make target
84 with open(generated, 'w'):
118 with open(generated, 'w'):
85 pass
119 pass
86
120
87 write_doc('terminal', 'Terminal IPython options', TerminalIPythonApp())
121 write_doc('terminal', 'Terminal IPython options', TerminalIPythonApp())
88 write_doc('kernel', 'IPython kernel options', IPKernelApp(),
122 write_doc('kernel', 'IPython kernel options', IPKernelApp(),
89 preamble=("These options can be used in :file:`ipython_kernel_config.py`. "
123 preamble=("These options can be used in :file:`ipython_kernel_config.py`. "
90 "The kernel also respects any options in `ipython_config.py`"),
124 "The kernel also respects any options in `ipython_config.py`"),
91 )
125 )
General Comments 0
You need to be logged in to leave comments. Login now