From cf3c5b7440e8b32465d91f16db55c4ba9d9656ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Nov 2024 15:26:37 +0100 Subject: [PATCH 1/2] doc: _extensions: apply ruff lint rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes all Python scripts in doc/_extensions compliant w.r.t current Ruff rules Signed-off-by: Benjamin Cabé --- .ruff-excludes.toml | 72 ------------ doc/_extensions/zephyr/api_overview.py | 12 +- doc/_extensions/zephyr/application.py | 105 ++++++++---------- doc/_extensions/zephyr/domain/__init__.py | 38 +++---- doc/_extensions/zephyr/doxybridge.py | 17 ++- doc/_extensions/zephyr/doxyrunner.py | 29 +++-- .../zephyr/doxytooltip/__init__.py | 5 +- doc/_extensions/zephyr/external_content.py | 11 +- doc/_extensions/zephyr/gh_utils.py | 15 ++- doc/_extensions/zephyr/kconfig/__init__.py | 35 +++--- doc/_extensions/zephyr/link-roles.py | 30 +++-- .../zephyr/manifest_projects_table.py | 20 ++-- 12 files changed, 156 insertions(+), 233 deletions(-) diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index 5506a90fae8c2b..93958bdeaee271 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -43,78 +43,6 @@ "./boards/microchip/mec172xevb_assy6906/support/mec172x_remote_flasher.py" = [ "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports ] -"./doc/_extensions/zephyr/api_overview.py" = [ - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/application.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "SIM102", # https://docs.astral.sh/ruff/rules/collapsible-if - "UP032", # https://docs.astral.sh/ruff/rules/f-string -] -"./doc/_extensions/zephyr/domain/__init__.py" = [ - "B023", # https://docs.astral.sh/ruff/rules/function-uses-loop-variable - "B026", # https://docs.astral.sh/ruff/rules/star-arg-unpacking-after-keyword-arg - "E402", # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "F401", # https://docs.astral.sh/ruff/rules/unused-import - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/doxybridge.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/doxyrunner.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation - "UP024", # https://docs.astral.sh/ruff/rules/os-error-alias - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/doxytooltip/__init__.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/external_content.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/gh_utils.py" = [ - "E402", # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/kconfig/__init__.py" = [ - "E402", # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file - "SIM112", # https://docs.astral.sh/ruff/rules/uncapitalized-environment-variables - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP007", # https://docs.astral.sh/ruff/rules/non-pep604-annotation - "UP028", # https://docs.astral.sh/ruff/rules/yield-in-for-loop - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] -"./doc/_extensions/zephyr/link-roles.py" = [ - "B006", # https://docs.astral.sh/ruff/rules/mutable-argument-default - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "SIM102", # https://docs.astral.sh/ruff/rules/collapsible-if - "UP010", # https://docs.astral.sh/ruff/rules/unnecessary-future-import -] -"./doc/_extensions/zephyr/manifest_projects_table.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "SIM114", # https://docs.astral.sh/ruff/rules/if-with-same-arms - "UP006", # https://docs.astral.sh/ruff/rules/non-pep585-annotation - "UP035", # https://docs.astral.sh/ruff/rules/deprecated-import -] "./doc/_scripts/gen_boards_catalog.py" = [ "E401", # https://docs.astral.sh/ruff/rules/multiple-imports-on-one-line "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports diff --git a/doc/_extensions/zephyr/api_overview.py b/doc/_extensions/zephyr/api_overview.py index 15bbe0e804b001..3d56e5eaee4fb3 100644 --- a/doc/_extensions/zephyr/api_overview.py +++ b/doc/_extensions/zephyr/api_overview.py @@ -1,14 +1,14 @@ # Copyright (c) 2023 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -import doxmlparser +from pathlib import Path +from typing import Any +import doxmlparser from docutils import nodes from doxmlparser.compound import DoxCompoundKind -from pathlib import Path from sphinx.application import Sphinx from sphinx.util.docutils import SphinxDirective -from typing import Any, Dict class ApiOverview(SphinxDirective): @@ -56,7 +56,9 @@ def visit_group(app, group, all_groups, rows, indent=0): if since: since_url = nodes.inline() - reference = nodes.reference(text=f"v{since.strip()}.0", refuri=f"{github_uri}/v{since.strip()}.0") + reference = nodes.reference( + text=f"v{since.strip()}.0", refuri=f"{github_uri}/v{since.strip()}.0" + ) reference.attributes["internal"] = True since_url += reference else: @@ -161,7 +163,7 @@ def sync_contents(app: Sphinx) -> None: app.builder.env.api_overview_table = generate_table(app, toplevel, groups) -def setup(app) -> Dict[str, Any]: +def setup(app) -> dict[str, Any]: app.add_config_value("api_overview_doxygen_xml_dir", "html/doxygen/xml", "env") app.add_config_value("api_overview_doxygen_base_url", "../../doxygen/html", "env") diff --git a/doc/_extensions/zephyr/application.py b/doc/_extensions/zephyr/application.py index d59cb4294b14b8..4b2867b6ab0636 100644 --- a/doc/_extensions/zephyr/application.py +++ b/doc/_extensions/zephyr/application.py @@ -4,11 +4,10 @@ '''Sphinx extensions related to managing Zephyr applications.''' -from docutils import nodes -from docutils.parsers.rst import Directive -from docutils.parsers.rst import directives from pathlib import Path +from docutils import nodes +from docutils.parsers.rst import Directive, directives ZEPHYR_BASE = Path(__file__).parents[3] @@ -79,8 +78,7 @@ def run(self): flash_args = self.options.get('flash-args', None) if tool not in self.TOOLS: - raise self.error('Unknown tool {}; choose from: {}'.format( - tool, self.TOOLS)) + raise self.error(f'Unknown tool {tool}; choose from: {self.TOOLS}') if app and zephyr_app: raise self.error('Both app and zephyr-app options were given.') @@ -92,25 +90,22 @@ def run(self): raise self.error('build-dir-fmt is only supported for the west build tool.') if generator not in self.GENERATORS: - raise self.error('Unknown generator {}; choose from: {}'.format( - generator, self.GENERATORS)) + raise self.error(f'Unknown generator {generator}; choose from: {self.GENERATORS}') if host_os not in self.HOST_OS: - raise self.error('Unknown host-os {}; choose from: {}'.format( - host_os, self.HOST_OS)) + raise self.error(f'Unknown host-os {host_os}; choose from: {self.HOST_OS}') if compact and skip_config: raise self.error('Both compact and maybe-skip-config options were given.') - if zephyr_app: - # as folks might use "<...>" notation to indicate a variable portion of the path, we - # deliberately don't check for the validity of such paths. - if not any([x in zephyr_app for x in ["<", ">"]]): - app_path = ZEPHYR_BASE / zephyr_app - if not app_path.is_dir(): - raise self.error( - f"zephyr-app: {zephyr_app} is not a valid folder in the zephyr tree." - ) + # as folks might use "<...>" notation to indicate a variable portion of the path, we + # deliberately don't check for the validity of such paths. + if zephyr_app and not any([x in zephyr_app for x in ["<", ">"]]): + app_path = ZEPHYR_BASE / zephyr_app + if not app_path.is_dir(): + raise self.error( + f"zephyr-app: {zephyr_app} is not a valid folder in the zephyr tree." + ) app = app or zephyr_app in_tree = self.IN_TREE_STR if zephyr_app else None @@ -168,7 +163,7 @@ def run(self): if tool_comment: paragraph = nodes.paragraph() paragraph += nodes.Text(tool_comment.format( - 'CMake and {}'.format(generator))) + f'CMake and {generator}')) content.append(paragraph) content.append(self._lit_block(c)) else: @@ -208,30 +203,30 @@ def _generate_west(self, **kwargs): # west always defaults to ninja gen_arg = ' -G\'Unix Makefiles\'' if generator == 'make' else '' cmake_args = gen_arg + self._cmake_args(**kwargs) - cmake_args = ' --{}'.format(cmake_args) if cmake_args != '' else '' + cmake_args = f' --{cmake_args}' if cmake_args != '' else '' build_args = "".join(f" -o {b}" for b in build_args) if build_args else "" - west_args = ' {}'.format(west_args) if west_args else '' - flash_args = ' {}'.format(flash_args) if flash_args else '' + west_args = f' {west_args}' if west_args else '' + flash_args = f' {flash_args}' if flash_args else '' snippet_args = ''.join(f' -S {s}' for s in snippets) if snippets else '' shield_args = ''.join(f' --shield {s}' for s in shield) if shield else '' # ignore zephyr_app since west needs to run within # the installation. Instead rely on relative path. - src = ' {}'.format(app) if app and not cd_into else '' + src = f' {app}' if app and not cd_into else '' if build_dir_fmt is None: - dst = ' -d {}'.format(build_dir) if build_dir != 'build' else '' + dst = f' -d {build_dir}' if build_dir != 'build' else '' build_dst = dst else: app_name = app.split('/')[-1] build_dir_formatted = build_dir_fmt.format(app=app_name, board=board, source_dir=app) - dst = ' -d {}'.format(build_dir_formatted) + dst = f' -d {build_dir_formatted}' build_dst = '' if in_tree and not compact: content.append(in_tree) if cd_into and app: - content.append('cd {}'.format(app)) + content.append(f'cd {app}') # We always have to run west build. # @@ -252,21 +247,21 @@ def _generate_west(self, **kwargs): # etc. commands can use the signed file which must be created # in this step. if 'sign' in goals: - content.append('west sign{}'.format(dst)) + content.append(f'west sign{dst}') for goal in goals: if goal in {'build', 'sign'}: continue elif goal == 'flash': - content.append('west flash{}{}'.format(flash_args, dst)) + content.append(f'west flash{flash_args}{dst}') elif goal == 'debug': - content.append('west debug{}'.format(dst)) + content.append(f'west debug{dst}') elif goal == 'debugserver': - content.append('west debugserver{}'.format(dst)) + content.append(f'west debugserver{dst}') elif goal == 'attach': - content.append('west attach{}'.format(dst)) + content.append(f'west attach{dst}') else: - content.append('west build -t {}{}'.format(goal, dst)) + content.append(f'west build -t {goal}{dst}') return content @@ -274,14 +269,15 @@ def _generate_west(self, **kwargs): def _mkdir(mkdir, build_dir, host_os, skip_config): content = [] if skip_config: - content.append("# If you already made a build directory ({}) and ran cmake, just 'cd {}' instead.".format(build_dir, build_dir)) # noqa: E501 + content.append(f"# If you already made a build directory ({build_dir}) and ran cmake, " + f"just 'cd {build_dir}' instead.") if host_os == 'all': - content.append('mkdir {} && cd {}'.format(build_dir, build_dir)) + content.append(f'mkdir {build_dir} && cd {build_dir}') if host_os == "unix": - content.append('{} {} && cd {}'.format(mkdir, build_dir, build_dir)) + content.append(f'{mkdir} {build_dir} && cd {build_dir}') elif host_os == "win": build_dir = build_dir.replace('/', '\\') - content.append('mkdir {} & cd {}'.format(build_dir, build_dir)) + content.append(f'mkdir {build_dir} & cd {build_dir}') return content @staticmethod @@ -289,11 +285,11 @@ def _cmake_args(**kwargs): board = kwargs['board'] conf = kwargs['conf'] gen_args = kwargs['gen_args'] - board_arg = ' -DBOARD={}'.format(board) if board else '' - conf_arg = ' -DCONF_FILE={}'.format(conf) if conf else '' - gen_args = ' {}'.format(gen_args) if gen_args else '' + board_arg = f' -DBOARD={board}' if board else '' + conf_arg = f' -DCONF_FILE={conf}' if conf else '' + gen_args = f' {gen_args}' if gen_args else '' - return '{}{}{}'.format(board_arg, conf_arg, gen_args) + return f'{board_arg}{conf_arg}{gen_args}' def _cd_into(self, mkdir, **kwargs): app = kwargs['app'] @@ -319,13 +315,13 @@ def _cd_into(self, mkdir, **kwargs): if os_comment: content.append(os_comment.format('Linux/macOS')) if app: - content.append('cd {}'.format(app)) + content.append(f'cd {app}') elif host == "win": if os_comment: content.append(os_comment.format('Windows')) if app: backslashified = app.replace('/', '\\') - content.append('cd {}'.format(backslashified)) + content.append(f'cd {backslashified}') if mkdir: content.extend(self._mkdir(mkdir, build_dir, host, skip_config)) if not compact: @@ -359,39 +355,36 @@ def _generate_cmake(self, **kwargs): cmake_build_dir = '' tool_build_dir = '' else: - source_dir = ' {}'.format(app) if app else ' .' - cmake_build_dir = ' -B{}'.format(build_dir) - tool_build_dir = ' -C{}'.format(build_dir) + source_dir = f' {app}' if app else ' .' + cmake_build_dir = f' -B{build_dir}' + tool_build_dir = f' -C{build_dir}' # Now generate the actual cmake and make/ninja commands gen_arg = ' -GNinja' if generator == 'ninja' else '' - build_args = ' {}'.format(build_args) if build_args else '' + build_args = f' {build_args}' if build_args else '' snippet_args = ' -DSNIPPET="{}"'.format(';'.join(snippets)) if snippets else '' shield_args = ' -DSHIELD="{}"'.format(';'.join(shield)) if shield else '' cmake_args = self._cmake_args(**kwargs) if not compact: if not cd_into and skip_config: - content.append("# If you already ran cmake with -B{}, you " \ - "can skip this step and run {} directly.". - format(build_dir, generator)) # noqa: E501 + content.append(f'# If you already ran cmake with -B{build_dir}, you ' + f'can skip this step and run {generator} directly.') else: - content.append('# Use cmake to configure a {}-based build' \ - 'system:'.format(generator.capitalize())) # noqa: E501 + content.append(f'# Use cmake to configure a {generator.capitalize()}-based build' + 'system:') - content.append('cmake{}{}{}{}{}{}'.format(cmake_build_dir, gen_arg, - cmake_args, snippet_args, shield_args, source_dir)) + content.append(f'cmake{cmake_build_dir}{gen_arg}{cmake_args}{snippet_args}{shield_args}{source_dir}') if not compact: content.extend(['', '# Now run the build tool on the generated build system:']) if 'build' in goals: - content.append('{}{}{}'.format(generator, tool_build_dir, - build_args)) + content.append(f'{generator}{tool_build_dir}{build_args}') for goal in goals: if goal == 'build': continue - content.append('{}{} {}'.format(generator, tool_build_dir, goal)) + content.append(f'{generator}{tool_build_dir} {goal}') return content diff --git a/doc/_extensions/zephyr/domain/__init__.py b/doc/_extensions/zephyr/domain/__init__.py index 4814e3cc591734..fd34fa9a6b9b98 100644 --- a/doc/_extensions/zephyr/domain/__init__.py +++ b/doc/_extensions/zephyr/domain/__init__.py @@ -26,15 +26,17 @@ """ +import json import sys +from collections.abc import Iterator from os import path from pathlib import Path -from typing import Any, Dict, Iterator, List, Tuple, Final +from typing import Any +from anytree import ChildResolverError, Node, PreOrderIter, Resolver, search from docutils import nodes from docutils.parsers.rst import directives from docutils.statemachine import StringList - from sphinx import addnodes from sphinx.application import Sphinx from sphinx.domains import Domain, ObjType @@ -51,20 +53,15 @@ from zephyr.doxybridge import DoxygenGroupDirective from zephyr.gh_utils import gh_link_get_url - -import json - -from anytree import Node, Resolver, ChildResolverError, PreOrderIter, search - __version__ = "0.2.0" -ZEPHYR_BASE = Path(__file__).parents[4] -sys.path.insert(0, str(ZEPHYR_BASE / "scripts/dts/python-devicetree/src")) +sys.path.insert(0, str(Path(__file__).parents[4] / "scripts/dts/python-devicetree/src")) sys.path.insert(0, str(Path(__file__).parents[3] / "_scripts")) from gen_boards_catalog import get_catalog +ZEPHYR_BASE = Path(__file__).parents[4] TEMPLATES_DIR = Path(__file__).parent / "templates" RESOURCES_DIR = Path(__file__).parent / "static" @@ -291,10 +288,10 @@ def output_sample_categories_list_items(self, tree, container: nodes.Node): reference = nodes.reference( "", "", + *[nodes.Text(tree.category["name"])], internal=True, refuri=docname, anchorname="", - *[nodes.Text(tree.category["name"])], classes=["category-link"], ) compact_paragraph += reference @@ -324,10 +321,10 @@ def output_sample_categories_list_items(self, tree, container: nodes.Node): sample_xref = nodes.reference( "", "", + *[nodes.Text(code_sample["name"])], internal=True, refuri=code_sample["docname"], anchorname="", - *[nodes.Text(code_sample["name"])], classes=["code-sample-link"], ) sample_xref["reftitle"] = code_sample["description"].astext() @@ -410,7 +407,8 @@ def run(self, **kwargs: Any) -> None: "", """ """, @@ -428,7 +426,8 @@ def run(self, **kwargs: Any) -> None: category_node = search.find( code_samples_categories_tree, - lambda node: hasattr(node, "category") and node.category["id"] == category, + lambda node, category=category: hasattr(node, "category") + and node.category["id"] == category, ) self.output_sample_categories_sections(category_node, container) @@ -717,13 +716,13 @@ class ZephyrDomain(Domain): "board": BoardDirective, } - object_types: Dict[str, ObjType] = { + object_types: dict[str, ObjType] = { "code-sample": ObjType("code sample", "code-sample"), "code-sample-category": ObjType("code sample category", "code-sample-category"), "board": ObjType("board", "board"), } - initial_data: Dict[str, Any] = { + initial_data: dict[str, Any] = { "code-samples": {}, # id -> code sample data "code-samples-categories": {}, # id -> code sample category data "code-samples-categories-tree": Node("samples"), @@ -750,11 +749,12 @@ def clear_doc(self, docname: str) -> None: self.data["has_code_sample_listing"].pop(docname, None) self.data["has_board_catalog"].pop(docname, None) - def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: + def merge_domaindata(self, docnames: list[str], otherdata: dict) -> None: self.data["code-samples"].update(otherdata["code-samples"]) self.data["code-samples-categories"].update(otherdata["code-samples-categories"]) - # self.data["boards"] contains all the boards right from builder-inited time, but it still # potentially needs merging since a board's docname property is set by BoardDirective to + # self.data["boards"] contains all the boards right from builder-inited time, but it still + # potentially needs merging since a board's docname property is set by BoardDirective to # indicate the board is documented in a specific document. for board_name, board in otherdata["boards"].items(): if "docname" in board: @@ -815,7 +815,7 @@ def get_objects(self): ) # used by Sphinx Immaterial theme - def get_object_synopses(self) -> Iterator[Tuple[Tuple[str, str], str]]: + def get_object_synopses(self) -> Iterator[tuple[tuple[str, str], str]]: for _, code_sample in self.data["code-samples"].items(): yield ( (code_sample["docname"], code_sample["id"]), @@ -895,7 +895,7 @@ def add_category_to_tree( class CustomDoxygenGroupDirective(DoxygenGroupDirective): """Monkey patch for Breathe's DoxygenGroupDirective.""" - def run(self) -> List[Node]: + def run(self) -> list[Node]: nodes = super().run() if self.config.zephyr_breathe_insert_related_samples: diff --git a/doc/_extensions/zephyr/doxybridge.py b/doc/_extensions/zephyr/doxybridge.py index b15b1fc2f9ac70..fe0074b65da776 100644 --- a/doc/_extensions/zephyr/doxybridge.py +++ b/doc/_extensions/zephyr/doxybridge.py @@ -4,22 +4,19 @@ SPDX-License-Identifier: Apache-2.0 """ -import os -from typing import Any, Dict - import concurrent.futures +import os +from typing import Any +import doxmlparser from docutils import nodes - +from doxmlparser.compound import DoxCompoundKind, DoxMemberKind from sphinx import addnodes from sphinx.application import Sphinx +from sphinx.domains.c import CXRefRole from sphinx.transforms.post_transforms import SphinxPostTransform from sphinx.util import logging from sphinx.util.docutils import SphinxDirective -from sphinx.domains.c import CXRefRole - -import doxmlparser -from doxmlparser.compound import DoxCompoundKind, DoxMemberKind logger = logging.getLogger(__name__) @@ -154,7 +151,7 @@ def parse_sections(compounddef): return cache -def parse_compound(inDirName, baseName) -> Dict: +def parse_compound(inDirName, baseName) -> dict: rootObj = doxmlparser.compound.parse(inDirName + "/" + baseName + ".xml", True) cache = {} group_titles = {} @@ -218,7 +215,7 @@ def doxygen_parse(app: Sphinx) -> None: parse_index(app, str(app.config.doxybridge_dir / "xml")) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value("doxybridge_dir", None, "env") app.add_directive("doxygengroup", DoxygenGroupDirective) diff --git a/doc/_extensions/zephyr/doxyrunner.py b/doc/_extensions/zephyr/doxyrunner.py index 64d4a2c793a478..bdbc0daba6efe7 100644 --- a/doc/_extensions/zephyr/doxyrunner.py +++ b/doc/_extensions/zephyr/doxyrunner.py @@ -43,19 +43,18 @@ import filecmp import hashlib -from pathlib import Path import re import shlex import shutil -from subprocess import Popen, PIPE, STDOUT import tempfile -from typing import List, Dict, Optional, Any +from pathlib import Path +from subprocess import PIPE, STDOUT, Popen +from typing import Any from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment from sphinx.util import logging - __version__ = "0.1.0" @@ -77,7 +76,7 @@ def hash_file(file: Path) -> str: return sha256.hexdigest() -def get_doxygen_option(doxyfile: str, option: str) -> List[str]: +def get_doxygen_option(doxyfile: str, option: str) -> list[str]: """Obtain the value of a Doxygen option. Args: @@ -133,9 +132,9 @@ def process_doxyfile( outdir: Path, silent: bool, fmt: bool = False, - fmt_pattern: Optional[str] = None, - fmt_vars: Optional[Dict[str, str]] = None, - outdir_var: Optional[str] = None, + fmt_pattern: str | None = None, + fmt_vars: dict[str, str] | None = None, + outdir_var: str | None = None, ) -> str: """Process Doxyfile. @@ -270,11 +269,11 @@ def run_doxygen(doxygen: str, doxyfile: str, silent: bool = False) -> None: silent: If Doxygen output should be logged or not. """ - f_doxyfile = tempfile.NamedTemporaryFile("w", delete=False) - f_doxyfile.write(doxyfile) - f_doxyfile.close() + with tempfile.NamedTemporaryFile("w", delete=False) as f_doxyfile: + f_doxyfile.write(doxyfile) + f_doxyfile_name = f_doxyfile.name - p = Popen([doxygen, f_doxyfile.name], stdout=PIPE, stderr=STDOUT, encoding="utf-8") + p = Popen([doxygen, f_doxyfile_name], stdout=PIPE, stderr=STDOUT, encoding="utf-8") while True: line = p.stdout.readline() # type: ignore if line: @@ -282,10 +281,10 @@ def run_doxygen(doxygen: str, doxyfile: str, silent: bool = False) -> None: if p.poll() is not None: break - Path(f_doxyfile.name).unlink() + Path(f_doxyfile_name).unlink() if p.returncode: - raise IOError(f"Doxygen process returned non-zero ({p.returncode})") + raise OSError(f"Doxygen process returned non-zero ({p.returncode})") def sync_doxygen(doxyfile: str, new: Path, prev: Path) -> None: @@ -380,7 +379,7 @@ def doxygen_build(app: Sphinx) -> None: shutil.rmtree(tmp_outdir) -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value("doxyrunner_doxygen", "doxygen", "env") app.add_config_value("doxyrunner_doxyfile", None, "env") app.add_config_value("doxyrunner_outdir", None, "env") diff --git a/doc/_extensions/zephyr/doxytooltip/__init__.py b/doc/_extensions/zephyr/doxytooltip/__init__.py index 8c768fded2705f..574e65be2c3bae 100644 --- a/doc/_extensions/zephyr/doxytooltip/__init__.py +++ b/doc/_extensions/zephyr/doxytooltip/__init__.py @@ -10,8 +10,7 @@ """ from pathlib import Path - -from typing import Any, Dict +from typing import Any from sphinx.application import Sphinx from sphinx.util import logging @@ -20,7 +19,7 @@ RESOURCES_DIR = Path(__file__).parent / "static" -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.config.html_static_path.append(RESOURCES_DIR.as_posix()) app.add_js_file("tippy/popper.min.js") diff --git a/doc/_extensions/zephyr/external_content.py b/doc/_extensions/zephyr/external_content.py index 7e739a5e244c3a..704e834e96ddba 100644 --- a/doc/_extensions/zephyr/external_content.py +++ b/doc/_extensions/zephyr/external_content.py @@ -32,15 +32,14 @@ import filecmp import os -from pathlib import Path import re import shutil import tempfile -from typing import Dict, Any, List, Optional +from pathlib import Path +from typing import Any from sphinx.application import Sphinx - __version__ = "0.1.0" @@ -51,9 +50,9 @@ def adjust_includes( fname: Path, basepath: Path, - directives: List[str], + directives: list[str], encoding: str, - dstpath: Optional[Path] = None, + dstpath: Path | None = None, ) -> None: """Adjust included content paths. @@ -162,7 +161,7 @@ def sync_contents(app: Sphinx) -> None: file.unlink() -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value("external_content_contents", [], "env") app.add_config_value("external_content_directives", DEFAULT_DIRECTIVES, "env") app.add_config_value("external_content_keep", [], "") diff --git a/doc/_extensions/zephyr/gh_utils.py b/doc/_extensions/zephyr/gh_utils.py index d367100812e0d4..67998cd4382f0d 100644 --- a/doc/_extensions/zephyr/gh_utils.py +++ b/doc/_extensions/zephyr/gh_utils.py @@ -33,26 +33,25 @@ for, e.g., auto-generated pages not in Git. """ -from functools import partial import os import re import subprocess import sys from datetime import datetime +from functools import partial from pathlib import Path from textwrap import dedent -from typing import Final, Optional, Tuple +from typing import Final from urllib.parse import quote from sphinx.application import Sphinx from sphinx.util.i18n import format_date -ZEPHYR_BASE : Final[str] = Path(__file__).parents[3] -SCRIPTS : Final[str] = ZEPHYR_BASE / "scripts" -sys.path.insert(0, str(SCRIPTS)) +sys.path.insert(0, str(Path(__file__).parents[3] / "scripts")) from get_maintainer import Maintainers +ZEPHYR_BASE : Final[str] = Path(__file__).parents[3] MAINTAINERS : Final[Maintainers] = Maintainers(filename=f"{ZEPHYR_BASE}/MAINTAINERS.yml") @@ -90,7 +89,7 @@ def get_page_prefix(app: Sphinx, pagename: str) -> str: return found_prefix -def gh_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional[str]: +def gh_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> str | None: """Obtain GitHub URL for the given page. Args: @@ -117,7 +116,7 @@ def gh_link_get_url(app: Sphinx, pagename: str, mode: str = "blob") -> Optional[ ) -def gh_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optional[str]: +def gh_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> str | None: """Link to open a new Github issue regarding "pagename" with title, body, and labels already pre-filled with useful information. @@ -164,7 +163,7 @@ def gh_link_get_open_issue_url(app: Sphinx, pagename: str, sha1: str) -> Optiona return f"{app.config.gh_link_base_url}/issues/new?title={title}&labels={labels}&body={body}" -def git_info_filter(app: Sphinx, pagename) -> Optional[Tuple[str, str]]: +def git_info_filter(app: Sphinx, pagename) -> tuple[str, str] | None: """Return a tuple with the date and SHA1 of the last commit made to a page. Arguments: diff --git a/doc/_extensions/zephyr/kconfig/__init__.py b/doc/_extensions/zephyr/kconfig/__init__.py index 905376d8168639..fe037d1c894a36 100644 --- a/doc/_extensions/zephyr/kconfig/__init__.py +++ b/doc/_extensions/zephyr/kconfig/__init__.py @@ -33,10 +33,11 @@ import os import re import sys +from collections.abc import Iterable from itertools import chain from pathlib import Path from tempfile import TemporaryDirectory -from typing import Any, Dict, Iterable, List, Optional, Tuple +from typing import Any from docutils import nodes from sphinx.addnodes import pending_xref @@ -53,22 +54,19 @@ __version__ = "0.1.0" -RESOURCES_DIR = Path(__file__).parent / "static" -ZEPHYR_BASE = Path(__file__).parents[4] - -SCRIPTS = ZEPHYR_BASE / "scripts" -sys.path.insert(0, str(SCRIPTS)) - -KCONFIGLIB = SCRIPTS / "kconfig" -sys.path.insert(0, str(KCONFIGLIB)) +sys.path.insert(0, str(Path(__file__).parents[4] / "scripts")) +sys.path.insert(0, str(Path(__file__).parents[4] / "scripts/kconfig")) import kconfiglib import list_boards import list_hardware import zephyr_module +RESOURCES_DIR = Path(__file__).parent / "static" +ZEPHYR_BASE = Path(__file__).parents[4] + -def kconfig_load(app: Sphinx) -> Tuple[kconfiglib.Kconfig, Dict[str, str]]: +def kconfig_load(app: Sphinx) -> tuple[kconfiglib.Kconfig, dict[str, str]]: """Load Kconfig""" with TemporaryDirectory() as td: modules = zephyr_module.parse_modules(ZEPHYR_BASE) @@ -131,7 +129,7 @@ def kconfig_load(app: Sphinx) -> Tuple[kconfiglib.Kconfig, Dict[str, str]]: # base environment os.environ["ZEPHYR_BASE"] = str(ZEPHYR_BASE) - os.environ["srctree"] = str(ZEPHYR_BASE) + os.environ["srctree"] = str(ZEPHYR_BASE) # noqa: SIM112 os.environ["KCONFIG_DOC_MODE"] = "1" os.environ["KCONFIG_BINARY_DIR"] = td @@ -232,13 +230,12 @@ class KconfigDomain(Domain): object_types = {"option": ObjType("option", "option")} roles = {"option": XRefRole()} directives = {"search": KconfigSearch} - initial_data: Dict[str, Any] = {"options": set()} + initial_data: dict[str, Any] = {"options": set()} - def get_objects(self) -> Iterable[Tuple[str, str, str, str, str, int]]: - for obj in self.data["options"]: - yield obj + def get_objects(self) -> Iterable[tuple[str, str, str, str, str, int]]: + yield from self.data["options"] - def merge_domaindata(self, docnames: List[str], otherdata: Dict) -> None: + def merge_domaindata(self, docnames: list[str], otherdata: dict) -> None: self.data["options"].update(otherdata["options"]) def resolve_xref( @@ -250,7 +247,7 @@ def resolve_xref( target: str, node: pending_xref, contnode: nodes.Element, - ) -> Optional[nodes.Element]: + ) -> nodes.Element | None: match = [ (docname, anchor) for name, _, _, docname, anchor, _ in self.get_objects() @@ -443,8 +440,8 @@ def kconfig_install( app: Sphinx, pagename: str, templatename: str, - context: Dict, - doctree: Optional[nodes.Node], + context: dict, + doctree: nodes.Node | None, ) -> None: """Install the Kconfig library files on pages that require it.""" if ( diff --git a/doc/_extensions/zephyr/link-roles.py b/doc/_extensions/zephyr/link-roles.py index be82226bd57108..64877b6383078b 100644 --- a/doc/_extensions/zephyr/link-roles.py +++ b/doc/_extensions/zephyr/link-roles.py @@ -4,14 +4,14 @@ # based on http://protips.readthedocs.io/link-roles.html -from __future__ import print_function -from __future__ import unicode_literals import re import subprocess -from docutils import nodes +from collections.abc import Sequence from pathlib import Path +from typing import Any, Final + +from docutils import nodes from sphinx.util import logging -from typing import Final ZEPHYR_BASE: Final[str] = Path(__file__).parents[3] @@ -58,8 +58,17 @@ def setup(app): def modulelink(default_module=None, format="blob"): - def role(name, rawtext, text, lineno, inliner, options={}, content=[]): - # Set default values + def role( + name: str, + rawtext: str, + text: str, + lineno: int, + inliner, + options: dict[str, Any] | None = None, + content: Sequence[str] = (), + ): + if options is None: + options = {} module = default_module rev = get_github_rev() config = inliner.document.settings.env.app.config @@ -110,11 +119,10 @@ def role(name, rawtext, text, lineno, inliner, options={}, content=[]): if not any( p.match(glob) for glob in config.link_roles_manifest_project_broken_links_ignore_globs - ): - if not Path(ZEPHYR_BASE, link).exists(): - logger.warning( - f"{link} not found in {config.link_roles_manifest_project} {trace}" - ) + ) and not Path(ZEPHYR_BASE, link).exists(): + logger.warning( + f"{link} not found in {config.link_roles_manifest_project} {trace}" + ) url = f"{baseurl}/{format}/{rev}/{link}" node = nodes.reference(rawtext, link_text, refuri=url, **options) diff --git a/doc/_extensions/zephyr/manifest_projects_table.py b/doc/_extensions/zephyr/manifest_projects_table.py index 0eaa06d45cf14c..2fc7069c004687 100644 --- a/doc/_extensions/zephyr/manifest_projects_table.py +++ b/doc/_extensions/zephyr/manifest_projects_table.py @@ -27,7 +27,7 @@ """ import re -from typing import Any, Dict, List +from typing import Any from docutils import nodes from docutils.parsers.rst import directives @@ -35,7 +35,6 @@ from sphinx.util.docutils import SphinxDirective from west.manifest import Manifest - __version__ = "0.1.0" @@ -67,7 +66,7 @@ def rev_url(base_url: str, rev: str) -> str: return f"{base_url}/releases/tag/{rev}" - def run(self) -> List[nodes.Element]: + def run(self) -> list[nodes.Element]: active_filter = self.options.get("filter", None) manifest = Manifest.from_file(self.env.config.manifest_projects_table_manifest) @@ -75,11 +74,14 @@ def run(self) -> List[nodes.Element]: for project in manifest.projects: if project.name == "manifest": continue - if active_filter == 'active' and manifest.is_active(project): - projects.append(project) - elif active_filter == 'inactive' and not manifest.is_active(project): - projects.append(project) - elif active_filter == 'all' or active_filter is None: + if ( + active_filter == "active" + and manifest.is_active(project) + or active_filter == "inactive" + and not manifest.is_active(project) + or active_filter == "all" + or active_filter is None + ): projects.append(project) # build table @@ -129,7 +131,7 @@ def run(self) -> List[nodes.Element]: return [table] -def setup(app: Sphinx) -> Dict[str, Any]: +def setup(app: Sphinx) -> dict[str, Any]: app.add_config_value("manifest_projects_table_manifest", None, "env") directives.register_directive("manifest-projects-table", ManifestProjectsTable) From 41bb6587ca507d2d88e5431260a131edb8572301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Fri, 22 Nov 2024 16:28:30 +0100 Subject: [PATCH 2/2] doc: _scripts: conf: apply ruff lint rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes all remaining Python scripts in doc compliant w.r.t current Ruff rules Signed-off-by: Benjamin Cabé --- .ruff-excludes.toml | 27 --------------- doc/_scripts/gen_boards_catalog.py | 5 +-- doc/_scripts/gen_devicetree_rest.py | 13 ++++---- doc/_scripts/gen_helpers.py | 3 +- doc/conf.py | 33 +++++++++++-------- .../test/twister/sample_blackbox_test.py | 10 +++--- 6 files changed, 35 insertions(+), 56 deletions(-) diff --git a/.ruff-excludes.toml b/.ruff-excludes.toml index 93958bdeaee271..44d6771959ecb8 100644 --- a/.ruff-excludes.toml +++ b/.ruff-excludes.toml @@ -43,36 +43,9 @@ "./boards/microchip/mec172xevb_assy6906/support/mec172x_remote_flasher.py" = [ "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports ] -"./doc/_scripts/gen_boards_catalog.py" = [ - "E401", # https://docs.astral.sh/ruff/rules/multiple-imports-on-one-line - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes -] -"./doc/_scripts/gen_devicetree_rest.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes - "UP034", # https://docs.astral.sh/ruff/rules/extraneous-parentheses -] -"./doc/_scripts/gen_helpers.py" = [ - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP015", # https://docs.astral.sh/ruff/rules/redundant-open-modes -] "./doc/_scripts/redirects.py" = [ "E501", # https://docs.astral.sh/ruff/rules/line-too-long ] -"./doc/conf.py" = [ - "E402", # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file - "E501", # https://docs.astral.sh/ruff/rules/line-too-long - "F541", # https://docs.astral.sh/ruff/rules/f-string-missing-placeholders - "F821", # https://docs.astral.sh/ruff/rules/undefined-name - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "SIM115", # https://docs.astral.sh/ruff/rules/open-file-with-context-handler -] -"./doc/develop/test/twister/sample_blackbox_test.py" = [ - "B905", # https://docs.astral.sh/ruff/rules/zip-without-explicit-strict - "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports - "UP026", # https://docs.astral.sh/ruff/rules/deprecated-mock-import -] "./modules/mbedtls/create_psa_files.py" = [ "E101", # https://docs.astral.sh/ruff/rules/mixed-spaces-and-tabs "I001", # https://docs.astral.sh/ruff/rules/unsorted-imports diff --git a/doc/_scripts/gen_boards_catalog.py b/doc/_scripts/gen_boards_catalog.py index 52be751e81f63e..db17c67314fe0c 100644 --- a/doc/_scripts/gen_boards_catalog.py +++ b/doc/_scripts/gen_boards_catalog.py @@ -5,7 +5,8 @@ from collections import namedtuple from pathlib import Path -import list_boards, list_hardware +import list_boards +import list_hardware import yaml import zephyr_module from gen_devicetree_rest import VndLookup @@ -96,7 +97,7 @@ def get_catalog(): pattern = f"{board.name}*.yaml" for twister_file in board.dir.glob(pattern): try: - with open(twister_file, "r") as f: + with open(twister_file) as f: board_data = yaml.safe_load(f) archs.add(board_data.get("arch")) except Exception as e: diff --git a/doc/_scripts/gen_devicetree_rest.py b/doc/_scripts/gen_devicetree_rest.py index f29f0403801034..ed5694675068ec 100644 --- a/doc/_scripts/gen_devicetree_rest.py +++ b/doc/_scripts/gen_devicetree_rest.py @@ -7,20 +7,19 @@ """ import argparse -from collections import defaultdict import glob import io import logging import os -from pathlib import Path import pprint import re import sys import textwrap - -from devicetree import edtlib +from collections import defaultdict +from pathlib import Path import gen_helpers +from devicetree import edtlib ZEPHYR_BASE = Path(__file__).parents[2] @@ -265,7 +264,7 @@ def load_driver_sources(): if not filename.endswith(('.c', '.h')): continue filepath = Path(dirpath) / filename - with open(filepath, "r", encoding="utf-8") as f: + with open(filepath, encoding="utf-8") as f: content = f.read() relative_path = filepath.relative_to(ZEPHYR_BASE) @@ -349,9 +348,9 @@ def write_dummy_index(bindings, out_dir): # build compatibles set and dump it compatibles = {binding.compatible for binding in bindings} - content += '\n'.join(( + content += '\n'.join( f'.. dtcompatible:: {compatible}' for compatible in compatibles - )) + ) write_if_updated(out_dir / 'bindings.rst', content) diff --git a/doc/_scripts/gen_helpers.py b/doc/_scripts/gen_helpers.py index 4a4efca45aebd4..3678d0e3ea9f40 100644 --- a/doc/_scripts/gen_helpers.py +++ b/doc/_scripts/gen_helpers.py @@ -7,6 +7,7 @@ import errno + def write_if_updated(path, s): """ Writes 's' as the contents of /, but only if it @@ -17,7 +18,7 @@ def write_if_updated(path, s): """ try: - with open(path, "r", encoding="utf-8") as f: + with open(path, encoding="utf-8") as f: if s == f.read(): return False except OSError as e: diff --git a/doc/conf.py b/doc/conf.py index 94068de899db86..479fd358ee70fb 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,11 +1,11 @@ # Zephyr documentation build configuration file. # Reference: https://www.sphinx-doc.org/en/master/usage/configuration.html -import sys import os -from pathlib import Path import re +import sys import textwrap +from pathlib import Path ZEPHYR_BASE = Path(__file__).resolve().parents[1] ZEPHYR_BUILD = Path(os.environ.get("OUTPUT_DIR")).resolve() @@ -25,7 +25,7 @@ # Add the directory which contains the pytest-twister-pytest sys.path.insert(0, str(ZEPHYR_BASE / "scripts" / "pylib" / "pytest-twister-harness" / "src")) -import redirects +import redirects # noqa: E402 try: import west as west_found @@ -100,7 +100,7 @@ # Ensure "sphinxcontrib.rsvgconverter" is added before "sphinx.ext.imgconverter" # as it's better at converting SVG with extended features (like the ones from # draw.io) to PDF format). -if tags.has("convertimages"): # pylint: disable=undefined-variable +if tags.has("convertimages"): # pylint: disable=undefined-variable # noqa: F821 extensions.append("sphinxcontrib.rsvgconverter") extensions.append("sphinx.ext.imgconverter") @@ -149,11 +149,16 @@ .. |sdk-version-ltrim| unicode:: {sdk_version} :ltrim: .. _Zephyr SDK bundle: https://github.com/zephyrproject-rtos/sdk-ng/releases/tag/v{sdk_version} -.. |sdk-url-linux| replace:: `{SDK_URL_BASE}/v{sdk_version}/zephyr-sdk-{sdk_version}_linux-x86_64.tar.xz` -.. |sdk-url-linux-sha| replace:: `{SDK_URL_BASE}/v{sdk_version}/sha256.sum` -.. |sdk-url-macos| replace:: `{SDK_URL_BASE}/v{sdk_version}/zephyr-sdk-{sdk_version}_macos-x86_64.tar.xz` -.. |sdk-url-macos-sha| replace:: `{SDK_URL_BASE}/v{sdk_version}/sha256.sum` -.. |sdk-url-windows| replace:: `{SDK_URL_BASE}/v{sdk_version}/zephyr-sdk-{sdk_version}_windows-x86_64.7z` +.. |sdk-url-linux| replace:: + `{SDK_URL_BASE}/v{sdk_version}/zephyr-sdk-{sdk_version}_linux-x86_64.tar.xz` +.. |sdk-url-linux-sha| replace:: + `{SDK_URL_BASE}/v{sdk_version}/sha256.sum` +.. |sdk-url-macos| replace:: + `{SDK_URL_BASE}/v{sdk_version}/zephyr-sdk-{sdk_version}_macos-x86_64.tar.xz` +.. |sdk-url-macos-sha| replace:: + `{SDK_URL_BASE}/v{sdk_version}/sha256.sum` +.. |sdk-url-windows| replace:: + `{SDK_URL_BASE}/v{sdk_version}/zephyr-sdk-{sdk_version}_windows-x86_64.7z` """ # -- Options for HTML output ---------------------------------------------- @@ -179,9 +184,9 @@ "gsearch": "gsearch.html" } -is_release = tags.has("release") # pylint: disable=undefined-variable +is_release = tags.has("release") # pylint: disable=undefined-variable # noqa: F821 reference_prefix = "" -if tags.has("publish"): # pylint: disable=undefined-variable +if tags.has("publish"): # pylint: disable=undefined-variable # noqa: F821 reference_prefix = f"/{version}" if is_release else "/latest" docs_title = "Docs / {}".format(version if is_release else "Latest") html_context = { @@ -213,8 +218,8 @@ latex_elements = { "papersize": "a4paper", - "maketitle": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "title.tex").read(), - "preamble": open(ZEPHYR_BASE / "doc" / "_static" / "latex" / "preamble.tex").read(), + "maketitle": (ZEPHYR_BASE / "doc" / "_static" / "latex" / "title.tex").read_text(), + "preamble": (ZEPHYR_BASE / "doc" / "_static" / "latex" / "preamble.tex").read_text(), "makeindex": r"\usepackage[columns=1]{idxlayout}\makeindex", "fontpkg": textwrap.dedent(r""" \usepackage{noto} @@ -271,7 +276,7 @@ # -- Options for zephyr.gh_utils ------------------------------------------ gh_link_version = f"v{version}" if is_release else "main" -gh_link_base_url = f"https://github.com/zephyrproject-rtos/zephyr" +gh_link_base_url = "https://github.com/zephyrproject-rtos/zephyr" gh_link_prefixes = { "samples/.*": "", "boards/.*": "", diff --git a/doc/develop/test/twister/sample_blackbox_test.py b/doc/develop/test/twister/sample_blackbox_test.py index c638af13dd8790..c391669f88928e 100644 --- a/doc/develop/test/twister/sample_blackbox_test.py +++ b/doc/develop/test/twister/sample_blackbox_test.py @@ -4,13 +4,13 @@ # SPDX-License-Identifier: Apache-2.0 import importlib -import mock +import json import os -import pytest import sys -import json +from unittest import mock -from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock +import pytest +from conftest import TEST_DATA, ZEPHYR_BASE, testsuite_filename_mock from twisterlib.testplan import TestPlan @@ -57,7 +57,7 @@ def test_level(self, capfd, out_path, level, expected_tests): # Flags related to platform selection + [ val - for pair in zip(["-p"] * len(test_platforms), test_platforms) + for pair in zip(["-p"] * len(test_platforms), test_platforms, strict=False) for val in pair ] )