Update hacking for Python3

The repo is Python 3 now, so update hacking to version 3.0 which
supports Python 3.

Fix problems found.

Update local hacking checks for new flake8.

Remove hacking and friends from lower-constraints, they are not needed
to be installed at run-time.

Fix flake8wrap to take arguments from tox.ini and not look at .tox
directory.

Change-Id: I1c5f5a85af02d9f11e475b6088fe1d9d9d252083
This commit is contained in:
Andreas Jaeger 2020-04-02 07:51:04 +02:00
parent 977b5ef7ce
commit 3fe89808c6
25 changed files with 99 additions and 81 deletions

View File

@ -32,7 +32,6 @@ eventlet==0.18.2
extras==1.0.0 extras==1.0.0
fasteners==0.14.1 fasteners==0.14.1
fixtures==3.0.0 fixtures==3.0.0
flake8==2.5.5
future==0.16.0 future==0.16.0
futurist==1.6.0 futurist==1.6.0
Flask==0.12.3 Flask==0.12.3
@ -40,7 +39,6 @@ gitdb2==2.0.3
GitPython==2.1.8 GitPython==2.1.8
greenlet==0.4.13 greenlet==0.4.13
grpcio==1.12.0 grpcio==1.12.0
hacking==0.12.0
idna==2.6 idna==2.6
imagesize==1.0.0 imagesize==1.0.0
iso8601==0.1.12 iso8601==0.1.12
@ -102,7 +100,6 @@ Paste==2.0.3
PasteDeploy==1.5.2 PasteDeploy==1.5.2
pbr==2.0.0 pbr==2.0.0
pecan==1.0.0 pecan==1.0.0
pep8==1.5.7
pika==0.10.0 pika==0.10.0
pika-pool==0.1.3 pika-pool==0.1.3
prettytable==0.7.2 prettytable==0.7.2
@ -111,7 +108,6 @@ psutil==3.2.2
pyasn1==0.4.2 pyasn1==0.4.2
pycadf==2.7.0 pycadf==2.7.0
pycparser==2.18 pycparser==2.18
pyflakes==0.8.1
pyroute2==0.5.7 pyroute2==0.5.7
Pygments==2.2.0 Pygments==2.2.0
pyinotify==0.9.6 pyinotify==0.9.6

View File

@ -8,7 +8,7 @@ doc8>=0.6.0 # Apache-2.0
coverage!=4.4,>=4.0 # Apache-2.0 coverage!=4.4,>=4.0 # Apache-2.0
mock>=2.0.0 # BSD mock>=2.0.0 # BSD
fixtures>=3.0.0 # Apache-2.0/BSD fixtures>=3.0.0 # Apache-2.0/BSD
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0 hacking>=3.0,<3.1.0 # Apache-2.0
oslotest>=3.2.0 # Apache-2.0 oslotest>=3.2.0 # Apache-2.0
osprofiler>=1.4.0 # Apache-2.0 osprofiler>=1.4.0 # Apache-2.0
os-testr>=1.0.0 # Apache-2.0 os-testr>=1.0.0 # Apache-2.0

View File

@ -16,5 +16,5 @@ if test "x$1" = "x-HEAD" ; then
diff -u --from-file /dev/null ${files} | flake8 --max-complexity 34 --exclude zun/criapi --diff "$@" diff -u --from-file /dev/null ${files} | flake8 --max-complexity 34 --exclude zun/criapi --diff "$@"
else else
echo "Running flake8 on all files" echo "Running flake8 on all files"
exec flake8 --max-complexity 34 --exclude zun/criapi "$@" exec flake8 "$@"
fi fi

22
tox.ini
View File

@ -94,12 +94,26 @@ enable-extensions = H203,H106,H904
# H405 is another one that is good as a guideline, but sometimes # H405 is another one that is good as a guideline, but sometimes
# multiline docstrings just don't have a natural summary line. # multiline docstrings just don't have a natural summary line.
# Rejecting code for this reason is wrong. # Rejecting code for this reason is wrong.
ignore = E123,E125,H405 # W503 line break before binary operator
# W504 line break after binary operator
# E402 module level import not at top of file
ignore = E123,E125,H405,W503,W504,E402
builtins = _ builtins = _
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,zun/criapi/
[hacking] [flake8:local-plugins]
local-check-factory = zun.hacking.checks.factory extension =
Z322 = checks:no_mutable_default_args
Z323 = checks:assert_equal_true_or_false
Z302 = checks:assert_equal_not_none
Z316 = checks:assert_true_isinstance
Z338 = checks:assert_equal_in
Z310 = checks:use_timeutils_utcnow
Z336 = checks:dict_constructor_with_list_copy
Z339 = checks:no_xrange
Z352 = checks:no_log_warn
Z353 = checks:no_translate_logs
paths = ./zun/hacking
[testenv:fast8] [testenv:fast8]
basepython = python3 basepython = python3

View File

@ -618,7 +618,7 @@ class ContainersController(base.Controller):
try: try:
return neutron_api.find_resourceid_by_name_or_id( return neutron_api.find_resourceid_by_name_or_id(
'security_group', security_group['name'], context.project_id) 'security_group', security_group['name'], context.project_id)
except n_exc.NeutronClientNoUniqueMatch as e: except n_exc.NeutronClientNoUniqueMatch:
msg = _("Multiple security group matches found for name " msg = _("Multiple security group matches found for name "
"%(name)s, use an ID to be more specific.") % { "%(name)s, use an ID to be more specific.") % {
'name': security_group['name']} 'name': security_group['name']}

View File

@ -95,7 +95,7 @@ auto_remove = {
cpu = { cpu = {
'type': ['number', 'string', 'null'], 'type': ['number', 'string', 'null'],
'pattern': '^[0-9]*(\.([0-9]+))?$', 'pattern': r'^[0-9]*(\.([0-9]+))?$',
'minLength': 1, 'minLength': 1,
'minimum': CONF.minimum_cpus, 'minimum': CONF.minimum_cpus,
'maximum': CONF.maximum_cpus, 'maximum': CONF.maximum_cpus,

View File

@ -33,7 +33,7 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
def __init__(self, app, conf, public_api_routes=None): def __init__(self, app, conf, public_api_routes=None):
if public_api_routes is None: if public_api_routes is None:
public_api_routes = [] public_api_routes = []
route_pattern_tpl = '%s(\.json)?$' route_pattern_tpl = r'%s(\.json)?$'
try: try:
self.public_api_routes = [re.compile(route_pattern_tpl % route_tpl) self.public_api_routes = [re.compile(route_pattern_tpl % route_tpl)

View File

@ -46,5 +46,6 @@ def main():
launcher.launch_service(server, workers=server.workers) launcher.launch_service(server, workers=server.workers)
launcher.wait() launcher.wait()
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View File

@ -32,5 +32,6 @@ def main():
service.CNIDaemonServiceManager().run() service.CNIDaemonServiceManager().run()
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View File

@ -16,7 +16,8 @@ import re
def _quote_meta(s): def _quote_meta(s):
special_chars = frozenset("()[]{}?*+|^$\\.-#&~") special_chars = frozenset("()[]{}?*+|^$\\.-#&~")
escape = lambda c: r'\{}'.format(c) if c in special_chars else c escape = lambda c: ( # noqa: E731
r'\{}'.format(c) if c in special_chars else c)
sp = (escape(c) for c in s) sp = (escape(c) for c in s)
return r''.join(sp) return r''.join(sp)

View File

@ -42,7 +42,7 @@ CONF = zun.conf.CONF
try: try:
CONF.import_opt('fatal_exception_format_errors', CONF.import_opt('fatal_exception_format_errors',
'oslo_versionedobjects.exception') 'oslo_versionedobjects.exception')
except cfg.NoSuchOptError as e: except cfg.NoSuchOptError:
# Note:work around for zun run against master branch # Note:work around for zun run against master branch
# in devstack gate job, as zun not branched yet # in devstack gate job, as zun not branched yet
# versionobjects kilo/master different version can # versionobjects kilo/master different version can

View File

@ -32,7 +32,8 @@ def _to_byte_string(value, num_bits):
""" """
shifts = six.moves.xrange(num_bits - 8, -8, -8) shifts = six.moves.xrange(num_bits - 8, -8, -8)
byte_at = lambda off: (value >> off if off >= 0 else value << -off) & 0xff byte_at = lambda off: ( # noqa: E731
(value >> off if off >= 0 else value << -off) & 0xff)
return ''.join(six.int2byte(byte_at(offset)) for offset in shifts) return ''.join(six.int2byte(byte_at(offset)) for offset in shifts)

View File

@ -1111,7 +1111,8 @@ class Manager(periodic_task.PeriodicTasks):
"different from %(tar_tag)s the tag in tar", "different from %(tar_tag)s the tag in tar",
{'glance_tag': pulled_image['tags'], {'glance_tag': pulled_image['tags'],
'tar_tag': pulled_image['tag']}) 'tar_tag': pulled_image['tag']})
repo_tag = ':'.join([pulled_image['repo'], pulled_image['tag']]) \ repo_tag = ':'.join([pulled_image['repo'],
pulled_image['tag']]) \
if pulled_image['tag'] else pulled_image['repo'] if pulled_image['tag'] else pulled_image['repo']
image_dict = self.driver.inspect_image(repo_tag) image_dict = self.driver.inspect_image(repo_tag)

View File

@ -76,9 +76,10 @@ class Host(object):
if backing_filesystem == 'xfs': if backing_filesystem == 'xfs':
# Check project quota mount option # Check project quota mount option
try: try:
cmd = "mount |grep $(df " + host_info['docker_root_dir'] + \ cmd = ("mount |grep $(df " +
" |awk 'FNR==2 {print $1}') | grep 'xfs'" \ host_info['docker_root_dir'] +
" |grep -E 'pquota|prjquota'" " |awk 'FNR==2 {print $1}') | grep 'xfs'"
" |grep -E 'pquota|prjquota'")
utils.execute(cmd, shell=True) utils.execute(cmd, shell=True)
except exception.CommandError: except exception.CommandError:
sp_disk_quota = False sp_disk_quota = False

View File

@ -42,9 +42,9 @@ class LinuxHost(host_capability.Host):
old_lscpu = True old_lscpu = True
if old_lscpu: if old_lscpu:
cpu_sock_pair = re.findall("\d+(?:,\d+)?", str(output)) cpu_sock_pair = re.findall(r"\d+(?:,\d+)?", str(output))
else: else:
cpu_sock_pair = re.findall("\d+(?:,\d+,[Y/N])?", str(output)) cpu_sock_pair = re.findall(r"\d+(?:,\d+,[Y/N])?", str(output))
sock_map = defaultdict(list) sock_map = defaultdict(list)
for value in cpu_sock_pair: for value in cpu_sock_pair:
val = value.split(",") val = value.split(",")
@ -64,7 +64,7 @@ class LinuxHost(host_capability.Host):
else: else:
raise raise
sizes = re.findall("size\: \d*", str(output)) sizes = re.findall(r"size\: \d*", str(output))
mem_numa = [] mem_numa = []
for size in sizes: for size in sizes:
mem_numa.append(int(size.split(' ')[1])) mem_numa.append(int(size.split(' ')[1]))

View File

@ -55,4 +55,5 @@ def run_migrations_online():
with context.begin_transaction(): with context.begin_transaction():
context.run_migrations() context.run_migrations()
run_migrations_online() run_migrations_online()

View File

@ -15,6 +15,8 @@
import re import re
from hacking import core
""" """
Guidelines for writing new hacking checks Guidelines for writing new hacking checks
@ -43,7 +45,7 @@ assert_equal_with_is_not_none_re = re.compile(
r"assertEqual\(.*?\s+is+\s+not+\s+None\)$") r"assertEqual\(.*?\s+is+\s+not+\s+None\)$")
assert_true_isinstance_re = re.compile( assert_true_isinstance_re = re.compile(
r"(.)*assertTrue\(isinstance\((\w|\.|\'|\"|\[|\])+, " r"(.)*assertTrue\(isinstance\((\w|\.|\'|\"|\[|\])+, "
"(\w|\.|\'|\"|\[|\])+\)\)") r"(\w|\.|\'|\"|\[|\])+\)\)")
dict_constructor_with_list_copy_re = re.compile(r".*\bdict\((\[)?(\(|\[)") dict_constructor_with_list_copy_re = re.compile(r".*\bdict\((\[)?(\(|\[)")
assert_xrange_re = re.compile( assert_xrange_re = re.compile(
r"\s*xrange\s*\(") r"\s*xrange\s*\(")
@ -53,12 +55,14 @@ translated_log = re.compile(r"(.)*LOG\.(%(levels)s)\(\s*_\(" %
{'levels': '|'.join(log_levels)}) {'levels': '|'.join(log_levels)})
@core.flake8ext
def no_mutable_default_args(logical_line): def no_mutable_default_args(logical_line):
msg = "Z322: Method's default argument shouldn't be mutable!" msg = "Z322: Method's default argument shouldn't be mutable!"
if mutable_default_args.match(logical_line): if mutable_default_args.match(logical_line):
yield (0, msg) yield (0, msg)
@core.flake8ext
def assert_equal_true_or_false(logical_line): def assert_equal_true_or_false(logical_line):
"""Check for assertEqual(True, A) or assertEqual(False, A) sentences """Check for assertEqual(True, A) or assertEqual(False, A) sentences
@ -71,6 +75,7 @@ def assert_equal_true_or_false(logical_line):
"sentences not allowed") "sentences not allowed")
@core.flake8ext
def assert_equal_not_none(logical_line): def assert_equal_not_none(logical_line):
"""Check for assertEqual(A is not None) sentences Z302""" """Check for assertEqual(A is not None) sentences Z302"""
msg = "Z302: assertEqual(A is not None) sentences not allowed." msg = "Z302: assertEqual(A is not None) sentences not allowed."
@ -79,6 +84,7 @@ def assert_equal_not_none(logical_line):
yield (0, msg) yield (0, msg)
@core.flake8ext
def assert_true_isinstance(logical_line): def assert_true_isinstance(logical_line):
"""Check for assertTrue(isinstance(a, b)) sentences """Check for assertTrue(isinstance(a, b)) sentences
@ -88,6 +94,7 @@ def assert_true_isinstance(logical_line):
yield (0, "Z316: assertTrue(isinstance(a, b)) sentences not allowed") yield (0, "Z316: assertTrue(isinstance(a, b)) sentences not allowed")
@core.flake8ext
def assert_equal_in(logical_line): def assert_equal_in(logical_line):
"""Check for assertEqual(True|False, A in B), assertEqual(A in B, True|False) """Check for assertEqual(True|False, A in B), assertEqual(A in B, True|False)
@ -101,6 +108,7 @@ def assert_equal_in(logical_line):
"contents.") "contents.")
@core.flake8ext
def no_xrange(logical_line): def no_xrange(logical_line):
"""Disallow 'xrange()' """Disallow 'xrange()'
@ -110,6 +118,7 @@ def no_xrange(logical_line):
yield(0, "Z339: Do not use xrange().") yield(0, "Z339: Do not use xrange().")
@core.flake8ext
def use_timeutils_utcnow(logical_line, filename): def use_timeutils_utcnow(logical_line, filename):
# tools are OK to use the standard datetime module # tools are OK to use the standard datetime module
if "/tools/" in filename: if "/tools/" in filename:
@ -123,6 +132,7 @@ def use_timeutils_utcnow(logical_line, filename):
yield (pos, msg % f) yield (pos, msg % f)
@core.flake8ext
def dict_constructor_with_list_copy(logical_line): def dict_constructor_with_list_copy(logical_line):
msg = ("Z336: Must use a dict comprehension instead of a dict constructor" msg = ("Z336: Must use a dict comprehension instead of a dict constructor"
" with a sequence of key-value pairs.") " with a sequence of key-value pairs.")
@ -130,6 +140,7 @@ def dict_constructor_with_list_copy(logical_line):
yield (0, msg) yield (0, msg)
@core.flake8ext
def no_log_warn(logical_line): def no_log_warn(logical_line):
"""Disallow 'LOG.warn(' """Disallow 'LOG.warn('
@ -144,6 +155,7 @@ def no_log_warn(logical_line):
yield (0, msg) yield (0, msg)
@core.flake8ext
def no_translate_logs(logical_line): def no_translate_logs(logical_line):
"""Check for 'LOG.*(_(' """Check for 'LOG.*(_('
@ -155,16 +167,3 @@ def no_translate_logs(logical_line):
msg = "Z353: Log messages should not be translated!" msg = "Z353: Log messages should not be translated!"
if translated_log.match(logical_line): if translated_log.match(logical_line):
yield (0, msg) yield (0, msg)
def factory(register):
register(no_mutable_default_args)
register(assert_equal_true_or_false)
register(assert_equal_not_none)
register(assert_true_isinstance)
register(assert_equal_in)
register(use_timeutils_utcnow)
register(dict_constructor_with_list_copy)
register(no_xrange)
register(no_log_warn)
register(no_translate_logs)

View File

@ -83,7 +83,7 @@ class DockerDriver(driver.ContainerImageDriver):
docker.pull(repo, tag=tag, auth_config=auth_config) docker.pull(repo, tag=tag, auth_config=auth_config)
except errors.NotFound as e: except errors.NotFound as e:
raise exception.ImageNotFound(message=six.text_type(e)) raise exception.ImageNotFound(message=six.text_type(e))
except errors.APIError as e: except errors.APIError:
LOG.exception('Error on pulling image') LOG.exception('Error on pulling image')
message = _('Error on pulling image: %(repo)s:%(tag)s') % { message = _('Error on pulling image: %(repo)s:%(tag)s') % {
'repo': repo, 'tag': tag} 'repo': repo, 'tag': tag}

View File

@ -189,8 +189,8 @@ class NeutronAPI(object):
def _refresh_neutron_extensions_cache(self): def _refresh_neutron_extensions_cache(self):
"""Refresh the neutron extensions cache when necessary.""" """Refresh the neutron extensions cache when necessary."""
if (not self.last_neutron_extension_sync or if (not self.last_neutron_extension_sync or
((time.time() - self.last_neutron_extension_sync) ((time.time() - self.last_neutron_extension_sync) >=
>= CONF.neutron.extension_sync_interval)): CONF.neutron.extension_sync_interval)):
extensions_list = self.neutron_api.list_extensions()['extensions'] extensions_list = self.neutron_api.list_extensions()['extensions']
self.last_neutron_extension_sync = time.time() self.last_neutron_extension_sync = time.time()
self.extensions.clear() self.extensions.clear()

View File

@ -26,10 +26,10 @@ from zun.common import exception
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
PCI_VENDOR_PATTERN = "^(hex{4})$".replace("hex", "[\da-fA-F]") PCI_VENDOR_PATTERN = "^(hex{4})$".replace("hex", r"[\da-fA-F]")
_PCI_ADDRESS_PATTERN = ("^(hex{4}):(hex{2}):(hex{2}).(oct{1})$". _PCI_ADDRESS_PATTERN = ("^(hex{4}):(hex{2}):(hex{2}).(oct{1})$".
replace("hex", "[\da-fA-F]"). replace("hex", r"[\da-fA-F]").
replace("oct", "[0-7]")) replace("oct", r"[0-7]"))
_PCI_ADDRESS_REGEX = re.compile(_PCI_ADDRESS_PATTERN) _PCI_ADDRESS_REGEX = re.compile(_PCI_ADDRESS_PATTERN)
_SRIOV_TOTALVFS = "sriov_totalvfs" _SRIOV_TOTALVFS = "sriov_totalvfs"
@ -167,7 +167,7 @@ def get_vf_num_by_pci_address(pci_addr):
A VF is associated with an VF number, which ip link command uses to A VF is associated with an VF number, which ip link command uses to
configure it. This number can be obtained from the PCI device filesystem. configure it. This number can be obtained from the PCI device filesystem.
""" """
VIRTFN_RE = re.compile("virtfn(\d+)") VIRTFN_RE = re.compile(r"virtfn(\d+)")
virtfns_path = "/sys/bus/pci/devices/%s/physfn/virtfn*" % (pci_addr) virtfns_path = "/sys/bus/pci/devices/%s/physfn/virtfn*" % (pci_addr)
vf_num = None vf_num = None
try: try:

View File

@ -40,8 +40,8 @@ class Scheduler(object):
services = objects.ZunService.list_by_binary(context, 'zun-compute') services = objects.ZunService.list_by_binary(context, 'zun-compute')
return [service.host return [service.host
for service in services for service in services
if self.servicegroup_api.service_is_up(service) if self.servicegroup_api.service_is_up(service) and
and not service.disabled] not service.disabled]
@abc.abstractmethod @abc.abstractmethod
def select_destinations(self, context, containers, extra_specs, def select_destinations(self, context, containers, extra_specs,

View File

@ -21,30 +21,31 @@ class TestRegexp(base.BaseTestCase):
separatorRegexp = r'(?:[._]|__|[-]*)' separatorRegexp = r'(?:[._]|__|[-]*)'
nameComponentRegexp = r'[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?' nameComponentRegexp = r'[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?'
hostnameComponentRegexp = r'(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\ hostnameComponentRegexp = r'(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\
'[a-zA-Z0-9])' r'[a-zA-Z0-9])'
hostnameRegexp = r'(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])'\ hostnameRegexp = r'(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\
'(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\ r'[a-zA-Z0-9])'\
'[a-zA-Z0-9]))+)?(?::[0-9]+)?' r'(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\
r'[a-zA-Z0-9]))+)?(?::[0-9]+)?'
TagRegexp = r'[\w][\w.-]{0,127}' TagRegexp = r'[\w][\w.-]{0,127}'
anchoredTagRegexp = r'^[\w][\w.-]{0,127}$' anchoredTagRegexp = r'^[\w][\w.-]{0,127}$'
NameRegexp = r'(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])'\ NameRegexp = r'(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])'\
'(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\ r'(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\
'[a-zA-Z0-9]))+)?(?::[0-9]+)?/)?[a-z0-9]+(?:(?:'\ r'[a-zA-Z0-9]))+)?(?::[0-9]+)?/)?[a-z0-9]+(?:(?:'\
'(?:[._]|__|[-]*)[a-z0-9]+)+)?(?:(?:/[a-z0-9]+'\ r'(?:[._]|__|[-]*)[a-z0-9]+)+)?(?:(?:/[a-z0-9]+'\
'(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?' r'(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?'
anchoredNameRegexp = r'^(?:((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\ anchoredNameRegexp = r'^(?:((?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\
'[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9]'\ r'[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9]'\
'[a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)/)?'\ r'[a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?)/)?'\
'([a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?'\ r'([a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?'\
'(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]'\ r'(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]'\
'+)+)?)+)?)$' r'+)+)?)+)?)$'
ReferenceRegexp = r'^((?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\ ReferenceRegexp = r'^((?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*'\
'[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9]'\ r'[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9]'\
'[a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?/)?'\ r'[a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?/)?'\
'[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?'\ r'[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?'\
'(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)'\ r'(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)'\
'+)?)+)?)(?::([\w][\w.-]{0,127}))?(?:@'\ r'+)?)+)?)(?::([\w][\w.-]{0,127}))?(?:@'\
'([a-zA-Z0-9-_+.]+:[a-fA-F0-9]+))?$' r'([a-zA-Z0-9-_+.]+:[a-fA-F0-9]+))?$'
ImageRegexps = regexp.ImageRegexps ImageRegexps = regexp.ImageRegexps
self.assertEqual(alphaNumericRegexp, self.assertEqual(alphaNumericRegexp,

View File

@ -89,16 +89,17 @@ class ModelsObjectComparatorMixin(object):
self.assertEqual(value, obj2[key]) self.assertEqual(value, obj2[key])
def _assertEqualListsOfObjects(self, objs1, objs2, ignored_keys=None): def _assertEqualListsOfObjects(self, objs1, objs2, ignored_keys=None):
obj_to_dict = lambda o: self._dict_from_object(o, ignored_keys) obj_to_dict = lambda o: self._dict_from_object(o, ignored_keys) # noqa
sort_key = lambda d: [d[k] for k in sorted(d)] sort_key = lambda d: [d[k] for k in sorted(d)] # noqa: E731
conv_and_sort = lambda obj: sorted(map(obj_to_dict, obj), key=sort_key) conv_and_sort = lambda obj: ( # noqa: E731
sorted(map(obj_to_dict, obj), key=sort_key))
self.assertEqual(conv_and_sort(objs1), conv_and_sort(objs2)) self.assertEqual(conv_and_sort(objs1), conv_and_sort(objs2))
def _assertEqualOrderedListOfObjects(self, objs1, objs2, def _assertEqualOrderedListOfObjects(self, objs1, objs2,
ignored_keys=None): ignored_keys=None):
obj_to_dict = lambda o: self._dict_from_object(o, ignored_keys) obj_to_dict = lambda o: self._dict_from_object(o, ignored_keys) # noqa
conv = lambda objs: [obj_to_dict(obj) for obj in objs] conv = lambda objs: [obj_to_dict(obj) for obj in objs] # noqa: E731
self.assertEqual(conv(objs1), conv(objs2)) self.assertEqual(conv(objs1), conv(objs2))

View File

@ -102,7 +102,7 @@ fake_db_devs_tree = [fake_db_dev_3, fake_db_dev_4, fake_db_dev_5]
class PciDevTrackerTestCase(base.DbTestCase): class PciDevTrackerTestCase(base.DbTestCase):
def _fake_get_pci_devices(self, node_id): def _fake_get_pci_devices(self, node_id):
return self.fake_devs return self.fake_devs
def _fake_pci_device_update(self, node_id, address, value): def _fake_pci_device_update(self, node_id, address, value):
self.update_called += 1 self.update_called += 1

View File

@ -15,7 +15,7 @@
import textwrap import textwrap
import mock import mock
import pep8 import pycodestyle
from zun.hacking import checks from zun.hacking import checks
from zun.tests import base from zun.tests import base
@ -25,10 +25,10 @@ class HackingTestCase(base.BaseTestCase):
"""Hacking test class. """Hacking test class.
This class tests the hacking checks zun .hacking.checks by passing This class tests the hacking checks zun .hacking.checks by passing
strings to the check methods like the pep8/flake8 parser would. The parser strings to the check methods like the pycodestyle/flake8 parser would. The
loops over each line in the file and then passes the parameters to the parser loops over each line in the file and then passes the parameters to
check method. The parameter names in the check method dictate what type of the check method. The parameter names in the check method dictate what
object is passed to the check method. The parameter types are:: type of object is passed to the check method. The parameter types are::
logical_line: A processed line with the following modifications: logical_line: A processed line with the following modifications:
- Multi-line statements converted to a single line. - Multi-line statements converted to a single line.
@ -45,7 +45,7 @@ class HackingTestCase(base.BaseTestCase):
indent_level: indentation (with tabs expanded to multiples of 8) indent_level: indentation (with tabs expanded to multiples of 8)
previous_indent_level: indentation on previous line previous_indent_level: indentation on previous line
previous_logical: previous logical line previous_logical: previous logical line
filename: Path of the file being run through pep8 filename: Path of the file being run through pycodestyle
When running a test on a check method the return will be False/None if When running a test on a check method the return will be False/None if
there is no violation in the sample input. If there is an error a tuple is there is no violation in the sample input. If there is an error a tuple is
@ -53,17 +53,17 @@ class HackingTestCase(base.BaseTestCase):
just assertTrue if the check is expected to fail and assertFalse if it just assertTrue if the check is expected to fail and assertFalse if it
should pass. should pass.
""" """
# We are patching pep8 so that only the check under test is actually # We are patching pycodestyle so that only the check under test is actually
# installed. # installed.
@mock.patch('pep8._checks', @mock.patch('pycodestyle._checks',
{'physical_line': {}, 'logical_line': {}, 'tree': {}}) {'physical_line': {}, 'logical_line': {}, 'tree': {}})
def _run_check(self, code, checker, filename=None): def _run_check(self, code, checker, filename=None):
pep8.register_check(checker) pycodestyle.register_check(checker)
lines = textwrap.dedent(code).strip().splitlines(True) lines = textwrap.dedent(code).strip().splitlines(True)
checker = pep8.Checker(filename=filename, lines=lines) checker = pycodestyle.Checker(filename=filename, lines=lines)
checker.check_all() checker.check_all()
checker.report._deferred_print.sort() checker.report._deferred_print.sort()
return checker.report._deferred_print return checker.report._deferred_print