Run pyupgrade to clean up Python 2 syntaxes

Update all .py source files by
 $ pyupgrade --py3-only $(git ls-files | grep ".py$")
to modernize the code according to Python 3 syntaxes.

pep8 errors are fixed by
 $ autopep8 --select=E127,E128,E501 --max-line-length 79 -r \
    --in-place oslo_rootwrap

Also add the pyupgrade hook to pre-commit to avoid merging additional
Python 2 syntaxes.

Change-Id: I5964917e735e11f9979ee95e92243bf012edcdbf
This commit is contained in:
Takashi Kajinami 2024-10-19 23:32:33 +09:00
parent 59f005d691
commit 863f06f1a6
13 changed files with 46 additions and 43 deletions

View File

@ -28,3 +28,8 @@ repos:
hooks: hooks:
- id: bandit - id: bandit
args: ['-x', 'tests,benchmark', '--skip', 'B404'] args: ['-x', 'tests,benchmark', '--skip', 'B404']
- repo: https://github.com/asottile/pyupgrade
rev: v3.18.0
hooks:
- id: pyupgrade
args: [--py3-only]

View File

@ -70,19 +70,19 @@ runners = [
def get_time_string(sec): def get_time_string(sec):
if sec > 0.9: if sec > 0.9:
return "{0:7.3f}s ".format(sec) return "{:7.3f}s ".format(sec)
elif sec > 0.0009: elif sec > 0.0009:
return "{0:7.3f}ms".format(sec * 1000.0) return "{:7.3f}ms".format(sec * 1000.0)
else: else:
return "{0:7.3f}us".format(sec * 1000000.0) return "{:7.3f}us".format(sec * 1000000.0)
def run_bench(cmd, runners): def run_bench(cmd, runners):
strcmd = ' '.join(cmd) strcmd = ' '.join(cmd)
max_name_len = max(len(name) for name, _ in runners) + len(strcmd) - 3 max_name_len = max(len(name) for name, _ in runners) + len(strcmd) - 3
print("Running '{0}':".format(strcmd)) print("Running '{}':".format(strcmd))
print("{0:^{1}} :".format("method", max_name_len), print("{0:^{1}} :".format("method", max_name_len),
"".join(map("{0:^10}".format, ["min", "avg", "max", "dev"]))) "".join(map("{:^10}".format, ["min", "avg", "max", "dev"])))
for name, runner in runners: for name, runner in runners:
results = timeit.repeat(run_one(runner, cmd), repeat=num_iterations, results = timeit.repeat(run_one(runner, cmd), repeat=num_iterations,
number=1) number=1)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Red Hat, Inc. # Copyright (C) 2020 Red Hat, Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -45,7 +45,7 @@ LOG = logging.getLogger(__name__)
SHUTDOWN_RETRIES = 3 SHUTDOWN_RETRIES = 3
class Client(object): class Client:
def __init__(self, rootwrap_daemon_cmd): def __init__(self, rootwrap_daemon_cmd):
self._start_command = rootwrap_daemon_cmd self._start_command = rootwrap_daemon_cmd
self._initialized = False self._initialized = False
@ -114,7 +114,7 @@ class Client(object):
try: try:
manager.rootwrap().shutdown() manager.rootwrap().shutdown()
break break
except (EOFError, IOError): except (EOFError, OSError):
break # assume it is dead already break # assume it is dead already
except RuntimeError: except RuntimeError:
time.sleep(0.2) time.sleep(0.2)
@ -167,7 +167,7 @@ class Client(object):
proxy = self._restart(proxy) proxy = self._restart(proxy)
try: try:
res = self._run_one_command(proxy, cmd, stdin) res = self._run_one_command(proxy, cmd, stdin)
except (EOFError, IOError): except (EOFError, OSError):
retry = True retry = True
# res can be None if we received final None sent by dying # res can be None if we received final None sent by dying
# server thread instead of response to our # server thread instead of response to our

View File

@ -51,7 +51,7 @@ SIGNAL_BASE = 128
def _exit_error(execname, message, errorcode, log=True): def _exit_error(execname, message, errorcode, log=True):
print("%s: %s" % (execname, message), file=sys.stderr) print("{}: {}".format(execname, message), file=sys.stderr)
if log: if log:
logging.error(message) logging.error(message)
sys.exit(errorcode) sys.exit(errorcode)
@ -81,7 +81,7 @@ def main(run_daemon=False):
rawconfig.read(configfile) rawconfig.read(configfile)
config = wrapper.RootwrapConfig(rawconfig) config = wrapper.RootwrapConfig(rawconfig)
except ValueError as exc: except ValueError as exc:
msg = "Incorrect value in %s: %s" % (configfile, exc.args[0]) msg = "Incorrect value in {}: {}".format(configfile, exc.args[0])
_exit_error(execname, msg, RC_BADCONFIG, log=False) _exit_error(execname, msg, RC_BADCONFIG, log=False)
except configparser.Error: except configparser.Error:
_exit_error(execname, "Incorrect configuration file: %s" % configfile, _exit_error(execname, "Incorrect configuration file: %s" % configfile,

View File

@ -38,7 +38,7 @@ LOG = logging.getLogger(__name__)
managers.listener_client['jsonrpc'] = jsonrpc.JsonListener, jsonrpc.JsonClient managers.listener_client['jsonrpc'] = jsonrpc.JsonListener, jsonrpc.JsonClient
class RootwrapClass(object): class RootwrapClass:
def __init__(self, config, filters): def __init__(self, config, filters):
self.config = config self.config = config
self.filters = filters self.filters = filters
@ -115,8 +115,8 @@ def get_manager_class(config=None, filters=None):
class RootwrapManager(managers.BaseManager): class RootwrapManager(managers.BaseManager):
def __init__(self, address=None, authkey=None): def __init__(self, address=None, authkey=None):
# Force jsonrpc because neither pickle nor xmlrpclib is secure # Force jsonrpc because neither pickle nor xmlrpclib is secure
super(RootwrapManager, self).__init__(address, authkey, super().__init__(address, authkey,
serializer='jsonrpc') serializer='jsonrpc')
if config is not None: if config is not None:
partial_class = functools.partial(RootwrapClass, config, filters) partial_class = functools.partial(RootwrapClass, config, filters)

View File

@ -46,7 +46,7 @@ def realpath(path):
return '' return ''
class CommandFilter(object): class CommandFilter:
"""Command filter only checking that the 1st argument matches exec_path.""" """Command filter only checking that the 1st argument matches exec_path."""
def __init__(self, exec_path, run_as, *args): def __init__(self, exec_path, run_as, *args):
@ -138,7 +138,7 @@ class PathFilter(CommandFilter):
arguments = userargs[1:] arguments = userargs[1:]
equal_args_num = len(self.args) == len(arguments) equal_args_num = len(self.args) == len(arguments)
exec_is_valid = super(PathFilter, self).match(userargs) exec_is_valid = super().match(userargs)
args_equal_or_pass = all( args_equal_or_pass = all(
arg == 'pass' or arg == value arg == 'pass' or arg == value
for arg, value in zip(self.args, arguments) for arg, value in zip(self.args, arguments)
@ -163,8 +163,8 @@ class PathFilter(CommandFilter):
args = [realpath(value) if os.path.isabs(arg) else value args = [realpath(value) if os.path.isabs(arg) else value
for arg, value in zip(self.args, arguments)] for arg, value in zip(self.args, arguments)]
return super(PathFilter, self).get_command([command] + args, return super().get_command([command] + args,
exec_dirs) exec_dirs)
class KillFilter(CommandFilter): class KillFilter(CommandFilter):
@ -180,7 +180,7 @@ class KillFilter(CommandFilter):
""" """
def __init__(self, *args): def __init__(self, *args):
super(KillFilter, self).__init__("/bin/kill", *args) super().__init__("/bin/kill", *args)
@staticmethod @staticmethod
def _program_path(command): def _program_path(command):
@ -209,7 +209,7 @@ class KillFilter(CommandFilter):
try: try:
command = os.readlink("/proc/%d/exe" % int(pid)) command = os.readlink("/proc/%d/exe" % int(pid))
except (ValueError, EnvironmentError): except (ValueError, OSError):
# Incorrect PID # Incorrect PID
return None return None
@ -241,7 +241,7 @@ class KillFilter(CommandFilter):
# as that will allow killing a process where the exe # as that will allow killing a process where the exe
# has been removed from the system rather than updated. # has been removed from the system rather than updated.
return command return command
except EnvironmentError: except OSError:
return None return None
def match(self, userargs): def match(self, userargs):
@ -282,7 +282,7 @@ class ReadFileFilter(CommandFilter):
def __init__(self, file_path, *args): def __init__(self, file_path, *args):
self.file_path = file_path self.file_path = file_path
super(ReadFileFilter, self).__init__("/bin/cat", "root", *args) super().__init__("/bin/cat", "root", *args)
def match(self, userargs): def match(self, userargs):
return (userargs == ['cat', self.file_path]) return (userargs == ['cat', self.file_path])
@ -319,7 +319,7 @@ class EnvFilter(CommandFilter):
return envs return envs
def __init__(self, exec_path, run_as, *args): def __init__(self, exec_path, run_as, *args):
super(EnvFilter, self).__init__(exec_path, run_as, *args) super().__init__(exec_path, run_as, *args)
env_list = self._extract_env(self.args) env_list = self._extract_env(self.args)
# Set exec_path to X when args are in the form of # Set exec_path to X when args are in the form of
@ -342,7 +342,7 @@ class EnvFilter(CommandFilter):
user_command = userargs[len(user_envs):len(user_envs) + 1] user_command = userargs[len(user_envs):len(user_envs) + 1]
# match first non-env argument with CommandFilter # match first non-env argument with CommandFilter
return (super(EnvFilter, self).match(user_command) and return (super().match(user_command) and
len(filter_envs) and user_envs == filter_envs) len(filter_envs) and user_envs == filter_envs)
def exec_args(self, userargs): def exec_args(self, userargs):

View File

@ -40,7 +40,7 @@ class RpcJSONEncoder(json.JSONEncoder):
# Other errors will fail to pass JSON encoding and will be visible on # Other errors will fail to pass JSON encoding and will be visible on
# client side # client side
else: else:
return super(RpcJSONEncoder, self).default(o) return super().default(o)
# Parse whatever RpcJSONEncoder supplied us with # Parse whatever RpcJSONEncoder supplied us with
@ -57,7 +57,7 @@ def rpc_object_hook(obj):
return obj return obj
class JsonListener(object): class JsonListener:
def __init__(self, address, backlog=1): def __init__(self, address, backlog=1):
self.address = address self.address = address
self._socket = socket.socket(socket.AF_UNIX) self._socket = socket.socket(socket.AF_UNIX)
@ -65,7 +65,7 @@ class JsonListener(object):
self._socket.setblocking(True) self._socket.setblocking(True)
self._socket.bind(address) self._socket.bind(address)
self._socket.listen(backlog) self._socket.listen(backlog)
except socket.error: except OSError:
self._socket.close() self._socket.close()
raise raise
self.closed = False self.closed = False
@ -75,7 +75,7 @@ class JsonListener(object):
while True: while True:
try: try:
s, _ = self._socket.accept() s, _ = self._socket.accept()
except socket.error as e: except OSError as e:
if e.errno in (errno.EINVAL, errno.EBADF): if e.errno in (errno.EINVAL, errno.EBADF):
raise EOFError raise EOFError
elif e.errno != errno.EINTR: elif e.errno != errno.EINTR:
@ -109,7 +109,7 @@ if hasattr(managers.Server, 'accepter'):
managers.Server.accepter = silent_accepter managers.Server.accepter = silent_accepter
class JsonConnection(object): class JsonConnection:
def __init__(self, sock): def __init__(self, sock):
sock.setblocking(True) sock.setblocking(True)
self._socket = sock self._socket = sock
@ -190,7 +190,7 @@ class JsonClient(JsonConnection):
sock = socket.socket(socket.AF_UNIX) sock = socket.socket(socket.AF_UNIX)
sock.setblocking(True) sock.setblocking(True)
sock.connect(address) sock.connect(address)
super(JsonClient, self).__init__(sock) super().__init__(sock)
if authkey is not None: if authkey is not None:
connection.answer_challenge(self, authkey) connection.answer_challenge(self, authkey)
connection.deliver_challenge(self, authkey) connection.deliver_challenge(self, authkey)

View File

@ -39,7 +39,7 @@ def forwarding_popen(f, old_popen=subprocess.Popen):
return popen return popen
class nonclosing(object): class nonclosing:
def __init__(self, f): def __init__(self, f):
self._f = f self._f = f

View File

@ -41,9 +41,9 @@ from oslo_rootwrap import subprocess
from oslo_rootwrap.tests import run_daemon from oslo_rootwrap.tests import run_daemon
class _FunctionalBase(object): class _FunctionalBase:
def setUp(self): def setUp(self):
super(_FunctionalBase, self).setUp() super().setUp()
tmpdir = self.useFixture(fixtures.TempDir()).path tmpdir = self.useFixture(fixtures.TempDir()).path
self.config_file = os.path.join(tmpdir, 'rootwrap.conf') self.config_file = os.path.join(tmpdir, 'rootwrap.conf')
self.later_cmd = os.path.join(tmpdir, 'later_install_cmd') self.later_cmd = os.path.join(tmpdir, 'later_install_cmd')
@ -52,9 +52,9 @@ class _FunctionalBase(object):
os.mkdir(filters_dir) os.mkdir(filters_dir)
with open(self.config_file, 'w') as f: with open(self.config_file, 'w') as f:
f.write("""[DEFAULT] f.write("""[DEFAULT]
filters_path=%s filters_path={}
daemon_timeout=10 daemon_timeout=10
exec_dirs=/bin""" % (filters_dir,)) exec_dirs=/bin""".format(filters_dir))
with open(filters_file, 'w') as f: with open(filters_file, 'w') as f:
f.write("""[Filters] f.write("""[Filters]
echo: CommandFilter, /bin/echo, root echo: CommandFilter, /bin/echo, root
@ -120,7 +120,7 @@ later_install_cmd: CommandFilter, %s, root
class RootwrapTest(_FunctionalBase, testtools.TestCase): class RootwrapTest(_FunctionalBase, testtools.TestCase):
def setUp(self): def setUp(self):
super(RootwrapTest, self).setUp() super().setUp()
self.cmd = [ self.cmd = [
sys.executable, '-c', sys.executable, '-c',
'from oslo_rootwrap import cmd; cmd.main()', 'from oslo_rootwrap import cmd; cmd.main()',
@ -157,7 +157,7 @@ class RootwrapDaemonTest(_FunctionalBase, testtools.TestCase):
def setUp(self): def setUp(self):
self.assert_unpatched() self.assert_unpatched()
super(RootwrapDaemonTest, self).setUp() super().setUp()
# Collect daemon logs # Collect daemon logs
daemon_log = io.BytesIO() daemon_log = io.BytesIO()

View File

@ -66,7 +66,7 @@ class RootwrapTestCase(testtools.TestCase):
_ip = '/bin/ip' _ip = '/bin/ip'
def setUp(self): def setUp(self):
super(RootwrapTestCase, self).setUp() super().setUp()
self.filters = [ self.filters = [
filters.RegExpFilter("/bin/ls", "root", 'ls', '/[a-z]+'), filters.RegExpFilter("/bin/ls", "root", 'ls', '/[a-z]+'),
filters.CommandFilter("/usr/bin/foo_bar_not_exist", "root"), filters.CommandFilter("/usr/bin/foo_bar_not_exist", "root"),
@ -528,7 +528,7 @@ class RootwrapTestCase(testtools.TestCase):
class PathFilterTestCase(testtools.TestCase): class PathFilterTestCase(testtools.TestCase):
def setUp(self): def setUp(self):
super(PathFilterTestCase, self).setUp() super().setUp()
self.tmp_root_dir = tempfile.mkdtemp() self.tmp_root_dir = tempfile.mkdtemp()
tmpdir = fixtures.TempDir(self.tmp_root_dir) tmpdir = fixtures.TempDir(self.tmp_root_dir)

View File

@ -38,7 +38,7 @@ class FilterMatchNotExecutable(Exception):
self.match = match self.match = match
class RootwrapConfig(object): class RootwrapConfig:
def __init__(self, config): def __init__(self, config):
# filters_path # filters_path
@ -106,7 +106,7 @@ def setup_syslog(execname, facility, level):
try: try:
handler = logging.handlers.SysLogHandler(address='/dev/log', handler = logging.handlers.SysLogHandler(address='/dev/log',
facility=facility) facility=facility)
except IOError: except OSError:
logging.warning("Unable to setup syslog, maybe /dev/log socket needs " logging.warning("Unable to setup syslog, maybe /dev/log socket needs "
"to be restarted. Ignoring syslog configuration " "to be restarted. Ignoring syslog configuration "
"options.") "options.")
@ -218,7 +218,7 @@ def start_subprocess(filter_list, userargs, exec_dirs=[], log=False, **kwargs):
command = filtermatch.get_command(userargs, exec_dirs) command = filtermatch.get_command(userargs, exec_dirs)
if log: if log:
logging.info("(%s > %s) Executing %s (filter match = %s)" % ( logging.info("({} > {}) Executing {} (filter match = {})".format(
_getlogin(), pwd.getpwuid(os.getuid())[0], _getlogin(), pwd.getpwuid(os.getuid())[0],
command, filtermatch.name)) command, filtermatch.name))

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Red Hat, Inc. # Copyright (C) 2020 Red Hat, Inc.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");