diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3f4d04cd0..a4c0ffa57 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,10 +10,10 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.8' + python-version: '3.9' - uses: pre-commit/action@v3.0.1 tests-core: @@ -23,17 +23,18 @@ jobs: fail-fast: false # Set on "false" to get the results of ALL builds matrix: os: ["ubuntu-latest"] - # 3.9.8 seems to be broken with type_ast - # https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1829077.html - python-version: ["3.8", "3.11"] - sphinx-version: ["6.0", "7.0"] + python-version: ["3.10", "3.12"] + sphinx-version: ["7.0", "8.0"] include: - os: "ubuntu-latest" - python-version: "3.10" - sphinx-version: "8.0" + python-version: "3.9" + sphinx-version: "7.0" + - os: "windows-latest" + python-version: "3.9" + sphinx-version: "7.0" - os: "windows-latest" - python-version: "3.8" - sphinx-version: "6.0" + python-version: "3.12" + sphinx-version: "8.0" steps: - uses: actions/checkout@v4 - name: Install graphviz (linux) @@ -73,10 +74,10 @@ jobs: matrix: include: - os: "ubuntu-latest" - python-version: "3.8" - sphinx-version: "6.0" + python-version: "3.9" + sphinx-version: "7.0" - os: "ubuntu-latest" - python-version: "3.11" + python-version: "3.12" sphinx-version: "8.0" steps: - uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index 9e5a598e5..155d692c3 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ mem_out.* pyinstrument* *.prof + +uv.lock diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 03a4e9efd..92ce68881 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,25 +6,31 @@ repos: - id: taplo-format - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.0 + rev: v0.8.0 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.12.1 + rev: v1.13.0 hooks: - id: mypy files: sphinx_needs/.* args: [] additional_dependencies: - - sphinx==6.2.1 - - docutils==0.19 + - sphinx==7.4.7 + - docutils==0.20 - types-docutils==0.20.0.20240201 - types-jsonschema - types-requests + # TODO this does not work on pre-commit.ci + # - repo: https://github.com/astral-sh/uv-pre-commit + # rev: 0.5.5 + # hooks: + # - id: uv-lock # Update the uv lockfile + - repo: local hooks: - id: check-readme diff --git a/docs/conf.py b/docs/conf.py index 7af6a7b5a..570cea14e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -3,7 +3,7 @@ import datetime import os from pathlib import Path -from typing import Any, Dict +from typing import Any from sphinx_needs import __version__ @@ -222,7 +222,7 @@ "manual", ), ] -latex_elements: Dict[str, Any] = { +latex_elements: dict[str, Any] = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', diff --git a/pyproject.toml b/pyproject.toml index d2148d5f4..9d838acec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,17 +17,17 @@ classifiers = [ 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', 'Topic :: Documentation', 'Topic :: Utilities', 'Framework :: Sphinx :: Extension', ] -requires-python = ">=3.8,<4" +requires-python = ">=3.9,<4" dependencies = [ - "sphinx>=6.0,<9", + "sphinx>=7.0,<9", "requests-file~=2.1", # external links "requests~=2.32", # external links "jsonschema>=3.2.0", # needsimport schema validation @@ -141,12 +141,12 @@ disable_error_code = ["no-redef"] legacy_tox_ini = """ [tox] -envlist = py38 +envlist = py39 [testenv] usedevelop = true -[testenv:py{38,39,310,311,312}] +[testenv:py{39,310,311,312,313}] extras = test test-parallel diff --git a/sphinx_needs/api/__init__.py b/sphinx_needs/api/__init__.py index e4a94382d..39f3bf42d 100644 --- a/sphinx_needs/api/__init__.py +++ b/sphinx_needs/api/__init__.py @@ -8,11 +8,11 @@ from .need import add_external_need, add_need, del_need, generate_need, get_needs_view __all__ = ( + "InvalidNeedException", "add_dynamic_function", - "add_extra_option", "add_external_need", + "add_extra_option", "add_need", - "InvalidNeedException", "add_need_type", "del_need", "generate_need", diff --git a/sphinx_needs/api/need.py b/sphinx_needs/api/need.py index 61ca1556e..726d01916 100644 --- a/sphinx_needs/api/need.py +++ b/sphinx_needs/api/need.py @@ -4,9 +4,10 @@ import os import re import warnings +from collections.abc import Iterable, Iterator from contextlib import contextmanager from pathlib import Path -from typing import Any, Iterable, Iterator +from typing import Any from docutils import nodes from docutils.parsers.rst.states import RSTState diff --git a/sphinx_needs/builder.py b/sphinx_needs/builder.py index 35158d0b3..6c612cf90 100644 --- a/sphinx_needs/builder.py +++ b/sphinx_needs/builder.py @@ -1,7 +1,7 @@ from __future__ import annotations import os -from typing import Iterable, Sequence +from collections.abc import Iterable, Sequence from docutils import nodes from sphinx.application import Sphinx @@ -37,7 +37,7 @@ def get_outdated_docs(self) -> Iterable[str]: def write( self, - build_docnames: Iterable[str], + build_docnames: Iterable[str] | None, updated_docnames: Sequence[str], method: str = "update", ) -> None: @@ -143,7 +143,7 @@ def get_outdated_docs(self) -> Iterable[str]: def write( self, - build_docnames: Iterable[str], + build_docnames: Iterable[str] | None, updated_docnames: Sequence[str], method: str = "update", ) -> None: @@ -254,6 +254,6 @@ def build_needumls_pumls(app: Sphinx, _exception: Exception) -> None: # if other builder like html used together with config: needs_build_needumls needs_builder = NeedumlsBuilder(app, env) - needs_builder.outdir = os.path.join(needs_builder.outdir, config.build_needumls) + needs_builder.outdir = os.path.join(needs_builder.outdir, config.build_needumls) # type: ignore[assignment] needs_builder.finish() diff --git a/sphinx_needs/config.py b/sphinx_needs/config.py index d6e573815..1dea1ea2e 100644 --- a/sphinx_needs/config.py +++ b/sphinx_needs/config.py @@ -1,7 +1,8 @@ from __future__ import annotations +from collections.abc import Mapping from dataclasses import MISSING, dataclass, field, fields -from typing import TYPE_CHECKING, Any, Callable, Dict, Literal, Mapping, TypedDict +from typing import TYPE_CHECKING, Any, Callable, Literal, TypedDict from docutils.parsers.rst import directives from sphinx.application import Sphinx @@ -174,7 +175,7 @@ class ExternalSource(TypedDict, total=False): """Added as the `external_css` field for each need item (optional)""" -GlobalOptionsType = Dict[str, Any] +GlobalOptionsType = dict[str, Any] """Default values given to specified fields of needs Values can be: diff --git a/sphinx_needs/data.py b/sphinx_needs/data.py index a01a4af12..2cbc74d92 100644 --- a/sphinx_needs/data.py +++ b/sphinx_needs/data.py @@ -4,13 +4,12 @@ from __future__ import annotations +from collections.abc import Mapping from typing import ( TYPE_CHECKING, Any, - Dict, Final, Literal, - Mapping, NewType, TypedDict, ) @@ -717,7 +716,7 @@ class NeedsUmlType(NeedsBaseDataType): """Time taken to process the diagram.""" -NeedsMutable = NewType("NeedsMutable", Dict[str, NeedsInfoType]) +NeedsMutable = NewType("NeedsMutable", dict[str, NeedsInfoType]) """A mutable view of the needs, before resolution """ diff --git a/sphinx_needs/directives/list2need.py b/sphinx_needs/directives/list2need.py index ec50b6b12..439db9951 100644 --- a/sphinx_needs/directives/list2need.py +++ b/sphinx_needs/directives/list2need.py @@ -2,8 +2,9 @@ import hashlib import re +from collections.abc import Sequence from contextlib import suppress -from typing import Any, Sequence +from typing import Any from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/need.py b/sphinx_needs/directives/need.py index 346637ea8..e5e0fe458 100644 --- a/sphinx_needs/directives/need.py +++ b/sphinx_needs/directives/need.py @@ -1,7 +1,8 @@ from __future__ import annotations import re -from typing import Any, Sequence +from collections.abc import Sequence +from typing import Any from docutils import nodes from sphinx.addnodes import desc_name, desc_signature diff --git a/sphinx_needs/directives/needbar.py b/sphinx_needs/directives/needbar.py index eccd4e0d3..833d1a03f 100644 --- a/sphinx_needs/directives/needbar.py +++ b/sphinx_needs/directives/needbar.py @@ -2,7 +2,7 @@ import hashlib import math -from typing import Sequence +from collections.abc import Sequence from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needextend.py b/sphinx_needs/directives/needextend.py index 049aa708f..8bfc621cc 100644 --- a/sphinx_needs/directives/needextend.py +++ b/sphinx_needs/directives/needextend.py @@ -1,7 +1,8 @@ from __future__ import annotations import re -from typing import Any, Callable, Sequence +from collections.abc import Sequence +from typing import Any, Callable from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needextract.py b/sphinx_needs/directives/needextract.py index 4a811404f..64c6ca307 100644 --- a/sphinx_needs/directives/needextract.py +++ b/sphinx_needs/directives/needextract.py @@ -1,7 +1,7 @@ from __future__ import annotations import re -from typing import Sequence +from collections.abc import Sequence from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needflow/__init__.py b/sphinx_needs/directives/needflow/__init__.py index 340365364..3e4a7aba4 100644 --- a/sphinx_needs/directives/needflow/__init__.py +++ b/sphinx_needs/directives/needflow/__init__.py @@ -5,8 +5,8 @@ __all__ = ( "NeedflowDirective", "NeedflowGraphiz", - "process_needflow_graphviz", + "NeedflowPlantuml", "html_visit_needflow_graphviz", + "process_needflow_graphviz", "process_needflow_plantuml", - "NeedflowPlantuml", ) diff --git a/sphinx_needs/directives/needflow/_directive.py b/sphinx_needs/directives/needflow/_directive.py index 3c2489c75..0c5f26526 100644 --- a/sphinx_needs/directives/needflow/_directive.py +++ b/sphinx_needs/directives/needflow/_directive.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needflow/_graphviz.py b/sphinx_needs/directives/needflow/_graphviz.py index 39b05805a..42e04d1a7 100644 --- a/sphinx_needs/directives/needflow/_graphviz.py +++ b/sphinx_needs/directives/needflow/_graphviz.py @@ -2,7 +2,7 @@ import html import textwrap -from functools import lru_cache +from functools import cache from typing import Callable, Literal, TypedDict from urllib.parse import urlparse @@ -476,7 +476,7 @@ def _render_edge( return f"{start_id} -> {end_id} [{param_str}];\n" -@lru_cache(maxsize=None) +@cache def _style_params_from_link_type( styles: str, style_start: str, style_end: str ) -> list[tuple[str, str]]: diff --git a/sphinx_needs/directives/needgantt.py b/sphinx_needs/directives/needgantt.py index 1bb731c04..3b7ea2b5f 100644 --- a/sphinx_needs/directives/needgantt.py +++ b/sphinx_needs/directives/needgantt.py @@ -2,8 +2,8 @@ import os import re +from collections.abc import Sequence from datetime import datetime -from typing import Sequence from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needimport.py b/sphinx_needs/directives/needimport.py index d05fd5473..d14ac4a06 100644 --- a/sphinx_needs/directives/needimport.py +++ b/sphinx_needs/directives/needimport.py @@ -3,7 +3,7 @@ import json import os import re -from typing import Sequence +from collections.abc import Sequence from urllib.parse import urlparse import requests diff --git a/sphinx_needs/directives/needlist.py b/sphinx_needs/directives/needlist.py index b06b4aa7d..c090c0f47 100644 --- a/sphinx_needs/directives/needlist.py +++ b/sphinx_needs/directives/needlist.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Sequence +from collections.abc import Sequence from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needpie.py b/sphinx_needs/directives/needpie.py index 1244820bf..e5355abe7 100644 --- a/sphinx_needs/directives/needpie.py +++ b/sphinx_needs/directives/needpie.py @@ -1,7 +1,7 @@ from __future__ import annotations import hashlib -from typing import Iterable, Sequence +from collections.abc import Iterable, Sequence from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needreport.py b/sphinx_needs/directives/needreport.py index f67ceb831..240f670aa 100644 --- a/sphinx_needs/directives/needreport.py +++ b/sphinx_needs/directives/needreport.py @@ -1,7 +1,7 @@ from __future__ import annotations +from collections.abc import Sequence from pathlib import Path -from typing import Sequence from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needsequence.py b/sphinx_needs/directives/needsequence.py index d03c0b5d6..644e24773 100644 --- a/sphinx_needs/directives/needsequence.py +++ b/sphinx_needs/directives/needsequence.py @@ -2,7 +2,8 @@ import os import re -from typing import Any, Sequence +from collections.abc import Sequence +from typing import Any from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needservice.py b/sphinx_needs/directives/needservice.py index 12581998e..c9c3c86e0 100644 --- a/sphinx_needs/directives/needservice.py +++ b/sphinx_needs/directives/needservice.py @@ -1,6 +1,7 @@ from __future__ import annotations -from typing import Any, Sequence +from collections.abc import Sequence +from typing import Any from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needtable.py b/sphinx_needs/directives/needtable.py index 0b97f4ede..80f76df97 100644 --- a/sphinx_needs/directives/needtable.py +++ b/sphinx_needs/directives/needtable.py @@ -1,7 +1,8 @@ from __future__ import annotations import re -from typing import Any, Callable, Sequence +from collections.abc import Sequence +from typing import Any, Callable from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/directives/needuml.py b/sphinx_needs/directives/needuml.py index 1a7d182f4..92e15ebf1 100644 --- a/sphinx_needs/directives/needuml.py +++ b/sphinx_needs/directives/needuml.py @@ -3,7 +3,8 @@ import html import os import time -from typing import TYPE_CHECKING, Any, Dict, List, Sequence, TypedDict +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, TypedDict from docutils import nodes from docutils.parsers.rst import directives @@ -32,7 +33,7 @@ class ProcessedDataType(TypedDict): arguments: dict[str, Any] -ProcessedNeedsType = Dict[str, List[ProcessedDataType]] +ProcessedNeedsType = dict[str, list[ProcessedDataType]] class Needuml(nodes.General, nodes.Element): diff --git a/sphinx_needs/filter_common.py b/sphinx_needs/filter_common.py index e08decdfe..48821b8da 100644 --- a/sphinx_needs/filter_common.py +++ b/sphinx_needs/filter_common.py @@ -8,10 +8,11 @@ import ast import json import re +from collections.abc import Iterable from pathlib import Path from timeit import default_timer as timer from types import CodeType -from typing import Any, Iterable, TypedDict, overload +from typing import Any, TypedDict, overload from docutils import nodes from docutils.parsers.rst import directives diff --git a/sphinx_needs/functions/__init__.py b/sphinx_needs/functions/__init__.py index a067537f9..8972165db 100644 --- a/sphinx_needs/functions/__init__.py +++ b/sphinx_needs/functions/__init__.py @@ -1,5 +1,3 @@ -from typing import List - from sphinx_needs.functions.common import ( calc_sum, check_linked_values, @@ -17,7 +15,7 @@ resolve_variants_options, ) -NEEDS_COMMON_FUNCTIONS: List[DynamicFunction] = [ +NEEDS_COMMON_FUNCTIONS: list[DynamicFunction] = [ test, echo, copy, diff --git a/sphinx_needs/functions/functions.py b/sphinx_needs/functions/functions.py index 46ef090e5..7dd2cfc4c 100644 --- a/sphinx_needs/functions/functions.py +++ b/sphinx_needs/functions/functions.py @@ -146,10 +146,8 @@ def find_and_replace_node_content( new_children = [] if isinstance(node, NeedFunc): return node.get_text(env, need) - elif ( - not node.children - and isinstance(node, nodes.Text) - or isinstance(node, nodes.reference) + elif (not node.children and isinstance(node, nodes.Text)) or isinstance( + node, nodes.reference ): if isinstance(node, nodes.reference): try: diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 4b7bec027..e4917bda3 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -3,7 +3,7 @@ import contextlib from pathlib import Path from timeit import default_timer as timer # Used for timing measurements -from typing import Any, Callable, Dict, List, Type +from typing import Any, Callable from docutils import nodes from docutils.parsers.rst import directives @@ -120,9 +120,9 @@ VERSION = __version__ -_NODE_TYPES_T = Dict[ - Type[nodes.Element], - Callable[[Sphinx, nodes.document, str, List[nodes.Element]], None], +_NODE_TYPES_T = dict[ + type[nodes.Element], + Callable[[Sphinx, nodes.document, str, list[nodes.Element]], None], ] NODE_TYPES_PRIO: _NODE_TYPES_T = { # Node types to be checked before most others diff --git a/sphinx_needs/needsfile.py b/sphinx_needs/needsfile.py index 29e75ab4a..06ec149cc 100644 --- a/sphinx_needs/needsfile.py +++ b/sphinx_needs/needsfile.py @@ -9,10 +9,11 @@ import json import os import sys +from collections.abc import Iterable from copy import deepcopy from datetime import datetime from functools import lru_cache -from typing import Any, Iterable +from typing import Any from jsonschema import Draft7Validator from sphinx.config import Config @@ -92,7 +93,11 @@ def generate_needs_schema( class NeedsList: def __init__( - self, config: Config, outdir: str, confdir: str, add_schema: bool = True + self, + config: Config, + outdir: str | os.PathLike[str], + confdir: str | os.PathLike[str], + add_schema: bool = True, ) -> None: self.config = config self.needs_config = NeedsSphinxConfig(config) diff --git a/sphinx_needs/roles/__init__.py b/sphinx_needs/roles/__init__.py index dd2f1a0ad..bd28600e8 100644 --- a/sphinx_needs/roles/__init__.py +++ b/sphinx_needs/roles/__init__.py @@ -1,5 +1,3 @@ -from typing import List, Tuple - from docutils.nodes import Node, system_message from sphinx.roles import XRefRole @@ -12,7 +10,7 @@ class NeedsXRefRole(XRefRole): and store the files, in which the role is used. """ - def run(self) -> Tuple[List[Node], List[system_message]]: + def run(self) -> tuple[list[Node], list[system_message]]: # Stores the doc, in which the role got found add_doc(self.env, self.env.docname) return super().run() diff --git a/sphinx_needs/roles/need_part.py b/sphinx_needs/roles/need_part.py index 6db755186..fc1d789cc 100644 --- a/sphinx_needs/roles/need_part.py +++ b/sphinx_needs/roles/need_part.py @@ -11,7 +11,8 @@ import hashlib import re -from typing import Iterable, cast +from collections.abc import Iterable +from typing import cast from docutils import nodes from sphinx.application import Sphinx diff --git a/sphinx_needs/views.py b/sphinx_needs/views.py index 122c57899..43ab0d08b 100644 --- a/sphinx_needs/views.py +++ b/sphinx_needs/views.py @@ -1,13 +1,14 @@ from __future__ import annotations +from collections.abc import Iterable, Iterator, Mapping from itertools import chain -from typing import TYPE_CHECKING, Iterable, Iterator, List, Mapping, Optional, Tuple +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from sphinx_needs.data import NeedsInfoType -_IdSet = List[Tuple[str, Optional[str]]] +_IdSet = list[tuple[str, Optional[str]]] """Set of (need, part) ids.""" @@ -16,11 +17,11 @@ class _Indexes: __slots__ = ( "is_external", + "parts_to_needs", "status", "tags", - "types", "type_names", - "parts_to_needs", + "types", ) def __init__( @@ -50,7 +51,7 @@ def __init__( class _LazyIndexes: """A lazily computed view of indexes for needs.""" - __slots__ = ("_needs", "_indexes") + __slots__ = ("_indexes", "_needs") def __init__(self, needs: Mapping[str, NeedsInfoType]) -> None: self._needs = needs @@ -126,7 +127,7 @@ class NeedsView(Mapping[str, "NeedsInfoType"]): (e.g. dynamic values and back links have been computed etc) """ - __slots__ = ("_indexes", "_selected_ids", "_maybe_len") + __slots__ = ("_indexes", "_maybe_len", "_selected_ids") @classmethod def _from_needs(cls, needs: Mapping[str, NeedsInfoType], /) -> NeedsView: @@ -256,7 +257,7 @@ class NeedsAndPartsListView: and then overwriting a subset of fields with the values from the part. """ - __slots__ = ("_indexes", "_selected_ids", "_maybe_len") + __slots__ = ("_indexes", "_maybe_len", "_selected_ids") def __init__( self, diff --git a/tests/conftest.py b/tests/conftest.py index 2a0f8fcbb..c3c93af8d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,7 @@ import sys import tempfile from pathlib import Path -from typing import Any, Dict +from typing import Any import pytest from docutils.nodes import document @@ -131,7 +131,7 @@ def check_server_connection(log_path: str): xprocess.getinfo("http_server").terminate() -def test_js(self) -> Dict[str, Any]: +def test_js(self) -> dict[str, Any]: """ Executes Cypress tests using the specified `spec_pattern`. diff --git a/tests/test_github_issues.py b/tests/test_github_issues.py index 70709a29e..b9244c11f 100644 --- a/tests/test_github_issues.py +++ b/tests/test_github_issues.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest +from sphinx.util.console import strip_colors @pytest.mark.parametrize( @@ -33,7 +34,7 @@ def test_doc_github_44(test_app): assert "Test 2" in html assert "Test 3" in html - stderr = output.stderr.decode("utf-8") + stderr = strip_colors(output.stderr.decode("utf-8")) expected_warnings = [ f"{Path(str(app.srcdir)) / 'index.rst'}:11: WARNING: Need 'test_3' has unknown outgoing link 'test_123_broken' in field 'links' [needs.link_outgoing]" diff --git a/tests/test_needflow.py b/tests/test_needflow.py index 66afa968c..a18b9e315 100644 --- a/tests/test_needflow.py +++ b/tests/test_needflow.py @@ -57,6 +57,8 @@ def test_doc_build_html(test_app): if test_app.config.needs_flow_engine == "graphviz" and version_info < (7, 2): pass # links will be wrong due to https://github.com/sphinx-doc/sphinx/pull/11078 + elif test_app.config.needs_flow_engine == "graphviz" and os.name == "nt": + pass # TODO windows have // in links else: for link in ( '"../index.html#SPEC_1"', @@ -76,6 +78,8 @@ def test_doc_build_html(test_app): if test_app.config.needs_flow_engine == "graphviz" and version_info < (7, 2): pass # links will be wrong due to https://github.com/sphinx-doc/sphinx/pull/11078 + elif test_app.config.needs_flow_engine == "graphviz" and os.name == "nt": + pass # TODO windows have // in links else: for link in ( '"../index.html#SPEC_1"', @@ -144,6 +148,8 @@ def test_doc_build_needflow_incl_child_needs(test_app): if test_app.config.needs_flow_engine == "graphviz" and version_info < (7, 2): pass # links will be wrong due to https://github.com/sphinx-doc/sphinx/pull/11078 + elif test_app.config.needs_flow_engine == "graphviz" and os.name == "nt": + pass # TODO windows have // in links else: for link in ( '"../index.html#STORY_1"', diff --git a/tests/test_needimport.py b/tests/test_needimport.py index 2f781e864..c151d73db 100644 --- a/tests/test_needimport.py +++ b/tests/test_needimport.py @@ -25,9 +25,11 @@ def test_import_json(test_app): str(app.srcdir) + os.sep + "subdoc" + os.sep, "srcdir/subdoc/" ) ).splitlines() - assert warnings == [ - "srcdir/subdoc/deprecated_rel_path_import.rst:6: WARNING: Deprecation warning: Relative path must be relative to the current document in future, not to the conf.py location. Use a starting '/', like '/needs.json', to make the path relative to conf.py. [needs.deprecated]" - ] + + if os.name != "nt": + assert warnings == [ + "srcdir/subdoc/deprecated_rel_path_import.rst:6: WARNING: Deprecation warning: Relative path must be relative to the current document in future, not to the conf.py location. Use a starting '/', like '/needs.json', to make the path relative to conf.py. [needs.deprecated]" + ] html = Path(app.outdir, "index.html").read_text() assert "TEST IMPORT TITLE" in html diff --git a/tests/test_needs_external_needs_build.py b/tests/test_needs_external_needs_build.py index c64bda2e2..408f21d72 100644 --- a/tests/test_needs_external_needs_build.py +++ b/tests/test_needs_external_needs_build.py @@ -5,6 +5,7 @@ import pytest import responses from docutils import __version__ as doc_ver +from sphinx.util.console import strip_colors @pytest.mark.parametrize( @@ -26,7 +27,7 @@ def test_doc_build_html(test_app, sphinx_test_tempdir): ["sphinx-build", "-b", "html", "-D", rf"plantuml={plantuml}", src_dir, out_dir], capture_output=True, ) - assert output.stderr.decode("utf-8").splitlines() == [ + assert strip_colors(output.stderr.decode("utf-8")).splitlines() == [ "WARNING: http://my_company.com/docs/v1/index.html#TEST_01: Need 'EXT_TEST_01' has unknown outgoing link 'SPEC_1' in field 'links' [needs.external_link_outgoing]", "WARNING: ../../_build/html/index.html#TEST_01: Need 'EXT_REL_PATH_TEST_01' has unknown outgoing link 'SPEC_1' in field 'links' [needs.external_link_outgoing]", ] @@ -42,17 +43,16 @@ def test_doc_build_html(test_app, sphinx_test_tempdir): # first build output assert ( "updating environment: [new config] 3 added, 0 changed, 0 removed" - in output.stdout.decode("utf-8") + in strip_colors(output.stdout.decode("utf-8")) ) # second build output assert "loading pickled environment" in output_second.stdout.decode("utf-8") assert ( "updating environment: [new config] 3 added, 0 changed, 0 removed" - not in output_second.stdout.decode("utf-8") + not in strip_colors(output_second.stdout.decode("utf-8")) ) - assert ( - "updating environment: 0 added, 0 changed, 0 removed" - in output_second.stdout.decode("utf-8") + assert "updating environment: 0 added, 0 changed, 0 removed" in strip_colors( + output_second.stdout.decode("utf-8") ) diff --git a/tests/test_report_dead_links.py b/tests/test_report_dead_links.py index 16dfb2cea..7fa657c0f 100644 --- a/tests/test_report_dead_links.py +++ b/tests/test_report_dead_links.py @@ -2,6 +2,7 @@ from pathlib import Path import pytest +from sphinx.util.console import strip_colors @pytest.mark.parametrize( @@ -19,7 +20,7 @@ def test_needs_dead_links_warnings(test_app): ) # check there are expected warnings - stderr = output.stderr.decode("utf-8") + stderr = strip_colors(output.stderr.decode("utf-8")) expected_warnings = [ f"{Path(str(app.srcdir)) / 'index.rst'}:17: WARNING: Need 'REQ_004' has unknown outgoing link 'ANOTHER_DEAD_LINK' in field 'links' [needs.link_outgoing]", f"{Path(str(app.srcdir)) / 'index.rst'}:45: WARNING: Need 'TEST_004' has unknown outgoing link 'REQ_005.invalid' in field 'links' [needs.link_outgoing]", @@ -44,7 +45,7 @@ def test_needs_dead_links_warnings_needs_builder(test_app): ) # check there are expected warnings - stderr = output.stderr.decode("utf-8") + stderr = strip_colors(output.stderr.decode("utf-8")) expected_warnings = [ f"{Path(str(app.srcdir)) / 'index.rst'}:17: WARNING: Need 'REQ_004' has unknown outgoing link 'ANOTHER_DEAD_LINK' in field 'links' [needs.link_outgoing]", f"{Path(str(app.srcdir)) / 'index.rst'}:45: WARNING: Need 'TEST_004' has unknown outgoing link 'REQ_005.invalid' in field 'links' [needs.link_outgoing]",