From b6bc366af0d992d7867d8f462412d40eccd7acce Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Tue, 8 Nov 2022 19:21:29 +0000 Subject: [PATCH] Run pyupgrade --py37-plus x 2 --- linkcheck/better_exchook2.py | 2 +- linkcheck/checker/__init__.py | 2 +- linkcheck/checker/mailtourl.py | 2 +- linkcheck/checker/unknownurl.py | 2 +- linkcheck/checker/urlbase.py | 2 +- linkcheck/command/arg_parser.py | 2 +- linkcheck/configuration/__init__.py | 4 ++-- linkcheck/configuration/confparse.py | 2 +- linkcheck/director/console.py | 2 +- linkcheck/htmlutil/loginformsearch.py | 2 +- linkcheck/loader.py | 2 +- linkcheck/logger/__init__.py | 2 +- linkcheck/logger/dot.py | 2 +- linkcheck/logger/xmllog.py | 2 +- linkcheck/plugins/anchorcheck.py | 2 +- linkcheck/plugins/httpheaderinfo.py | 2 +- linkcheck/strformat.py | 12 ++++++------ linkcheck/url.py | 22 +++++++++++----------- scripts/update_iana_uri_schemes.py | 2 +- tests/checker/httpserver.py | 4 ++-- tests/checker/telnetserver.py | 4 ++-- tests/checker/test_httpbin.py | 2 +- tests/configuration/test_config.py | 2 +- tests/htmllib.py | 4 ++-- tests/test_ftpparse.py | 2 +- tests/test_parser.py | 2 +- tests/test_po.py | 2 +- tests/test_robotparser.py | 2 +- 28 files changed, 47 insertions(+), 47 deletions(-) diff --git a/linkcheck/better_exchook2.py b/linkcheck/better_exchook2.py index cd5cc4f1..f4a5dee6 100644 --- a/linkcheck/better_exchook2.py +++ b/linkcheck/better_exchook2.py @@ -232,7 +232,7 @@ def better_exchook(etype, value, tb, out=sys.stdout): if value is None or not valuestr: line = "%s" % etype else: - line = "%s: %s" % (etype, valuestr) + line = f"{etype}: {valuestr}" return line if (isinstance(etype, BaseException) or (hasattr(types, "InstanceType") and isinstance(etype, types.InstanceType)) or diff --git a/linkcheck/checker/__init__.py b/linkcheck/checker/__init__.py index dd0a28f5..e8b2f6de 100644 --- a/linkcheck/checker/__init__.py +++ b/linkcheck/checker/__init__.py @@ -197,7 +197,7 @@ def get_index_html(urls): except KeyError: # Some unicode entries raise KeyError. url = name - lines.append('%s' % (url, name)) + lines.append(f'{name}') lines.extend(["", ""]) return os.linesep.join(lines) diff --git a/linkcheck/checker/mailtourl.py b/linkcheck/checker/mailtourl.py index 536f0baa..04842c6b 100644 --- a/linkcheck/checker/mailtourl.py +++ b/linkcheck/checker/mailtourl.py @@ -370,7 +370,7 @@ class MailtoUrl(urlbase.UrlBase): The cache url is a comma separated list of emails. """ emails = ",".join(sorted(self.addresses)) - self.cache_url = "%s:%s" % (self.scheme, emails) + self.cache_url = f"{self.scheme}:{emails}" def can_get_content(self): """ diff --git a/linkcheck/checker/unknownurl.py b/linkcheck/checker/unknownurl.py index 44422a49..f4e5a34d 100644 --- a/linkcheck/checker/unknownurl.py +++ b/linkcheck/checker/unknownurl.py @@ -423,7 +423,7 @@ ignored_schemes_other = r""" |whatsapp # WhatsApp """ -ignored_schemes = "^(%s%s%s%s)$" % ( +ignored_schemes = "^({}{}{}{})$".format( ignored_schemes_permanent, ignored_schemes_provisional, ignored_schemes_historical, diff --git a/linkcheck/checker/urlbase.py b/linkcheck/checker/urlbase.py index 969ba972..bf448fcd 100644 --- a/linkcheck/checker/urlbase.py +++ b/linkcheck/checker/urlbase.py @@ -508,7 +508,7 @@ class UrlBase: else: host = "%s:%d" % (self.host, self.port) if self.userinfo: - urlparts[1] = "%s@%s" % (self.userinfo, host) + urlparts[1] = f"{self.userinfo}@{host}" else: urlparts[1] = host # save anchor for later checking diff --git a/linkcheck/command/arg_parser.py b/linkcheck/command/arg_parser.py index 0f1fa291..1e8c346a 100644 --- a/linkcheck/command/arg_parser.py +++ b/linkcheck/command/arg_parser.py @@ -180,7 +180,7 @@ file entry: ) + "\n".join( [ - " o %s - %s" % (tag, desc) + f" o {tag} - {desc}" for tag, desc in sorted(checker.const.Warnings.items()) ] ) diff --git a/linkcheck/configuration/__init__.py b/linkcheck/configuration/__init__.py index 9892da0d..f940c5ba 100644 --- a/linkcheck/configuration/__init__.py +++ b/linkcheck/configuration/__init__.py @@ -46,7 +46,7 @@ HtmlCopyright = ( HtmlAppInfo = App + ", " + HtmlCopyright Url = _release.__url__ SupportUrl = _release.__support_url__ -UserAgent = "Mozilla/5.0 (compatible; %s/%s; +%s)" % (AppName, Version, Url) +UserAgent = f"Mozilla/5.0 (compatible; {AppName}/{Version}; +{Url})" Freeware = ( AppName + """ comes with ABSOLUTELY NO WARRANTY! @@ -87,7 +87,7 @@ def get_modules_info(): if version_attr and hasattr(mod, version_attr): attr = getattr(mod, version_attr) version = attr() if callable(attr) else attr - module_infos.append("%s %s" % (name, version)) + module_infos.append(f"{name} {version}") else: # ignore attribute errors in case library developers # change the version information attribute diff --git a/linkcheck/configuration/confparse.py b/linkcheck/configuration/confparse.py index 2d64c75a..544dce3e 100644 --- a/linkcheck/configuration/confparse.py +++ b/linkcheck/configuration/confparse.py @@ -227,7 +227,7 @@ class LCConfigParser(RawConfigParser): self.config.add_auth( pattern=auth[0], user=auth[1], password=auth[2] ) - password_fields.append("entry/%s/%s" % (auth[0], auth[1])) + password_fields.append(f"entry/{auth[0]}/{auth[1]}") elif len(auth) == 2: self.config.add_auth(pattern=auth[0], user=auth[1]) else: diff --git a/linkcheck/director/console.py b/linkcheck/director/console.py index e2bc6e06..761b7fab 100644 --- a/linkcheck/director/console.py +++ b/linkcheck/director/console.py @@ -53,7 +53,7 @@ class StatusLogger: def writeln(self, msg): """Write status message and line break to file descriptor.""" - self.fd.write("%s%s" % (msg, os.linesep)) + self.fd.write(f"{msg}{os.linesep}") def flush(self): """Flush file descriptor.""" diff --git a/linkcheck/htmlutil/loginformsearch.py b/linkcheck/htmlutil/loginformsearch.py index 77103414..238994e7 100644 --- a/linkcheck/htmlutil/loginformsearch.py +++ b/linkcheck/htmlutil/loginformsearch.py @@ -34,7 +34,7 @@ class Form: def __repr__(self): """Return string displaying URL and form data.""" - return "" % (self.url, self.data) + return f"" def search_form(content, cgiuser, cgipassword): diff --git a/linkcheck/loader.py b/linkcheck/loader.py index ecf5853e..25e94879 100644 --- a/linkcheck/loader.py +++ b/linkcheck/loader.py @@ -34,7 +34,7 @@ def get_package_modules(packagename, packagepath): for mod in pkgutil.iter_modules(packagepath): if not mod.ispkg: try: - name = "..%s.%s" % (packagename, mod.name) + name = f"..{packagename}.{mod.name}" yield importlib.import_module(name, __name__) except ImportError as msg: print(_("WARN: could not load module %s: %s") % (mod.name, msg)) diff --git a/linkcheck/logger/__init__.py b/linkcheck/logger/__init__.py index 4d5c4c43..f69ab088 100644 --- a/linkcheck/logger/__init__.py +++ b/linkcheck/logger/__init__.py @@ -325,7 +325,7 @@ class _Logger(abc.ABC): """ Write string to output descriptor plus a newline. """ - self.write("%s%s" % (s, os.linesep), **args) + self.write(f"{s}{os.linesep}", **args) def has_part(self, name): """ diff --git a/linkcheck/logger/dot.py b/linkcheck/logger/dot.py index fb17d0a1..52db5472 100644 --- a/linkcheck/logger/dot.py +++ b/linkcheck/logger/dot.py @@ -70,7 +70,7 @@ class DOTLogger(_GraphLogger): """Write edge from parent to node.""" source = dotquote(self.nodes[node["parent_url"]]["label"]) target = dotquote(node["label"]) - self.writeln(' "%s" -> "%s" [' % (source, target)) + self.writeln(f' "{source}" -> "{target}" [') self.writeln(' label="%s",' % dotquote(node["edge"])) if self.has_part("result"): self.writeln(" valid=%d," % node["valid"]) diff --git a/linkcheck/logger/xmllog.py b/linkcheck/logger/xmllog.py index 33338d0a..995acb8c 100644 --- a/linkcheck/logger/xmllog.py +++ b/linkcheck/logger/xmllog.py @@ -113,4 +113,4 @@ class _XMLLogger(_Logger): for aname, avalue in attrs.items(): args = (xmlquote(aname), xmlquoteattr(avalue)) self.write(' %s="%s"' % args) - self.writeln(">%s" % (xmlquote(content), xmlquote(name))) + self.writeln(f">{xmlquote(content)}") diff --git a/linkcheck/plugins/anchorcheck.py b/linkcheck/plugins/anchorcheck.py index 35248c62..e9a8a200 100644 --- a/linkcheck/plugins/anchorcheck.py +++ b/linkcheck/plugins/anchorcheck.py @@ -66,7 +66,7 @@ class UrlAnchorCheck: else: anchors = "-" args = {"name": url_data.anchor, "decoded": decoded_anchor, "anchors": anchors} - msg = "%s %s" % ( + msg = "{} {}".format( _("Anchor `%(name)s' (decoded: `%(decoded)s') not found.") % args, _("Available anchors: %(anchors)s.") % args, ) diff --git a/linkcheck/plugins/httpheaderinfo.py b/linkcheck/plugins/httpheaderinfo.py index 7e299d47..0c925274 100644 --- a/linkcheck/plugins/httpheaderinfo.py +++ b/linkcheck/plugins/httpheaderinfo.py @@ -39,7 +39,7 @@ class HttpHeaderInfo(_ConnectionPlugin): headers.append(name.lower()) if headers: items = [ - "%s=%s" % (name.capitalize(), url_data.headers[name]) + f"{name.capitalize()}={url_data.headers[name]}" for name in headers ] info = "HTTP headers %s" % ", ".join(items) diff --git a/linkcheck/strformat.py b/linkcheck/strformat.py index f16d6e3e..0783fab7 100644 --- a/linkcheck/strformat.py +++ b/linkcheck/strformat.py @@ -73,10 +73,10 @@ def unquote(s, matching=False): return s -_para_mac = r"(?:%(sep)s)(?:(?:%(sep)s)\s*)+" % {'sep': '\r'} -_para_posix = r"(?:%(sep)s)(?:(?:%(sep)s)\s*)+" % {'sep': '\n'} -_para_win = r"(?:%(sep)s)(?:(?:%(sep)s)\s*)+" % {'sep': '\r\n'} -_para_ro = re.compile("%s|%s|%s" % (_para_mac, _para_posix, _para_win)) +_para_mac = r"(?:{sep})(?:(?:{sep})\s*)+".format(sep='\r') +_para_posix = r"(?:{sep})(?:(?:{sep})\s*)+".format(sep='\n') +_para_win = r"(?:{sep})(?:(?:{sep})\s*)+".format(sep='\r\n') +_para_ro = re.compile(f"{_para_mac}|{_para_posix}|{_para_win}") def get_paragraphs(text): @@ -104,7 +104,7 @@ def wrap(text, width, **kwargs): def indent(text, indent_string=" "): """Indent each line of text with the given indent string.""" - return os.linesep.join("%s%s" % (indent_string, x) for x in text.splitlines()) + return os.linesep.join(f"{indent_string}{x}" for x in text.splitlines()) def paginate(text): @@ -191,7 +191,7 @@ def strduration_long(duration, do_translate=True): time_str.reverse() if len(time_str) > 2: time_str.pop() - return "%s%s" % (prefix, ", ".join(time_str)) + return "{}{}".format(prefix, ", ".join(time_str)) def strtimezone(): diff --git a/linkcheck/url.py b/linkcheck/url.py index e6ad1df5..ed1e52dd 100644 --- a/linkcheck/url.py +++ b/linkcheck/url.py @@ -61,10 +61,10 @@ _safe_path_pattern = ( r"(%%[%(_hex_safe)s][%(_hex_full)s]))+)*/?)" % _basic ) _safe_fragment_pattern = r"%s*" % _safe_char -_safe_cgi = r"%s+(=(%s|/)+)?" % (_safe_char, _safe_char) -_safe_query_pattern = r"(%s(&%s)*)?" % (_safe_cgi, _safe_cgi) -_safe_param_pattern = r"(%s(;%s)*)?" % (_safe_cgi, _safe_cgi) -safe_url_pattern = r"%s://%s%s(#%s)?" % ( +_safe_cgi = fr"{_safe_char}+(=({_safe_char}|/)+)?" +_safe_query_pattern = fr"({_safe_cgi}(&{_safe_cgi})*)?" +_safe_param_pattern = fr"({_safe_cgi}(;{_safe_cgi})*)?" +safe_url_pattern = r"{}://{}{}(#{})?".format( _safe_scheme_pattern, _safe_host_pattern, _safe_path_pattern, @@ -195,7 +195,7 @@ def url_fix_host(urlparts, encoding): if not urlparts[2] or urlparts[2] == '/': urlparts[2] = comps else: - urlparts[2] = "%s%s" % ( + urlparts[2] = "{}{}".format( comps, urllib.parse.unquote(urlparts[2], encoding=encoding), ) @@ -255,12 +255,12 @@ def url_parse_query(query, encoding): k = urllib.parse.quote(k, safe='/-:,;') if v: v = urllib.parse.quote(v, safe='/-:,;') - f.append("%s=%s%s" % (k, v, sep)) + f.append(f"{k}={v}{sep}") elif v is None: - f.append("%s%s" % (k, sep)) + f.append(f"{k}{sep}") else: # some sites do not work when the equal sign is missing - f.append("%s=%s" % (k, sep)) + f.append(f"{k}={sep}") return ''.join(f) + append @@ -381,9 +381,9 @@ def url_quote(url, encoding): k = urllib.parse.quote(k, safe='/-:,;') if v: v = urllib.parse.quote(v, safe='/-:,;') - f.append("%s=%s%s" % (k, v, sep)) + f.append(f"{k}={v}{sep}") else: - f.append("%s%s" % (k, sep)) + f.append(f"{k}{sep}") urlparts[3] = ''.join(f) urlparts[4] = urllib.parse.quote(urlparts[4]) # anchor return urlunsplit(urlparts) @@ -397,7 +397,7 @@ def document_quote(document): query = None doc = urllib.parse.quote(doc, safe='/=,') if query: - return "%s?%s" % (doc, query) + return f"{doc}?{query}" return doc diff --git a/scripts/update_iana_uri_schemes.py b/scripts/update_iana_uri_schemes.py index 261e5d0a..48b5cc12 100644 --- a/scripts/update_iana_uri_schemes.py +++ b/scripts/update_iana_uri_schemes.py @@ -87,7 +87,7 @@ def main(args): def get_regex(schemes): expr = [ - "|%s # %s" % (re.escape(scheme).ljust(10), description) + f"|{re.escape(scheme).ljust(10)} # {description}" for scheme, description in sorted(schemes.items()) ] return "\n".join(expr) diff --git a/tests/checker/httpserver.py b/tests/checker/httpserver.py index 4a28d5e4..6b58dd63 100644 --- a/tests/checker/httpserver.py +++ b/tests/checker/httpserver.py @@ -132,7 +132,7 @@ class NoQueryHttpRequestHandler(StoppableHttpRequestHandler): list = ["example1.txt", "example2.html", "example3"] for name in list: displayname = linkname = name - list_item = '
  • %s\n' % ( + list_item = '
  • {}\n'.format( urllib.parse.quote(linkname), html.escape(displayname), ) @@ -247,7 +247,7 @@ def get_cookie(maxage=2000): ("Version", "1"), ("Foo", "Bar"), ) - return "; ".join('%s="%s"' % (key, value) for key, value in data) + return "; ".join(f'{key}="{value}"' for key, value in data) class CookieRedirectHttpRequestHandler(NoQueryHttpRequestHandler): diff --git a/tests/checker/telnetserver.py b/tests/checker/telnetserver.py index 15f12dc1..fa23851c 100644 --- a/tests/checker/telnetserver.py +++ b/tests/checker/telnetserver.py @@ -40,9 +40,9 @@ class TelnetServerTest(LinkCheckTest): def get_url(self, user=None, password=None): if user is not None: if password is not None: - netloc = "%s:%s@%s" % (user, password, self.host) + netloc = f"{user}:{password}@{self.host}" else: - netloc = "%s@%s" % (user, self.host) + netloc = f"{user}@{self.host}" else: netloc = self.host return "telnet://%s:%d" % (netloc, self.port) diff --git a/tests/checker/test_httpbin.py b/tests/checker/test_httpbin.py index 7b449585..e24f4a7e 100644 --- a/tests/checker/test_httpbin.py +++ b/tests/checker/test_httpbin.py @@ -54,7 +54,7 @@ class TestHttpbin(LinkCheckTest): def test_basic_auth(self): user = "testuser" password = "testpassword" - url = get_httpbin_url("/basic-auth/%s/%s" % (user, password)) + url = get_httpbin_url(f"/basic-auth/{user}/{password}") nurl = self.norm(url) entry = dict(user=user, password=password, pattern=re.compile(r".*")) confargs = dict(authentication=[entry]) diff --git a/tests/configuration/test_config.py b/tests/configuration/test_config.py index 959c7e05..4a2fbf27 100644 --- a/tests/configuration/test_config.py +++ b/tests/configuration/test_config.py @@ -64,7 +64,7 @@ class TestConfig(TestBase): patterns = [x["pattern"].pattern for x in config["externlinks"]] for prefix in ("ignore_", "nofollow_"): for suffix in ("1", "2"): - key = "%simadoofus%s" % (prefix, suffix) + key = f"{prefix}imadoofus{suffix}" self.assertTrue(key in patterns) for key in ("url-unicode-domain",): self.assertTrue(key in config["ignorewarnings"]) diff --git a/tests/htmllib.py b/tests/htmllib.py index a59d03dc..16d56c0d 100644 --- a/tests/htmllib.py +++ b/tests/htmllib.py @@ -37,9 +37,9 @@ def pretty_print_html(fd, soup): if val is None: fd.write(" %s" % key) else: - fd.write(' %s="%s"' % (key, quote_attrval(val))) + fd.write(f' {key}="{quote_attrval(val)}"') if element_text: - fd.write(">%s" % (element_text, tag)) + fd.write(f">{element_text}") else: fd.write("/>") diff --git a/tests/test_ftpparse.py b/tests/test_ftpparse.py index 7a9b617f..56ed3ba9 100644 --- a/tests/test_ftpparse.py +++ b/tests/test_ftpparse.py @@ -125,5 +125,5 @@ class TestFtpparse(unittest.TestCase): for line, expected in patterns: res = ftpparse(line) self.assertEqual( - expected, res, "got %r\nexpected %r\n%r" % (res, expected, line) + expected, res, f"got {res!r}\nexpected {expected!r}\n{line!r}" ) diff --git a/tests/test_parser.py b/tests/test_parser.py index 40bc922c..465656a8 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -165,7 +165,7 @@ class TestParser(unittest.TestCase): Check parse results. """ res = out.getvalue() - msg = "Test error; in: %r, out: %r, expect: %r" % (_in, res, _out) + msg = f"Test error; in: {_in!r}, out: {res!r}, expect: {_out!r}" self.assertEqual(res, _out, msg=msg) def test_encoding_detection_utf_content(self): diff --git a/tests/test_po.py b/tests/test_po.py index 30d5f459..e5b49103 100644 --- a/tests/test_po.py +++ b/tests/test_po.py @@ -70,5 +70,5 @@ class TestGTranslator(unittest.TestCase): continue self.assertFalse( "ยท" in line, - "Broken GTranslator copy/paste in %r:\n%s" % (f, line), + f"Broken GTranslator copy/paste in {f!r}:\n{line}", ) diff --git a/tests/test_robotparser.py b/tests/test_robotparser.py index bebf3afd..c6b452ea 100644 --- a/tests/test_robotparser.py +++ b/tests/test_robotparser.py @@ -40,7 +40,7 @@ class TestRobotParser(unittest.TestCase): else: ac = "access allowed" if a != b: - self.fail("%s != %s (%s)" % (a, b, ac)) + self.fail(f"{a} != {b} ({ac})") @need_network def test_nonexisting_robots(self):