Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speedup modify module #70475

Merged
merged 6 commits into from Jul 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions changelogs/fragments/70475-modify-module.yaml
@@ -0,0 +1,5 @@
minor_changes:
- AnsiballZ - Improve performance of ``ModuleDepFinder`` by using faster
lookups and reducing the object types that are walked while looking for
``import`` statements.
(https://github.com/ansible/ansible/pull/70475)
25 changes: 24 additions & 1 deletion lib/ansible/executor/module_common.py
Expand Up @@ -29,6 +29,7 @@
import zipfile
import re
import pkgutil
from ast import AST, Import, ImportFrom
from io import BytesIO

from ansible.release import __version__, __author__
Expand Down Expand Up @@ -464,6 +465,28 @@ def __init__(self, module_fqn, *args, **kwargs):
self.submodules = set()
self.module_fqn = module_fqn

self._visit_map = {
Import: self.visit_Import,
ImportFrom: self.visit_ImportFrom,
}

def generic_visit(self, node):
"""Overridden ``generic_visit`` that makes some assumptions about our
use case, and improves performance by calling visitors directly instead
of calling ``visit`` to offload calling visitors.
"""
visit_map = self._visit_map
generic_visit = self.generic_visit
for field, value in ast.iter_fields(node):
if isinstance(value, list):
for item in value:
if isinstance(item, (Import, ImportFrom)):
visit_map[item.__class__](item)
elif isinstance(item, AST):
generic_visit(item)

visit = generic_visit

def visit_Import(self, node):
"""
Handle import ansible.module_utils.MODLIB[.MODLIBn] [as asname]
Expand Down Expand Up @@ -710,7 +733,7 @@ def recursive_finder(name, module_fqn, data, py_module_names, py_module_cache, z
"""
# Parse the module and find the imports of ansible.module_utils
try:
tree = ast.parse(data)
tree = compile(data, '<unknown>', 'exec', ast.PyCF_ONLY_AST)
except (SyntaxError, IndentationError) as e:
raise AnsibleError("Unable to import %s due to %s" % (name, e.msg))

Expand Down