Skip to content

Commit 4930409

Browse files
committed
Add required to top level parameter documentation
Also, reformats to have '[required]' in line with the parameter name instead of on a separate line. Lint and format to use f-strings and change super() use.
1 parent 0f8ab49 commit 4930409

File tree

2 files changed

+99
-80
lines changed

2 files changed

+99
-80
lines changed

awscli/clidocs.py

Lines changed: 85 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def doc_breadcrumbs(self, help_command, **kwargs):
114114
doc.write(' . ')
115115
full_cmd_list.append(cmd)
116116
full_cmd_name = ' '.join(full_cmd_list)
117-
doc.write(':ref:`%s <cli:%s>`' % (cmd, full_cmd_name))
117+
doc.write(f':ref:`{cmd} <cli:{full_cmd_name}>`')
118118
doc.write(' ]')
119119

120120
def doc_title(self, help_command, **kwargs):
@@ -123,7 +123,7 @@ def doc_title(self, help_command, **kwargs):
123123
reference = help_command.event_class.replace('.', ' ')
124124
if reference != 'aws':
125125
reference = 'aws ' + reference
126-
doc.writeln('.. _cli:%s:' % reference)
126+
doc.writeln(f'.. _cli:{reference}:')
127127
doc.style.h1(help_command.name)
128128

129129
def doc_description(self, help_command, **kwargs):
@@ -137,7 +137,7 @@ def doc_synopsis_start(self, help_command, **kwargs):
137137
doc = help_command.doc
138138
doc.style.h2('Synopsis')
139139
doc.style.start_codeblock()
140-
doc.writeln('%s' % help_command.name)
140+
doc.writeln(f'{help_command.name}')
141141

142142
def doc_synopsis_option(self, arg_name, help_command, **kwargs):
143143
doc = help_command.doc
@@ -151,15 +151,15 @@ def doc_synopsis_option(self, arg_name, help_command, **kwargs):
151151
)
152152
self._documented_arg_groups.append(argument.group_name)
153153
elif argument.cli_name.startswith('--'):
154-
option_str = '%s <value>' % argument.cli_name
154+
option_str = f'{argument.cli_name} <value>'
155155
else:
156-
option_str = '<%s>' % argument.cli_name
156+
option_str = f'<{argument.cli_name}>'
157157
if not (
158158
argument.required
159159
or getattr(argument, '_DOCUMENT_AS_REQUIRED', False)
160160
):
161-
option_str = '[%s]' % option_str
162-
doc.writeln('%s' % option_str)
161+
option_str = f'[{option_str}]'
162+
doc.writeln(f'{option_str}')
163163

164164
def doc_synopsis_end(self, help_command, **kwargs):
165165
doc = help_command.doc
@@ -180,28 +180,32 @@ def doc_options_start(self, help_command, **kwargs):
180180
def doc_option(self, arg_name, help_command, **kwargs):
181181
doc = help_command.doc
182182
argument = help_command.arg_table[arg_name]
183+
if argument.required or getattr(
184+
argument, '_DOCUMENT_AS_REQUIRED', False
185+
):
186+
required_field = ' [required]'
187+
else:
188+
required_field = ''
189+
183190
if argument.group_name in self._arg_groups:
184191
if argument.group_name in self._documented_arg_groups:
185192
# This arg is already documented so we can move on.
186193
return
187194
name = ' | '.join(
188195
[
189-
'``%s``' % a.cli_name
196+
f'``{a.cli_name}``'
190197
for a in self._arg_groups[argument.group_name]
191198
]
192199
)
193200
self._documented_arg_groups.append(argument.group_name)
194201
else:
195-
name = '``%s``' % argument.cli_name
202+
name = f'``{argument.cli_name}``'
196203
doc.write(
197-
'%s (%s)\n'
198-
% (
199-
name,
200-
self._get_argument_type_name(
201-
argument.argument_model, argument.cli_type_name
202-
),
203-
)
204+
f'{name} '
205+
f'({self._get_argument_type_name(argument.argument_model, argument.cli_type_name)})'
206+
f'{required_field}\n'
204207
)
208+
205209
doc.style.indent()
206210
doc.include_doc_string(argument.documentation)
207211
if is_streaming_blob_type(argument.argument_model):
@@ -229,7 +233,7 @@ def doc_relateditem(self, help_command, related_item, **kwargs):
229233
doc = help_command.doc
230234
doc.write('* ')
231235
doc.style.sphinx_reference_label(
232-
label='cli:%s' % related_item, text=related_item
236+
label=f'cli:{related_item}', text=related_item
233237
)
234238
doc.write('\n')
235239

@@ -241,7 +245,7 @@ def _document_enums(self, model, doc):
241245
doc.write('Possible values:')
242246
doc.style.start_ul()
243247
for enum in model.enum:
244-
doc.style.li('``%s``' % enum)
248+
doc.style.li(f'``{enum}``')
245249
doc.style.end_ul()
246250

247251
def _document_nested_structure(self, model, doc):
@@ -252,19 +256,35 @@ def _document_nested_structure(self, model, doc):
252256
for member_name, member_shape in model.members.items():
253257
is_required = member_name in required_members
254258
self._doc_member(
255-
doc, member_name, member_shape, stack=[model.name], required=is_required
259+
doc,
260+
member_name,
261+
member_shape,
262+
stack=[model.name],
263+
required=is_required,
256264
)
257265
elif member_type_name == 'list':
258-
self._doc_member(doc, '', model.member, stack=[model.name], required=False)
266+
self._doc_member(
267+
doc, '', model.member, stack=[model.name], required=False
268+
)
259269
elif member_type_name == 'map':
260270
key_shape = model.key
261271
key_name = key_shape.serialization.get('name', 'key')
262-
self._doc_member(doc, key_name, key_shape, stack=[model.name], required=False)
272+
self._doc_member(
273+
doc, key_name, key_shape, stack=[model.name], required=False
274+
)
263275
value_shape = model.value
264276
value_name = value_shape.serialization.get('name', 'value')
265-
self._doc_member(doc, value_name, value_shape, stack=[model.name], required=False)
277+
self._doc_member(
278+
doc,
279+
value_name,
280+
value_shape,
281+
stack=[model.name],
282+
required=False,
283+
)
266284

267-
def _doc_member(self, doc, member_name, member_shape, stack, required=False):
285+
def _doc_member(
286+
self, doc, member_name, member_shape, stack, required=False
287+
):
268288
if member_shape.name in stack:
269289
# Document the recursion once, otherwise just
270290
# note the fact that it's recursive and return.
@@ -274,29 +294,36 @@ def _doc_member(self, doc, member_name, member_shape, stack, required=False):
274294
return
275295
stack.append(member_shape.name)
276296
try:
277-
self._do_doc_member(doc, member_name, member_shape, stack, required)
297+
self._do_doc_member(
298+
doc, member_name, member_shape, stack, required
299+
)
278300
finally:
279301
stack.pop()
280302

281-
def _do_doc_member(self, doc, member_name, member_shape, stack, required=False):
303+
def _do_doc_member(
304+
self, doc, member_name, member_shape, stack, required=False
305+
):
282306
docs = member_shape.documentation
283307
type_name = self._get_argument_type_name(
284308
member_shape, member_shape.type_name
285309
)
310+
286311
if member_name:
287-
doc.write('%s -> (%s)' % (member_name, type_name))
312+
tmp = f'{member_name} -> ({type_name})'
288313
else:
289-
doc.write('(%s)' % type_name)
314+
tmp = f'({type_name})'
315+
316+
if required:
317+
tmp += ' [required]'
318+
319+
doc.write(tmp)
320+
290321
doc.style.indent()
291322
doc.style.new_paragraph()
292323
doc.include_doc_string(docs)
293324
if is_tagged_union_type(member_shape):
294325
self._add_tagged_union_note(member_shape, doc)
295326

296-
if required:
297-
doc.style.new_paragraph()
298-
doc.write('This parameter is required.')
299-
300327
self._document_enums(member_shape, doc)
301328
self._document_constraints(member_shape, doc)
302329
doc.style.new_paragraph()
@@ -305,16 +332,22 @@ def _do_doc_member(self, doc, member_name, member_shape, stack, required=False):
305332
required_members = member_shape.metadata.get('required', [])
306333
for sub_name, sub_shape in member_shape.members.items():
307334
sub_required = sub_name in required_members
308-
self._doc_member(doc, sub_name, sub_shape, stack, required=sub_required)
335+
self._doc_member(
336+
doc, sub_name, sub_shape, stack, required=sub_required
337+
)
309338
elif member_type_name == 'map':
310339
key_shape = member_shape.key
311340
key_name = key_shape.serialization.get('name', 'key')
312341
self._doc_member(doc, key_name, key_shape, stack, required=False)
313342
value_shape = member_shape.value
314343
value_name = value_shape.serialization.get('name', 'value')
315-
self._doc_member(doc, value_name, value_shape, stack, required=False)
344+
self._doc_member(
345+
doc, value_name, value_shape, stack, required=False
346+
)
316347
elif member_type_name == 'list':
317-
self._doc_member(doc, '', member_shape.member, stack, required=False)
348+
self._doc_member(
349+
doc, '', member_shape.member, stack, required=False
350+
)
318351
doc.style.dedent()
319352
doc.style.new_paragraph()
320353

@@ -387,7 +420,7 @@ def doc_subitems_start(self, help_command, **kwargs):
387420

388421
def doc_subitem(self, command_name, help_command, **kwargs):
389422
doc = help_command.doc
390-
file_name = '%s/index' % command_name
423+
file_name = f'{command_name}/index'
391424
doc.style.tocitem(command_name, file_name=file_name)
392425

393426

@@ -438,7 +471,7 @@ def doc_subitem(self, command_name, help_command, **kwargs):
438471
# direct the subitem to the command's index because
439472
# it has more subcommands to be documented.
440473
if len(subcommand_table) > 0:
441-
file_name = '%s/index' % command_name
474+
file_name = f'{command_name}/index'
442475
doc.style.tocitem(command_name, file_name=file_name)
443476
else:
444477
doc.style.tocitem(command_name)
@@ -467,24 +500,20 @@ def _add_webapi_crosslink(self, help_command):
467500
return
468501
doc.style.new_paragraph()
469502
doc.write("See also: ")
470-
link = '%s/%s/%s' % (
471-
self.AWS_DOC_BASE,
472-
service_uid,
473-
operation_model.name,
474-
)
503+
link = f'{self.AWS_DOC_BASE}/{service_uid}/{operation_model.name}'
475504
doc.style.external_link(title="AWS API Documentation", link=link)
476505
doc.writeln('')
477506

478507
def _add_note_for_document_types_if_used(self, help_command):
479508
if operation_uses_document_types(help_command.obj):
480509
help_command.doc.style.new_paragraph()
481510
help_command.doc.writeln(
482-
'``%s`` uses document type values. Document types follow the '
511+
f'``{help_command.name}`` uses document type values. Document types follow the '
483512
'JSON data model where valid values are: strings, numbers, '
484513
'booleans, null, arrays, and objects. For command input, '
485514
'options and nested parameters that are labeled with the type '
486515
'``document`` must be provided as JSON. Shorthand syntax does '
487-
'not support document types.' % help_command.name
516+
'not support document types.'
488517
)
489518

490519
def _json_example_value_name(
@@ -495,13 +524,13 @@ def _json_example_value_name(
495524
if isinstance(argument_model, StringShape):
496525
if argument_model.enum and include_enum_values:
497526
choices = argument_model.enum
498-
return '|'.join(['"%s"' % c for c in choices])
527+
return '|'.join([f'"{c}"' for c in choices])
499528
else:
500529
return '"string"'
501530
elif argument_model.type_name == 'boolean':
502531
return 'true|false'
503532
else:
504-
return '%s' % argument_model.type_name
533+
return f'{argument_model.type_name}'
505534

506535
def _json_example(self, doc, argument_model, stack):
507536
if argument_model.name in stack:
@@ -522,8 +551,7 @@ def _do_json_example(self, doc, argument_model, stack):
522551
doc.write('[')
523552
if argument_model.member.type_name in SCALAR_TYPES:
524553
doc.write(
525-
'%s, ...'
526-
% self._json_example_value_name(argument_model.member)
554+
f'{self._json_example_value_name(argument_model.member)}, ...'
527555
)
528556
else:
529557
doc.style.indent()
@@ -538,7 +566,7 @@ def _do_json_example(self, doc, argument_model, stack):
538566
doc.write('{')
539567
doc.style.indent()
540568
key_string = self._json_example_value_name(argument_model.key)
541-
doc.write('%s: ' % key_string)
569+
doc.write(f'{key_string}: ')
542570
if argument_model.value.type_name in SCALAR_TYPES:
543571
doc.write(self._json_example_value_name(argument_model.value))
544572
else:
@@ -568,20 +596,16 @@ def _doc_input_structure_members(self, doc, argument_model, stack):
568596
member_type_name = member_model.type_name
569597
if member_type_name in SCALAR_TYPES:
570598
doc.write(
571-
'"%s": %s'
572-
% (
573-
member_name,
574-
self._json_example_value_name(member_model),
575-
)
599+
f'"{member_name}": {self._json_example_value_name(member_model)}'
576600
)
577601
elif member_type_name == 'structure':
578-
doc.write('"%s": ' % member_name)
602+
doc.write(f'"{member_name}": ')
579603
self._json_example(doc, member_model, stack)
580604
elif member_type_name == 'map':
581-
doc.write('"%s": ' % member_name)
605+
doc.write(f'"{member_name}": ')
582606
self._json_example(doc, member_model, stack)
583607
elif member_type_name == 'list':
584-
doc.write('"%s": ' % member_name)
608+
doc.write(f'"{member_name}": ')
585609
self._json_example(doc, member_model, stack)
586610
if i < len(members) - 1:
587611
doc.write(',')
@@ -637,7 +661,7 @@ def doc_option_example(self, arg_name, help_command, event_name, **kwargs):
637661
example_type = self._json_example_value_name(
638662
member, include_enum_values=False
639663
)
640-
doc.write('%s %s ...' % (example_type, example_type))
664+
doc.write(f'{example_type} {example_type} ...')
641665
doc.style.end_codeblock()
642666
doc.style.new_paragraph()
643667
elif cli_argument.cli_type_name not in SCALAR_TYPES:
@@ -687,7 +711,7 @@ def doc_title(self, help_command, **kwargs):
687711
doc = help_command.doc
688712
doc.style.new_paragraph()
689713
doc.style.link_target_definition(
690-
refname='cli:aws help %s' % self.help_command.name, link=''
714+
refname=f'cli:aws help {self.help_command.name}', link=''
691715
)
692716
doc.style.h1('AWS CLI Topic Guide')
693717

@@ -732,9 +756,9 @@ def doc_subitems_start(self, help_command, **kwargs):
732756
)
733757
doc.write('* ')
734758
doc.style.sphinx_reference_label(
735-
label='cli:aws help %s' % topic_name, text=topic_name
759+
label=f'cli:aws help {topic_name}', text=topic_name
736760
)
737-
doc.write(': %s\n' % description)
761+
doc.write(f': {description}\n')
738762
# Add a hidden toctree to make sure everything is connected in
739763
# the document.
740764
doc.style.hidden_toctree()
@@ -758,7 +782,7 @@ def doc_title(self, help_command, **kwargs):
758782
doc = help_command.doc
759783
doc.style.new_paragraph()
760784
doc.style.link_target_definition(
761-
refname='cli:aws help %s' % self.help_command.name, link=''
785+
refname=f'cli:aws help {self.help_command.name}', link=''
762786
)
763787
title = self._topic_tag_db.get_tag_single_value(
764788
help_command.name, 'title'

0 commit comments

Comments
 (0)