Set up mypy defaults and make sure codebase passes --strict
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ def setup_logging(verbose: bool = False, log_file: str | None = None) -> None:
|
|||||||
logger.addHandler(console)
|
logger.addHandler(console)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
setup_logging(verbose=True)
|
setup_logging(verbose=True)
|
||||||
site = Site(Path("."))
|
site = Site(Path("."))
|
||||||
site.build()
|
site.build()
|
||||||
|
|||||||
+17
-8
@@ -3,9 +3,9 @@ import re
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import date
|
from datetime import date
|
||||||
import typing
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from omicron.ssg.site import Site
|
from omicron.ssg.site import Site
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
@@ -34,19 +34,26 @@ def _highlight_code(code: str, lang: str, attrs: str) -> str:
|
|||||||
return pygments_highlight(code, lexer, HtmlFormatter())
|
return pygments_highlight(code, lexer, HtmlFormatter())
|
||||||
|
|
||||||
|
|
||||||
def read_frontmatter(path) -> dict:
|
def read_frontmatter(path: Path) -> dict[str, Any]:
|
||||||
lines = []
|
lines = []
|
||||||
with path.open("r", encoding="utf-8") as f:
|
with path.open("r", encoding="utf-8") as f:
|
||||||
if f.readline() != "---\n":
|
if f.readline() != "---\n":
|
||||||
raise ContentError(f"Frontmatter opening delimiter not found for {path}")
|
raise ContentError(f"Frontmatter opening delimiter not found for {path}")
|
||||||
while (line := f.readline()) != "---\n":
|
while (line := f.readline()) != "---\n":
|
||||||
if line == "":
|
if line == "":
|
||||||
raise ContentError(f"Frontmatter closing delimiter not found for {path}")
|
raise ContentError(
|
||||||
|
f"Frontmatter closing delimiter not found for {path}"
|
||||||
|
)
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
return yaml.safe_load("".join(lines))
|
data = yaml.safe_load("".join(lines))
|
||||||
|
if not isinstance(data, dict) or not all(isinstance(k, str) for k in data):
|
||||||
|
raise ContentError(
|
||||||
|
f"Frontmatter must be a YAML mapping with string keys in {path}"
|
||||||
|
)
|
||||||
|
return cast(dict[str, Any], data)
|
||||||
|
|
||||||
|
|
||||||
def create_content(path) -> Content:
|
def create_content(path: Path) -> Content:
|
||||||
if path.suffix in FRONTMATTER_CONTENT:
|
if path.suffix in FRONTMATTER_CONTENT:
|
||||||
meta = read_frontmatter(path)
|
meta = read_frontmatter(path)
|
||||||
elif path.suffix == ".yml":
|
elif path.suffix == ".yml":
|
||||||
@@ -93,7 +100,9 @@ class Content(ABC):
|
|||||||
f.readline() # opening ---
|
f.readline() # opening ---
|
||||||
while (line := f.readline()) != "---\n":
|
while (line := f.readline()) != "---\n":
|
||||||
if line == "":
|
if line == "":
|
||||||
raise ContentError(f"Frontmatter closing delimiter not found for {self.source}")
|
raise ContentError(
|
||||||
|
f"Frontmatter closing delimiter not found for {self.source}"
|
||||||
|
)
|
||||||
return f.read()
|
return f.read()
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@@ -102,7 +111,7 @@ class Content(ABC):
|
|||||||
|
|
||||||
|
|
||||||
class Article(Content):
|
class Article(Content):
|
||||||
def __init__(self, path: Path, meta: dict):
|
def __init__(self, path: Path, meta: dict[str, Any]):
|
||||||
if "tags" not in meta:
|
if "tags" not in meta:
|
||||||
log.warning("no tags for article in '%s'", path)
|
log.warning("no tags for article in '%s'", path)
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
|||||||
+5
-3
@@ -1,5 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any, cast
|
||||||
|
|
||||||
from omicron.ssg.content import (
|
from omicron.ssg.content import (
|
||||||
Content,
|
Content,
|
||||||
@@ -39,11 +39,13 @@ class Site:
|
|||||||
log.debug("Reading config file %s", config_path)
|
log.debug("Reading config file %s", config_path)
|
||||||
with open(config_path, "r") as f:
|
with open(config_path, "r") as f:
|
||||||
config = yaml.safe_load(f)
|
config = yaml.safe_load(f)
|
||||||
|
if not isinstance(config, dict) or not all(isinstance(k, str) for k in config):
|
||||||
|
raise ConfigError("config file must be a YAML mapping with string keys")
|
||||||
if "name" not in config:
|
if "name" not in config:
|
||||||
raise ConfigError("name value missing from config")
|
raise ConfigError("name value missing from config")
|
||||||
if "template" not in config:
|
if "template" not in config:
|
||||||
raise ConfigError("template value missing from config")
|
raise ConfigError("template value missing from config")
|
||||||
return config
|
return cast(dict[str, Any], config)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def resolve_template_path(template: str) -> Path:
|
def resolve_template_path(template: str) -> Path:
|
||||||
@@ -84,7 +86,7 @@ class Site:
|
|||||||
self.content.append(content)
|
self.content.append(content)
|
||||||
log.info("Discovered %d content items", len(self.content))
|
log.info("Discovered %d content items", len(self.content))
|
||||||
|
|
||||||
def build(self):
|
def build(self) -> None:
|
||||||
self.discover()
|
self.discover()
|
||||||
self.output_path.mkdir(parents=True, exist_ok=True)
|
self.output_path.mkdir(parents=True, exist_ok=True)
|
||||||
(self.output_path / "pygments.css").write_text(
|
(self.output_path / "pygments.css").write_text(
|
||||||
|
|||||||
@@ -13,9 +13,19 @@ dependencies = [
|
|||||||
"PyYAML",
|
"PyYAML",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"mypy",
|
||||||
|
"types-PyYAML",
|
||||||
|
"types-Pygments",
|
||||||
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
ossg = "omicron.ssg.cli:main"
|
ossg = "omicron.ssg.cli:main"
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
strict = true
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["."]
|
where = ["."]
|
||||||
include = ["omicron.ssg*"]
|
include = ["omicron.ssg*"]
|
||||||
|
|||||||
Reference in New Issue
Block a user