mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Merge pull request #3241 from getpelican/pyupgrade-py38-plus
This commit is contained in:
commit
e92ccb8a46
15 changed files with 58 additions and 64 deletions
|
|
@ -273,7 +273,7 @@ class PrintSettings(argparse.Action):
|
|||
)
|
||||
)
|
||||
else:
|
||||
console.print("\n{} is not a recognized setting.".format(setting))
|
||||
console.print(f"\n{setting} is not a recognized setting.")
|
||||
break
|
||||
else:
|
||||
# No argument was given to --print-settings, so print all settings
|
||||
|
|
@ -611,9 +611,7 @@ def listen(server, port, output, excqueue=None):
|
|||
return
|
||||
|
||||
try:
|
||||
console.print(
|
||||
"Serving site at: http://{}:{} - Tap CTRL-C to stop".format(server, port)
|
||||
)
|
||||
console.print(f"Serving site at: http://{server}:{port} - Tap CTRL-C to stop")
|
||||
httpd.serve_forever()
|
||||
except Exception as e:
|
||||
if excqueue is not None:
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ class Content:
|
|||
def _expand_settings(self, key, klass=None):
|
||||
if not klass:
|
||||
klass = self.__class__.__name__
|
||||
fq_key = ("{}_{}".format(klass, key)).upper()
|
||||
fq_key = (f"{klass}_{key}").upper()
|
||||
return str(self.settings[fq_key]).format(**self.url_format)
|
||||
|
||||
def get_url_setting(self, key):
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class Page:
|
|||
self.settings = settings
|
||||
|
||||
def __repr__(self):
|
||||
return "<Page {} of {}>".format(self.number, self.paginator.num_pages)
|
||||
return f"<Page {self.number} of {self.paginator.num_pages}>"
|
||||
|
||||
def has_next(self):
|
||||
return self.number < self.paginator.num_pages
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ def plugin_enabled(name, plugin_list=None):
|
|||
# search name as is
|
||||
return True
|
||||
|
||||
if "pelican.plugins.{}".format(name) in plugin_list:
|
||||
if f"pelican.plugins.{name}" in plugin_list:
|
||||
# check if short name is a namespace plugin
|
||||
return True
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ def load_legacy_plugin(plugin, plugin_paths):
|
|||
# If failed, try to find it in normal importable locations
|
||||
spec = importlib.util.find_spec(plugin)
|
||||
if spec is None:
|
||||
raise ImportError("Cannot import plugin `{}`".format(plugin))
|
||||
raise ImportError(f"Cannot import plugin `{plugin}`")
|
||||
else:
|
||||
# Avoid loading the same plugin twice
|
||||
if spec.name in sys.modules:
|
||||
|
|
@ -106,8 +106,8 @@ def load_plugins(settings):
|
|||
# try to find in namespace plugins
|
||||
if plugin in namespace_plugins:
|
||||
plugin = namespace_plugins[plugin]
|
||||
elif "pelican.plugins.{}".format(plugin) in namespace_plugins:
|
||||
plugin = namespace_plugins["pelican.plugins.{}".format(plugin)]
|
||||
elif f"pelican.plugins.{plugin}" in namespace_plugins:
|
||||
plugin = namespace_plugins[f"pelican.plugins.{plugin}"]
|
||||
# try to import it
|
||||
else:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ class HTMLReader(BaseReader):
|
|||
self._in_body = False
|
||||
self._in_top_level = True
|
||||
elif self._in_body:
|
||||
self._data_buffer += "</{}>".format(escape(tag))
|
||||
self._data_buffer += f"</{escape(tag)}>"
|
||||
|
||||
def handle_startendtag(self, tag, attrs):
|
||||
if tag == "meta" and self._in_head:
|
||||
|
|
@ -410,28 +410,28 @@ class HTMLReader(BaseReader):
|
|||
self._data_buffer += self.build_tag(tag, attrs, True)
|
||||
|
||||
def handle_comment(self, data):
|
||||
self._data_buffer += "<!--{}-->".format(data)
|
||||
self._data_buffer += f"<!--{data}-->"
|
||||
|
||||
def handle_data(self, data):
|
||||
self._data_buffer += data
|
||||
|
||||
def handle_entityref(self, data):
|
||||
self._data_buffer += "&{};".format(data)
|
||||
self._data_buffer += f"&{data};"
|
||||
|
||||
def handle_charref(self, data):
|
||||
self._data_buffer += "&#{};".format(data)
|
||||
self._data_buffer += f"&#{data};"
|
||||
|
||||
def build_tag(self, tag, attrs, close_tag):
|
||||
result = "<{}".format(escape(tag))
|
||||
result = f"<{escape(tag)}"
|
||||
for k, v in attrs:
|
||||
result += " " + escape(k)
|
||||
if v is not None:
|
||||
# If the attribute value contains a double quote, surround
|
||||
# with single quotes, otherwise use double quotes.
|
||||
if '"' in v:
|
||||
result += "='{}'".format(escape(v, quote=False))
|
||||
result += f"='{escape(v, quote=False)}'"
|
||||
else:
|
||||
result += '="{}"'.format(escape(v, quote=False))
|
||||
result += f'="{escape(v, quote=False)}"'
|
||||
if close_tag:
|
||||
return result + " />"
|
||||
return result + ">"
|
||||
|
|
@ -439,7 +439,7 @@ class HTMLReader(BaseReader):
|
|||
def _handle_meta_tag(self, attrs):
|
||||
name = self._attr_value(attrs, "name")
|
||||
if name is None:
|
||||
attr_list = ['{}="{}"'.format(k, v) for k, v in attrs]
|
||||
attr_list = [f'{k}="{v}"' for k, v in attrs]
|
||||
attr_serialized = ", ".join(attr_list)
|
||||
logger.warning(
|
||||
"Meta tag in file %s does not have a 'name' "
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ def _printf_s_to_format_field(printf_string, format_field):
|
|||
format_field
|
||||
)
|
||||
if result.format(**{format_field: TEST_STRING}) != expected:
|
||||
raise ValueError("Failed to safely replace %s with {{{}}}".format(format_field))
|
||||
raise ValueError(f"Failed to safely replace %s with {{{format_field}}}")
|
||||
|
||||
return result
|
||||
|
||||
|
|
@ -350,9 +350,9 @@ def handle_deprecated_settings(settings):
|
|||
),
|
||||
]:
|
||||
if old in settings:
|
||||
message = "The {} setting has been removed in favor of {}".format(old, new)
|
||||
message = f"The {old} setting has been removed in favor of {new}"
|
||||
if doc:
|
||||
message += ", see {} for details".format(doc)
|
||||
message += f", see {doc} for details"
|
||||
logger.warning(message)
|
||||
|
||||
# PAGINATED_DIRECT_TEMPLATES -> PAGINATED_TEMPLATES
|
||||
|
|
|
|||
|
|
@ -61,6 +61,6 @@ def test_sdist_contents(pytestconfig, expected_file):
|
|||
filtered_values = [
|
||||
path
|
||||
for path in files_list
|
||||
if match(f"^pelican-\d\.\d\.\d/{expected_file}{dir_matcher}$", path)
|
||||
if match(rf"^pelican-\d\.\d\.\d/{expected_file}{dir_matcher}$", path)
|
||||
]
|
||||
assert len(filtered_values) > 0
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ def skipIfNoExecutable(executable):
|
|||
res = None
|
||||
|
||||
if res is None:
|
||||
return unittest.skip("{} executable not found".format(executable))
|
||||
return unittest.skip(f"{executable} executable not found")
|
||||
|
||||
return lambda func: func
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,7 @@ class ReaderTest(unittest.TestCase):
|
|||
% (key, value, real_value),
|
||||
)
|
||||
else:
|
||||
self.fail(
|
||||
"Expected %s to have value %s, but was not in Dict" % (key, value)
|
||||
)
|
||||
self.fail(f"Expected {key} to have value {value}, but was not in Dict")
|
||||
|
||||
|
||||
class TestAssertDictHasSubset(ReaderTest):
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ class TestSettingsConfiguration(unittest.TestCase):
|
|||
|
||||
def test__printf_s_to_format_field(self):
|
||||
for s in ("%s", "{%s}", "{%s"):
|
||||
option = "foo/{}/bar.baz".format(s)
|
||||
option = f"foo/{s}/bar.baz"
|
||||
result = _printf_s_to_format_field(option, "slug")
|
||||
expected = option % "qux"
|
||||
found = result.format(slug="qux")
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def decode_wp_content(content, br=True):
|
|||
if start == -1:
|
||||
content = content + pre_part
|
||||
continue
|
||||
name = "<pre wp-pre-tag-{}></pre>".format(pre_index)
|
||||
name = f"<pre wp-pre-tag-{pre_index}></pre>"
|
||||
pre_tags[name] = pre_part[start:] + "</pre>"
|
||||
content = content + pre_part[0:start] + name
|
||||
pre_index += 1
|
||||
|
|
@ -765,7 +765,7 @@ def download_attachments(output_path, urls):
|
|||
|
||||
if not os.path.exists(full_path):
|
||||
os.makedirs(full_path)
|
||||
print("downloading {}".format(filename))
|
||||
print(f"downloading {filename}")
|
||||
try:
|
||||
urlretrieve(url, os.path.join(full_path, filename))
|
||||
locations[url] = os.path.join(localpath, filename)
|
||||
|
|
@ -782,7 +782,7 @@ def is_pandoc_needed(in_markup):
|
|||
def get_pandoc_version():
|
||||
cmd = ["pandoc", "--version"]
|
||||
try:
|
||||
output = subprocess.check_output(cmd, universal_newlines=True)
|
||||
output = subprocess.check_output(cmd, text=True)
|
||||
except (subprocess.CalledProcessError, OSError) as e:
|
||||
logger.warning("Pandoc version unknown: %s", e)
|
||||
return ()
|
||||
|
|
@ -898,7 +898,7 @@ def fields2pelican(
|
|||
new_content = decode_wp_content(content)
|
||||
else:
|
||||
paragraphs = content.splitlines()
|
||||
paragraphs = ["<p>{}</p>".format(p) for p in paragraphs]
|
||||
paragraphs = [f"<p>{p}</p>" for p in paragraphs]
|
||||
new_content = "".join(paragraphs)
|
||||
with open(html_filename, "w", encoding="utf-8") as fp:
|
||||
fp.write(new_content)
|
||||
|
|
|
|||
|
|
@ -90,9 +90,9 @@ def ask(question, answer=str, default=None, length=None):
|
|||
r = ""
|
||||
while True:
|
||||
if default:
|
||||
r = input("> {} [{}] ".format(question, default))
|
||||
r = input(f"> {question} [{default}] ")
|
||||
else:
|
||||
r = input("> {} ".format(question))
|
||||
r = input(f"> {question} ")
|
||||
|
||||
r = r.strip()
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ def ask(question, answer=str, default=None, length=None):
|
|||
print("You must enter something")
|
||||
else:
|
||||
if length and len(r) != length:
|
||||
print("Entry must be {} characters long".format(length))
|
||||
print(f"Entry must be {length} characters long")
|
||||
else:
|
||||
break
|
||||
|
||||
|
|
@ -114,11 +114,11 @@ def ask(question, answer=str, default=None, length=None):
|
|||
r = None
|
||||
while True:
|
||||
if default is True:
|
||||
r = input("> {} (Y/n) ".format(question))
|
||||
r = input(f"> {question} (Y/n) ")
|
||||
elif default is False:
|
||||
r = input("> {} (y/N) ".format(question))
|
||||
r = input(f"> {question} (y/N) ")
|
||||
else:
|
||||
r = input("> {} (y/n) ".format(question))
|
||||
r = input(f"> {question} (y/n) ")
|
||||
|
||||
r = r.strip().lower()
|
||||
|
||||
|
|
@ -138,9 +138,9 @@ def ask(question, answer=str, default=None, length=None):
|
|||
r = None
|
||||
while True:
|
||||
if default:
|
||||
r = input("> {} [{}] ".format(question, default))
|
||||
r = input(f"> {question} [{default}] ")
|
||||
else:
|
||||
r = input("> {} ".format(question))
|
||||
r = input(f"> {question} ")
|
||||
|
||||
r = r.strip()
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ def render_jinja_template(tmpl_name: str, tmpl_vars: Mapping, target_path: str):
|
|||
_template = _jinja_env.get_template(tmpl_name)
|
||||
fd.write(_template.render(**tmpl_vars))
|
||||
except OSError as e:
|
||||
print("Error: {}".format(e))
|
||||
print(f"Error: {e}")
|
||||
|
||||
|
||||
def main():
|
||||
|
|
@ -376,12 +376,12 @@ needed by Pelican.
|
|||
try:
|
||||
os.makedirs(os.path.join(CONF["basedir"], "content"))
|
||||
except OSError as e:
|
||||
print("Error: {}".format(e))
|
||||
print(f"Error: {e}")
|
||||
|
||||
try:
|
||||
os.makedirs(os.path.join(CONF["basedir"], "output"))
|
||||
except OSError as e:
|
||||
print("Error: {}".format(e))
|
||||
print(f"Error: {e}")
|
||||
|
||||
conf_python = dict()
|
||||
for key, value in CONF.items():
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ def main():
|
|||
"-V",
|
||||
"--version",
|
||||
action="version",
|
||||
version="pelican-themes v{}".format(__version__),
|
||||
version=f"pelican-themes v{__version__}",
|
||||
help="Print the version of this script",
|
||||
)
|
||||
|
||||
|
|
@ -224,7 +224,7 @@ def install(path, v=False, u=False):
|
|||
install(path, v)
|
||||
else:
|
||||
if v:
|
||||
print("Copying '{p}' to '{t}' ...".format(p=path, t=theme_path))
|
||||
print(f"Copying '{path}' to '{theme_path}' ...")
|
||||
try:
|
||||
shutil.copytree(path, theme_path)
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ def symlink(path, v=False):
|
|||
err(path + " : already exists")
|
||||
else:
|
||||
if v:
|
||||
print("Linking `{p}' to `{t}' ...".format(p=path, t=theme_path))
|
||||
print(f"Linking `{path}' to `{theme_path}' ...")
|
||||
try:
|
||||
os.symlink(path, theme_path)
|
||||
except Exception as e:
|
||||
|
|
@ -288,12 +288,12 @@ def clean(v=False):
|
|||
path = os.path.join(_THEMES_PATH, path)
|
||||
if os.path.islink(path) and is_broken_link(path):
|
||||
if v:
|
||||
print("Removing {}".format(path))
|
||||
print(f"Removing {path}")
|
||||
try:
|
||||
os.remove(path)
|
||||
except OSError:
|
||||
print("Error: cannot remove {}".format(path))
|
||||
print(f"Error: cannot remove {path}")
|
||||
else:
|
||||
c += 1
|
||||
|
||||
print("\nRemoved {} broken links".format(c))
|
||||
print(f"\nRemoved {c} broken links")
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class URLWrapper:
|
|||
@property
|
||||
def slug(self):
|
||||
if self._slug is None:
|
||||
class_key = "{}_REGEX_SUBSTITUTIONS".format(self.__class__.__name__.upper())
|
||||
class_key = f"{self.__class__.__name__.upper()}_REGEX_SUBSTITUTIONS"
|
||||
regex_subs = self.settings.get(
|
||||
class_key, self.settings.get("SLUG_REGEX_SUBSTITUTIONS", [])
|
||||
)
|
||||
|
|
@ -60,7 +60,7 @@ class URLWrapper:
|
|||
return hash(self.slug)
|
||||
|
||||
def _normalize_key(self, key):
|
||||
class_key = "{}_REGEX_SUBSTITUTIONS".format(self.__class__.__name__.upper())
|
||||
class_key = f"{self.__class__.__name__.upper()}_REGEX_SUBSTITUTIONS"
|
||||
regex_subs = self.settings.get(
|
||||
class_key, self.settings.get("SLUG_REGEX_SUBSTITUTIONS", [])
|
||||
)
|
||||
|
|
@ -98,7 +98,7 @@ class URLWrapper:
|
|||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
return "<{} {}>".format(type(self).__name__, repr(self._name))
|
||||
return f"<{type(self).__name__} {repr(self._name)}>"
|
||||
|
||||
def _from_settings(self, key, get_page_name=False):
|
||||
"""Returns URL information as defined in settings.
|
||||
|
|
@ -108,7 +108,7 @@ class URLWrapper:
|
|||
"cat/{slug}" Useful for pagination.
|
||||
|
||||
"""
|
||||
setting = "{}_{}".format(self.__class__.__name__.upper(), key)
|
||||
setting = f"{self.__class__.__name__.upper()}_{key}"
|
||||
value = self.settings[setting]
|
||||
if isinstance(value, pathlib.Path):
|
||||
value = str(value)
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ def sanitised_join(base_directory, *parts):
|
|||
joined = posixize_path(os.path.abspath(os.path.join(base_directory, *parts)))
|
||||
base = posixize_path(os.path.abspath(base_directory))
|
||||
if not joined.startswith(base):
|
||||
raise RuntimeError(
|
||||
"Attempted to break out of output directory to {}".format(joined)
|
||||
)
|
||||
raise RuntimeError(f"Attempted to break out of output directory to {joined}")
|
||||
|
||||
return joined
|
||||
|
||||
|
|
@ -71,7 +69,7 @@ def strftime(date, date_format):
|
|||
# check for '-' prefix
|
||||
if len(candidate) == 3:
|
||||
# '-' prefix
|
||||
candidate = "%{}".format(candidate[-1])
|
||||
candidate = f"%{candidate[-1]}"
|
||||
conversion = strip_zeros
|
||||
else:
|
||||
conversion = None
|
||||
|
|
@ -178,11 +176,11 @@ def deprecated_attribute(old, new, since=None, remove=None, doc=None):
|
|||
|
||||
def _warn():
|
||||
version = ".".join(str(x) for x in since)
|
||||
message = ["{} has been deprecated since {}".format(old, version)]
|
||||
message = [f"{old} has been deprecated since {version}"]
|
||||
if remove:
|
||||
version = ".".join(str(x) for x in remove)
|
||||
message.append(" and will be removed by version {}".format(version))
|
||||
message.append(". Use {} instead.".format(new))
|
||||
message.append(f" and will be removed by version {version}")
|
||||
message.append(f". Use {new} instead.")
|
||||
logger.warning("".join(message))
|
||||
logger.debug("".join(str(x) for x in traceback.format_stack()))
|
||||
|
||||
|
|
@ -210,7 +208,7 @@ def get_date(string):
|
|||
try:
|
||||
return dateutil.parser.parse(string, default=default)
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError("{!r} is not a valid date".format(string))
|
||||
raise ValueError(f"{string!r} is not a valid date")
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
|
@ -763,9 +761,9 @@ def order_content(content_list, order_by="slug"):
|
|||
def wait_for_changes(settings_file, reader_class, settings):
|
||||
content_path = settings.get("PATH", "")
|
||||
theme_path = settings.get("THEME", "")
|
||||
ignore_files = set(
|
||||
ignore_files = {
|
||||
fnmatch.translate(pattern) for pattern in settings.get("IGNORE_FILES", [])
|
||||
)
|
||||
}
|
||||
|
||||
candidate_paths = [
|
||||
settings_file,
|
||||
|
|
@ -838,7 +836,7 @@ def split_all(path):
|
|||
return None
|
||||
else:
|
||||
raise TypeError(
|
||||
'"path" was {}, must be string, None, or pathlib.Path'.format(type(path))
|
||||
f'"path" was {type(path)}, must be string, None, or pathlib.Path'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -873,7 +871,7 @@ def maybe_pluralize(count, singular, plural):
|
|||
selection = plural
|
||||
if count == 1:
|
||||
selection = singular
|
||||
return "{} {}".format(count, selection)
|
||||
return f"{count} {selection}"
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue