We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Profile does not return region or output format if it contains a SPACE character
The AWS CLI tool allows you to create a profile name with a space character in it, and writes the values to the credentials and config file as expected. However when getting that config using the quoted profile name, it doesn't return the region or default output format.

Setting the profile credentials and config:

    $ aws configure --profile 'Foo Bar'
    AWS Access Key ID [None]: foo
    AWS Secret Access Key [None]: bar
    Default region name [None]: eu-west-1
    Default output format [None]: json

    $ cat .aws/config
    [profile Foo Bar]
    output = json
    region = eu-west-1

    $ cat .aws/credentials
    [Foo Bar]
    aws_access_key_id = foo
    aws_secret_access_key = bar


Checking the profile credentials and config:

    $ aws configure --profile 'Foo Bar'
    AWS Access Key ID [****************foo]:
    AWS Secret Access Key [****************bar]:
    Default region name [None]:
    Default output format [None]:

CLI commands then prompt for a region when using the profile name. The **credentials** do still work, and are retrieved from the profile, but the **config** ,e.g. the region, has to be specified on the command line still:

    $ aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names group_name --profile 'Foo Bar'
    You must specify a region. You can also configure your region by running "aws configure".

When performing the same steps above with a profile name without a space character (Foo_Bar), everything works as expected.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `awscli/customizations/configure/set.py`
Content:
```
1 # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"). You
4 # may not use this file except in compliance with the License. A copy of
5 # the License is located at
6 #
7 #     http://aws.amazon.com/apache2.0/
8 #
9 # or in the "license" file accompanying this file. This file is
10 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 # ANY KIND, either express or implied. See the License for the specific
12 # language governing permissions and limitations under the License.
13 import os
14 
15 from awscli.customizations.commands import BasicCommand
16 from awscli.customizations.configure.writer import ConfigFileWriter
17 
18 from . import PREDEFINED_SECTION_NAMES
19 
20 
21 class ConfigureSetCommand(BasicCommand):
22     NAME = 'set'
23     DESCRIPTION = BasicCommand.FROM_FILE('configure', 'set',
24                                          '_description.rst')
25     SYNOPSIS = 'aws configure set varname value [--profile profile-name]'
26     EXAMPLES = BasicCommand.FROM_FILE('configure', 'set', '_examples.rst')
27     ARG_TABLE = [
28         {'name': 'varname',
29          'help_text': 'The name of the config value to set.',
30          'action': 'store',
31          'cli_type_name': 'string', 'positional_arg': True},
32         {'name': 'value',
33          'help_text': 'The value to set.',
34          'action': 'store',
35          'no_paramfile': True,  # To disable the default paramfile behavior
36          'cli_type_name': 'string', 'positional_arg': True},
37     ]
38     # Any variables specified in this list will be written to
39     # the ~/.aws/credentials file instead of ~/.aws/config.
40     _WRITE_TO_CREDS_FILE = ['aws_access_key_id', 'aws_secret_access_key',
41                             'aws_session_token']
42 
43     def __init__(self, session, config_writer=None):
44         super(ConfigureSetCommand, self).__init__(session)
45         if config_writer is None:
46             config_writer = ConfigFileWriter()
47         self._config_writer = config_writer
48 
49     def _run_main(self, args, parsed_globals):
50         varname = args.varname
51         value = args.value
52         section = 'default'
53         # Before handing things off to the config writer,
54         # we need to find out three things:
55         # 1. What section we're writing to (section).
56         # 2. The name of the config key (varname)
57         # 3. The actual value (value).
58         if '.' not in varname:
59             # unqualified name, scope it to the current
60             # profile (or leave it as the 'default' section if
61             # no profile is set).
62             if self._session.profile is not None:
63                 section = 'profile %s' % self._session.profile
64         else:
65             # First figure out if it's been scoped to a profile.
66             parts = varname.split('.')
67             if parts[0] in ('default', 'profile'):
68                 # Then we know we're scoped to a profile.
69                 if parts[0] == 'default':
70                     section = 'default'
71                     remaining = parts[1:]
72                 else:
73                     # [profile, profile_name, ...]
74                     section = "profile %s" % parts[1]
75                     remaining = parts[2:]
76                 varname = remaining[0]
77                 if len(remaining) == 2:
78                     value = {remaining[1]: value}
79             elif parts[0] not in PREDEFINED_SECTION_NAMES:
80                 if self._session.profile is not None:
81                     section = 'profile %s' % self._session.profile
82                 else:
83                     profile_name = self._session.get_config_variable('profile')
84                     if profile_name is not None:
85                         section = profile_name
86                 varname = parts[0]
87                 if len(parts) == 2:
88                     value = {parts[1]: value}
89             elif len(parts) == 2:
90                 # Otherwise it's something like "set preview.service true"
91                 # of something in the [plugin] section.
92                 section, varname = parts
93         config_filename = os.path.expanduser(
94             self._session.get_config_variable('config_file'))
95         updated_config = {'__section__': section, varname: value}
96         if varname in self._WRITE_TO_CREDS_FILE:
97             config_filename = os.path.expanduser(
98                 self._session.get_config_variable('credentials_file'))
99             section_name = updated_config['__section__']
100             if section_name.startswith('profile '):
101                 updated_config['__section__'] = section_name[8:]
102         self._config_writer.update_config(updated_config, config_filename)
103
```

Path: `awscli/customizations/configure/__init__.py`
Content:
```
1 # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"). You
4 # may not use this file except in compliance with the License. A copy of
5 # the License is located at
6 #
7 #     http://aws.amazon.com/apache2.0/
8 #
9 # or in the "license" file accompanying this file. This file is
10 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 # ANY KIND, either express or implied. See the License for the specific
12 # language governing permissions and limitations under the License.
13 NOT_SET = '<not set>'
14 PREDEFINED_SECTION_NAMES = ('preview', 'plugins')
15 
16 
17 class ConfigValue(object):
18 
19     def __init__(self, value, config_type, config_variable):
20         self.value = value
21         self.config_type = config_type
22         self.config_variable = config_variable
23 
24     def mask_value(self):
25         if self.value is NOT_SET:
26             return
27         self.value = mask_value(self.value)
28 
29 
30 class SectionNotFoundError(Exception):
31     pass
32 
33 
34 def mask_value(current_value):
35     if current_value is None:
36         return 'None'
37     else:
38         return ('*' * 16) + current_value[-4:]
39
```

Path: `awscli/customizations/configure/configure.py`
Content:
```
1 # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"). You
4 # may not use this file except in compliance with the License. A copy of
5 # the License is located at
6 #
7 #     http://aws.amazon.com/apache2.0/
8 #
9 # or in the "license" file accompanying this file. This file is
10 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 # ANY KIND, either express or implied. See the License for the specific
12 # language governing permissions and limitations under the License.
13 import os
14 import logging
15 
16 from botocore.exceptions import ProfileNotFound
17 
18 from awscli.compat import compat_input
19 from awscli.customizations.commands import BasicCommand
20 from awscli.customizations.configure.addmodel import AddModelCommand
21 from awscli.customizations.configure.set import ConfigureSetCommand
22 from awscli.customizations.configure.get import ConfigureGetCommand
23 from awscli.customizations.configure.list import ConfigureListCommand
24 from awscli.customizations.configure.writer import ConfigFileWriter
25 
26 from . import mask_value
27 
28 
29 logger = logging.getLogger(__name__)
30 
31 
32 def register_configure_cmd(cli):
33     cli.register('building-command-table.main',
34                  ConfigureCommand.add_command)
35 
36 
37 class InteractivePrompter(object):
38 
39     def get_value(self, current_value, config_name, prompt_text=''):
40         if config_name in ('aws_access_key_id', 'aws_secret_access_key'):
41             current_value = mask_value(current_value)
42         response = compat_input("%s [%s]: " % (prompt_text, current_value))
43         if not response:
44             # If the user hits enter, we return a value of None
45             # instead of an empty string.  That way we can determine
46             # whether or not a value has changed.
47             response = None
48         return response
49 
50 
51 class ConfigureCommand(BasicCommand):
52     NAME = 'configure'
53     DESCRIPTION = BasicCommand.FROM_FILE()
54     SYNOPSIS = ('aws configure [--profile profile-name]')
55     EXAMPLES = (
56         'To create a new configuration::\n'
57         '\n'
58         '    $ aws configure\n'
59         '    AWS Access Key ID [None]: accesskey\n'
60         '    AWS Secret Access Key [None]: secretkey\n'
61         '    Default region name [None]: us-west-2\n'
62         '    Default output format [None]:\n'
63         '\n'
64         'To update just the region name::\n'
65         '\n'
66         '    $ aws configure\n'
67         '    AWS Access Key ID [****]:\n'
68         '    AWS Secret Access Key [****]:\n'
69         '    Default region name [us-west-1]: us-west-2\n'
70         '    Default output format [None]:\n'
71     )
72     SUBCOMMANDS = [
73         {'name': 'list', 'command_class': ConfigureListCommand},
74         {'name': 'get', 'command_class': ConfigureGetCommand},
75         {'name': 'set', 'command_class': ConfigureSetCommand},
76         {'name': 'add-model', 'command_class': AddModelCommand}
77     ]
78 
79     # If you want to add new values to prompt, update this list here.
80     VALUES_TO_PROMPT = [
81         # (logical_name, config_name, prompt_text)
82         ('aws_access_key_id', "AWS Access Key ID"),
83         ('aws_secret_access_key', "AWS Secret Access Key"),
84         ('region', "Default region name"),
85         ('output', "Default output format"),
86     ]
87 
88     def __init__(self, session, prompter=None, config_writer=None):
89         super(ConfigureCommand, self).__init__(session)
90         if prompter is None:
91             prompter = InteractivePrompter()
92         self._prompter = prompter
93         if config_writer is None:
94             config_writer = ConfigFileWriter()
95         self._config_writer = config_writer
96 
97     def _run_main(self, parsed_args, parsed_globals):
98         # Called when invoked with no args "aws configure"
99         new_values = {}
100         # This is the config from the config file scoped to a specific
101         # profile.
102         try:
103             config = self._session.get_scoped_config()
104         except ProfileNotFound:
105             config = {}
106         for config_name, prompt_text in self.VALUES_TO_PROMPT:
107             current_value = config.get(config_name)
108             new_value = self._prompter.get_value(current_value, config_name,
109                                                  prompt_text)
110             if new_value is not None and new_value != current_value:
111                 new_values[config_name] = new_value
112         config_filename = os.path.expanduser(
113             self._session.get_config_variable('config_file'))
114         if new_values:
115             self._write_out_creds_file_values(new_values,
116                                               parsed_globals.profile)
117             if parsed_globals.profile is not None:
118                 new_values['__section__'] = (
119                     'profile %s' % parsed_globals.profile)
120             self._config_writer.update_config(new_values, config_filename)
121 
122     def _write_out_creds_file_values(self, new_values, profile_name):
123         # The access_key/secret_key are now *always* written to the shared
124         # credentials file (~/.aws/credentials), see aws/aws-cli#847.
125         # post-conditions: ~/.aws/credentials will have the updated credential
126         # file values and new_values will have the cred vars removed.
127         credential_file_values = {}
128         if 'aws_access_key_id' in new_values:
129             credential_file_values['aws_access_key_id'] = new_values.pop(
130                 'aws_access_key_id')
131         if 'aws_secret_access_key' in new_values:
132             credential_file_values['aws_secret_access_key'] = new_values.pop(
133                 'aws_secret_access_key')
134         if credential_file_values:
135             if profile_name is not None:
136                 credential_file_values['__section__'] = profile_name
137             shared_credentials_filename = os.path.expanduser(
138                 self._session.get_config_variable('credentials_file'))
139             self._config_writer.update_config(
140                 credential_file_values,
141                 shared_credentials_filename)
142
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/awscli/customizations/configure/__init__.py b/awscli/customizations/configure/__init__.py
--- a/awscli/customizations/configure/__init__.py
+++ b/awscli/customizations/configure/__init__.py
@@ -10,8 +10,12 @@
 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
+import string
+from botocore.vendored.six.moves import shlex_quote
+
 NOT_SET = '<not set>'
 PREDEFINED_SECTION_NAMES = ('preview', 'plugins')
+_WHITESPACE = ' \t'
 
 
 class ConfigValue(object):
@@ -36,3 +40,10 @@
         return 'None'
     else:
         return ('*' * 16) + current_value[-4:]
+
+
+def profile_to_section(profile_name):
+    """Converts a profile name to a section header to be used in the config."""
+    if any(c in _WHITESPACE for c in profile_name):
+        profile_name = shlex_quote(profile_name)
+    return 'profile %s' % profile_name
diff --git a/awscli/customizations/configure/configure.py b/awscli/customizations/configure/configure.py
--- a/awscli/customizations/configure/configure.py
+++ b/awscli/customizations/configure/configure.py
@@ -23,7 +23,7 @@
 from awscli.customizations.configure.list import ConfigureListCommand
 from awscli.customizations.configure.writer import ConfigFileWriter
 
-from . import mask_value
+from . import mask_value, profile_to_section
 
 
 logger = logging.getLogger(__name__)
@@ -115,8 +115,8 @@
             self._write_out_creds_file_values(new_values,
                                               parsed_globals.profile)
             if parsed_globals.profile is not None:
-                new_values['__section__'] = (
-                    'profile %s' % parsed_globals.profile)
+                section = profile_to_section(parsed_globals.profile)
+                new_values['__section__'] = section
             self._config_writer.update_config(new_values, config_filename)
 
     def _write_out_creds_file_values(self, new_values, profile_name):
diff --git a/awscli/customizations/configure/set.py b/awscli/customizations/configure/set.py
--- a/awscli/customizations/configure/set.py
+++ b/awscli/customizations/configure/set.py
@@ -15,7 +15,7 @@
 from awscli.customizations.commands import BasicCommand
 from awscli.customizations.configure.writer import ConfigFileWriter
 
-from . import PREDEFINED_SECTION_NAMES
+from . import PREDEFINED_SECTION_NAMES, profile_to_section
 
 
 class ConfigureSetCommand(BasicCommand):
@@ -60,7 +60,7 @@
             # profile (or leave it as the 'default' section if
             # no profile is set).
             if self._session.profile is not None:
-                section = 'profile %s' % self._session.profile
+                section = profile_to_section(self._session.profile)
         else:
             # First figure out if it's been scoped to a profile.
             parts = varname.split('.')
@@ -71,14 +71,14 @@
                     remaining = parts[1:]
                 else:
                     # [profile, profile_name, ...]
-                    section = "profile %s" % parts[1]
+                    section = profile_to_section(parts[1])
                     remaining = parts[2:]
                 varname = remaining[0]
                 if len(remaining) == 2:
                     value = {remaining[1]: value}
             elif parts[0] not in PREDEFINED_SECTION_NAMES:
                 if self._session.profile is not None:
-                    section = 'profile %s' % self._session.profile
+                    section = profile_to_section(self._session.profile)
                 else:
                     profile_name = self._session.get_config_variable('profile')
                     if profile_name is not None:

{"golden_diff": "diff --git a/awscli/customizations/configure/__init__.py b/awscli/customizations/configure/__init__.py\n--- a/awscli/customizations/configure/__init__.py\n+++ b/awscli/customizations/configure/__init__.py\n@@ -10,8 +10,12 @@\n # distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n # ANY KIND, either express or implied. See the License for the specific\n # language governing permissions and limitations under the License.\n+import string\n+from botocore.vendored.six.moves import shlex_quote\n+\n NOT_SET = '<not set>'\n PREDEFINED_SECTION_NAMES = ('preview', 'plugins')\n+_WHITESPACE = ' \\t'\n \n \n class ConfigValue(object):\n@@ -36,3 +40,10 @@\n         return 'None'\n     else:\n         return ('*' * 16) + current_value[-4:]\n+\n+\n+def profile_to_section(profile_name):\n+    \"\"\"Converts a profile name to a section header to be used in the config.\"\"\"\n+    if any(c in _WHITESPACE for c in profile_name):\n+        profile_name = shlex_quote(profile_name)\n+    return 'profile %s' % profile_name\ndiff --git a/awscli/customizations/configure/configure.py b/awscli/customizations/configure/configure.py\n--- a/awscli/customizations/configure/configure.py\n+++ b/awscli/customizations/configure/configure.py\n@@ -23,7 +23,7 @@\n from awscli.customizations.configure.list import ConfigureListCommand\n from awscli.customizations.configure.writer import ConfigFileWriter\n \n-from . import mask_value\n+from . import mask_value, profile_to_section\n \n \n logger = logging.getLogger(__name__)\n@@ -115,8 +115,8 @@\n             self._write_out_creds_file_values(new_values,\n                                               parsed_globals.profile)\n             if parsed_globals.profile is not None:\n-                new_values['__section__'] = (\n-                    'profile %s' % parsed_globals.profile)\n+                section = profile_to_section(parsed_globals.profile)\n+                new_values['__section__'] = section\n             self._config_writer.update_config(new_values, config_filename)\n \n     def _write_out_creds_file_values(self, new_values, profile_name):\ndiff --git a/awscli/customizations/configure/set.py b/awscli/customizations/configure/set.py\n--- a/awscli/customizations/configure/set.py\n+++ b/awscli/customizations/configure/set.py\n@@ -15,7 +15,7 @@\n from awscli.customizations.commands import BasicCommand\n from awscli.customizations.configure.writer import ConfigFileWriter\n \n-from . import PREDEFINED_SECTION_NAMES\n+from . import PREDEFINED_SECTION_NAMES, profile_to_section\n \n \n class ConfigureSetCommand(BasicCommand):\n@@ -60,7 +60,7 @@\n             # profile (or leave it as the 'default' section if\n             # no profile is set).\n             if self._session.profile is not None:\n-                section = 'profile %s' % self._session.profile\n+                section = profile_to_section(self._session.profile)\n         else:\n             # First figure out if it's been scoped to a profile.\n             parts = varname.split('.')\n@@ -71,14 +71,14 @@\n                     remaining = parts[1:]\n                 else:\n                     # [profile, profile_name, ...]\n-                    section = \"profile %s\" % parts[1]\n+                    section = profile_to_section(parts[1])\n                     remaining = parts[2:]\n                 varname = remaining[0]\n                 if len(remaining) == 2:\n                     value = {remaining[1]: value}\n             elif parts[0] not in PREDEFINED_SECTION_NAMES:\n                 if self._session.profile is not None:\n-                    section = 'profile %s' % self._session.profile\n+                    section = profile_to_section(self._session.profile)\n                 else:\n                     profile_name = self._session.get_config_variable('profile')\n                     if profile_name is not None:\n", "issue": "Profile does not return region or output format if it contains a SPACE character\nThe AWS CLI tool allows you to create a profile name with a space character in it, and writes the values to the credentials and config file as expected. However when getting that config using the quoted profile name, it doesn't return the region or default output format.\r\n\r\nSetting the profile credentials and config:\r\n\r\n    $ aws configure --profile 'Foo Bar'\r\n    AWS Access Key ID [None]: foo\r\n    AWS Secret Access Key [None]: bar\r\n    Default region name [None]: eu-west-1\r\n    Default output format [None]: json\r\n\r\n    $ cat .aws/config\r\n    [profile Foo Bar]\r\n    output = json\r\n    region = eu-west-1\r\n\r\n    $ cat .aws/credentials\r\n    [Foo Bar]\r\n    aws_access_key_id = foo\r\n    aws_secret_access_key = bar\r\n\r\n\r\nChecking the profile credentials and config:\r\n\r\n    $ aws configure --profile 'Foo Bar'\r\n    AWS Access Key ID [****************foo]:\r\n    AWS Secret Access Key [****************bar]:\r\n    Default region name [None]:\r\n    Default output format [None]:\r\n\r\nCLI commands then prompt for a region when using the profile name. The **credentials** do still work, and are retrieved from the profile, but the **config** ,e.g. the region, has to be specified on the command line still:\r\n\r\n    $ aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names group_name --profile 'Foo Bar'\r\n    You must specify a region. You can also configure your region by running \"aws configure\".\r\n\r\nWhen performing the same steps above with a profile name without a space character (Foo_Bar), everything works as expected.\n", "before_files": [{"content": "# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nimport os\n\nfrom awscli.customizations.commands import BasicCommand\nfrom awscli.customizations.configure.writer import ConfigFileWriter\n\nfrom . import PREDEFINED_SECTION_NAMES\n\n\nclass ConfigureSetCommand(BasicCommand):\n    NAME = 'set'\n    DESCRIPTION = BasicCommand.FROM_FILE('configure', 'set',\n                                         '_description.rst')\n    SYNOPSIS = 'aws configure set varname value [--profile profile-name]'\n    EXAMPLES = BasicCommand.FROM_FILE('configure', 'set', '_examples.rst')\n    ARG_TABLE = [\n        {'name': 'varname',\n         'help_text': 'The name of the config value to set.',\n         'action': 'store',\n         'cli_type_name': 'string', 'positional_arg': True},\n        {'name': 'value',\n         'help_text': 'The value to set.',\n         'action': 'store',\n         'no_paramfile': True,  # To disable the default paramfile behavior\n         'cli_type_name': 'string', 'positional_arg': True},\n    ]\n    # Any variables specified in this list will be written to\n    # the ~/.aws/credentials file instead of ~/.aws/config.\n    _WRITE_TO_CREDS_FILE = ['aws_access_key_id', 'aws_secret_access_key',\n                            'aws_session_token']\n\n    def __init__(self, session, config_writer=None):\n        super(ConfigureSetCommand, self).__init__(session)\n        if config_writer is None:\n            config_writer = ConfigFileWriter()\n        self._config_writer = config_writer\n\n    def _run_main(self, args, parsed_globals):\n        varname = args.varname\n        value = args.value\n        section = 'default'\n        # Before handing things off to the config writer,\n        # we need to find out three things:\n        # 1. What section we're writing to (section).\n        # 2. The name of the config key (varname)\n        # 3. The actual value (value).\n        if '.' not in varname:\n            # unqualified name, scope it to the current\n            # profile (or leave it as the 'default' section if\n            # no profile is set).\n            if self._session.profile is not None:\n                section = 'profile %s' % self._session.profile\n        else:\n            # First figure out if it's been scoped to a profile.\n            parts = varname.split('.')\n            if parts[0] in ('default', 'profile'):\n                # Then we know we're scoped to a profile.\n                if parts[0] == 'default':\n                    section = 'default'\n                    remaining = parts[1:]\n                else:\n                    # [profile, profile_name, ...]\n                    section = \"profile %s\" % parts[1]\n                    remaining = parts[2:]\n                varname = remaining[0]\n                if len(remaining) == 2:\n                    value = {remaining[1]: value}\n            elif parts[0] not in PREDEFINED_SECTION_NAMES:\n                if self._session.profile is not None:\n                    section = 'profile %s' % self._session.profile\n                else:\n                    profile_name = self._session.get_config_variable('profile')\n                    if profile_name is not None:\n                        section = profile_name\n                varname = parts[0]\n                if len(parts) == 2:\n                    value = {parts[1]: value}\n            elif len(parts) == 2:\n                # Otherwise it's something like \"set preview.service true\"\n                # of something in the [plugin] section.\n                section, varname = parts\n        config_filename = os.path.expanduser(\n            self._session.get_config_variable('config_file'))\n        updated_config = {'__section__': section, varname: value}\n        if varname in self._WRITE_TO_CREDS_FILE:\n            config_filename = os.path.expanduser(\n                self._session.get_config_variable('credentials_file'))\n            section_name = updated_config['__section__']\n            if section_name.startswith('profile '):\n                updated_config['__section__'] = section_name[8:]\n        self._config_writer.update_config(updated_config, config_filename)\n", "path": "awscli/customizations/configure/set.py"}, {"content": "# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nNOT_SET = '<not set>'\nPREDEFINED_SECTION_NAMES = ('preview', 'plugins')\n\n\nclass ConfigValue(object):\n\n    def __init__(self, value, config_type, config_variable):\n        self.value = value\n        self.config_type = config_type\n        self.config_variable = config_variable\n\n    def mask_value(self):\n        if self.value is NOT_SET:\n            return\n        self.value = mask_value(self.value)\n\n\nclass SectionNotFoundError(Exception):\n    pass\n\n\ndef mask_value(current_value):\n    if current_value is None:\n        return 'None'\n    else:\n        return ('*' * 16) + current_value[-4:]\n", "path": "awscli/customizations/configure/__init__.py"}, {"content": "# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nimport os\nimport logging\n\nfrom botocore.exceptions import ProfileNotFound\n\nfrom awscli.compat import compat_input\nfrom awscli.customizations.commands import BasicCommand\nfrom awscli.customizations.configure.addmodel import AddModelCommand\nfrom awscli.customizations.configure.set import ConfigureSetCommand\nfrom awscli.customizations.configure.get import ConfigureGetCommand\nfrom awscli.customizations.configure.list import ConfigureListCommand\nfrom awscli.customizations.configure.writer import ConfigFileWriter\n\nfrom . import mask_value\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef register_configure_cmd(cli):\n    cli.register('building-command-table.main',\n                 ConfigureCommand.add_command)\n\n\nclass InteractivePrompter(object):\n\n    def get_value(self, current_value, config_name, prompt_text=''):\n        if config_name in ('aws_access_key_id', 'aws_secret_access_key'):\n            current_value = mask_value(current_value)\n        response = compat_input(\"%s [%s]: \" % (prompt_text, current_value))\n        if not response:\n            # If the user hits enter, we return a value of None\n            # instead of an empty string.  That way we can determine\n            # whether or not a value has changed.\n            response = None\n        return response\n\n\nclass ConfigureCommand(BasicCommand):\n    NAME = 'configure'\n    DESCRIPTION = BasicCommand.FROM_FILE()\n    SYNOPSIS = ('aws configure [--profile profile-name]')\n    EXAMPLES = (\n        'To create a new configuration::\\n'\n        '\\n'\n        '    $ aws configure\\n'\n        '    AWS Access Key ID [None]: accesskey\\n'\n        '    AWS Secret Access Key [None]: secretkey\\n'\n        '    Default region name [None]: us-west-2\\n'\n        '    Default output format [None]:\\n'\n        '\\n'\n        'To update just the region name::\\n'\n        '\\n'\n        '    $ aws configure\\n'\n        '    AWS Access Key ID [****]:\\n'\n        '    AWS Secret Access Key [****]:\\n'\n        '    Default region name [us-west-1]: us-west-2\\n'\n        '    Default output format [None]:\\n'\n    )\n    SUBCOMMANDS = [\n        {'name': 'list', 'command_class': ConfigureListCommand},\n        {'name': 'get', 'command_class': ConfigureGetCommand},\n        {'name': 'set', 'command_class': ConfigureSetCommand},\n        {'name': 'add-model', 'command_class': AddModelCommand}\n    ]\n\n    # If you want to add new values to prompt, update this list here.\n    VALUES_TO_PROMPT = [\n        # (logical_name, config_name, prompt_text)\n        ('aws_access_key_id', \"AWS Access Key ID\"),\n        ('aws_secret_access_key', \"AWS Secret Access Key\"),\n        ('region', \"Default region name\"),\n        ('output', \"Default output format\"),\n    ]\n\n    def __init__(self, session, prompter=None, config_writer=None):\n        super(ConfigureCommand, self).__init__(session)\n        if prompter is None:\n            prompter = InteractivePrompter()\n        self._prompter = prompter\n        if config_writer is None:\n            config_writer = ConfigFileWriter()\n        self._config_writer = config_writer\n\n    def _run_main(self, parsed_args, parsed_globals):\n        # Called when invoked with no args \"aws configure\"\n        new_values = {}\n        # This is the config from the config file scoped to a specific\n        # profile.\n        try:\n            config = self._session.get_scoped_config()\n        except ProfileNotFound:\n            config = {}\n        for config_name, prompt_text in self.VALUES_TO_PROMPT:\n            current_value = config.get(config_name)\n            new_value = self._prompter.get_value(current_value, config_name,\n                                                 prompt_text)\n            if new_value is not None and new_value != current_value:\n                new_values[config_name] = new_value\n        config_filename = os.path.expanduser(\n            self._session.get_config_variable('config_file'))\n        if new_values:\n            self._write_out_creds_file_values(new_values,\n                                              parsed_globals.profile)\n            if parsed_globals.profile is not None:\n                new_values['__section__'] = (\n                    'profile %s' % parsed_globals.profile)\n            self._config_writer.update_config(new_values, config_filename)\n\n    def _write_out_creds_file_values(self, new_values, profile_name):\n        # The access_key/secret_key are now *always* written to the shared\n        # credentials file (~/.aws/credentials), see aws/aws-cli#847.\n        # post-conditions: ~/.aws/credentials will have the updated credential\n        # file values and new_values will have the cred vars removed.\n        credential_file_values = {}\n        if 'aws_access_key_id' in new_values:\n            credential_file_values['aws_access_key_id'] = new_values.pop(\n                'aws_access_key_id')\n        if 'aws_secret_access_key' in new_values:\n            credential_file_values['aws_secret_access_key'] = new_values.pop(\n                'aws_secret_access_key')\n        if credential_file_values:\n            if profile_name is not None:\n                credential_file_values['__section__'] = profile_name\n            shared_credentials_filename = os.path.expanduser(\n                self._session.get_config_variable('credentials_file'))\n            self._config_writer.update_config(\n                credential_file_values,\n                shared_credentials_filename)\n", "path": "awscli/customizations/configure/configure.py"}], "after_files": [{"content": "# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nimport os\n\nfrom awscli.customizations.commands import BasicCommand\nfrom awscli.customizations.configure.writer import ConfigFileWriter\n\nfrom . import PREDEFINED_SECTION_NAMES, profile_to_section\n\n\nclass ConfigureSetCommand(BasicCommand):\n    NAME = 'set'\n    DESCRIPTION = BasicCommand.FROM_FILE('configure', 'set',\n                                         '_description.rst')\n    SYNOPSIS = 'aws configure set varname value [--profile profile-name]'\n    EXAMPLES = BasicCommand.FROM_FILE('configure', 'set', '_examples.rst')\n    ARG_TABLE = [\n        {'name': 'varname',\n         'help_text': 'The name of the config value to set.',\n         'action': 'store',\n         'cli_type_name': 'string', 'positional_arg': True},\n        {'name': 'value',\n         'help_text': 'The value to set.',\n         'action': 'store',\n         'no_paramfile': True,  # To disable the default paramfile behavior\n         'cli_type_name': 'string', 'positional_arg': True},\n    ]\n    # Any variables specified in this list will be written to\n    # the ~/.aws/credentials file instead of ~/.aws/config.\n    _WRITE_TO_CREDS_FILE = ['aws_access_key_id', 'aws_secret_access_key',\n                            'aws_session_token']\n\n    def __init__(self, session, config_writer=None):\n        super(ConfigureSetCommand, self).__init__(session)\n        if config_writer is None:\n            config_writer = ConfigFileWriter()\n        self._config_writer = config_writer\n\n    def _run_main(self, args, parsed_globals):\n        varname = args.varname\n        value = args.value\n        section = 'default'\n        # Before handing things off to the config writer,\n        # we need to find out three things:\n        # 1. What section we're writing to (section).\n        # 2. The name of the config key (varname)\n        # 3. The actual value (value).\n        if '.' not in varname:\n            # unqualified name, scope it to the current\n            # profile (or leave it as the 'default' section if\n            # no profile is set).\n            if self._session.profile is not None:\n                section = profile_to_section(self._session.profile)\n        else:\n            # First figure out if it's been scoped to a profile.\n            parts = varname.split('.')\n            if parts[0] in ('default', 'profile'):\n                # Then we know we're scoped to a profile.\n                if parts[0] == 'default':\n                    section = 'default'\n                    remaining = parts[1:]\n                else:\n                    # [profile, profile_name, ...]\n                    section = profile_to_section(parts[1])\n                    remaining = parts[2:]\n                varname = remaining[0]\n                if len(remaining) == 2:\n                    value = {remaining[1]: value}\n            elif parts[0] not in PREDEFINED_SECTION_NAMES:\n                if self._session.profile is not None:\n                    section = profile_to_section(self._session.profile)\n                else:\n                    profile_name = self._session.get_config_variable('profile')\n                    if profile_name is not None:\n                        section = profile_name\n                varname = parts[0]\n                if len(parts) == 2:\n                    value = {parts[1]: value}\n            elif len(parts) == 2:\n                # Otherwise it's something like \"set preview.service true\"\n                # of something in the [plugin] section.\n                section, varname = parts\n        config_filename = os.path.expanduser(\n            self._session.get_config_variable('config_file'))\n        updated_config = {'__section__': section, varname: value}\n        if varname in self._WRITE_TO_CREDS_FILE:\n            config_filename = os.path.expanduser(\n                self._session.get_config_variable('credentials_file'))\n            section_name = updated_config['__section__']\n            if section_name.startswith('profile '):\n                updated_config['__section__'] = section_name[8:]\n        self._config_writer.update_config(updated_config, config_filename)\n", "path": "awscli/customizations/configure/set.py"}, {"content": "# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nimport string\nfrom botocore.vendored.six.moves import shlex_quote\n\nNOT_SET = '<not set>'\nPREDEFINED_SECTION_NAMES = ('preview', 'plugins')\n_WHITESPACE = ' \\t'\n\n\nclass ConfigValue(object):\n\n    def __init__(self, value, config_type, config_variable):\n        self.value = value\n        self.config_type = config_type\n        self.config_variable = config_variable\n\n    def mask_value(self):\n        if self.value is NOT_SET:\n            return\n        self.value = mask_value(self.value)\n\n\nclass SectionNotFoundError(Exception):\n    pass\n\n\ndef mask_value(current_value):\n    if current_value is None:\n        return 'None'\n    else:\n        return ('*' * 16) + current_value[-4:]\n\n\ndef profile_to_section(profile_name):\n    \"\"\"Converts a profile name to a section header to be used in the config.\"\"\"\n    if any(c in _WHITESPACE for c in profile_name):\n        profile_name = shlex_quote(profile_name)\n    return 'profile %s' % profile_name\n", "path": "awscli/customizations/configure/__init__.py"}, {"content": "# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nimport os\nimport logging\n\nfrom botocore.exceptions import ProfileNotFound\n\nfrom awscli.compat import compat_input\nfrom awscli.customizations.commands import BasicCommand\nfrom awscli.customizations.configure.addmodel import AddModelCommand\nfrom awscli.customizations.configure.set import ConfigureSetCommand\nfrom awscli.customizations.configure.get import ConfigureGetCommand\nfrom awscli.customizations.configure.list import ConfigureListCommand\nfrom awscli.customizations.configure.writer import ConfigFileWriter\n\nfrom . import mask_value, profile_to_section\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef register_configure_cmd(cli):\n    cli.register('building-command-table.main',\n                 ConfigureCommand.add_command)\n\n\nclass InteractivePrompter(object):\n\n    def get_value(self, current_value, config_name, prompt_text=''):\n        if config_name in ('aws_access_key_id', 'aws_secret_access_key'):\n            current_value = mask_value(current_value)\n        response = compat_input(\"%s [%s]: \" % (prompt_text, current_value))\n        if not response:\n            # If the user hits enter, we return a value of None\n            # instead of an empty string.  That way we can determine\n            # whether or not a value has changed.\n            response = None\n        return response\n\n\nclass ConfigureCommand(BasicCommand):\n    NAME = 'configure'\n    DESCRIPTION = BasicCommand.FROM_FILE()\n    SYNOPSIS = ('aws configure [--profile profile-name]')\n    EXAMPLES = (\n        'To create a new configuration::\\n'\n        '\\n'\n        '    $ aws configure\\n'\n        '    AWS Access Key ID [None]: accesskey\\n'\n        '    AWS Secret Access Key [None]: secretkey\\n'\n        '    Default region name [None]: us-west-2\\n'\n        '    Default output format [None]:\\n'\n        '\\n'\n        'To update just the region name::\\n'\n        '\\n'\n        '    $ aws configure\\n'\n        '    AWS Access Key ID [****]:\\n'\n        '    AWS Secret Access Key [****]:\\n'\n        '    Default region name [us-west-1]: us-west-2\\n'\n        '    Default output format [None]:\\n'\n    )\n    SUBCOMMANDS = [\n        {'name': 'list', 'command_class': ConfigureListCommand},\n        {'name': 'get', 'command_class': ConfigureGetCommand},\n        {'name': 'set', 'command_class': ConfigureSetCommand},\n        {'name': 'add-model', 'command_class': AddModelCommand}\n    ]\n\n    # If you want to add new values to prompt, update this list here.\n    VALUES_TO_PROMPT = [\n        # (logical_name, config_name, prompt_text)\n        ('aws_access_key_id', \"AWS Access Key ID\"),\n        ('aws_secret_access_key', \"AWS Secret Access Key\"),\n        ('region', \"Default region name\"),\n        ('output', \"Default output format\"),\n    ]\n\n    def __init__(self, session, prompter=None, config_writer=None):\n        super(ConfigureCommand, self).__init__(session)\n        if prompter is None:\n            prompter = InteractivePrompter()\n        self._prompter = prompter\n        if config_writer is None:\n            config_writer = ConfigFileWriter()\n        self._config_writer = config_writer\n\n    def _run_main(self, parsed_args, parsed_globals):\n        # Called when invoked with no args \"aws configure\"\n        new_values = {}\n        # This is the config from the config file scoped to a specific\n        # profile.\n        try:\n            config = self._session.get_scoped_config()\n        except ProfileNotFound:\n            config = {}\n        for config_name, prompt_text in self.VALUES_TO_PROMPT:\n            current_value = config.get(config_name)\n            new_value = self._prompter.get_value(current_value, config_name,\n                                                 prompt_text)\n            if new_value is not None and new_value != current_value:\n                new_values[config_name] = new_value\n        config_filename = os.path.expanduser(\n            self._session.get_config_variable('config_file'))\n        if new_values:\n            self._write_out_creds_file_values(new_values,\n                                              parsed_globals.profile)\n            if parsed_globals.profile is not None:\n                section = profile_to_section(parsed_globals.profile)\n                new_values['__section__'] = section\n            self._config_writer.update_config(new_values, config_filename)\n\n    def _write_out_creds_file_values(self, new_values, profile_name):\n        # The access_key/secret_key are now *always* written to the shared\n        # credentials file (~/.aws/credentials), see aws/aws-cli#847.\n        # post-conditions: ~/.aws/credentials will have the updated credential\n        # file values and new_values will have the cred vars removed.\n        credential_file_values = {}\n        if 'aws_access_key_id' in new_values:\n            credential_file_values['aws_access_key_id'] = new_values.pop(\n                'aws_access_key_id')\n        if 'aws_secret_access_key' in new_values:\n            credential_file_values['aws_secret_access_key'] = new_values.pop(\n                'aws_secret_access_key')\n        if credential_file_values:\n            if profile_name is not None:\n                credential_file_values['__section__'] = profile_name\n            shared_credentials_filename = os.path.expanduser(\n                self._session.get_config_variable('credentials_file'))\n            self._config_writer.update_config(\n                credential_file_values,\n                shared_credentials_filename)\n", "path": "awscli/customizations/configure/configure.py"}]}