Skip to content

Commit

Permalink
Cleanups of the routing code:
Browse files Browse the repository at this point in the history
* Move compare_all_but() into a utils file
* Eliminate a second loop from the compare_all_but() function.
* Rename unused variables from _ to dummy to avoid potential gettext
  conventions.
* rename remove_flatmapping_artefacts() to
  remove_flatmapping_artifacts() (artefacts is the British English spelling)
  • Loading branch information
abadger committed Feb 17, 2021
1 parent bac0aca commit 2457b27
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 25 deletions.
29 changes: 6 additions & 23 deletions antsibull/docs_parsing/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from .. import app_context
from .. import yaml
from ..utils.collections import compare_all_but
from ..utils.get_pkg_data import get_antsibull_data
from . import AnsibleCollectionMetadata
from .fqcn import get_fqcn_parts
Expand Down Expand Up @@ -83,7 +84,7 @@ def find_symlink_redirects(collection_name: str,
"""
plugin_type_routing = dict()
if os.path.isdir(directory_path):
for path, _, files in os.walk(directory_path):
for path, dummy, files in os.walk(directory_path):
rel_path = os.path.relpath(path, directory_path)
for filename in files:
src_basename, ext = os.path.splitext(filename)
Expand Down Expand Up @@ -154,7 +155,7 @@ def find_flatmapping_short_long_maps(plugin_routing_type: t.Dict[str, t.Dict[str
return shortname_to_longname, longname_to_shortname


def remove_flatmapping_artefacts(plugin_routing: t.Dict[str, t.Dict[str, t.Dict[str, t.Any]]]
def remove_flatmapping_artifacts(plugin_routing: t.Dict[str, t.Dict[str, t.Dict[str, t.Any]]]
) -> None:
"""
For collections which use flatmapping (like community.general and community.network),
Expand Down Expand Up @@ -237,7 +238,7 @@ async def load_collection_routing(collection_name: str,
plugin_type_routing[redirect_name]['redirect_is_symlink'] = True

if collection_name in COLLECTIONS_WITH_FLATMAPPING:
remove_flatmapping_artefacts(plugin_routing_out)
remove_flatmapping_artifacts(plugin_routing_out)

return plugin_routing_out

Expand Down Expand Up @@ -265,24 +266,6 @@ async def load_all_collection_routing(collection_metadata: t.Mapping[str,
return global_plugin_routing


def compare_all_but(dict_a, dict_b, *keys_to_ignore):
"""
Compare two dictionaries
"""
sentinel = object()
for key, value in dict_a.items():
if key in keys_to_ignore:
continue
if value != dict_b.get(key, sentinel):
return False
for key, value in dict_b.items():
if key in keys_to_ignore:
continue
if value != dict_a.get(key, sentinel):
return False
return True


def remove_redirect_duplicates(plugin_info: t.MutableMapping[str, t.MutableMapping[str, t.Any]],
collection_routing: CollectionRoutingT) -> None:
"""
Expand All @@ -299,8 +282,8 @@ def remove_redirect_duplicates(plugin_info: t.MutableMapping[str, t.MutableMappi
# Heuristic: if we have a redirect, and docs for both this plugin and the
# redirected one are generated from the same plugin filename, then we can
# remove this plugin's docs and generate a redirect stub instead.
if compare_all_but(
plugin_record['doc'], plugin_map[destination]['doc'], 'filename'):
if compare_all_but(plugin_record['doc'], plugin_map[destination]['doc'],
'filename'):
del plugin_map[plugin_name]


Expand Down
37 changes: 35 additions & 2 deletions antsibull/utils/collections.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Author: Toshio Kuratomi <[email protected]>
# License: GPLv3+
# Copyright: Ansible Project, 2020
"""General functions for working with collections and classes for new data types."""
"""General functions for working with python collections and classes for new data types."""

import typing as t
from collections.abc import Sequence
from collections.abc import Sequence, Set


def is_sequence(obj: t.Any, include_string: bool = False) -> bool:
Expand All @@ -25,3 +25,36 @@ def is_sequence(obj: t.Any, include_string: bool = False) -> bool:
if isinstance(obj, Sequence):
return True
return False


def compare_all_but(dict_a: t.Mapping, dict_b: t.Mapping,
keys_to_ignore: t.Iterable = None) -> bool:
"""
Compare two dictionaries, with the possibility to ignore some fields.
:arg dict_a: First dictionary to compare
:arg dict_b: Second dictionary to compare
:kwarg keys_to_ignore: An iterable of keys whose values in the dictionaries will not be
compared.
:returns: True if the dictionaries have matching values for all of the keys which were not
ignored. False otherwise.
"""
if keys_to_ignore is None:
return dict_a == dict_b

if not isinstance(keys_to_ignore, Set):
keys_to_ignore = frozenset(keys_to_ignore)

length_a = len(frozenset(dict_a.keys()) - keys_to_ignore)
length_b = len(frozenset(dict_b.keys()) - keys_to_ignore)

if length_a != length_b:
return False

sentinel = object()

for key, value in ((k, v) for k, v in dict_a.items() if k not in keys_to_ignore):
if value != dict_b.get(key, sentinel):
return False

return True

0 comments on commit 2457b27

Please sign in to comment.