From cbe6c08f444cb583c835830903c4adea57a6d20d Mon Sep 17 00:00:00 2001 From: boxydog Date: Fri, 31 May 2024 08:48:32 -0500 Subject: [PATCH 1/2] Don't ignore ruff B007, RUF015, PLR1722 --- pyproject.toml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b7e39a4a3..606a05bac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -168,7 +168,6 @@ select = [ ignore = [ # suppression in order of # of violations in Dec 2023: - "B007", # unused-loop-control-variable "T201", # print "PLW2901", # redefined-loop-name "SLF001", # private-member-access @@ -176,12 +175,18 @@ ignore = [ "PLR2004", # magic-value-comparison "PLR0912", # too-many-branches "PLR0913", # too-many-arguments + # RUF005: this is a different style of concatenating literals. It perhaps performs + # a bit better, but doesn't seem any more readable to me. So, ignore it. "RUF005", # collection-literal-concatenation + # TODO: several classes have class variables. If that is correct, we should + # annotate them with ClassVar. + # See https://docs.astral.sh/ruff/rules/mutable-class-default/ "RUF012", # mutable-class-default "PLR0915", # too-many-statements + # Note: we have a couple of "namespace packages" (i.e. missing __init__.py) + # Not sure if we should add __init__.py to them, or they really need to be + # namespace packages. "INP001", # implicit-namespace-package - "RUF015", # unnecessary-iterable-allocation-for-first-element - "PLR1722", # sys-exit-alias # ruff-format wants us to ignore ISC001. I don't love that, but okay. # "warning: The following rules may cause conflicts when used with the formatter: # `ISC001`. To avoid unexpected behavior, we recommend disabling these rules, From 9b77a9027bea3596c9ced8ba4890c2928e978ce1 Mon Sep 17 00:00:00 2001 From: boxydog Date: Fri, 31 May 2024 08:48:44 -0500 Subject: [PATCH 2/2] File fixes for ruff B007, RUF015, PLR1722 --- pelican/tests/test_importer.py | 72 ++++++++++++++++----------------- pelican/tests/test_utils.py | 11 ++--- pelican/tools/pelican_import.py | 12 +++--- pelican/utils.py | 2 +- pelican/writers.py | 2 +- 5 files changed, 48 insertions(+), 51 deletions(-) diff --git a/pelican/tests/test_importer.py b/pelican/tests/test_importer.py index 46d83432f..b00970f4a 100644 --- a/pelican/tests/test_importer.py +++ b/pelican/tests/test_importer.py @@ -108,15 +108,15 @@ def test_ignore_empty_posts(self): self.assertTrue(self.posts) for ( title, - content, - fname, - date, - author, - categ, - tags, - status, - kind, - format, + _content, + _fname, + _date, + _author, + _categ, + _tags, + _status, + _kind, + _format, ) in self.posts: self.assertTrue(title.strip()) @@ -127,15 +127,15 @@ def test_recognise_page_kind(self): pages_data = [] for ( title, - content, + _content, fname, - date, - author, - categ, - tags, - status, + _date, + _author, + _categ, + _tags, + _status, kind, - format, + _format, ) in self.posts: if kind == "page": pages_data.append((title, fname)) @@ -147,7 +147,7 @@ def test_dirpage_directive_for_page_kind(self): silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Empty Page"), self.posts) with temporary_folder() as temp: - fname = list(silent_f2p(test_post, "markdown", temp, dirpage=True))[0] + fname = next(iter(silent_f2p(test_post, "markdown", temp, dirpage=True))) self.assertTrue(fname.endswith("pages%sempty.md" % os.path.sep)) def test_dircat(self): @@ -176,15 +176,15 @@ def test_unless_custom_post_all_items_should_be_pages_or_posts(self): pages_data = [] for ( title, - content, + _content, fname, - date, - author, - categ, - tags, - status, + _date, + _author, + _categ, + _tags, + _status, kind, - format, + _format, ) in self.posts: if kind in {"page", "article"}: pass @@ -197,15 +197,15 @@ def test_recognise_custom_post_type(self): cust_data = [] for ( title, - content, - fname, - date, - author, - categ, - tags, - status, + _content, + _fname, + _date, + _author, + _categ, + _tags, + _status, kind, - format, + _format, ) in self.custposts: if kind in {"page", "article"}: pass @@ -346,7 +346,7 @@ def r(f): silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Code in List"), self.posts) with temporary_folder() as temp: - md = [r(f) for f in silent_f2p(test_post, "markdown", temp)][0] + md = next(r(f) for f in silent_f2p(test_post, "markdown", temp)) self.assertTrue(re.search(r"\s+a = \[1, 2, 3\]", md)) self.assertTrue(re.search(r"\s+b = \[4, 5, 6\]", md)) @@ -362,7 +362,7 @@ def r(f): silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Code in List"), self.posts) with temporary_folder() as temp: - md = [r(f) for f in silent_f2p(test_post, "markdown", temp)][0] + md = next(r(f) for f in silent_f2p(test_post, "markdown", temp)) sample_line = re.search(r"- This is a code sample", md).group(0) code_line = re.search(r"\s+a = \[1, 2, 3\]", md).group(0) self.assertTrue(sample_line.rindex("This") < code_line.rindex("a")) @@ -375,7 +375,7 @@ def r(f): silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Post with raw data"), self.posts) with temporary_folder() as temp: - md = [r(f) for f in silent_f2p(test_post, "markdown", temp)][0] + md = next(r(f) for f in silent_f2p(test_post, "markdown", temp)) escaped_quotes = re.search(r'\\[\'"“”‘’]', md) self.assertFalse(escaped_quotes) @@ -387,7 +387,7 @@ def r(f): silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Caption on image"), self.posts) with temporary_folder() as temp: - md = [r(f) for f in silent_f2p(test_post, "markdown", temp)][0] + md = next(r(f) for f in silent_f2p(test_post, "markdown", temp)) caption = re.search(r"\[caption", md) self.assertFalse(caption) diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index 6c25cf455..beda71406 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -210,13 +210,10 @@ def test_slugify_use_unicode(self): ) # check with preserve case - for value, expected in samples: - self.assertEqual( - utils.slugify( - "Çığ", regex_subs=subs, preserve_case=True, use_unicode=True - ), - "Çığ", - ) + self.assertEqual( + utils.slugify("Çığ", regex_subs=subs, preserve_case=True, use_unicode=True), + "Çığ", + ) # check normalization samples = ( diff --git a/pelican/tools/pelican_import.py b/pelican/tools/pelican_import.py index c9742d54a..39504edbe 100755 --- a/pelican/tools/pelican_import.py +++ b/pelican/tools/pelican_import.py @@ -1070,14 +1070,14 @@ def fields2pelican( rc = subprocess.call(cmd, shell=True) if rc < 0: error = "Child was terminated by signal %d" % -rc - exit(error) + sys.exit(error) elif rc > 0: error = "Please, check your Pandoc installation." - exit(error) + sys.exit(error) except OSError as e: error = "Pandoc execution failed: %s" % e - exit(error) + sys.exit(error) with open(out_filename, encoding="utf-8") as fs: content = fs.read() @@ -1222,18 +1222,18 @@ def main(): "You must provide one of --blogger, --dotclear, " "--medium, --tumblr, --wpfile or --feed options" ) - exit(error) + sys.exit(error) if not os.path.exists(args.output): try: os.mkdir(args.output) except OSError: error = "Unable to create the output folder: " + args.output - exit(error) + sys.exit(error) if args.wp_attach and input_type != "wordpress": error = "You must be importing a wordpress xml to use the --wp-attach option" - exit(error) + sys.exit(error) if input_type == "blogger": fields = blogger2fields(args.input) diff --git a/pelican/utils.py b/pelican/utils.py index b33eaa22a..43acdd7fb 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -483,7 +483,7 @@ def feed(self, *args, **kwargs) -> None: def getoffset(self) -> int: line_start = 0 lineno, line_offset = self.getpos() - for i in range(lineno - 1): + for _ in range(lineno - 1): line_start = self.rawdata.index("\n", line_start) + 1 return line_start + line_offset diff --git a/pelican/writers.py b/pelican/writers.py index 683ae30b5..91b1caebe 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -259,7 +259,7 @@ def _get_localcontext(context, name, kwargs, relative_urls): } # generated pages, and write - for page_num in range(list(paginators.values())[0].num_pages): + for page_num in range(next(iter(paginators.values())).num_pages): paginated_kwargs = kwargs.copy() for key in paginators.keys(): paginator = paginators[key]