Use sorted dictionary before iteration

In Python 3, dict.values() method returns a view of the dictionary's
values but in a different order than Python 2, which returns a
list. This patch sorts the data dictionary first to be sure to get the
same order whatever the Python version.

In Python 3.3 "abstract base classes" in collections (like Mapping or
Sequence) were moved to second-level module collections.abc. So in
Python 3.3+ the real type is collections.abc.Mapping and so
on. Documentation states that the old alias
names (e.g. collections.Mapping) will be available up to Python
3.7 (currently the latest version), however in 3.8 these aliases will be
removed. This patch prepares the code to the future Python 3.8 version.

This patch also fixes the warnings and errors lists to get only unique
messages.

Change-Id: If2c22ad982fafc37ef48b7cd870ea6cf01e7913a
Signed-off-by: Gael Chamoulaud <gchamoul@redhat.com>
(cherry picked from commit 90bb581601)
This commit is contained in:
Gael Chamoulaud 2019-06-20 16:44:43 +02:00
parent 4b30953929
commit 673148df6f
2 changed files with 21 additions and 10 deletions

View File

@ -15,6 +15,12 @@
# under the License.
import collections
try:
collectionsAbc = collections.abc
except AttributeError:
collectionsAbc = collections
import os.path
import yaml
@ -114,18 +120,18 @@ def validate_switch_vlans(netenv_path, template_files, introspection_data):
# Get the VLANs which are actually used in nic configs
for nic_config_name, nic_config_path, nic_config in nic_configs:
resources = nic_config.get('resources')
if not isinstance(nic_config, collections.Mapping):
if not isinstance(nic_config, collectionsAbc.Mapping):
return [], ["nic_config parameter must be a dictionary."]
if not isinstance(resources, collections.Mapping):
if not isinstance(resources, collectionsAbc.Mapping):
return [], ["The nic_data must contain the 'resources' key "
"and it must be a dictionary."]
for name, resource in six.iteritems(resources):
try:
nested_path = [
('properties', collections.Mapping, 'dictionary'),
('config', collections.Mapping, 'dictionary'),
('network_config', collections.Iterable, 'list'),
('properties', collectionsAbc.Mapping, 'dictionary'),
('config', collectionsAbc.Mapping, 'dictionary'),
('network_config', collectionsAbc.Iterable, 'list'),
]
nw_config = utils.get_nested(resource, name, nested_path)
except ValueError as e:
@ -159,7 +165,7 @@ def validate_switch_vlans(netenv_path, template_files, introspection_data):
if not vlans_in_templates:
warnings.append("No VLANs are used on templates files")
return warnings, errors
return set(warnings), set(errors)
def vlan_exists_on_switch(vlan_id, introspection_data):

View File

@ -20,6 +20,11 @@ from six import string_types
import collections
try:
collectionsAbc = collections.abc
except AttributeError:
collectionsAbc = collections
from glanceclient import client as glance_client
from heatclient import client as heat_client
from ironicclient import client as ironic_client
@ -101,12 +106,12 @@ def get_nested(data, name, path):
raise ValueError("The '{}' property of '{}' must be a {}."
"".format(key, name, instance_name))
return data[key]
for item in data.values():
if isinstance(item, collections.Mapping):
return deep_find_key(key_data, item, name)
for k, v in sorted(data.items()):
if isinstance(v, collectionsAbc.Mapping):
return deep_find_key(key_data, v, name)
return None
if not isinstance(data, collections.Mapping):
if not isinstance(data, collectionsAbc.Mapping):
raise ValueError(
"'{}' is not a valid resource.".format(name))