# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # NOTE(morganfainberg) This file shouldn't have flake8 run on it as it has # code examples that will fail normal CI pep8/flake8 tests. This is expected. # The code has been moved here to ensure that proper tests occur on the # test_hacking_checks test cases. # flake8: noqa import fixtures class HackingCode(fixtures.Fixture): """A fixture to house the various code examples for the keystone hacking style checks. """ mutable_default_args = { 'code': """ def f(): pass def f(a, b='', c=None): pass def f(bad=[]): pass def f(foo, bad=[], more_bad=[x for x in range(3)]): pass def f(foo, bad={}): pass def f(foo, bad={}, another_bad=[], fine=None): pass def f(bad=[]): # noqa pass def funcs(bad=dict(), more_bad=list(), even_more_bad=set()): "creating mutables through builtins" def funcs(bad=something(), more_bad=some_object.something()): "defaults from any functions" def f(bad=set(), more_bad={x for x in range(3)}, even_more_bad={1, 2, 3}): "set and set comprehession" def f(bad={x: x for x in range(3)}): "dict comprehension" """, 'expected_errors': [ (7, 10, 'K001'), (10, 15, 'K001'), (10, 29, 'K001'), (13, 15, 'K001'), (16, 15, 'K001'), (16, 31, 'K001'), (22, 14, 'K001'), (22, 31, 'K001'), (22, 53, 'K001'), (25, 14, 'K001'), (25, 36, 'K001'), (28, 10, 'K001'), (28, 27, 'K001'), (29, 21, 'K001'), (32, 11, 'K001'), ]} comments_begin_with_space = { 'code': """ # This is a good comment #This is a bad one # This is alright and can # be continued with extra indentation # if that's what the developer wants. """, 'expected_errors': [ (3, 0, 'K002'), ]} asserting_none_equality = { 'code': """ class Test(object): def test(self): self.assertEqual('', '') self.assertEqual('', None) self.assertEqual(None, '') self.assertNotEqual('', None) self.assertNotEqual(None, '') self.assertNotEqual('', None) # noqa self.assertNotEqual(None, '') # noqa """, 'expected_errors': [ (5, 8, 'K003'), (6, 8, 'K003'), (7, 8, 'K004'), (8, 8, 'K004'), ]} assert_no_translations_for_debug_logging = { 'code': """ import logging import logging as stlib_logging from keystone.i18n import _ from keystone.i18n import _ as oslo_i18n from keystone.openstack.common import log from keystone.openstack.common import log as oslo_logging # stdlib logging L0 = logging.getLogger() L0.debug(_('text')) class C: def __init__(self): L0.debug(oslo_i18n('text', {})) # stdlib logging w/ alias and specifying a logger class C: def __init__(self): self.L1 = logging.getLogger(__name__) def m(self): self.L1.debug( _('text'), {} ) # oslo logging and specifying a logger L2 = log.getLogger(__name__) L2.debug(oslo_i18n('text')) # oslo logging w/ alias class C: def __init__(self): self.L3 = oslo_logging.getLogger() self.L3.debug(_('text')) # translation on a separate line msg = _('text') L2.debug(msg) # this should not fail if True: msg = _('message %s') % X L2.error(msg) raise TypeError(msg) if True: msg = 'message' L2.debug(msg) # this should not fail if True: if True: msg = _('message') else: msg = _('message') L2.debug(msg) raise Exception(msg) """, 'expected_errors': [ (10, 9, 'K005'), (13, 17, 'K005'), (21, 12, 'K005'), (26, 9, 'K005'), (32, 22, 'K005'), (36, 9, 'K005'), ] } oslo_namespace_imports = { 'code': """ import oslo.utils import oslo_utils import oslo.utils.encodeutils import oslo_utils.encodeutils from oslo import utils from oslo.utils import encodeutils from oslo_utils import encodeutils import oslo.serialization import oslo_serialization import oslo.serialization.jsonutils import oslo_serialization.jsonutils from oslo import serialization from oslo.serialization import jsonutils from oslo_serialization import jsonutils import oslo.messaging import oslo_messaging import oslo.messaging.conffixture import oslo_messaging.conffixture from oslo import messaging from oslo.messaging import conffixture from oslo_messaging import conffixture import oslo.db import oslo_db import oslo.db.api import oslo_db.api from oslo import db from oslo.db import api from oslo_db import api import oslo.config import oslo_config import oslo.config.cfg import oslo_config.cfg from oslo import config from oslo.config import cfg from oslo_config import cfg import oslo.i18n import oslo_i18n import oslo.i18n.log import oslo_i18n.log from oslo import i18n from oslo.i18n import log from oslo_i18n import log """, 'expected_errors': [ (1, 0, 'K333'), (3, 0, 'K333'), (5, 0, 'K333'), (6, 0, 'K333'), (9, 0, 'K333'), (11, 0, 'K333'), (13, 0, 'K333'), (14, 0, 'K333'), (17, 0, 'K333'), (19, 0, 'K333'), (21, 0, 'K333'), (22, 0, 'K333'), (25, 0, 'K333'), (27, 0, 'K333'), (29, 0, 'K333'), (30, 0, 'K333'), (33, 0, 'K333'), (35, 0, 'K333'), (37, 0, 'K333'), (38, 0, 'K333'), (41, 0, 'K333'), (43, 0, 'K333'), (45, 0, 'K333'), (46, 0, 'K333'), ], } class HackingLogging(fixtures.Fixture): shared_imports = """ import logging import logging as stlib_logging from keystone.i18n import _ from keystone.i18n import _ as oslo_i18n from keystone.i18n import _LC from keystone.i18n import _LE from keystone.i18n import _LE as error_hint from keystone.i18n import _LI from keystone.i18n import _LW from keystone.openstack.common import log from keystone.openstack.common import log as oslo_logging """ examples = [ { 'code': """ # stdlib logging LOG = logging.getLogger() LOG.info(_('text')) class C: def __init__(self): LOG.warn(oslo_i18n('text', {})) LOG.warn(_LW('text', {})) """, 'expected_errors': [ (3, 9, 'K006'), (6, 17, 'K006'), ], }, { 'code': """ # stdlib logging w/ alias and specifying a logger class C: def __init__(self): self.L = logging.getLogger(__name__) def m(self): self.L.warning( _('text'), {} ) self.L.warning( _LW('text'), {} ) """, 'expected_errors': [ (7, 12, 'K006'), ], }, { 'code': """ # oslo logging and specifying a logger L = log.getLogger(__name__) L.error(oslo_i18n('text')) L.error(error_hint('text')) """, 'expected_errors': [ (3, 8, 'K006'), ], }, { 'code': """ # oslo logging w/ alias class C: def __init__(self): self.LOG = oslo_logging.getLogger() self.LOG.critical(_('text')) self.LOG.critical(_LC('text')) """, 'expected_errors': [ (5, 26, 'K006'), ], }, { 'code': """ LOG = log.getLogger(__name__) # translation on a separate line msg = _('text') LOG.exception(msg) msg = _LE('text') LOG.exception(msg) """, 'expected_errors': [ (4, 14, 'K006'), ], }, { 'code': """ LOG = logging.getLogger() # ensure the correct helper is being used LOG.warn(_LI('this should cause an error')) # debug should not allow any helpers either LOG.debug(_LI('this should cause an error')) """, 'expected_errors': [ (4, 9, 'K006'), (7, 10, 'K005'), ], }, { 'code': """ # this should not be an error L = log.getLogger(__name__) msg = _('text') L.warn(msg) raise Exception(msg) """, 'expected_errors': [], }, { 'code': """ L = log.getLogger(__name__) def f(): msg = _('text') L2.warn(msg) something = True # add an extra statement here raise Exception(msg) """, 'expected_errors': [], }, { 'code': """ LOG = log.getLogger(__name__) def func(): msg = _('text') LOG.warn(msg) raise Exception('some other message') """, 'expected_errors': [ (4, 13, 'K006'), ], }, { 'code': """ LOG = log.getLogger(__name__) if True: msg = _('text') else: msg = _('text') LOG.warn(msg) raise Exception(msg) """, 'expected_errors': [ ], }, { 'code': """ LOG = log.getLogger(__name__) if True: msg = _('text') else: msg = _('text') LOG.warn(msg) """, 'expected_errors': [ (6, 9, 'K006'), ], }, { 'code': """ LOG = log.getLogger(__name__) msg = _LW('text') LOG.warn(msg) raise Exception(msg) """, 'expected_errors': [ (3, 9, 'K007'), ], }, { 'code': """ LOG = log.getLogger(__name__) msg = _LW('text') LOG.warn(msg) msg = _('something else') raise Exception(msg) """, 'expected_errors': [], }, { 'code': """ LOG = log.getLogger(__name__) msg = _LW('hello %s') % 'world' LOG.warn(msg) raise Exception(msg) """, 'expected_errors': [ (3, 9, 'K007'), ], }, { 'code': """ LOG = log.getLogger(__name__) msg = _LW('hello %s') % 'world' LOG.warn(msg) """, 'expected_errors': [], }, ]