Skip to content

Commit 6da857c

Browse files
authored
Update to Sphinx-Needs 7.0.0 (#451)
* Update to Sphinx-Needs 7.0.0 Migrate from deprecated needs_extra_options/needs_extra_links to needs_fields/needs_links replace needs_global_options with needs_default_layout remove obsolete filterwarnings
1 parent 1d195b0 commit 6da857c

8 files changed

Lines changed: 49 additions & 45 deletions

File tree

pyproject.toml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,6 @@ junit_family = "xunit1"
5151

5252
filterwarnings = [
5353
"ignore::pytest.PytestExperimentalApiWarning",
54-
# Silence third-party deprecations from sphinx_needs targeting Python 3.14 removals.
55-
# We'll drop these ignores once sphinx_needs releases a fix.
56-
"ignore:.*deprecated.*Python 3\\.14.*:DeprecationWarning:sphinx_needs\\..*",
57-
# Docutils is deprecating OptionParser in favor of argparse (0.21+).
58-
# This one originates inside sphinx_needs.layout.
59-
# We'll drop these ignores once sphinx/sphinx_needs releases a fix.
60-
"ignore:^The frontend\\.OptionParser class will be replaced by a subclass of argparse\\.ArgumentParser in Docutils 0\\.21 or later\\.:DeprecationWarning:sphinx_needs\\.layout",
61-
# This one bubbles up from stdlib optparse but is *explicitly* a Docutils message.
62-
# We match the full message to avoid silencing unrelated optparse warnings.
63-
# We'll drop these ignores once sphinx/sphinx_needs releases a fix.
64-
"ignore:^The frontend\\.Option class will be removed in Docutils 0\\.21 or later\\.:DeprecationWarning:optparse",
6554
]
6655
pythonpath = [
6756
"src/extensions/",

src/extensions/score_layout/__init__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,9 @@ def update_config(app: Sphinx, _config: Any):
4242
**sphinx_options.needs_layouts,
4343
**app.config.needs_layouts,
4444
}
45-
app.config.needs_global_options = {
46-
**sphinx_options.needs_global_options,
47-
**app.config.needs_global_options,
48-
}
45+
config_setdefault(
46+
app.config, "needs_default_layout", sphinx_options.needs_default_layout
47+
)
4948
config_setdefault(app.config, "html_theme", html_options.html_theme)
5049
app.config.html_context = {
5150
**html_options.return_html_context(app),

src/extensions/score_layout/sphinx_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,4 @@ class SingleLayout(TypedDict):
5757
},
5858
}
5959

60-
needs_global_options = {"layout": {"default": "score"}}
60+
needs_default_layout = "score"

src/extensions/score_metamodel/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ def setup(app: Sphinx) -> dict[str, str | bool]:
240240

241241
# Extend sphinx-needs config rather than overwriting
242242
app.config.needs_types += metamodel.needs_types
243-
app.config.needs_extra_links += metamodel.needs_extra_links
244-
app.config.needs_extra_options += metamodel.needs_extra_options
243+
app.config.needs_links.update(metamodel.needs_links)
244+
app.config.needs_fields.update(metamodel.needs_fields)
245245
app.config.graph_checks = metamodel.needs_graph_check
246246
app.config.prohibited_words_checks = metamodel.prohibited_words_checks
247247

src/extensions/score_metamodel/tests/test_metamodel_load.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,17 @@ def test_load_metamodel_data():
5252
assert result.needs_types[0]["mandatory_links"] == {"link1": "value1"}
5353
assert result.needs_types[0]["optional_links"] == {"link2": "value2"}
5454

55-
assert len(result.needs_extra_links) == 1
56-
assert result.needs_extra_links[0] == {
57-
"option": "link_option1",
58-
"incoming": "incoming1",
59-
"outgoing": "outgoing1",
55+
assert result.needs_links == {
56+
"link_option1": {
57+
"incoming": "incoming1",
58+
"outgoing": "outgoing1",
59+
}
6060
}
6161

62-
assert result.needs_extra_options == ["global_opt", "opt1", "opt2", "opt3"]
62+
assert result.needs_fields == {
63+
name: {"schema": {"type": "string"}, "default": ""}
64+
for name in ["global_opt", "opt1", "opt2", "opt3"]
65+
}
6366

6467
assert result.prohibited_words_checks[0] == ProhibitedWordCheck(
6568
name="title_check", option_check={"title": ["stop_word1"]}

src/extensions/score_metamodel/yaml_parser.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
@dataclass
3131
class MetaModelData:
3232
needs_types: list[ScoreNeedType]
33-
needs_extra_links: list[dict[str, str]]
34-
needs_extra_options: list[str]
33+
needs_links: dict[str, dict[str, str]]
34+
needs_fields: dict[str, dict[str, Any]]
3535
prohibited_words_checks: list[ProhibitedWordCheck]
3636
needs_graph_check: dict[str, object]
3737

@@ -147,20 +147,17 @@ def _parse_needs_types(
147147
return needs_types
148148

149149

150-
def _parse_links(links_dict: dict[str, dict[str, str]]) -> list[dict[str, str]]:
150+
def _parse_links(links_dict: dict[str, dict[str, str]]) -> dict[str, dict[str, str]]:
151151
"""
152-
Generate 'needs_extra_links' for sphinx-needs.
153-
154-
It has a slightly different structure than in our metamodel.yaml.
152+
Generate 'needs_links' for sphinx-needs.
155153
"""
156-
return [
157-
{
158-
"option": k,
154+
return {
155+
k: {
159156
"incoming": v["incoming"],
160157
"outgoing": v["outgoing"],
161158
}
162159
for k, v in links_dict.items()
163-
]
160+
}
164161

165162

166163
def _collect_all_options(needs_types: dict[str, ScoreNeedType]) -> set[str]:
@@ -173,13 +170,16 @@ def _collect_all_options(needs_types: dict[str, ScoreNeedType]) -> set[str]:
173170

174171
def _collect_all_custom_options(
175172
needs_types: dict[str, ScoreNeedType],
176-
):
177-
"""Generate 'needs_extra_options' for sphinx-needs."""
173+
) -> dict[str, dict[str, Any]]:
174+
"""Generate 'needs_fields' entries for sphinx-needs."""
178175

179176
defaults = default_options()
180177
all_options = _collect_all_options(needs_types)
181178

182-
return sorted(all_options - defaults)
179+
return {
180+
name: {"schema": {"type": "string"}, "default": ""}
181+
for name in sorted(all_options - defaults)
182+
}
183183

184184

185185
def load_metamodel_data() -> MetaModelData:
@@ -209,8 +209,8 @@ def load_metamodel_data() -> MetaModelData:
209209

210210
return MetaModelData(
211211
needs_types=list(needs_types.values()),
212-
needs_extra_links=_parse_links(data.get("needs_extra_links", {})),
213-
needs_extra_options=_collect_all_custom_options(needs_types),
212+
needs_links=_parse_links(data.get("needs_extra_links", {})),
213+
needs_fields=_collect_all_custom_options(needs_types),
214214
prohibited_words_checks=prohibited_words_checks,
215215
needs_graph_check=data.get("graph_checks", {}),
216216
)

src/requirements.in

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
Sphinx>=8.1.3,<9
22

3-
# At least 4.2.0, as it fixes a bug in combination with esbonio live preview:
4-
# https://github.com/useblocks/sphinx-needs/issues/1350
5-
sphinx-needs>=6.3.0,<7
3+
# At least 7.0.0 for Sphinx-Needs 7 support
4+
sphinx-needs>=7.0.0,<8
65

76
# Due to needed bugfix in 0.3.1
87
sphinx-collections>=0.3.1

src/requirements.txt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,20 @@ mdurl==0.1.2 \
806806
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
807807
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
808808
# via markdown-it-py
809+
minijinja==2.18.0 \
810+
--hash=sha256:01cd85bdae15c8ce44afd0cadb07808a0b0f55363f3ee3f9459c4e1663707095 \
811+
--hash=sha256:0b32f66d7138e6eefeabca39583a9d98e3bf8c8c7ebe0e287250dff436f4234f \
812+
--hash=sha256:168de945c4fe2a12f17e9190b80780646b68e487c341fcde8cba32680f7869a8 \
813+
--hash=sha256:1928d1522fb53adf50bf5a781068e8ad1b925f0f03579b48b1e98e7ae7526feb \
814+
--hash=sha256:1bb6a6be7851961a9192b158d436ad6c7b8b6d58e620c5da9d638a7e2f4a6b6d \
815+
--hash=sha256:2fb4e8a94e9f8337f894842084570e290a1cc39fb306cab457d405a129cf1fc7 \
816+
--hash=sha256:42daaf7310956b491f50ea356b751ed12d9ebb23e82e7136871afd19f87aab80 \
817+
--hash=sha256:8b252458a3a51dc09bef48422f68595684984785e40300b426e318c5916c2704 \
818+
--hash=sha256:c3ccdc1d48939068c08962e6051541fd9a3af67d20ceb08262a540ea9364dcf7 \
819+
--hash=sha256:d77e7bce8fe2ddd3dfa13f142b2e8d858c3a1ea77c927337a2c9eade0da227bc \
820+
--hash=sha256:f2116a9b0f1211d42d6b148bb6abd34695b0351f5c8cfa8533a21e7cf109d090 \
821+
--hash=sha256:f6e9ac8256fc5453e2c5ab91a44201447ea4975c341535a7aa623447b88b7c4e
822+
# via sphinx-needs
809823
myst-parser==5.0.0 \
810824
--hash=sha256:ab31e516024918296e169139072b81592336f2fef55b8986aa31c9f04b5f7211 \
811825
--hash=sha256:f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a
@@ -1242,9 +1256,9 @@ sphinx-design==0.7.0 \
12421256
--hash=sha256:d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a \
12431257
--hash=sha256:f82bf179951d58f55dca78ab3706aeafa496b741a91b1911d371441127d64282
12441258
# via -r src/requirements.in
1245-
sphinx-needs[plotting]==6.3.0 \
1246-
--hash=sha256:761901765844c69f6181580065b099b31016895a86962a25e7860a9f5bea54a2 \
1247-
--hash=sha256:a8a1cccc1525b94551e7a2f9525bf36eaae88654abceb5047b5470d57472b346
1259+
sphinx-needs[plotting]==7.0.0 \
1260+
--hash=sha256:3fa665181c323d0b76f6de0d8565f925f36933e8af4c253d34127755eff07371 \
1261+
--hash=sha256:7ea120a1127cc532ea4610e814c26824b05d296ce8c2f6d046d5f6ed64d85d0f
12481262
# via
12491263
# -r src/requirements.in
12501264
# needs-config-writer

0 commit comments

Comments
 (0)