Add hacking check for explicit import of _

Unit tests are not guaranteed to discover whether
the _() function has been explicitly imported to a file.

To ensure that people do not add messages with _() translations
without importing the function, I am adding this hacking check
to enforce the import of _ when it is needed.

The commit includes fixes for offenders found by the new
check.

Change-Id: I616dce6a9da461b3ad2cfaf5e114a2aaa8ced9fa
Closes-Bug: #1348129
This commit is contained in:
Jay S. Bryant
2014-07-24 15:05:33 -05:00
parent 8e72357c21
commit 3e2b111729
6 changed files with 48 additions and 0 deletions

View File

@@ -26,6 +26,7 @@ import webob.exc
from cinder.api.openstack import wsgi
from cinder import context
from cinder.openstack.common.gettextutils import _
from cinder.openstack.common import jsonutils
from cinder.openstack.common import log as logging
from cinder.openstack.common.middleware import request_id

View File

@@ -29,6 +29,12 @@ Guidelines for writing new hacking checks
"""
UNDERSCORE_IMPORT_FILES = []
log_translation = re.compile(
r"(.)*LOG\.(audit|error|info|warn|warning|critical|exception)_\(\s*('|\")")
string_translation = re.compile(r"(.)*_\(\s*('|\")")
def no_translate_debug_logs(logical_line, filename):
"""Check for 'LOG.debug(_('
@@ -53,6 +59,27 @@ def no_mutable_default_args(logical_line):
yield (0, msg)
def check_explicit_underscore_import(logical_line, filename):
"""Check for explicit import of the _ function
We need to ensure that any files that are using the _() function
to translate logs are explicitly importing the _ function. We
can't trust unit test to catch whether the import has been
added so we need to check for it here.
"""
# Build a list of the files that have _ imported. No further
# checking needed once it is found.
if filename in UNDERSCORE_IMPORT_FILES:
pass
elif logical_line.endswith("import _"):
UNDERSCORE_IMPORT_FILES.append(filename)
elif(log_translation.match(logical_line) or
string_translation.match(logical_line)):
yield(0, "N323: Found use of _() without explicit import of _ !")
def factory(register):
register(no_translate_debug_logs)
register(no_mutable_default_args)
register(check_explicit_underscore_import)

View File

@@ -29,6 +29,7 @@ from cinder.backup.drivers.swift import SwiftBackupDriver
from cinder import context
from cinder import db
from cinder import exception
from cinder.openstack.common.gettextutils import _
from cinder.openstack.common import log as logging
from cinder import test
from cinder.tests.backup.fake_swift_client import FakeSwiftClient

View File

@@ -58,3 +58,20 @@ class HackingTestCase(test.TestCase):
self.assertEqual(len(list(checks.no_translate_debug_logs(
"LOG.info(_('foo'))", "cinder/scheduler/foo.py"))), 0)
def test_check_explicit_underscore_import(self):
self.assertEqual(len(list(checks.check_explicit_underscore_import(
"LOG.info(_('My info message'))",
"cinder/tests/other_files.py"))), 1)
self.assertEqual(len(list(checks.check_explicit_underscore_import(
"msg = _('My message')",
"cinder/tests/other_files.py"))), 1)
self.assertEqual(len(list(checks.check_explicit_underscore_import(
"from cinder.i18n import _",
"cinder/tests/other_files.py"))), 0)
self.assertEqual(len(list(checks.check_explicit_underscore_import(
"LOG.info(_('My info message'))",
"cinder/tests/other_files.py"))), 0)
self.assertEqual(len(list(checks.check_explicit_underscore_import(
"msg = _('My message')",
"cinder/tests/other_files.py"))), 0)

View File

@@ -28,6 +28,7 @@ from oslo.config import cfg
from suds import client
from cinder import exception
from cinder.openstack.common.gettextutils import _
from cinder.openstack.common import log as logging
from cinder.openstack.common import units
from cinder.volume.drivers.san.san import SanISCSIDriver

View File

@@ -19,6 +19,7 @@ Utility functions related to the Zone Manager.
"""
import logging
from cinder.openstack.common.gettextutils import _
from cinder.openstack.common import log
from cinder.volume.configuration import Configuration
from cinder.volume import manager