diff --git a/builder/tests/test_ossec_package.py b/builder/tests/test_ossec_package.py index e2118d4b54b..f409b0fa78e 100644 --- a/builder/tests/test_ossec_package.py +++ b/builder/tests/test_ossec_package.py @@ -29,7 +29,7 @@ def test_ossec_binaries_are_present_agent(): contents = subprocess.check_output(["dpkg-deb", "-c", str(path)]).decode() for wanted_file in wanted_files: assert re.search( - r"^.* .{}$".format(wanted_file), + rf"^.* .{wanted_file}$", contents, re.M, ) @@ -71,7 +71,7 @@ def test_ossec_binaries_are_present_server(): contents = subprocess.check_output(["dpkg-deb", "-c", str(path)]).decode() for wanted_file in wanted_files: assert re.search( - r"^.* .{}$".format(wanted_file), + rf"^.* .{wanted_file}$", contents, re.M, ) diff --git a/pyproject.toml b/pyproject.toml index 28626489482..694fbb4a788 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,8 @@ select = [ "RET", # flake8-simplify "SIM", + # pyupgrade + "UP", # pycodestyle warnings "W", # Unused noqa directive diff --git a/redwood/redwood.pyi b/redwood/redwood.pyi index da430af3206..d25a7679e22 100644 --- a/redwood/redwood.pyi +++ b/redwood/redwood.pyi @@ -1,9 +1,8 @@ # type stub for redwood module # see https://pyo3.rs/v0.16.4/python_typing_hints.html from pathlib import Path -from typing import List def generate_source_key_pair(passphrase: str, email: str) -> (str, str, str): ... -def encrypt_message(recipients: List[str], plaintext: str, destination: Path) -> None: ... -def encrypt_file(recipients: List[str], plaintext: Path, destination: Path) -> None: ... +def encrypt_message(recipients: list[str], plaintext: str, destination: Path) -> None: ... +def encrypt_file(recipients: list[str], plaintext: Path, destination: Path) -> None: ... def decrypt(ciphertext: bytes, secret_key: str, passphrase: str) -> str: ... diff --git a/securedrop/models.py b/securedrop/models.py index 6c66657674c..b5d5a89d3a6 100644 --- a/securedrop/models.py +++ b/securedrop/models.py @@ -40,8 +40,7 @@ def get_one_or_else( return query.one() except MultipleResultsFound as e: logger.error( - "Found multiple while executing %s when one was expected: %s" - % ( + "Found multiple while executing {} when one was expected: {}".format( query, e, ) @@ -867,10 +866,9 @@ class InstanceConfig(db.Model): def __repr__(self) -> str: return ( - "" - % ( + "".format( self.version, self.valid_until, self.allow_document_uploads, diff --git a/securedrop/pretty_bad_protocol/_meta.py b/securedrop/pretty_bad_protocol/_meta.py index 9ea61331369..368f37e8545 100644 --- a/securedrop/pretty_bad_protocol/_meta.py +++ b/securedrop/pretty_bad_protocol/_meta.py @@ -286,7 +286,7 @@ def remove_program_from_path(path, prog_base): # type: ignore[no-untyped-def] path.remove(directory) self._removed_path_entries.append(directory) log.debug("Deleted all found instance of %s." % directory) - log.debug("PATH is now:{}{}".format(os.linesep, path)) + log.debug(f"PATH is now:{os.linesep}{path}") return ":".join([p for p in path]) @staticmethod @@ -586,7 +586,7 @@ def _open_subprocess(self, args=None, passphrase=False): # type: ignore[no-unty # see http://docs.python.org/2/library/subprocess.html#converting-an\ # -argument-sequence-to-a-string-on-windows cmd = shlex.split(" ".join(self._make_args(args, passphrase))) - log.debug("Sending command to GnuPG process:{}{}".format(os.linesep, cmd)) + log.debug(f"Sending command to GnuPG process:{os.linesep}{cmd}") environment = { "LANGUAGE": os.environ.get("LANGUAGE") or "en", @@ -774,7 +774,7 @@ def _recv_keys(self, keyids, keyserver=None): # type: ignore[no-untyped-def] keyserver = self.keyserver args = [f"--keyserver {keyserver}", f"--recv-keys {keyids}"] - log.info("Requesting keys from {}: {}".format(keyserver, keyids)) + log.info(f"Requesting keys from {keyserver}: {keyids}") result = self._result_map["import"](self) proc = self._open_subprocess(args) @@ -1010,8 +1010,7 @@ def _encrypt( # type: ignore[no-untyped-def] if len(recipients) >= 1: log.debug( - "GPG.encrypt() called for recipients '%s' with type '%s'" - % (recipients, type(recipients)) + f"GPG.encrypt() called for recipients '{recipients}' with type '{type(recipients)}'" ) if isinstance(recipients, (list, tuple)): @@ -1027,7 +1026,7 @@ def _encrypt( # type: ignore[no-untyped-def] log.debug("Don't know what to do with recipients: %r" % recipients) result = self._result_map["crypt"](self) - log.debug("Got data '{}' with type '{}'.".format(data, type(data))) + log.debug(f"Got data '{data}' with type '{type(data)}'.") self._handle_io(args, data, result, passphrase=passphrase, binary=True) # Avoid writing raw encrypted bytes to terminal loggers and breaking # them in that adorable way where they spew hieroglyphics until reset: diff --git a/securedrop/pretty_bad_protocol/_parsers.py b/securedrop/pretty_bad_protocol/_parsers.py index 965d2ccaac8..c29a8ec917b 100644 --- a/securedrop/pretty_bad_protocol/_parsers.py +++ b/securedrop/pretty_bad_protocol/_parsers.py @@ -64,7 +64,7 @@ def _check_keyserver(location): # type: ignore[no-untyped-def] url = location.replace(proto, "") host, slash, extra = url.partition("/") if extra: - log.warn("URI text for {}: '{}'".format(host, extra)) + log.warn(f"URI text for {host}: '{extra}'") log.debug("Got host string for keyserver setting: '%s'" % host) host = _fix_unsafe(host) @@ -311,7 +311,7 @@ def _check_option(arg, value): # type: ignore[no-untyped-def] if _is_hex(v): checked += v + " " else: - log.debug("'{} {}' not hex.".format(flag, v)) + log.debug(f"'{flag} {v}' not hex.") if (flag in hex_or_none_options) and (v is None): log.debug("Allowing '%s' for all keys" % flag) continue @@ -334,7 +334,7 @@ def _check_option(arg, value): # type: ignore[no-untyped-def] assert v is not None assert not v.isspace() except: # noqa: E722 - log.debug("Dropping {} {}".format(flag, v)) + log.debug(f"Dropping {flag} {v}") continue if flag in [ @@ -348,7 +348,7 @@ def _check_option(arg, value): # type: ignore[no-untyped-def] if (_util._is_file(val)) or ((flag == "--verify") and (val == "-")): checked += val + " " else: - log.debug("{} not file: {}".format(flag, val)) + log.debug(f"{flag} not file: {val}") elif flag in [ "--cipher-algo", @@ -437,7 +437,7 @@ def _check_groups(groups): # type: ignore[no-untyped-def] log.debug("Appending option: %s" % safe) checked_groups.append(safe) else: - log.warn("Dropped option: '{} {}'".format(a, v)) + log.warn(f"Dropped option: '{a} {v}'") return checked_groups if args is not None: @@ -457,7 +457,7 @@ def _check_groups(groups): # type: ignore[no-untyped-def] arg.reverse() option_groups.update(_make_groups(arg)) else: - log.warn("Got non-str/list arg: '%s', type '%s'" % (arg, type(arg))) + log.warn(f"Got non-str/list arg: '{arg}', type '{type(arg)}'") checked = _check_groups(option_groups) return " ".join(x for x in checked) else: @@ -892,7 +892,7 @@ def _clean_key_expiration_option(self): # type: ignore[no-untyped-def] def _input_passphrase(self, _input): # type: ignore[no-untyped-def] if self._passphrase: - return "{}{}\n".format(_input, self._passphrase) + return f"{_input}{self._passphrase}\n" return _input def _main_key_command(self): # type: ignore[no-untyped-def] @@ -972,7 +972,7 @@ def _handle_status(self, key, value): # type: ignore[no-untyped-def] self.status = "{}: {}".format(key.replace("_", " ").lower(), value) else: self.status = "failed" - raise ValueError("Key signing, unknown status message: {!r} ::{}".format(key, value)) + raise ValueError(f"Key signing, unknown status message: {key!r} ::{value}") class GenKey: @@ -1650,7 +1650,7 @@ def _handle_status(self, key, value): # type: ignore[no-untyped-def] # case of WARNING or ERROR) additional text. # Have fun figuring out what it means. self.status = value - log.warn("{} status emitted from gpg process: {}".format(key, value)) + log.warn(f"{key} status emitted from gpg process: {value}") elif key == "NO_PUBKEY": self.valid = False self.key_id = value @@ -1666,7 +1666,7 @@ def _handle_status(self, key, value): # type: ignore[no-untyped-def] elif key in ("EXPKEYSIG", "REVKEYSIG"): self.valid = False self.key_id = value.split()[0] - self.status = (("%s %s") % (key[:3], key[3:])).lower() + self.status = (f"{key[:3]} {key[3:]}").lower() # This is super annoying, and bad design on the part of GnuPG, in my # opinion. # @@ -1755,7 +1755,7 @@ def _handle_status(self, key, value): # type: ignore[no-untyped-def] else: pass else: - raise ValueError("Unknown status message: {!r} {!r}".format(key, value)) + raise ValueError(f"Unknown status message: {key!r} {value!r}") class Crypt(Verify): diff --git a/securedrop/pretty_bad_protocol/_trust.py b/securedrop/pretty_bad_protocol/_trust.py index 878cd0bf34b..03eef6a232a 100644 --- a/securedrop/pretty_bad_protocol/_trust.py +++ b/securedrop/pretty_bad_protocol/_trust.py @@ -34,8 +34,9 @@ def _create_trustdb(cls): # type: ignore[no-untyped-def] trustdb = os.path.join(cls.homedir, "trustdb.gpg") if not os.path.isfile(trustdb): log.info( - "GnuPG complained that your trustdb file was missing. %s" - % "This is likely due to changing to a new homedir." + "GnuPG complained that your trustdb file was missing. {}".format( + "This is likely due to changing to a new homedir." + ) ) log.info("Creating trustdb.gpg file in your GnuPG homedir.") cls.fix_trustdb(trustdb) diff --git a/securedrop/pretty_bad_protocol/_util.py b/securedrop/pretty_bad_protocol/_util.py index fdccc2f5d52..f8e49438a86 100644 --- a/securedrop/pretty_bad_protocol/_util.py +++ b/securedrop/pretty_bad_protocol/_util.py @@ -93,7 +93,7 @@ def _copy_data(instream, outstream): # type: ignore[no-untyped-def] else: encoded = data log.debug("Sending %d bytes of data..." % sent) - log.debug("Encoded data (type {}):\n{}".format(type(encoded), encoded)) + log.debug(f"Encoded data (type {type(encoded)}):\n{encoded}") try: outstream.write(bytes(encoded)) @@ -137,7 +137,7 @@ def _copy_data(instream, outstream): # type: ignore[no-untyped-def] try: outstream.close() except OSError as ioe: - log.error("Unable to close outstream {}:\r\t{}".format(outstream, ioe)) + log.error(f"Unable to close outstream {outstream}:\r\t{ioe}") else: log.debug("Closed outstream: %d bytes sent." % sent) @@ -195,9 +195,9 @@ def create_uid_email(username=None, hostname=None): # type: ignore[no-untyped-d else: username = username.replace(" ", "_") if (not hostname) and (username.find("@") == 0): - uid = "{}@{}".format(username, gethostname()) + uid = f"{username}@{gethostname()}" elif hostname: - uid = "{}@{}".format(username, hostname) + uid = f"{username}@{hostname}" else: uid = username @@ -221,7 +221,7 @@ def _deprefix(line, prefix, callback=None): # type: ignore[no-untyped-def] try: assert line.upper().startswith("".join(prefix).upper()) except AssertionError: - log.debug("Line doesn't start with prefix '{}':\n{}".format(prefix, line)) + log.debug(f"Line doesn't start with prefix '{prefix}':\n{line}") return line else: newline = line[len(prefix) :] @@ -299,7 +299,7 @@ def _is_file(filename): # type: ignore[no-untyped-def] try: statinfo = os.lstat(filename) log.debug( - "lstat(%r) with type=%s gave us %r" % (repr(filename), type(filename), repr(statinfo)) + f"lstat({repr(filename)!r}) with type={type(filename)} gave us {repr(statinfo)!r}" ) if not (statinfo.st_size > 0): raise ValueError("'%s' appears to be an empty file!" % filename) diff --git a/securedrop/pretty_bad_protocol/gnupg.py b/securedrop/pretty_bad_protocol/gnupg.py index 0aaef7bcef0..ba5b9232480 100644 --- a/securedrop/pretty_bad_protocol/gnupg.py +++ b/securedrop/pretty_bad_protocol/gnupg.py @@ -236,7 +236,7 @@ def sign(self, data, **kwargs): # type: ignore[no-untyped-def] The default, if unspecified, is ``'SHA512'``. """ if "default_key" in kwargs: - log.info("Signing message '%r' with keyid: %s" % (data, kwargs["default_key"])) + log.info("Signing message '{!r}' with keyid: {}".format(data, kwargs["default_key"])) else: log.warn("No 'default_key' given! Using first key on secring.") @@ -247,7 +247,7 @@ def sign(self, data, **kwargs): # type: ignore[no-untyped-def] result = self._sign_file(stream, **kwargs) stream.close() else: - log.warn("Unable to sign message '%s' with type %s" % (data, type(data))) + log.warn(f"Unable to sign message '{data}' with type {type(data)}") result = None return result @@ -435,7 +435,7 @@ def export_keys(self, keyids, secret=False, subkeys=False): # type: ignore[no-u # stdout, stderr = p.communicate() result = self._result_map["export"](self) self._collect_output(p, result, stdin=p.stdin) - log.debug("Exported:{}{!r}".format(os.linesep, result.fingerprints)) + log.debug(f"Exported:{os.linesep}{result.fingerprints!r}") return result.data.decode(self._encoding, self._decode_errors) def list_keys(self, secret=False): # type: ignore[no-untyped-def] @@ -863,8 +863,9 @@ def gen_key_input(self, separate_keyring=False, save_batchfile=False, testing=Fa parms.setdefault("Key-Type", "default") log.debug( - "GnuPG v%s detected: setting default key type to %s." - % (self.binary_version, parms["Key-Type"]) + "GnuPG v{} detected: setting default key type to {}.".format( + self.binary_version, parms["Key-Type"] + ) ) parms.setdefault("Key-Length", 4096) parms.setdefault("Name-Real", "Autogenerated Key") @@ -908,7 +909,7 @@ def gen_key_input(self, separate_keyring=False, save_batchfile=False, testing=Fa out += "Subkey-Length: %s\n" % parms.pop("Subkey-Length") for key, val in list(parms.items()): - out += "{}: {}\n".format(key, val) + out += f"{key}: {val}\n" # There is a problem where, in the batch files, if the '%%pubring' # and '%%secring' are given as any static string, i.e. 'pubring.gpg', diff --git a/securedrop/tests/utils/__init__.py b/securedrop/tests/utils/__init__.py index b3985cef048..0f9effe244e 100644 --- a/securedrop/tests/utils/__init__.py +++ b/securedrop/tests/utils/__init__.py @@ -13,7 +13,7 @@ def flaky_filter_xfail(err, *args): If the test is expected to fail, let's not run it again. """ return ( - "{}.{}".format(err[0].__class__.__module__, err[0].__class__.__qualname__) + f"{err[0].__class__.__module__}.{err[0].__class__.__qualname__}" == "_pytest.outcomes.XFailed" )