The current (docname, lineno) sort (added in #1657) provides determinism, but users have no way to explicitly control the order in which needextend directives are applied. This matters when multiple extends target the same need and the result depends on application order (e.g., one sets a field, another appends to it).
Proposed: :extend_order: directive option
Add an optional :extend_order: option to the needextend directive that accepts an integer value (default 0). Extensions are then sorted by (extend_order, docname, lineno), with lower values applied first.
Why extend_order and not priority? The needextend directive uses a DummyOptionSpec that accepts any option name as a need field modification. A generic name like priority could clash with a user-defined field of the same name. extend_order is clearly namespaced to the extension mechanism and very unlikely to collide with user fields.
Example usage:
.. needextend:: REQ_001
:extend_order: 10
:status: in_progress
.. needextend:: REQ_001
:extend_order: 20
:+tags: reviewed
This guarantees the status is set before tags are appended, regardless of source file location.
Implementation outline
-
Directive option: Pop "extend_order" from options in run() (same pattern as strict), parse it as an integer defaulting to 0. Store it in the NeedsExtendType data dict.
-
Data schema: Add extend_order: int field to NeedsExtendType in sphinx_needs/data.py.
-
Sort key: Update the sort in extend_needs_data() from: python sorted(extends.values(), key=lambda x: (x["docname"], x["lineno"])) to: python sorted(extends.values(), key=lambda x: (x["extend_order"], x["docname"], x["lineno"]))
-
Global default: Optionally add a needs_needextend_order config option to set a default order for all needextend directives (default 0).
-
Documentation: Document the :extend_order: option in docs/directives/needextend.rst with examples showing ordering control.
-
Tests: Add test cases verifying that priority ordering overrides source-location ordering.
The current
(docname, lineno)sort (added in #1657) provides determinism, but users have no way to explicitly control the order in whichneedextenddirectives are applied. This matters when multiple extends target the same need and the result depends on application order (e.g., one sets a field, another appends to it).Proposed:
:extend_order:directive optionAdd an optional
:extend_order:option to theneedextenddirective that accepts an integer value (default0). Extensions are then sorted by(extend_order, docname, lineno), with lower values applied first.Example usage:
This guarantees the status is set before tags are appended, regardless of source file location.
Implementation outline
Directive option: Pop
"extend_order"from options inrun()(same pattern asstrict), parse it as an integer defaulting to0. Store it in theNeedsExtendTypedata dict.Data schema: Add
extend_order: intfield toNeedsExtendTypeinsphinx_needs/data.py.Sort key: Update the sort in
extend_needs_data()from:python sorted(extends.values(), key=lambda x: (x["docname"], x["lineno"]))to:python sorted(extends.values(), key=lambda x: (x["extend_order"], x["docname"], x["lineno"]))Global default: Optionally add a
needs_needextend_orderconfig option to set a default order for all needextend directives (default0).Documentation: Document the
:extend_order:option indocs/directives/needextend.rstwith examples showing ordering control.Tests: Add test cases verifying that priority ordering overrides source-location ordering.