Fix hacking test to handle namespace packages.

This removes our workaround for namespace packages and improves
detection of missing imports due to non-existent dependencies.

Fixes bug 1130411

Change-Id: I89ee8249580e395f786289792cdf74219d041f2f
This commit is contained in:
Vishvananda Ishaya
2013-02-19 16:59:53 -08:00
parent 706a137005
commit 3b649422a6
+18 -26
View File
@@ -29,7 +29,6 @@ import re
import subprocess
import sys
import tokenize
import warnings
import pep8
@@ -49,8 +48,6 @@ logging.disable('LOG')
IMPORT_EXCEPTIONS = ['sqlalchemy', 'migrate', 'nova.db.sqlalchemy.session',
'nova.openstack.common.log.logging',
'nova.db.sqlalchemy.migration.versioning_api']
# imp.find_module() doesn't support namespace packages
IMPORT_EXCEPTIONS += ['oslo', 'paste']
# Paste is missing a __init__ in top level directory
START_DOCSTRING_TRIPLE = ['u"""', 'r"""', '"""', "u'''", "r'''", "'''"]
END_DOCSTRING_TRIPLE = ['"""', "'''"]
@@ -191,39 +188,34 @@ def nova_import_rules(logical_line):
def is_module_for_sure(mod, search_path=sys.path):
try:
while '.' in mod:
pack_name, _sep, mod = mod.partition('.')
mod_name = mod
while '.' in mod_name:
pack_name, _sep, mod_name = mod.partition('.')
f, p, d = imp.find_module(pack_name, search_path)
search_path = [p]
imp.find_module(mod, search_path)
imp.find_module(mod_name, search_path)
except ImportError:
return False
try:
# NOTE(vish): handle namespace modules
module = __import__(mod)
except ImportError, exc:
# NOTE(vish): the import error might be due
# to a missing dependency
missing = str(exc).split()[-1]
if missing != mod.split('.')[-1]:
_missingImport.add(missing)
return True
return False
return True
def is_module_for_sure_cached(mod):
def is_module(mod):
"""Checks for non module imports."""
if mod in modules_cache:
return modules_cache[mod]
res = is_module_for_sure(mod)
modules_cache[mod] = res
return res
def is_module(mod):
"""Checks for non module imports.
If can't find module on first try, recursively check for the parent
modules.
When parsing 'from x import y,' x is the parent.
"""
if is_module_for_sure_cached(mod):
return True
parts = mod.split('.')
for i in range(len(parts) - 1, 0, -1):
path = '.'.join(parts[0:i])
if is_module_for_sure_cached(path):
return False
_missingImport.add(mod)
return True
current_path = os.path.dirname(pep8.current_file)
current_mod = os.path.basename(pep8.current_file)
if current_mod[-3:] == ".py":
@@ -264,7 +256,7 @@ def nova_import_rules(logical_line):
# The guestfs module now imports guestfs
mod = split_line[1]
if (current_mod != mod and
not is_module_for_sure_cached(mod) and
not is_module(mod) and
is_module_for_sure(mod, [current_path])):
yield 0, ("N304: No relative imports."
" '%s' is a relative import"