Skip to content

Commit 7640110

Browse files
authored
‼️ Improve needs default field application (via needs_global_options) (#1478)
Previously defaults would be applied to any fields of a need with a "falsy" value, e.g. `None`, `False`, `0` , `""`, `[]`. ... This is an issue, if the user wants to specifically set fields to these values, without them being overridden by defaults. Therefore, now defaults are only applied to fields with a missing or `None` value. In the need directive context, this means that defaults will only be set for fields not specifically set in the directive options. In the external/import need context, defaults will only be applied to missing keys in the `needs.json`, or fields with the value set to `null`. For predicate defaults, the context passed to the expression has been restricted to a subset of fields, and these values are no longer mutated by previous defaults, i.e. each predicate gets the same immutable context data. This makes these predicates more isolated / understandable, and allows for them potentially later being co-located with the type information. ---- ‼️ Breaking This PR may be breaking: 1. For users expecting defaults to be applied to external/import `needs.json`, although I would suggest this was never the intention for these defaults and that `needs.json` should, at least by default, be seen as static ingest data which has already had defaults etc applied. 2. For users with "exotic" predicate expressions, that potentially rely on the application of previous defaults.
1 parent 54d82a8 commit 7640110

18 files changed

+356
-182
lines changed

docs/configuration.rst

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,22 @@ Defaults will be used if the field is not set specifically by the user and thus
349349
}
350350
351351
To set a default based on a one or more predicates, use the ``predicates`` key.
352-
These predicates are a list of (:ref:`filter string <filter_string>`, value), evaluated in order, with the first match set as the default value.
352+
These predicates are a list of ``(match expression, value)``, evaluated in order, with the first match set as the default value.
353+
354+
A match expression is a string, using Python syntax, that will be evaluated against data from each need (before the resolution of defaults or dynamic functions etc):
355+
356+
- `id` (`str`)
357+
- `type` (`str`)
358+
- `title` (`str`)
359+
- `tags` (`tuple[str, ...]`)
360+
- `status` (`str | None`)
361+
- `docname` (`str | None`)
362+
- `is_external` (`bool`)
363+
- `is_import` (`bool`)
364+
- :ref:`needs_extra_options` (`str`)
365+
- :ref:`needs_extra_links` (`tuple[str, ...]`)
366+
- :ref:`needs_filter_data`
367+
353368
If no predicates match, the ``default`` value is used (if present).
354369

355370
.. code-block:: python
@@ -380,17 +395,6 @@ If no predicates match, the ``default`` value is used (if present).
380395
"option1": {"default": '[[copy("id")]]'}
381396
}
382397
383-
.. warning::
384-
385-
The filter string gets executed against the current need only and has no access to other needs.
386-
So avoid any references to other needs in the filter string.
387-
388-
If you need access to other needs for complex filtering, you can maybe provide your own :ref:`dynamic_functions`
389-
and perform the filtering there.
390-
391-
Default replacements are done, for each field, in the order they are defined in the configuration,
392-
so a filter string should not depend on the value of a field below it in the configuration.
393-
394398
.. _`needs_report_dead_links`:
395399

396400
needs_report_dead_links

0 commit comments

Comments
 (0)