1515from botocore import model , xform_name
1616from botocore .compat import OrderedDict
1717
18+ from awscli .argparser import ArgTableArgParser
1819from awscli .argprocess import (
1920 ParamError ,
2021 ParamShorthandDocGen ,
@@ -69,7 +70,7 @@ def create_argument(self, argument_model, argument_name=None):
6970
7071class TestURIParams (BaseArgProcessTest ):
7172 def setUp (self ):
72- super (TestURIParams , self ).setUp ()
73+ super ().setUp ()
7374 self .uri_param = URIArgumentHandler (LOCAL_PREFIX_MAP .copy ())
7475
7576 def test_uri_param (self ):
@@ -80,7 +81,7 @@ def test_uri_param(self):
8081 )
8182 f .write (json_argument )
8283 f .flush ()
83- result = self .uri_param ('event-name' , p , 'file://%s' % f .name )
84+ result = self .uri_param ('event-name' , p , f 'file://{ f .name } ' )
8485 self .assertEqual (result , json_argument )
8586
8687
@@ -173,7 +174,7 @@ class TestParamShorthand(BaseArgProcessTest):
173174 maxDiff = None
174175
175176 def setUp (self ):
176- super (TestParamShorthand , self ).setUp ()
177+ super ().setUp ()
177178 self ._shorthand = ParamShorthandParser ()
178179
179180 def parse_shorthand (self , cli_argument , value , event_name = None ):
@@ -490,7 +491,7 @@ def test_csv_syntax_errors(self):
490491
491492class TestParamShorthandCustomArguments (BaseArgProcessTest ):
492493 def setUp (self ):
493- super (TestParamShorthandCustomArguments , self ).setUp ()
494+ super ().setUp ()
494495 self .shorthand = ParamShorthandParser ()
495496
496497 def test_list_structure_list_scalar_custom_arg (self ):
@@ -555,7 +556,7 @@ class TestDocGen(BaseArgProcessTest):
555556 # flexible and allow the docs to slightly change without breaking these
556557 # tests.
557558 def setUp (self ):
558- super (TestDocGen , self ).setUp ()
559+ super ().setUp ()
559560 self .shorthand_documenter = ParamShorthandDocGen ()
560561 self .service_name = 'foo'
561562 self .operation_name = 'bar'
@@ -728,7 +729,7 @@ def test_gen_structure_list_scalar_docs(self):
728729
729730 def test_can_gen_recursive_structure (self ):
730731 argument = self .get_param_model ('dynamodb.PutItem.Item' )
731- generated_example = self .get_generated_example_for (argument )
732+ self .get_generated_example_for (argument )
732733
733734 def test_can_document_nested_structs (self ):
734735 argument = self .get_param_model ('ec2.RunInstances.BlockDeviceMappings' )
@@ -885,12 +886,14 @@ def test_structure_within_map(self):
885886 }
886887 )
887888 generated_example = self .get_generated_example_for (argument )
888- self .assertEqual ('A={KeyName1={B=string},KeyName2={B=string}}' , generated_example )
889+ self .assertEqual (
890+ 'A={KeyName1={B=string},KeyName2={B=string}}' , generated_example
891+ )
889892
890893
891894class TestUnpackJSONParams (BaseArgProcessTest ):
892895 def setUp (self ):
893- super (TestUnpackJSONParams , self ).setUp ()
896+ super ().setUp ()
894897 self .simplify = ParamShorthandParser ()
895898
896899 def test_json_with_spaces (self ):
@@ -925,7 +928,7 @@ def test_json_with_spaces(self):
925928
926929class TestJSONValueHeaderParams (BaseArgProcessTest ):
927930 def setUp (self ):
928- super (TestJSONValueHeaderParams , self ).setUp ()
931+ super ().setUp ()
929932 self .p = self .get_param_model (
930933 'lex-runtime.PostContent.sessionAttributes'
931934 )
@@ -968,5 +971,46 @@ def test_json_value_decode_error(self):
968971 unpack_cli_arg (self .p , value )
969972
970973
974+ class TestArgumentPercentEscaping (BaseArgProcessTest ):
975+ def _test_percent_escaping (self , arg_type , arg_class , doc_string ):
976+ argument = self .create_argument (
977+ {
978+ 'Test' : {
979+ 'type' : arg_type ,
980+ 'documentation' : doc_string ,
981+ }
982+ }
983+ )
984+ arg = arg_class (
985+ 'test-arg' ,
986+ argument .argument_model .members ['Test' ],
987+ mock .Mock (),
988+ mock .Mock (),
989+ is_required = False ,
990+ )
991+ arg_table = {arg .name : arg }
992+ parser = ArgTableArgParser (arg_table )
993+ help_output = parser .format_help ()
994+ self .assertIn (doc_string , help_output )
995+
996+ def test_cli_argument_escapes_percent (self ):
997+ self ._test_percent_escaping ('string' , CLIArgument , 'Symbols: % ^ & *' )
998+
999+ def test_boolean_argument_escapes_percent (self ):
1000+ self ._test_percent_escaping (
1001+ 'boolean' , BooleanArgument , 'Symbols: % ^ & *'
1002+ )
1003+
1004+ def test_cli_argument_escapes_url_encoded_percent (self ):
1005+ self ._test_percent_escaping (
1006+ 'string' , CLIArgument , 'File: test%28file%29.png'
1007+ )
1008+
1009+ def test_boolean_argument_escapes_url_encoded_percent (self ):
1010+ self ._test_percent_escaping (
1011+ 'boolean' , BooleanArgument , 'File: test%28file%29.png'
1012+ )
1013+
1014+
9711015if __name__ == '__main__' :
9721016 unittest .main ()
0 commit comments