feat/strict-pyright (#5451)
continuous-integration/drone/push Build is passing

- enable pyright strict mode
- fix the issues raised

This should make the build process cleaner and more resilient.
It should make it much easier to catch design flaws.

Co-authored-by: Darragh Elliott <me@delliott.net>
Reviewed-on: #5451
Reviewed-by: tobiasd <tobiasd@fsfe.org>
Co-authored-by: delliott <delliott@fsfe.org>
Co-committed-by: delliott <delliott@fsfe.org>
This commit was merged in pull request #5451.
This commit is contained in:
2025-11-03 08:53:49 +00:00
committed by tobiasd
parent d563fb9fbe
commit b5256f8812
23 changed files with 46 additions and 49 deletions
+3 -8
View File
@@ -14,14 +14,9 @@ from lxml import etree
logger = logging.getLogger(__name__)
def keys_exists(element: dict, *keys: str) -> bool:
def keys_exists(element: dict[Any, Any], *keys: str) -> bool:
"""Check if *keys (nested) exists in `element` (dict)."""
if not isinstance(element, dict):
message = "keys_exists() expects dict as first argument."
logger.error(message)
raise TypeError(message)
_element = element
_element = element # make a copy to prevent manipulating up the scope
for key in keys:
try:
_element = _element[key]
@@ -83,7 +78,7 @@ def lang_from_filename(file: Path) -> str:
return lang
def run_command(commands: list) -> str:
def run_command(commands: list[str]) -> str:
"""Run the passed command.
Useful to standardise how we manage output,
+6 -7
View File
@@ -8,6 +8,7 @@ import logging
import re
from datetime import datetime
from pathlib import Path
from typing import Any
from lxml import etree
@@ -16,14 +17,14 @@ from fsfe_website_build.lib.misc import get_basename, get_version, lang_from_fil
logger = logging.getLogger(__name__)
def _get_xmls(file: Path, parser: etree.XMLParser) -> list:
def _get_xmls(file: Path, parser: etree.XMLParser) -> list[etree.Element]:
"""Include second level elements of a given XML file.
This emulates the behaviour of the original
build script which wasn't able to load top
level elements from any file
"""
elements = []
elements: list[etree.Element] = []
if file.exists():
tree = etree.parse(file, parser)
root = tree.getroot()
@@ -38,7 +39,7 @@ def _get_xmls(file: Path, parser: etree.XMLParser) -> list:
return elements
def _get_attributes(file: Path) -> dict:
def _get_attributes(file: Path) -> dict[str, Any]:
"""Get attributes of top level element in a given XHTML file."""
tree = etree.parse(file)
root = tree.getroot()
@@ -194,9 +195,7 @@ def _build_xmlstream(
return page
def process_file(
source: Path, infile: Path, transform: etree.XSLT
) -> etree._XSLTResultTree:
def process_file(source: Path, infile: Path, transform: etree.XSLT) -> str:
"""Process a given file using the correct xsl sheet."""
logger.debug("Processing %s", infile)
lang = lang_from_filename(infile)
@@ -237,4 +236,4 @@ def process_file(
)
except AssertionError:
logger.debug("Output generated for file %s is not valid xml", infile)
return result
return str(result)
@@ -26,7 +26,7 @@ def prepare_early_subdirectories(
# here for out subdir scripts
import early_subdir # noqa: PLC0415 # pyright: ignore [reportMissingImports]
early_subdir.run(source, processes, subdir_path)
early_subdir.run(source, processes, subdir_path) # pyright: ignore [reportUnknownMemberType]
# Remove its path from where things can be imported
sys.path.remove(str(subdir_path.resolve()))
# Remove it from loaded modules
@@ -30,7 +30,7 @@ def prepare_subdirectories(
# here for out subdir scripts
import subdir # noqa: PLC0415 # pyright: ignore [reportMissingImports]
subdir.run(source, languages, processes, subdir_path)
subdir.run(source, languages, processes, subdir_path) # pyright: ignore [reportUnknownMemberType]
# Remove its path from where things can be imported
sys.path.remove(str(subdir_path.resolve()))
# Remove it from loaded modules
@@ -11,7 +11,7 @@ distributed to the web server.
import logging
from pathlib import Path
import minify
import minify # pyright: ignore [reportMissingTypeStubs]
from fsfe_website_build.lib.misc import run_command, update_if_changed
@@ -40,7 +40,7 @@ def _update_for_base( # noqa: PLR0913
lastyear: str,
) -> None:
"""Update the xmllist for a given base file."""
matching_files = set()
matching_files: set[str] = set()
# If sources exist
if base.with_suffix(".sources").exists():
# Load every file that matches the pattern
@@ -94,7 +94,7 @@ def _update_for_base( # noqa: PLR0913
matching_files.add(
f"{source}/global/data/modules/{module.get('id').strip()}"
)
matching_files = sorted(matching_files)
matching_files = set(sorted(matching_files)) # noqa: C414
update_if_changed(
Path(f"{base.parent}/.{base.name}.xmllist"),
("\n".join(matching_files) + "\n") if matching_files else "",
@@ -139,7 +139,7 @@ def _update_module_xmllists(
def _check_xmllist_deps(source: Path, file: Path) -> None:
"""If any of the sources in an xmllist are newer than it, touch the xmllist."""
xmls = set()
xmls: set[Path] = set()
with file.open(mode="r") as fileobj:
for line in fileobj:
path_line = source.joinpath(line.strip())
@@ -73,7 +73,7 @@ def _process_set( # noqa: PLR0913
logger.debug("Building %s", target_file)
result = process_file(source, source_file, transform)
target_file.parent.mkdir(parents=True, exist_ok=True)
result.write_output(target_file)
target_file.write_text(result)
def process_files(
@@ -19,14 +19,14 @@ logger = logging.getLogger(__name__)
def _run_webserver(path: str, port: int) -> None:
"""Given a path and a port it will serve that dir on that localhost:port."""
os.chdir(path)
handler = http.server.CGIHTTPRequestHandler
handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", port), handler) as httpd:
httpd.serve_forever()
def serve_websites(
serve_dir: Path, sites: list, base_port: int, increment_number: int
serve_dir: Path, sites: list[Path], base_port: int, increment_number: int
) -> None:
"""Serve the sites in serve_dir from base port.
@@ -40,7 +40,7 @@ def serve_websites(
for path in Path(serve_dir).iterdir()
if (path.is_dir() and (path.name in site_names))
)
serves = []
serves: list[tuple[str, int]] = []
for index, directory in enumerate(dirs):
port = base_port + (increment_number * index)
url = f"http://127.0.0.1:{port}"
View File
@@ -70,8 +70,8 @@ def process_file_link_rewrites_test(
assert isinstance(sample_xsl_transformer, etree.XSLT)
result_doc = process_file(Path(), xml_path, sample_xsl_transformer)
assert isinstance(result_doc, etree._XSLTResultTree)
assert isinstance(result_doc, str)
# We get a list, but as we have only one link in the above sample
# we only need to care about the first one
link_node = result_doc.xpath("//a[@href and @test_url]")[0]
link_node = etree.fromstring(result_doc).xpath("//a[@href and @test_url]")[0]
assert link_node.get("href") == link_out