From 2a2c1242fa12d5b832caef5e746e2f80b77625a0 Mon Sep 17 00:00:00 2001 From: Alex Verrico Date: Sun, 30 Aug 2026 15:20:16 +1000 Subject: [PATCH 1/3] add ruff & address findings --- .pre-commit-config.yaml | 6 ++++ docs/macros.py | 69 +++++++++++++++++++++++++---------------- pyproject.toml | 29 +++++++++++++++++ scripts/new_post.py | 63 +++++++++++++++++++++++++++---------- 4 files changed, 124 insertions(+), 43 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c41a2c5609..4ba43ec78c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,6 +9,12 @@ repos: # PO files may not have a trailing EOL, as they are tool generated exclude: "locales" - id: trailing-whitespace + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.16.3 + hooks: + - id: ruff-check + args: [ --fix ] + - id: ruff-format - repo: https://github.com/rvben/rumdl-pre-commit rev: v0.2.43 hooks: diff --git a/docs/macros.py b/docs/macros.py index 5783804281..bd308cda5b 100644 --- a/docs/macros.py +++ b/docs/macros.py @@ -1,6 +1,7 @@ import datetime from pathlib import Path from textwrap import dedent + import yaml @@ -54,7 +55,7 @@ def generate_resource_post(resource):
- """) + """) # noqa content.append(video_url) content.append(f"""{resource["description"]}\n""") @@ -87,7 +88,7 @@ def generate_resource_post(resource): elif resource["type"] == "video" and resource["embeddable"]: content.append( - f"\n\nAs seen at [{resource['event_name']}]({resource['event_url']}).\n\n" + f"\n\nAs seen at [{resource['event_name']}]({resource['event_url']}).\n\n" # noqa ) content.append("") @@ -110,26 +111,30 @@ def generate_event_post(authors, event, involvement, team): show_participation = False for inv in involvement: if inv["type"] == "organizing": - highlight_authors.update({m for m in inv["team_members"]}) + highlight_authors.update(set(inv["team_members"])) content.append( dedent(f"""\ {attendees(inv["team_members"], team)} will be organizing [{event.name}]({event.url}), which will happen {event_timeframe}!\n\n - """) + """) # noqa ) elif inv["type"] == "keynote": - highlight_authors.update({m for m in inv["team_members"]}) - content.append(dedent(f""" + highlight_authors.update(set(inv["team_members"])) + content.append( + dedent(f""" {attendees(inv["team_members"], team)} will be keynoting {event.name}, giving a presentation entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) \n\n - """)) + """) # noqa + ) elif inv["type"] != "attending": show_participation = True inv_types = {inv["type"] for inv in involvement} if "keynote" in inv_types or "organizing" in inv_types: - other_authors = [author for author in authors if author not in highlight_authors] + other_authors = [ + author for author in authors if author not in highlight_authors + ] if other_authors: content.append( dedent(f"""\ @@ -144,19 +149,22 @@ def generate_event_post(authors, event, involvement, team): {attendees(authors, team)} will be attending [{event.name}]({event.url}) {event_timeframe}! \n\n - """) + """) # noqa ) content.append(f"{event.description}\n\n") - _, first_pronoun, second_pronoun = pronouns(team["authors"][authors[-1]]["pronoun"]) - + _, first_pronoun, second_pronoun = pronouns( + team["authors"][authors[-1]]["pronoun"] + ) if show_participation: if len(authors) > 1: - content.append(f"You can find us throughout the event:\n\n") + content.append("You can find us throughout the event:\n\n") else: - content.append(f"You can find {second_pronoun} throughout the event:\n\n") + content.append( + f"You can find {second_pronoun} throughout the event:\n\n" + ) for inv in involvement: if len(authors) > 1: @@ -165,24 +173,26 @@ def generate_event_post(authors, event, involvement, team): team_members = first_pronoun.capitalize() if inv["type"] == "talk": - talk = dedent(f""" + talk = dedent( + f""" - {team_members} will be giving a talk entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """) + """ # noqa + ) content.append(talk) elif inv["type"] == "tutorial": tutorial = dedent(f""" - {team_members} will be hosting a tutorial entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """) + """) # noqa content.append(tutorial) elif inv["type"] == "workshop": tutorial = dedent(f""" - {team_members} will be hosting a workshop entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """) + """) # noqa content.append(tutorial) elif inv["type"] == "sprint": @@ -203,7 +213,7 @@ def generate_event_post(authors, event, involvement, team): tutorial = dedent(f""" - {team_members} will be hosting the [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """) + """) # noqa content.append(tutorial) if len(authors) > 1: @@ -216,11 +226,11 @@ def generate_event_post(authors, event, involvement, team): f"Please come say hello, {first_pronoun}'d love to meet you. " ) if first_pronoun == "he": - content.append(f"He's looking forward to seeing you there!") + content.append("He's looking forward to seeing you there!") elif first_pronoun == "she": - content.append(f"She's looking forward to seeing you there!") + content.append("She's looking forward to seeing you there!") elif first_pronoun == "they": - content.append(f"They're looking forward to seeing you there!") + content.append("They're looking forward to seeing you there!") return "".join(content) @@ -240,14 +250,16 @@ def generate_team_members(team, page, current): try: mastodon = member_details["mastodon"].split("@") - member_image_details_mastodon = f"""
{fa("mastodon", "lg", "brands")} [{member_details["mastodon"]}](https://{mastodon[2]}/@{mastodon[1]})
""" + member_image_details_mastodon = f"""
{fa("mastodon", "lg", "brands")} [{member_details["mastodon"]}](https://{mastodon[2]}/@{mastodon[1]})
""" # noqa except KeyError: member_image_details_mastodon = "" - pronoun_logo, first_pronoun, second_pronoun = pronouns(member_details["pronoun"]) + pronoun_logo, first_pronoun, second_pronoun = pronouns( + member_details["pronoun"] + ) try: - member_email_details = f"""
{fa("envelope", "lg", "solid")} <{member_details["email"]}>
""" + member_email_details = f"""
{fa("envelope", "lg", "solid")} <{member_details["email"]}>
""" # noqa except KeyError: member_email_details = "" @@ -266,14 +278,19 @@ def generate_team_members(team, page, current):
- """ + """ # noqa ) member_bio = ( Path(page.file.src_dir) / f"about/team/{github_id}.md" ).read_text() - team_member = member_title + member_image_details + member_bio + "
" + team_member = ( + member_title + + member_image_details + + member_bio + + "" + ) if not current and "emeritus_date" in member_details: team_member_content.append( diff --git a/pyproject.toml b/pyproject.toml index 6734a71fad..0cc635e009 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,35 @@ translate = [ {include-group = "wlc"}, ] +[tool.ruff.lint] +# In addition to the default rules, these additional rules will be used: +extend-select = [ + "E", # pycodestyle + "W", # pycodestyle + "F", # pyflakes + "UP", # pyupgrade + "B", # flake8-bugbear + "ASYNC", # flake8-async + "C4", # flake8-comprehensions + "I", # isort + # The SIM rules are *very* opinionated, and don't necessarily make for better code. + # They may be worth occasionally turning on just to see if something could actually + # use improvement. + # "SIM", # flake8-simplify +] +# Ignores needed to pass the Ruff 0.16 update. +ignore = [ + "BLE001", + "DTZ001", + "DTZ005", + "DTZ006", + "DTZ011", + "DTZ012", + "RUF009", + # The SIM rules are *very* opinionated, and don't necessarily make for better code. + "SIM102", # collapsible-if makes code (and testing paths) harder to verify. +] + [tool.rumdl] flavor = "mkdocs" include = ["**/*.md"] diff --git a/scripts/new_post.py b/scripts/new_post.py index acb51c6f8a..5e1fb0181d 100644 --- a/scripts/new_post.py +++ b/scripts/new_post.py @@ -1,8 +1,8 @@ +import datetime import re from pathlib import Path -import datetime from textwrap import dedent -from urllib.error import URLError, HTTPError +from urllib.error import HTTPError, URLError from urllib.parse import urlparse from urllib.request import Request, urlopen @@ -62,7 +62,11 @@ def input_date(prompt: str, default: datetime.date | None = None) -> datetime.da if not date and default: return default try: - return datetime.datetime.strptime(date, "%Y-%m-%d").date() + return ( + datetime.datetime.strptime(date, "%Y-%m-%d") + .replace(tzinfo=datetime.UTC) + .date() + ) except ValueError: print("Invalid date format. Must be YYYY-DD-MM format.") @@ -147,27 +151,46 @@ def request_event_metadata(): presentation_title = input("Presentation title: ") involvement_metadata["title"] = presentation_title - if involvement_type in ["keynote", "talk", "tutorial", "workshop", "sprint", "booth", "track"]: + if involvement_type in [ + "keynote", + "talk", + "tutorial", + "workshop", + "sprint", + "booth", + "track", + ]: involvement_metadata["url"] = input_url( f"{involvement_type} URL (leave blank if unavailable): ", event_url ) involvement_metadata["date"] = input_date( - f"Start date of {involvement_type} at {event_name} (e.g. 2026-01-01, leave blank if same as {event_name} start date): ", + f"Start date of {involvement_type} at {event_name} (e.g. 2026-01-01, leave blank if same as {event_name} start date): ", # noqa event_start_date, ) involvement_metadata["end_date"] = input_date( - f"End date of {involvement_type} (e.g. 2026-01-01; leave blank if same as {involvement_type} start date): ", + f"End date of {involvement_type} (e.g. 2026-01-01; leave blank if same as {involvement_type} start date): ", # noqa involvement_metadata["date"], ) - if involvement_type in ["keynote", "talk", "tutorial", "workshop", "sprint", "booth", "track"]: - # if statement duplicated for the purposes of preserving desired metadata order - involvement_metadata["description"] = dedent(f"""\ + if involvement_type in [ + "keynote", + "talk", + "tutorial", + "workshop", + "sprint", + "booth", + "track", + ]: + # if statement duplicated for the purposes of + # preserving desired metadata order + involvement_metadata["description"] = dedent( + f"""\ TODO: Remove this content and update with {involvement_type} description. Description should begin on the line below 'description: |-' with that line left intact. - """) + """ # noqa + ) involvements.append(involvement_metadata) @@ -177,17 +200,19 @@ def request_event_metadata(): return { "title": f"We'll be at {event_name}!", "date": datetime.date.today(), - "authors": sorted(list(authors)), + "authors": sorted(authors), "categories": ["Events"], "event": { "name": event_name, "url": event_url, "date": event_start_date, "end_date": event_end_date, - "description": dedent(f"""\ + "description": dedent( + """\ TODO: Remove this content and update with event description. - Description should begin on the line below 'description: |-' with that line left intact."""), + Description should begin on the line below 'description: |-' with that line left intact.""" # noqa + ), }, "involvement": involvements, } @@ -213,10 +238,12 @@ def request_resource_metadata(): resource_metadata["event_name"] = input("Event name: ") resource_metadata["event_url"] = input_url("Event URL: ") - resource_metadata["description"] = dedent(f"""\ + resource_metadata["description"] = dedent( + """\ TODO: Remove this content and update with resource description. - Description should begin on the line below 'description: |-' with that line left intact.""") + Description should begin on the line below 'description: |-' with that line left intact.""" # noqa + ) authors = set() resource_authors = input( @@ -293,13 +320,15 @@ def generate_entry(metadata, payload): ) if post_type == "blog": metadata = request_blog_metadata() - payload = dedent("""\ + payload = dedent( + """\ Add blog post introduction here. Leave newline between frontmatter and content. - Add blog post content here.""") + Add blog post content here.""" # noqa + ) elif post_type == "event": metadata = request_event_metadata() payload = "\n{{ generate_event_post(authors, event, involvement, team) }}" From 8f4600d2b274c16992751266adee26f94dad0f9c Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Mon, 31 Aug 2026 10:25:38 +0800 Subject: [PATCH 2/3] Narrow some noqa declarations. --- docs/macros.py | 36 +++++++++++++++++++----------------- scripts/new_post.py | 21 +++++++++++++++------ 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/docs/macros.py b/docs/macros.py index bd308cda5b..23606f1b86 100644 --- a/docs/macros.py +++ b/docs/macros.py @@ -53,9 +53,11 @@ def generate_resource_post(resource): if resource["type"] == "video" and resource["embeddable"]: video_url = dedent(f"""\
- +
- """) # noqa + """) content.append(video_url) content.append(f"""{resource["description"]}\n""") @@ -88,7 +90,7 @@ def generate_resource_post(resource): elif resource["type"] == "video" and resource["embeddable"]: content.append( - f"\n\nAs seen at [{resource['event_name']}]({resource['event_url']}).\n\n" # noqa + f"\n\nAs seen at [{resource['event_name']}]({resource['event_url']}).\n\n" # noqa: E501 ) content.append("") @@ -115,7 +117,7 @@ def generate_event_post(authors, event, involvement, team): content.append( dedent(f"""\ {attendees(inv["team_members"], team)} will be organizing [{event.name}]({event.url}), which will happen {event_timeframe}!\n\n - """) # noqa + """) # noqa: E501 ) elif inv["type"] == "keynote": highlight_authors.update(set(inv["team_members"])) @@ -124,7 +126,7 @@ def generate_event_post(authors, event, involvement, team): {attendees(inv["team_members"], team)} will be keynoting {event.name}, giving a presentation entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) \n\n - """) # noqa + """) # noqa: E501 ) elif inv["type"] != "attending": show_participation = True @@ -149,7 +151,7 @@ def generate_event_post(authors, event, involvement, team): {attendees(authors, team)} will be attending [{event.name}]({event.url}) {event_timeframe}! \n\n - """) # noqa + """) # noqa: E501 ) content.append(f"{event.description}\n\n") @@ -177,7 +179,7 @@ def generate_event_post(authors, event, involvement, team): f""" - {team_members} will be giving a talk entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """ # noqa + """ # noqa: E501 ) content.append(talk) @@ -185,14 +187,14 @@ def generate_event_post(authors, event, involvement, team): tutorial = dedent(f""" - {team_members} will be hosting a tutorial entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """) # noqa + """) # noqa: E501 content.append(tutorial) elif inv["type"] == "workshop": tutorial = dedent(f""" - {team_members} will be hosting a workshop entitled [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """) # noqa + """) # noqa: E501 content.append(tutorial) elif inv["type"] == "sprint": @@ -213,7 +215,7 @@ def generate_event_post(authors, event, involvement, team): tutorial = dedent(f""" - {team_members} will be hosting the [{talk_title_punctuation(inv["title"])}]({inv["url"]}) - """) # noqa + """) # noqa: E501 content.append(tutorial) if len(authors) > 1: @@ -250,7 +252,7 @@ def generate_team_members(team, page, current): try: mastodon = member_details["mastodon"].split("@") - member_image_details_mastodon = f"""
{fa("mastodon", "lg", "brands")} [{member_details["mastodon"]}](https://{mastodon[2]}/@{mastodon[1]})
""" # noqa + member_image_details_mastodon = f"""
{fa("mastodon", "lg", "brands")} [{member_details["mastodon"]}](https://{mastodon[2]}/@{mastodon[1]})
""" # noqa: E501 except KeyError: member_image_details_mastodon = "" @@ -259,7 +261,7 @@ def generate_team_members(team, page, current): ) try: - member_email_details = f"""""" # noqa + member_email_details = f"""""" # noqa: E501 except KeyError: member_email_details = "" @@ -269,16 +271,16 @@ def generate_team_members(team, page, current): ![{member_details["name"]}](/{member_details["avatar"]}) -
-
{fa("regular", pronoun_logo)} {first_pronoun}/{second_pronoun}
-
{fa("github", "lg", "brands")} [{github_id}](https://github.com/{github_id})
+
+
{fa("regular", pronoun_logo)} {first_pronoun}/{second_pronoun}
+
{fa("github", "lg", "brands")} [{github_id}](https://github.com/{github_id})
{member_image_details_mastodon} {member_email_details} -
+
- """ # noqa + """ # noqa: E501 ) member_bio = ( diff --git a/scripts/new_post.py b/scripts/new_post.py index 5e1fb0181d..9bd20def04 100644 --- a/scripts/new_post.py +++ b/scripts/new_post.py @@ -165,11 +165,17 @@ def request_event_metadata(): ) involvement_metadata["date"] = input_date( - f"Start date of {involvement_type} at {event_name} (e.g. 2026-01-01, leave blank if same as {event_name} start date): ", # noqa + ( + f"Start date of {involvement_type} at {event_name} " + f"(e.g. 2026-01-01, leave blank if same as {event_name} start date): " + ), event_start_date, ) involvement_metadata["end_date"] = input_date( - f"End date of {involvement_type} (e.g. 2026-01-01; leave blank if same as {involvement_type} start date): ", # noqa + ( + f"End date of {involvement_type} (e.g. 2026-01-01; " + f"leave blank if same as {involvement_type} start date): " + ), involvement_metadata["date"], ) @@ -189,7 +195,7 @@ def request_event_metadata(): TODO: Remove this content and update with {involvement_type} description. Description should begin on the line below 'description: |-' with that line left intact. - """ # noqa + """ # noqa: E501 ) involvements.append(involvement_metadata) @@ -211,7 +217,8 @@ def request_event_metadata(): """\ TODO: Remove this content and update with event description. - Description should begin on the line below 'description: |-' with that line left intact.""" # noqa + Description should begin on the line below 'description: |-' with that line left intact. + """ # noqa: E501 ), }, "involvement": involvements, @@ -242,7 +249,8 @@ def request_resource_metadata(): """\ TODO: Remove this content and update with resource description. - Description should begin on the line below 'description: |-' with that line left intact.""" # noqa + Description should begin on the line below 'description: |-' with that line left intact. + """ # noqa: E501 ) authors = set() @@ -327,7 +335,8 @@ def generate_entry(metadata, payload): - Add blog post content here.""" # noqa + Add blog post content here. + """ # noqa: E501 ) elif post_type == "event": metadata = request_event_metadata() From 7b075eb70d97c0222c75e9562b4efdac6ab3dd5e Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Mon, 31 Aug 2026 10:37:23 +0800 Subject: [PATCH 3/3] Indentation in markdown matters... --- docs/macros.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/macros.py b/docs/macros.py index 23606f1b86..653c8ada44 100644 --- a/docs/macros.py +++ b/docs/macros.py @@ -271,12 +271,12 @@ def generate_team_members(team, page, current): ![{member_details["name"]}](/{member_details["avatar"]}) -
-
{fa("regular", pronoun_logo)} {first_pronoun}/{second_pronoun}
-
{fa("github", "lg", "brands")} [{github_id}](https://github.com/{github_id})
+
+
{fa("regular", pronoun_logo)} {first_pronoun}/{second_pronoun}
+
{fa("github", "lg", "brands")} [{github_id}](https://github.com/{github_id})
{member_image_details_mastodon} {member_email_details} -
+