/
usr
/
lib
/
rads
/
venv
/
lib
/
python3.13
/
site-packages
/
botocore
/
/usr/lib/rads/venv/lib/python3.13/site-packages/botocore
mkdir
upload
Name
Size
Mode
Actions
crt/
-
0755
rm
data/
-
0755
rm
docs/
-
0755
rm
retries/
-
0755
rm
vendored/
-
0755
rm
__pycache__/
-
0755
rm
args.py
38460
0644
edit
dl
rm
auth.py
46062
0644
edit
dl
rm
awsrequest.py
23178
0644
edit
dl
rm
cacert.pem
266617
0644
edit
dl
rm
client.py
54154
0644
edit
dl
rm
compat.py
11607
0644
edit
dl
rm
compress.py
4533
0644
edit
dl
rm
config.py
20092
0644
edit
dl
rm
configloader.py
10039
0644
edit
dl
rm
configprovider.py
38092
0644
edit
dl
rm
context.py
3782
0644
edit
dl
rm
credentials.py
88913
0644
edit
dl
rm
discovery.py
11069
0644
edit
dl
rm
endpoint.py
16739
0644
edit
dl
rm
endpoint_provider.py
23005
0644
edit
dl
rm
errorfactory.py
3722
0644
edit
dl
rm
eventstream.py
20279
0644
edit
dl
rm
exceptions.py
23333
0644
edit
dl
rm
handlers.py
66230
0644
edit
dl
rm
history.py
1744
0644
edit
dl
rm
hooks.py
25053
0644
edit
dl
rm
httpchecksum.py
19452
0644
edit
dl
rm
httpsession.py
18696
0644
edit
dl
rm
loaders.py
18834
0644
edit
dl
rm
model.py
32347
0644
edit
dl
rm
monitoring.py
20594
0644
edit
dl
rm
paginate.py
27909
0644
edit
dl
rm
parsers.py
60400
0644
edit
dl
rm
plugin.py
2534
0644
edit
dl
rm
regions.py
33932
0644
edit
dl
rm
response.py
7865
0644
edit
dl
rm
retryhandler.py
14702
0644
edit
dl
rm
serialize.py
49017
0644
edit
dl
rm
session.py
51661
0644
edit
dl
rm
signers.py
34519
0644
edit
dl
rm
stub.py
16193
0644
edit
dl
rm
tokens.py
11764
0644
edit
dl
rm
translate.py
3406
0644
edit
dl
rm
useragent.py
23171
0644
edit
dl
rm
utils.py
136764
0644
edit
dl
rm
validate.py
13759
0644
edit
dl
rm
waiter.py
14711
0644
edit
dl
rm
__init__.py
8019
0644
edit
dl
rm
Edit:
/usr/lib/rads/venv/lib/python3.13/site-packages/botocore/configloader.py
(10039B)
# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/ # Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You # may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file is # 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 configparser import copy import os import shlex import sys import botocore.exceptions def multi_file_load_config(*filenames): """Load and combine multiple INI configs with profiles. This function will take a list of filesnames and return a single dictionary that represents the merging of the loaded config files. If any of the provided filenames does not exist, then that file is ignored. It is therefore ok to provide a list of filenames, some of which may not exist. Configuration files are **not** deep merged, only the top level keys are merged. The filenames should be passed in order of precedence. The first config file has precedence over the second config file, which has precedence over the third config file, etc. The only exception to this is that the "profiles" key is merged to combine profiles from multiple config files into a single profiles mapping. However, if a profile is defined in multiple config files, then the config file with the highest precedence is used. Profile values themselves are not merged. For example:: FileA FileB FileC [foo] [foo] [bar] a=1 a=2 a=3 b=2 [bar] [baz] [profile a] a=2 a=3 region=e [profile a] [profile b] [profile c] region=c region=d region=f The final result of ``multi_file_load_config(FileA, FileB, FileC)`` would be:: {"foo": {"a": 1}, "bar": {"a": 2}, "baz": {"a": 3}, "profiles": {"a": {"region": "c"}}, {"b": {"region": d"}}, {"c": {"region": "f"}}} Note that the "foo" key comes from A, even though it's defined in both FileA and FileB. Because "foo" was defined in FileA first, then the values for "foo" from FileA are used and the values for "foo" from FileB are ignored. Also note where the profiles originate from. Profile "a" comes FileA, profile "b" comes from FileB, and profile "c" comes from FileC. """ configs = [] profiles = [] for filename in filenames: try: loaded = load_config(filename) except botocore.exceptions.ConfigNotFound: continue profiles.append(loaded.pop('profiles')) configs.append(loaded) merged_config = _merge_list_of_dicts(configs) merged_profiles = _merge_list_of_dicts(profiles) merged_config['profiles'] = merged_profiles return merged_config def _merge_list_of_dicts(list_of_dicts): merged_dicts = {} for single_dict in list_of_dicts: for key, value in single_dict.items(): if key not in merged_dicts: merged_dicts[key] = value return merged_dicts def load_config(config_filename): """Parse a INI config with profiles. This will parse an INI config file and map top level profiles into a top level "profile" key. If you want to parse an INI file and map all section names to top level keys, use ``raw_config_parse`` instead. """ parsed = raw_config_parse(config_filename) return build_profile_map(parsed) def raw_config_parse(config_filename, parse_subsections=True): """Returns the parsed INI config contents. Each section name is a top level key. :param config_filename: The name of the INI file to parse :param parse_subsections: If True, parse indented blocks as subsections that represent their own configuration dictionary. For example, if the config file had the contents:: s3 = signature_version = s3v4 addressing_style = path The resulting ``raw_config_parse`` would be:: {'s3': {'signature_version': 's3v4', 'addressing_style': 'path'}} If False, do not try to parse subsections and return the indented block as its literal value:: {'s3': '\nsignature_version = s3v4\naddressing_style = path'} :returns: A dict with keys for each profile found in the config file and the value of each key being a dict containing name value pairs found in that profile. :raises: ConfigNotFound, ConfigParseError """ config = {} path = config_filename if path is not None: path = os.path.expandvars(path) path = os.path.expanduser(path) if not os.path.isfile(path): raise botocore.exceptions.ConfigNotFound(path=_unicode_path(path)) cp = configparser.RawConfigParser() try: cp.read([path]) except (configparser.Error, UnicodeDecodeError) as e: raise botocore.exceptions.ConfigParseError( path=_unicode_path(path), error=e ) from None else: for section in cp.sections(): config[section] = {} for option in cp.options(section): config_value = cp.get(section, option) if parse_subsections and config_value.startswith('\n'): # Then we need to parse the inner contents as # hierarchical. We support a single level # of nesting for now. try: config_value = _parse_nested(config_value) except ValueError as e: raise botocore.exceptions.ConfigParseError( path=_unicode_path(path), error=e ) from None config[section][option] = config_value return config def _unicode_path(path): if isinstance(path, str): return path # According to the documentation getfilesystemencoding can return None # on unix in which case the default encoding is used instead. filesystem_encoding = sys.getfilesystemencoding() if filesystem_encoding is None: filesystem_encoding = sys.getdefaultencoding() return path.decode(filesystem_encoding, 'replace') def _parse_nested(config_value): # Given a value like this: # \n # foo = bar # bar = baz # We need to parse this into # {'foo': 'bar', 'bar': 'baz} parsed = {} for line in config_value.splitlines(): line = line.strip() if not line: continue # The caller will catch ValueError # and raise an appropriate error # if this fails. key, value = line.split('=', 1) parsed[key.strip()] = value.strip() return parsed def _parse_section(key, values): result = {} try: parts = shlex.split(key) except ValueError: return result if len(parts) == 2: result[parts[1]] = values return result def build_profile_map(parsed_ini_config): """Convert the parsed INI config into a profile map. The config file format requires that every profile except the default to be prepended with "profile", e.g.:: [profile test] aws_... = foo aws_... = bar [profile bar] aws_... = foo aws_... = bar # This is *not* a profile [preview] otherstuff = 1 # Neither is this [foobar] morestuff = 2 The build_profile_map will take a parsed INI config file where each top level key represents a section name, and convert into a format where all the profiles are under a single top level "profiles" key, and each key in the sub dictionary is a profile name. For example, the above config file would be converted from:: {"profile test": {"aws_...": "foo", "aws...": "bar"}, "profile bar": {"aws...": "foo", "aws...": "bar"}, "preview": {"otherstuff": ...}, "foobar": {"morestuff": ...}, } into:: {"profiles": {"test": {"aws_...": "foo", "aws...": "bar"}, "bar": {"aws...": "foo", "aws...": "bar"}, "preview": {"otherstuff": ...}, "foobar": {"morestuff": ...}, } If there are no profiles in the provided parsed INI contents, then an empty dict will be the value associated with the ``profiles`` key. .. note:: This will not mutate the passed in parsed_ini_config. Instead it will make a deepcopy and return that value. """ parsed_config = copy.deepcopy(parsed_ini_config) profiles = {} sso_sessions = {} services = {} final_config = {} for key, values in parsed_config.items(): if key.startswith("profile"): profiles.update(_parse_section(key, values)) elif key.startswith("sso-session"): sso_sessions.update(_parse_section(key, values)) elif key.startswith("services"): services.update(_parse_section(key, values)) elif key == 'default': # default section is special and is considered a profile # name but we don't require you use 'profile "default"' # as a section. profiles[key] = values else: final_config[key] = values final_config['profiles'] = profiles final_config['sso_sessions'] = sso_sessions final_config['services'] = services return final_config
Save
cmd:
run