Enable type-checking in scripts/

This commit is contained in:
Bruno Oliveira 2023-12-31 10:25:13 -03:00 committed by Bruno Oliveira
parent 5aa289e478
commit 6321b74fae
6 changed files with 50 additions and 26 deletions

View File

@ -59,7 +59,7 @@ repos:
rev: v1.8.0 rev: v1.8.0
hooks: hooks:
- id: mypy - id: mypy
files: ^(src/|testing/) files: ^(src/|testing/|scripts/)
args: [] args: []
additional_dependencies: additional_dependencies:
- iniconfig>=1.1.0 - iniconfig>=1.1.0
@ -67,6 +67,7 @@ repos:
- packaging - packaging
- tomli - tomli
- types-pkg_resources - types-pkg_resources
- types-tabulate
# for mypy running on python>=3.11 since exceptiongroup is only a dependency # for mypy running on python>=3.11 since exceptiongroup is only a dependency
# on <3.11 # on <3.11
- exceptiongroup>=1.0.0rc8 - exceptiongroup>=1.0.0rc8

View File

@ -23,11 +23,12 @@ Requires Python3.6+.
import re import re
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Sequence
import pypandoc import pypandoc
def parse_changelog(tag_name): def parse_changelog(tag_name: str) -> str:
p = Path(__file__).parent.parent / "doc/en/changelog.rst" p = Path(__file__).parent.parent / "doc/en/changelog.rst"
changelog_lines = p.read_text(encoding="UTF-8").splitlines() changelog_lines = p.read_text(encoding="UTF-8").splitlines()
@ -49,13 +50,15 @@ def parse_changelog(tag_name):
return "\n".join(version_lines) return "\n".join(version_lines)
def convert_rst_to_md(text): def convert_rst_to_md(text: str) -> str:
return pypandoc.convert_text( result = pypandoc.convert_text(
text, "md", format="rst", extra_args=["--wrap=preserve"] text, "md", format="rst", extra_args=["--wrap=preserve"]
) )
assert isinstance(result, str), repr(result)
return result
def main(argv): def main(argv: Sequence[str]) -> int:
if len(argv) != 3: if len(argv) != 3:
print("Usage: generate-gh-release-notes VERSION FILE") print("Usage: generate-gh-release-notes VERSION FILE")
return 2 return 2

View File

@ -1,3 +1,4 @@
# mypy: disallow-untyped-defs
""" """
This script is part of the pytest release process which is triggered manually in the Actions This script is part of the pytest release process which is triggered manually in the Actions
tab of the repository. tab of the repository.

View File

@ -1,3 +1,4 @@
# mypy: disallow-untyped-defs
"""Invoke development tasks.""" """Invoke development tasks."""
import argparse import argparse
import os import os
@ -10,15 +11,15 @@ from colorama import Fore
from colorama import init from colorama import init
def announce(version, template_name, doc_version): def announce(version: str, template_name: str, doc_version: str) -> None:
"""Generates a new release announcement entry in the docs.""" """Generates a new release announcement entry in the docs."""
# Get our list of authors # Get our list of authors
stdout = check_output(["git", "describe", "--abbrev=0", "--tags"]) stdout = check_output(["git", "describe", "--abbrev=0", "--tags"], encoding="UTF-8")
stdout = stdout.decode("utf-8")
last_version = stdout.strip() last_version = stdout.strip()
stdout = check_output(["git", "log", f"{last_version}..HEAD", "--format=%aN"]) stdout = check_output(
stdout = stdout.decode("utf-8") ["git", "log", f"{last_version}..HEAD", "--format=%aN"], encoding="UTF-8"
)
contributors = { contributors = {
name name
@ -61,7 +62,7 @@ def announce(version, template_name, doc_version):
check_call(["git", "add", str(target)]) check_call(["git", "add", str(target)])
def regen(version): def regen(version: str) -> None:
"""Call regendoc tool to update examples and pytest output in the docs.""" """Call regendoc tool to update examples and pytest output in the docs."""
print(f"{Fore.CYAN}[generate.regen] {Fore.RESET}Updating docs") print(f"{Fore.CYAN}[generate.regen] {Fore.RESET}Updating docs")
check_call( check_call(
@ -70,7 +71,7 @@ def regen(version):
) )
def fix_formatting(): def fix_formatting() -> None:
"""Runs pre-commit in all files to ensure they are formatted correctly""" """Runs pre-commit in all files to ensure they are formatted correctly"""
print( print(
f"{Fore.CYAN}[generate.fix linting] {Fore.RESET}Fixing formatting using pre-commit" f"{Fore.CYAN}[generate.fix linting] {Fore.RESET}Fixing formatting using pre-commit"
@ -78,13 +79,15 @@ def fix_formatting():
call(["pre-commit", "run", "--all-files"]) call(["pre-commit", "run", "--all-files"])
def check_links(): def check_links() -> None:
"""Runs sphinx-build to check links""" """Runs sphinx-build to check links"""
print(f"{Fore.CYAN}[generate.check_links] {Fore.RESET}Checking links") print(f"{Fore.CYAN}[generate.check_links] {Fore.RESET}Checking links")
check_call(["tox", "-e", "docs-checklinks"]) check_call(["tox", "-e", "docs-checklinks"])
def pre_release(version, template_name, doc_version, *, skip_check_links): def pre_release(
version: str, template_name: str, doc_version: str, *, skip_check_links: bool
) -> None:
"""Generates new docs, release announcements and creates a local tag.""" """Generates new docs, release announcements and creates a local tag."""
announce(version, template_name, doc_version) announce(version, template_name, doc_version)
regen(version) regen(version)
@ -102,12 +105,12 @@ def pre_release(version, template_name, doc_version, *, skip_check_links):
print("Please push your branch and open a PR.") print("Please push your branch and open a PR.")
def changelog(version, write_out=False): def changelog(version: str, write_out: bool = False) -> None:
addopts = [] if write_out else ["--draft"] addopts = [] if write_out else ["--draft"]
check_call(["towncrier", "--yes", "--version", version] + addopts) check_call(["towncrier", "--yes", "--version", version] + addopts)
def main(): def main() -> None:
init(autoreset=True) init(autoreset=True)
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("version", help="Release version") parser.add_argument("version", help="Release version")

View File

@ -1,11 +1,12 @@
# mypy: disallow-untyped-defs
import sys import sys
from subprocess import call from subprocess import call
def main(): def main() -> int:
""" """
Platform agnostic wrapper script for towncrier. Platform-agnostic wrapper script for towncrier.
Fixes the issue (#7251) where windows users are unable to natively run tox -e docs to build pytest docs. Fixes the issue (#7251) where Windows users are unable to natively run tox -e docs to build pytest docs.
""" """
with open( with open(
"doc/en/_changelog_towncrier_draft.rst", "w", encoding="utf-8" "doc/en/_changelog_towncrier_draft.rst", "w", encoding="utf-8"

View File

@ -1,8 +1,13 @@
# mypy: disallow-untyped-defs
import datetime import datetime
import pathlib import pathlib
import re import re
from textwrap import dedent from textwrap import dedent
from textwrap import indent from textwrap import indent
from typing import Any
from typing import Iterable
from typing import Iterator
from typing import TypedDict
import packaging.version import packaging.version
import platformdirs import platformdirs
@ -109,7 +114,17 @@ def pytest_plugin_projects_from_pypi(session: CachedSession) -> dict[str, int]:
} }
def iter_plugins(): class PluginInfo(TypedDict):
"""Relevant information about a plugin to generate the summary."""
name: str
summary: str
last_release: str
status: str
requires: str
def iter_plugins() -> Iterator[PluginInfo]:
session = get_session() session = get_session()
name_2_serial = pytest_plugin_projects_from_pypi(session) name_2_serial = pytest_plugin_projects_from_pypi(session)
@ -136,7 +151,7 @@ def iter_plugins():
requires = requirement requires = requirement
break break
def version_sort_key(version_string): def version_sort_key(version_string: str) -> Any:
""" """
Return the sort key for the given version string Return the sort key for the given version string
returned by the API. returned by the API.
@ -162,20 +177,20 @@ def iter_plugins():
yield { yield {
"name": name, "name": name,
"summary": summary.strip(), "summary": summary.strip(),
"last release": last_release, "last_release": last_release,
"status": status, "status": status,
"requires": requires, "requires": requires,
} }
def plugin_definitions(plugins): def plugin_definitions(plugins: Iterable[PluginInfo]) -> Iterator[str]:
"""Return RST for the plugin list that fits better on a vertical page.""" """Return RST for the plugin list that fits better on a vertical page."""
for plugin in plugins: for plugin in plugins:
yield dedent( yield dedent(
f""" f"""
{plugin['name']} {plugin['name']}
*last release*: {plugin["last release"]}, *last release*: {plugin["last_release"]},
*status*: {plugin["status"]}, *status*: {plugin["status"]},
*requires*: {plugin["requires"]} *requires*: {plugin["requires"]}
@ -184,7 +199,7 @@ def plugin_definitions(plugins):
) )
def main(): def main() -> None:
plugins = [*iter_plugins()] plugins = [*iter_plugins()]
reference_dir = pathlib.Path("doc", "en", "reference") reference_dir = pathlib.Path("doc", "en", "reference")