Detect duplicate globals from basic.py

reviewable/pr18001/r3
Matt Martz 9 years ago committed by John Barker
parent 3760ae3bfe
commit 2ce2b7a416

@ -10,9 +10,11 @@ import sys
import argparse import argparse
from fnmatch import fnmatch from fnmatch import fnmatch
from utils import find_globals
from ansible.executor.module_common import REPLACER_WINDOWS from ansible.executor.module_common import REPLACER_WINDOWS
from ansible.utils.module_docs import get_docstring, BLACKLIST_MODULES from ansible.utils.module_docs import get_docstring, BLACKLIST_MODULES
from ansible.module_utils import basic as module_utils_basic
try: try:
from cStringIO import StringIO from cStringIO import StringIO
@ -22,6 +24,7 @@ except ImportError:
BLACKLIST_DIRS = frozenset(('.git',)) BLACKLIST_DIRS = frozenset(('.git',))
INDENT_REGEX = re.compile(r'(^[ \t]*)') INDENT_REGEX = re.compile(r'(^[ \t]*)')
BASIC_RESERVED = frozenset((r for r in dir(module_utils_basic) if r[0] != '_'))
class Validator(object): class Validator(object):
@ -288,6 +291,14 @@ class ModuleValidator(Validator):
if not os.path.isfile(py_path): if not os.path.isfile(py_path):
self.errors.append('Missing python documentation file') self.errors.append('Missing python documentation file')
def _find_redeclarations(self):
g = set()
find_globals(g, self.ast.body)
redeclared = BASIC_RESERVED.intersection(g)
if redeclared:
self.warnings.append('Redeclared basic.py variable or '
'function: %s' % ', '.join(redeclared))
def validate(self): def validate(self):
super(ModuleValidator, self).validate() super(ModuleValidator, self).validate()
@ -320,7 +331,7 @@ class ModuleValidator(Validator):
doc, examples, ret = get_docstring(self.path) doc, examples, ret = get_docstring(self.path)
trace = sys.stdout.getvalue() trace = sys.stdout.getvalue()
sys.stdout = sys_stdout sys.stdout = sys_stdout
sys.stderr = sys.stderr sys.stderr = sys_stderr
if trace: if trace:
self.traces.append(trace) self.traces.append(trace)
if not bool(doc): if not bool(doc):
@ -337,6 +348,7 @@ class ModuleValidator(Validator):
self._find_module_utils(main) self._find_module_utils(main)
self._find_has_import() self._find_has_import()
self._check_for_tabs() self._check_for_tabs()
self._find_redeclarations()
if self._powershell_module(): if self._powershell_module():
self._find_ps_replacers() self._find_ps_replacers()
@ -373,6 +385,7 @@ class PythonPackageValidator(Validator):
self.errors.append('Ansible module subdirectories must contain an ' self.errors.append('Ansible module subdirectories must contain an '
'__init__.py') '__init__.py')
def re_compile(value): def re_compile(value):
""" """
Argparse expects things to raise TypeError, re.compile raises an re.error Argparse expects things to raise TypeError, re.compile raises an re.error

@ -0,0 +1,24 @@
import ast
def find_globals(g, tree):
"""Uses AST to find globals in an ast tree"""
for child in tree:
if hasattr(child, 'body') and isinstance(child.body, list):
find_globals(g, child.body)
elif isinstance(child, (ast.FunctionDef, ast.ClassDef)):
g.add(child.name)
continue
elif isinstance(child, ast.Assign):
try:
g.add(child.targets[0].id)
except (IndexError, AttributeError):
pass
elif isinstance(child, ast.Import):
g.add(child.names[0].name)
elif isinstance(child, ast.ImportFrom):
for name in child.names:
g_name = name.asname or name.name
if g_name == '*':
continue
g.add(g_name)
Loading…
Cancel
Save