Skip to content

Conversation

@chrisjsewell
Copy link
Member

@chrisjsewell chrisjsewell commented Dec 23, 2025

This pull request introduces a new, more flexible way to enable variant support for need fields and links by adding a parse_variants option to the configuration. It deprecates the old needs_variant_options setting in favor of specifying parse_variants directly in needs_fields and needs_extra_links. The documentation and codebase are updated to reflect this change, improving clarity and flexibility for users configuring variant handling.

Configuration and API changes:

  • Added a parse_variants boolean option to needs_fields and needs_extra_links, allowing users to enable variant parsing on a per-field or per-link basis. This replaces the previous global needs_variant_options list.

  • Updated the API (add_extra_option) and configuration loading logic to accept and propagate the new parse_variants parameter.

Deprecation and backward compatibility:

  • Deprecated the needs_variant_options configuration option. If used, a warning is issued, and backward compatibility is maintained by enabling parse_variants for the specified fields.
    Documentation updates:

  • Updated documentation in docs/configuration.rst and docs/dynamic_functions.rst to describe the new parse_variants option and mark needs_variant_options as deprecated. Examples and usage instructions are revised accordingly.

Schema and internal logic changes:

  • Refactored schema and internal logic to use parse_variants instead of allow_variant_functions, and updated related variable names and validation.

Example and test configuration updates:

  • Updated example project configuration (docs/ubproject.toml) to use the new parse_variants option instead of the deprecated variant_options list.

@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 80.95238% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.33%. Comparing base (4e10030) to head (e88b223).
⚠️ Report is 223 commits behind head on master.

Files with missing lines Patch % Lines
sphinx_needs/needs_schema.py 76.19% 5 Missing ⚠️
sphinx_needs/needs.py 76.92% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1614      +/-   ##
==========================================
+ Coverage   86.87%   88.33%   +1.45%     
==========================================
  Files          56       70      +14     
  Lines        6532     9947    +3415     
==========================================
+ Hits         5675     8787    +3112     
- Misses        857     1160     +303     
Flag Coverage Δ
pytests 88.33% <80.95%> (+1.45%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chrisjsewell chrisjsewell marked this pull request as ready for review December 23, 2025 22:45
@chrisjsewell chrisjsewell requested a review from ubmarco December 24, 2025 09:22
Copy link
Member

@ubmarco ubmarco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! We should document how to use variants for array items. Can be done in another PR. I added test cases for typed variants. If you look at those you see that multi value input for a non-array field is not detected as error:

:field_bool: <<['tag_a' in build_tags]:1, 0>>, <<['tag_b' in build_tags]:0, 1>>

It's picking up the first value and does not care about the rest. It should complain, as it does for non-variant literals:

:field_bool: 1, 0

then I correctly get

Need could not be created: Extra option 'field_bool' is invalid: Cannot convert '1, 0' to boolean

@chrisjsewell
Copy link
Member Author

Looks good! We should document how to use variants for array items. Can be done in another PR. I added test cases for typed variants. If you look at those you see that multi value input for a non-array field is not detected as error:

I don't think this is behaving as you think @ubmarco

see:

case "boolean" | "integer" | "number":
if (
self.allow_dynamic_functions
and value.lstrip().startswith("[[")
and value.rstrip().endswith("]]")
):
return FieldFunctionArray(
(DynamicFunctionParsed.from_string(value.strip()[2:-2]),)
)
elif (
self.allow_variant_functions
and value.lstrip().startswith("<<")
and value.rstrip().endswith(">>")
):
return FieldFunctionArray(
(
VariantFunctionParsed.from_string(
value.strip()[2:-2],
partial(_from_string_item, item_type=self.type),
),
)
)
else:
return FieldLiteralValue(_from_string_item(value, self.type))

The entire thing is parsed as a single variant, e.g. ['tag_a' in build_tags]:1, 0>>, <<['tag_b' in build_tags]:0, 1,
and this is what the parsed item looks like:
FieldFunctionArray(value=(VariantFunctionParsed(expressions=(("'tag_a' in build_tags", True, True), ("0>>, <<['tag_b' in build_tags]", False, False)), final_value=True),))

Of course, we could consider changing that behaviour, like finding the "first" closing >>. But yeh that would be for another PR

@chrisjsewell chrisjsewell requested a review from ubmarco December 25, 2025 13:44
@chrisjsewell chrisjsewell changed the title ✨ Add parse_variants to needs_fields / needs_extra_link, deprecate needs_variant_options ✨🎄 Add parse_variants to needs_fields / needs_extra_link, deprecate needs_variant_options Dec 25, 2025
@ubmarco
Copy link
Member

ubmarco commented Dec 30, 2025

I'm confused about the behavior. When looking at

:field_array_int: <<['tag_a' in build_tags]:1, 2>>, <<['tag_b' in build_tags]:3, 4>>

which is an array of int, it delivers [1, 3]:
'SPEC_007': dict({
'docname': 'index',

If the outer type is an array, doesn't it split first?
def _split_list(

So works as expected from my point of view. After the split the type is checked and correctly evaluated.

@chrisjsewell
Copy link
Member Author

If the outer type is an array, doesn't it split first?

Yes, the parsing logic for arrays is different to non-arrays, that's the point.

Anyway, the parsing logic had not changed in this PR

@chrisjsewell chrisjsewell merged commit 029cff3 into master Dec 30, 2025
22 checks passed
@chrisjsewell chrisjsewell deleted the dynamic-parse-config branch December 30, 2025 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

With Sphinx-Needs 6.0.0 it is not possible to use variant information on links

3 participants