diff --git a/changelogs/fragments/8814-dict-comprehension.yml b/changelogs/fragments/8814-dict-comprehension.yml new file mode 100644 index 0000000000..01b5da4bae --- /dev/null +++ b/changelogs/fragments/8814-dict-comprehension.yml @@ -0,0 +1,23 @@ +minor_changes: + - hashids filter plugin - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - keep_keys filter plugin - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - remove_keys filter plugin - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - replace_keys filter plugin - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - csv module utils - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - vars MH module utils - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - vardict module utils - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - apache2_mod_proxy - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - gitlab_group - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - keycloak_client - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - keycloak_clientscope - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - keycloak_identity_provider - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - keycloak_user_federation - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - linode - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - lxd_container - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - manageiq_provider - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - one_service - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - one_vm - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - proxmox - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - proxmox_disk - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - proxmox_kvm - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). + - unsafe plugin utils - replace Python 2.6 construct with dict comprehensions (https://github.com/ansible-collections/community.general/pull/8814). diff --git a/plugins/filter/hashids.py b/plugins/filter/hashids.py index 45fba83c03..ac771e6219 100644 --- a/plugins/filter/hashids.py +++ b/plugins/filter/hashids.py @@ -27,7 +27,7 @@ def initialize_hashids(**kwargs): if not HAS_HASHIDS: raise AnsibleError("The hashids library must be installed in order to use this plugin") - params = dict((k, v) for k, v in kwargs.items() if v) + params = {k: v for k, v in kwargs.items() if v} try: return Hashids(**params) diff --git a/plugins/filter/keep_keys.py b/plugins/filter/keep_keys.py index dffccba356..97b706a950 100644 --- a/plugins/filter/keep_keys.py +++ b/plugins/filter/keep_keys.py @@ -127,7 +127,7 @@ def keep_keys(data, target=None, matching_parameter='equal'): def keep_key(key): return tt.match(key) is not None - return [dict((k, v) for k, v in d.items() if keep_key(k)) for d in data] + return [{k: v for k, v in d.items() if keep_key(k)} for d in data] class FilterModule(object): diff --git a/plugins/filter/remove_keys.py b/plugins/filter/remove_keys.py index cabce14682..7a4d912d34 100644 --- a/plugins/filter/remove_keys.py +++ b/plugins/filter/remove_keys.py @@ -127,7 +127,7 @@ def remove_keys(data, target=None, matching_parameter='equal'): def keep_key(key): return tt.match(key) is None - return [dict((k, v) for k, v in d.items() if keep_key(k)) for d in data] + return [{k: v for k, v in d.items() if keep_key(k)} for d in data] class FilterModule(object): diff --git a/plugins/filter/replace_keys.py b/plugins/filter/replace_keys.py index d3b12c05d0..70b264eba6 100644 --- a/plugins/filter/replace_keys.py +++ b/plugins/filter/replace_keys.py @@ -169,7 +169,7 @@ def replace_keys(data, target=None, matching_parameter='equal'): return a return key - return [dict((replace_key(k), v) for k, v in d.items()) for d in data] + return [{replace_key(k): v for k, v in d.items()} for d in data] class FilterModule(object): diff --git a/plugins/module_utils/csv.py b/plugins/module_utils/csv.py index 200548a46d..46408e4877 100644 --- a/plugins/module_utils/csv.py +++ b/plugins/module_utils/csv.py @@ -43,7 +43,7 @@ def initialize_dialect(dialect, **kwargs): raise DialectNotAvailableError("Dialect '%s' is not supported by your version of python." % dialect) # Create a dictionary from only set options - dialect_params = dict((k, v) for k, v in kwargs.items() if v is not None) + dialect_params = {k: v for k, v in kwargs.items() if v is not None} if dialect_params: try: csv.register_dialect('custom', dialect, **dialect_params) diff --git a/plugins/module_utils/mh/mixins/vars.py b/plugins/module_utils/mh/mixins/vars.py index 1615609735..7db9904f93 100644 --- a/plugins/module_utils/mh/mixins/vars.py +++ b/plugins/module_utils/mh/mixins/vars.py @@ -113,7 +113,7 @@ class VarDict(object): self._meta[name] = meta def output(self): - return dict((k, v) for k, v in self._data.items() if self.meta(k).output) + return {k: v for k, v in self._data.items() if self.meta(k).output} def diff(self): diff_results = [(k, self.meta(k).diff_result) for k in self._data] @@ -125,7 +125,7 @@ class VarDict(object): return None def facts(self): - facts_result = dict((k, v) for k, v in self._data.items() if self._meta[k].fact) + facts_result = {k: v for k, v in self._data.items() if self._meta[k].fact} return facts_result if facts_result else None def change_vars(self): diff --git a/plugins/module_utils/vardict.py b/plugins/module_utils/vardict.py index 51f802483d..9bd104ce37 100644 --- a/plugins/module_utils/vardict.py +++ b/plugins/module_utils/vardict.py @@ -175,18 +175,18 @@ class VarDict(object): self.__vars__[name] = var def output(self, verbosity=0): - return dict((n, v.value) for n, v in self.__vars__.items() if v.output and v.is_visible(verbosity)) + return {n: v.value for n, v in self.__vars__.items() if v.output and v.is_visible(verbosity)} def diff(self, verbosity=0): diff_results = [(n, v.diff_result) for n, v in self.__vars__.items() if v.diff_result and v.is_visible(verbosity)] if diff_results: - before = dict((n, dr['before']) for n, dr in diff_results) - after = dict((n, dr['after']) for n, dr in diff_results) + before = {n: dr['before'] for n, dr in diff_results} + after = {n: dr['after'] for n, dr in diff_results} return {'before': before, 'after': after} return None def facts(self, verbosity=0): - facts_result = dict((n, v.value) for n, v in self.__vars__.items() if v.fact and v.is_visible(verbosity)) + facts_result = {n: v.value for n, v in self.__vars__.items() if v.fact and v.is_visible(verbosity)} return facts_result if facts_result else None @property @@ -194,4 +194,4 @@ class VarDict(object): return any(var.has_changed for var in self.__vars__.values()) def as_dict(self): - return dict((name, var.value) for name, var in self.__vars__.items()) + return {name: var.value for name, var in self.__vars__.items()} diff --git a/plugins/modules/apache2_mod_proxy.py b/plugins/modules/apache2_mod_proxy.py index 8f561e8ae0..87e99bdd9a 100644 --- a/plugins/modules/apache2_mod_proxy.py +++ b/plugins/modules/apache2_mod_proxy.py @@ -286,7 +286,7 @@ class BalancerMember(object): 'hot_standby': 'Stby', 'ignore_errors': 'Ign'} actual_status = str(self.attributes['Status']) - status = dict((mode, patt in actual_status) for mode, patt in iteritems(status_mapping)) + status = {mode: patt in actual_status for mode, patt in iteritems(status_mapping)} return status def set_member_status(self, values): diff --git a/plugins/modules/gitlab_group.py b/plugins/modules/gitlab_group.py index 3d57b18528..1f4dadff70 100644 --- a/plugins/modules/gitlab_group.py +++ b/plugins/modules/gitlab_group.py @@ -261,7 +261,7 @@ class GitLabGroup(object): try: # Filter out None values - filtered = dict((arg_key, arg_value) for arg_key, arg_value in arguments.items() if arg_value is not None) + filtered = {arg_key: arg_value for arg_key, arg_value in arguments.items() if arg_value is not None} group = self._gitlab.groups.create(filtered) except (gitlab.exceptions.GitlabCreateError) as e: diff --git a/plugins/modules/keycloak_client.py b/plugins/modules/keycloak_client.py index efaa66e26d..d7e4fb0b7e 100644 --- a/plugins/modules/keycloak_client.py +++ b/plugins/modules/keycloak_client.py @@ -1006,7 +1006,7 @@ def main(): # Unfortunately, the ansible argument spec checker introduces variables with null values when # they are not specified if client_param == 'protocol_mappers': - new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value] + new_param_value = [{k: v for k, v in x.items() if v is not None} for x in new_param_value] elif client_param == 'authentication_flow_binding_overrides': new_param_value = flow_binding_from_dict_to_model(new_param_value, realm, kc) diff --git a/plugins/modules/keycloak_clientscope.py b/plugins/modules/keycloak_clientscope.py index b8ee842195..576a831bdb 100644 --- a/plugins/modules/keycloak_clientscope.py +++ b/plugins/modules/keycloak_clientscope.py @@ -428,7 +428,7 @@ def main(): # Unfortunately, the ansible argument spec checker introduces variables with null values when # they are not specified if clientscope_param == 'protocol_mappers': - new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value] + new_param_value = [{k: v for k, v in x.items() if v is not None} for x in new_param_value] changeset[camel(clientscope_param)] = new_param_value # Prepare the desired values using the existing values (non-existence results in a dict that is save to use as a basis) diff --git a/plugins/modules/keycloak_identity_provider.py b/plugins/modules/keycloak_identity_provider.py index bb958d9e94..609673653b 100644 --- a/plugins/modules/keycloak_identity_provider.py +++ b/plugins/modules/keycloak_identity_provider.py @@ -534,7 +534,7 @@ def main(): # special handling of mappers list to allow change detection if module.params.get('mappers') is not None: for change in module.params['mappers']: - change = dict((k, v) for k, v in change.items() if change[k] is not None) + change = {k: v for k, v in change.items() if v is not None} if change.get('id') is None and change.get('name') is None: module.fail_json(msg='Either `name` or `id` has to be specified on each mapper.') if before_idp == dict(): diff --git a/plugins/modules/keycloak_user_federation.py b/plugins/modules/keycloak_user_federation.py index 22cd36a64f..05f884cc1e 100644 --- a/plugins/modules/keycloak_user_federation.py +++ b/plugins/modules/keycloak_user_federation.py @@ -724,7 +724,7 @@ from copy import deepcopy def sanitize(comp): compcopy = deepcopy(comp) if 'config' in compcopy: - compcopy['config'] = dict((k, v[0]) for k, v in compcopy['config'].items()) + compcopy['config'] = {k: v[0] for k, v in compcopy['config'].items()} if 'bindCredential' in compcopy['config']: compcopy['config']['bindCredential'] = '**********' # an empty string is valid for krbPrincipalAttribute but is filtered out in diff @@ -733,7 +733,7 @@ def sanitize(comp): if 'mappers' in compcopy: for mapper in compcopy['mappers']: if 'config' in mapper: - mapper['config'] = dict((k, v[0]) for k, v in mapper['config'].items()) + mapper['config'] = {k: v[0] for k, v in mapper['config'].items()} return compcopy @@ -886,7 +886,7 @@ def main(): new_param_value = module.params.get(param) old_value = before_comp[camel(param)] if camel(param) in before_comp else None if param == 'mappers': - new_param_value = [dict((k, v) for k, v in x.items() if x[k] is not None) for x in new_param_value] + new_param_value = [{k: v for k, v in x.items() if v is not None} for x in new_param_value] if new_param_value != old_value: changeset[camel(param)] = new_param_value @@ -895,7 +895,7 @@ def main(): if module.params['provider_id'] in ['kerberos', 'sssd']: module.fail_json(msg='Cannot configure mappers for {type} provider.'.format(type=module.params['provider_id'])) for change in module.params['mappers']: - change = dict((k, v) for k, v in change.items() if change[k] is not None) + change = {k: v for k, v in change.items() if v is not None} if change.get('id') is None and change.get('name') is None: module.fail_json(msg='Either `name` or `id` has to be specified on each mapper.') if cid is None: diff --git a/plugins/modules/linode.py b/plugins/modules/linode.py index 9e04ac63da..9b0dabdff2 100644 --- a/plugins/modules/linode.py +++ b/plugins/modules/linode.py @@ -670,7 +670,7 @@ def main(): backupwindow=backupwindow, ) - kwargs = dict((k, v) for k, v in check_items.items() if v is not None) + kwargs = {k: v for k, v in check_items.items() if v is not None} # setup the auth try: diff --git a/plugins/modules/lxd_container.py b/plugins/modules/lxd_container.py index f44523a751..88e502e7c8 100644 --- a/plugins/modules/lxd_container.py +++ b/plugins/modules/lxd_container.py @@ -616,8 +616,15 @@ class LXDContainerManagement(object): def _instance_ipv4_addresses(self, ignore_devices=None): ignore_devices = ['lo'] if ignore_devices is None else ignore_devices data = (self._get_instance_state_json() or {}).get('metadata', None) or {} - network = dict((k, v) for k, v in (data.get('network', None) or {}).items() if k not in ignore_devices) - addresses = dict((k, [a['address'] for a in v['addresses'] if a['family'] == 'inet']) for k, v in network.items()) + network = { + k: v + for k, v in data.get('network', {}).items() + if k not in ignore_devices + } + addresses = { + k: [a['address'] for a in v['addresses'] if a['family'] == 'inet'] + for k, v in network.items() + } return addresses @staticmethod @@ -748,19 +755,22 @@ class LXDContainerManagement(object): def run(self): """Run the main method.""" + def adjust_content(content): + return content if not isinstance(content, dict) else { + k: v for k, v in content.items() if not (self.ignore_volatile_options and k.startswith('volatile.')) + } + try: if self.trust_password is not None: self.client.authenticate(self.trust_password) self.ignore_volatile_options = self.module.params.get('ignore_volatile_options') self.old_instance_json = self._get_instance_json() - self.old_sections = dict( - (section, content) if not isinstance(content, dict) - else (section, dict((k, v) for k, v in content.items() - if not (self.ignore_volatile_options and k.startswith('volatile.')))) - for section, content in (self.old_instance_json.get('metadata', None) or {}).items() + self.old_sections = { + section: adjust_content(content) + for section, content in self.old_instance_json.get('metadata', {}).items() if section in set(CONFIG_PARAMS) - set(CONFIG_CREATION_PARAMS) - ) + } self.diff['before']['instance'] = self.old_sections # preliminary, will be overwritten in _apply_instance_configs() if called diff --git a/plugins/modules/manageiq_provider.py b/plugins/modules/manageiq_provider.py index e6ded9ea7a..af5c147f46 100644 --- a/plugins/modules/manageiq_provider.py +++ b/plugins/modules/manageiq_provider.py @@ -715,7 +715,7 @@ def delete_nulls(h): if isinstance(h, list): return [delete_nulls(i) for i in h] if isinstance(h, dict): - return dict((k, delete_nulls(v)) for k, v in h.items() if v is not None) + return {k: delete_nulls(v) for k, v in h.items() if v is not None} return h diff --git a/plugins/modules/one_service.py b/plugins/modules/one_service.py index 81b42c0ecc..2c89e9b8ad 100644 --- a/plugins/modules/one_service.py +++ b/plugins/modules/one_service.py @@ -339,7 +339,7 @@ def get_service_info(module, auth, service): def create_service(module, auth, template_id, service_name, custom_attrs, unique, wait, wait_timeout): # make sure that the values in custom_attrs dict are strings - custom_attrs_with_str = dict((k, str(v)) for k, v in custom_attrs.items()) + custom_attrs_with_str = {k: str(v) for k, v in custom_attrs.items()} data = { "action": { diff --git a/plugins/modules/one_vm.py b/plugins/modules/one_vm.py index 8ee9c85609..2f4ee25354 100644 --- a/plugins/modules/one_vm.py +++ b/plugins/modules/one_vm.py @@ -1559,11 +1559,11 @@ def main(): one_client = pyone.OneServer(auth.url, session=auth.username + ':' + auth.password) if attributes: - attributes = dict((key.upper(), value) for key, value in attributes.items()) + attributes = {key.upper(): value for key, value in attributes.items()} check_attributes(module, attributes) if count_attributes: - count_attributes = dict((key.upper(), value) for key, value in count_attributes.items()) + count_attributes = {key.upper(): value for key, value in count_attributes.items()} if not attributes: import copy module.warn('When you pass `count_attributes` without `attributes` option when deploying, `attributes` option will have same values implicitly.') diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index 20e20e9a88..52d5a849f3 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -771,7 +771,7 @@ class ProxmoxLxcAnsible(ProxmoxAnsible): ) # Remove all empty kwarg entries - kwargs = dict((key, val) for key, val in kwargs.items() if val is not None) + kwargs = {key: val for key, val in kwargs.items() if val is not None} if cpus is not None: kwargs["cpulimit"] = cpus @@ -842,7 +842,7 @@ class ProxmoxLxcAnsible(ProxmoxAnsible): proxmox_node = self.proxmox_api.nodes(node) # Remove all empty kwarg entries - kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) + kwargs = {k: v for k, v in kwargs.items() if v is not None} pve_version = self.version() diff --git a/plugins/modules/proxmox_disk.py b/plugins/modules/proxmox_disk.py index 979e551336..a4a9dd8791 100644 --- a/plugins/modules/proxmox_disk.py +++ b/plugins/modules/proxmox_disk.py @@ -524,8 +524,11 @@ class ProxmoxDiskAnsible(ProxmoxAnsible): # - Remove not defined args # - Ensure True and False converted to int. # - Remove unnecessary parameters - params = dict((k, v) for k, v in self.module.params.items() if v is not None and k in self.create_update_fields) - params.update(dict((k, int(v)) for k, v in params.items() if isinstance(v, bool))) + params = { + k: int(v) if isinstance(v, bool) else v + for k, v in self.module.params.items() + if v is not None and k in self.create_update_fields + } return params def wait_till_complete_or_timeout(self, node_name, task_id): @@ -598,7 +601,7 @@ class ProxmoxDiskAnsible(ProxmoxAnsible): if iso_image is not None: playbook_config['volume'] = iso_image # Values in params are numbers, but strings are needed to compare with disk_config - playbook_config = dict((k, str(v)) for k, v in playbook_config.items()) + playbook_config = {k: str(v) for k, v in playbook_config.items()} # Now compare old and new config to detect if changes are needed if proxmox_config == playbook_config: @@ -626,7 +629,7 @@ class ProxmoxDiskAnsible(ProxmoxAnsible): params['format'] = self.module.params['format'] params['delete'] = 1 if self.module.params.get('delete_moved', False) else 0 # Remove not defined args - params = dict((k, v) for k, v in params.items() if v is not None) + params = {k: v for k, v in params.items() if v is not None} if params.get('storage', False): disk_config = disk_conf_str_to_dict(vm_config[disk]) diff --git a/plugins/modules/proxmox_kvm.py b/plugins/modules/proxmox_kvm.py index 71cbb51fc1..e2b708170e 100644 --- a/plugins/modules/proxmox_kvm.py +++ b/plugins/modules/proxmox_kvm.py @@ -970,7 +970,7 @@ class ProxmoxKvmAnsible(ProxmoxAnsible): self.module.fail_json(msg='Getting information for VM with vmid = %s failed with exception: %s' % (vmid, e)) # Sanitize kwargs. Remove not defined args and ensure True and False converted to int. - kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) + kwargs = {k: v for k, v in kwargs.items() if v is not None} # Convert all dict in kwargs to elements. # For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n] @@ -996,7 +996,7 @@ class ProxmoxKvmAnsible(ProxmoxAnsible): proxmox_node = self.proxmox_api.nodes(node) # Sanitize kwargs. Remove not defined args and ensure True and False converted to int. - kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) + kwargs = {k: v for k, v in kwargs.items() if v is not None} return proxmox_node.qemu(vmid).config.set(**kwargs) is None @@ -1031,7 +1031,7 @@ class ProxmoxKvmAnsible(ProxmoxAnsible): proxmox_node = self.proxmox_api.nodes(node) # Sanitize kwargs. Remove not defined args and ensure True and False converted to int. - kwargs = dict((k, v) for k, v in kwargs.items() if v is not None) + kwargs = {k: v for k, v in kwargs.items() if v is not None} kwargs.update(dict([k, int(v)] for k, v in kwargs.items() if isinstance(v, bool))) version = self.version() diff --git a/plugins/plugin_utils/unsafe.py b/plugins/plugin_utils/unsafe.py index 1eb61bea0f..4fdb8b3d51 100644 --- a/plugins/plugin_utils/unsafe.py +++ b/plugins/plugin_utils/unsafe.py @@ -24,7 +24,7 @@ def make_unsafe(value): return value if isinstance(value, Mapping): - return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items()) + return {make_unsafe(key): make_unsafe(val) for key, val in value.items()} elif isinstance(value, Set): return set(make_unsafe(elt) for elt in value) elif is_sequence(value): diff --git a/tests/sanity/extra/botmeta.py b/tests/sanity/extra/botmeta.py index 459d3ba14d..d7828ebabb 100755 --- a/tests/sanity/extra/botmeta.py +++ b/tests/sanity/extra/botmeta.py @@ -190,7 +190,7 @@ def main(): try: for file, filedata in (botmeta.get('files') or {}).items(): file = convert_macros(file, macros) - filedata = dict((k, convert_macros(v, macros)) for k, v in filedata.items()) + filedata = {k: convert_macros(v, macros) for k, v in filedata.items()} files[file] = filedata for k, v in filedata.items(): if k in LIST_ENTRIES: