From 4904141e90108f94fac0b71f17a0cfeee01fcef4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Sep 2024 21:40:00 +0200 Subject: [PATCH] [pre-commit.ci] pre-commit autoupdate (#1306) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Chris Sewell --- .pre-commit-config.yaml | 2 +- docs/api.rst | 2 +- docs/filter.rst | 144 +++++++++---------------------- sphinx_needs/functions/common.py | 130 +++++----------------------- 4 files changed, 64 insertions(+), 214 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1446ea40f..558d9d342 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.5 + rev: v0.6.7 hooks: - id: ruff args: [--fix] diff --git a/docs/api.rst b/docs/api.rst index e8aa1801f..f71acb4d7 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -38,4 +38,4 @@ Data ---- .. automodule:: sphinx_needs.data - :members: NeedsInfoType, NeedsView + :members: NeedsInfoType, NeedsView, NeedsPartsView diff --git a/docs/filter.rst b/docs/filter.rst index f33699bc3..8f4fc004e 100644 --- a/docs/filter.rst +++ b/docs/filter.rst @@ -44,16 +44,12 @@ You can easily filter for multiple statuses by separating them by ";". Example: .. dropdown:: Show example - .. code-block:: rst + .. need-example:: .. needlist:: :status: open :show_status: - .. needlist:: - :status: open - :show_status: - .. _option_tags: tags @@ -65,17 +61,12 @@ To search for multiple tags, simply separate them by using ";". .. dropdown:: Show example - .. code-block:: rst + .. need-example:: .. needlist:: :tags: main_example :show_tags: - .. needlist:: - :tags: main_example - :show_tags: - - .. _option_types: types @@ -84,16 +75,11 @@ For **:types:** the type itself or the human-readable type-title can be used as .. dropdown:: Show example - .. code-block:: rst + .. need-example:: .. needtable:: :types: test - .. needtable:: - :types: test - :style: table - - .. _option_sort_by: sort_by @@ -102,20 +88,12 @@ Sorts the result list. Allowed values are ``status`` or any alphanumerical prope .. dropdown:: Show example - .. code-block:: rst + .. need-example:: .. needtable:: :sort_by: id :status: open - - .. needtable:: - :sort_by: id - :status: open - :style: table - - - .. _option_filter: filter @@ -141,9 +119,9 @@ The usage of a filter string is supported/required by: The filter string must be a valid Python expression: -.. code-block:: rst +.. need-example:: - :need_count:`type=='spec' and status.upper()!='OPEN'` + :need_count:`type=='spec' and status != 'open'` A filter string gets evaluated on needs and need_parts! A need_part inherits all options from its parent need, if the need_part has no own content for this option. @@ -157,11 +135,11 @@ This allows to perform searches for need_parts, where search options are based o The following filter will find all need_parts, which are part of a need, which has a tag called *important*. -.. code-block:: rst +.. need-example:: - :need_count:`is_part and 'important' in tags` + :need_count:`is_part and 'car' in tags` -Inside a filter string the following variables/functions can be used: +Inside a filter string all the fields of :py:class:`.NeedsInfoType` can be used, including: * **tags** as Python list (compare like ``"B" in tags``) * **type** as Python string (compare like ``"story" == type``) @@ -176,8 +154,6 @@ Inside a filter string the following variables/functions can be used: * **is_need** as Python boolean. (compare like ``is_need``) * **is_part** as Python boolean. (compare like ``is_part``) * **parts** as Python list with :ref:`need_part` of the current need. (compare like ``len(parts)>0``) -* :ref:`re_search`, as Python function for performing searches with a regular expression -* **needs** as Python dict. Contains all needs. Helpful to perform complex filters on links (added 0.3.15). * **sections** as list of sections names, th which the need belongs to. * **section_name** as string, which defines the last/lowest section a need belongs to. * **docname** as string, which defines the name of the document in which a need is defined, without the extension (similar to Sphinx' ``:doc:`` role) @@ -193,67 +169,50 @@ Additional variables for :ref:`need_part`: * **id_complete** as Python string. Contains the concatenated ids of parent need and need_part. (compare like ``id_complete != 'ABC_01.03'``) - .. note:: If extra options were specified using :ref:`needs_extra_options` then those will be available for use in filter expressions as well. -If your expression is valid and it's True, the related need is added to the filter result list. -If it is invalid or returns False, the related need is not taken into account for the current filter. - -.. dropdown:: Show example - - .. code-block:: rst - .. req:: Requirement A - :tags: A; filter_example - :status: open +Finally, the following are available: - .. req:: Requirement B - :tags: B; filter_example - :status: closed - - .. spec:: Specification A - :tags: A; filter_example - :status: closed +* :ref:`re_search`, as Python function for performing searches with a regular expression +* **needs** as :class:`.NeedsPartsView` object, which contains all needs and need_parts. - .. spec:: Specification B - :tags: B; filter_example - :status: open +If your expression is valid and it's True, the related need is added to the filter result list. +If it is invalid or returns False, the related need is not taken into account for the current filter. - .. test:: Test 1 - :tags: filter_example +.. dropdown:: Show example - .. needtable:: - :filter: "filter_example" in tags and ("B" in tags or ("spec" == type and "closed" == status)) or "test" == type + .. need-example:: ``filter`` option - This will have the following result: + needs: - .. req:: Requirement A - :tags: A; filter_example - :status: open - :hide: + .. req:: Requirement A + :tags: A; filter_example + :status: open + :hide: - .. req:: Requirement B - :tags: B; filter_example - :status: closed - :hide: + .. req:: Requirement B + :tags: B; filter_example + :status: closed + :hide: - .. spec:: Specification A - :tags: A; filter_example - :status: closed - :hide: + .. spec:: Specification A + :tags: A; filter_example + :status: closed + :hide: - .. spec:: Specification B - :tags: B; filter_example - :status: open - :hide: + .. spec:: Specification B + :tags: B; filter_example + :status: open + :hide: - .. test:: Test 1 - :tags: filter_example - :hide: + .. test:: Test 1 + :tags: filter_example + :hide: - .. needfilter:: - :filter: "filter_example" in tags and (("B" in tags or ("spec" == type and "closed" == status)) or "test" == type) + .. needfilter:: + :filter: "filter_example" in tags and (("B" in tags or ("spec" == type and "closed" == status)) or "test" == type) .. _re_search: @@ -270,18 +229,13 @@ The second parameter should be one of the above variables(status, id, content, . This example uses a regular expressions to find all needs with an e-mail address in title. - .. code-block:: rst + .. need-example:: .. req:: Set admin e-mail to admin@mycompany.com .. needlist:: :filter: search("([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", title) - .. req:: Set admin e-mail to admin@mycompany.com - - .. needlist:: - :filter: search("([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", title) - .. _export_id: export_id @@ -311,7 +265,7 @@ with the help of Python. The used code must define a variable ``results``, which must be a list and contains the filtered needs. -.. code-block:: rst +.. need-example:: .. needtable:: :columns: id, title, type, links, links_back @@ -331,24 +285,6 @@ The used code must define a variable ``results``, which must be a list and conta results.append(need) results.append(needs_dict[links_id]) -.. needtable:: - :columns: id, title, type, links, links_back - :style: table - - # Collect all requirements and specs, - # which are linked to each other. - - results = [] - # Lets create a needs_dict to address needs by ids more easily. - needs_dict = {x['id']: x for x in needs} - - for need in needs: - if need['type'] == 'req': - for links_id in need['links']: - if needs_dict[links_id]['type'] == 'spec': - results.append(need) - results.append(needs_dict[links_id]) - The code has access to a variable called ``needs``, which contains a copy of all needs. So manipulations on the values in ``needs`` do not have any affects. diff --git a/sphinx_needs/functions/common.py b/sphinx_needs/functions/common.py index 105d21565..5bd1e1787 100644 --- a/sphinx_needs/functions/common.py +++ b/sphinx_needs/functions/common.py @@ -35,16 +35,12 @@ def test( Collects every given args and kwargs and returns a single string, which contains their values/keys. - .. code-block:: jinja + .. need-example:: .. req:: test requirement :ndf:`test('arg_1', [1,2,3], my_keyword='awesome')` - .. req:: test requirement - - :ndf:`test('arg_1', [1,2,3], my_keyword='awesome')` - :return: single test string """ need_id = "none" if need is None else need["id"] @@ -65,12 +61,10 @@ def echo( Just returns the given string back. Mostly useful for tests. - .. code-block:: jinja + .. need-example:: A nice :ndf:`echo("first test")` for a dynamic function. - **Result**: A nice :ndf:`echo("first test")` for a dynamic function. - """ return text @@ -88,7 +82,7 @@ def copy( """ Copies the value of one need option to another - .. code-block:: jinja + .. need-example:: .. req:: copy-example :id: copy_1 @@ -113,29 +107,6 @@ def copy( Also copies all tags from copy_1. - .. req:: copy-example - :id: copy_1 - :tags: tag_1, tag_2, tag_3 - :status: open - - .. spec:: copy-example implementation - :id: copy_2 - :status: [[copy("status", "copy_1")]] - :links: copy_1 - :comment: [[copy("id")]] - - Copies status of ``copy_1`` to own status. - Sets also a comment, which copies the id of own need. - - .. test:: test of specification and requirement - :id: copy_3 - :links: copy_2; [[copy('links', 'copy_2')]] - :tags: [[copy('tags', 'copy_1')]] - - Set own link to ``copy_2`` and also copies all links from it. - - Also copies all tags from copy_1. - If the filter_string needs to compare a value from the current need and the value is unknown yet, you can reference the valued field by using ``current_need["my_field"]`` inside the filter string. Small example:: @@ -219,7 +190,7 @@ def check_linked_values( **Needs used as input data** - .. code-block:: jinja + .. need-example:: .. req:: Input A :id: clv_A @@ -233,71 +204,38 @@ def check_linked_values( :id: clv_C :status: closed - .. req:: Input A - :id: clv_A - :status: in progress - :collapse: False - - .. req:: Input B - :id: clv_B - :status: in progress - :collapse: False - - .. spec:: Input C - :id: clv_C - :status: closed - :collapse: False - - **Example 1: Positive check** Status gets set to *progress*. - .. code-block:: jinja + .. need-example:: .. spec:: result 1: Positive check :links: clv_A, clv_B :status: [[check_linked_values('progress', 'status', 'in progress' )]] - - .. spec:: result 1: Positive check - :id: clv_1 - :links: clv_A, clv_B - :status: [[check_linked_values('progress', 'status', 'in progress' )]] - :collapse: False - + :collapse: False **Example 2: Negative check** Status gets not set to *progress*, because status of linked need *clv_C* does not match *"in progress"*. - .. code-block:: jinja + .. need-example:: .. spec:: result 2: Negative check :links: clv_A, clv_B, clv_C :status: [[check_linked_values('progress', 'status', 'in progress' )]] - - .. spec:: result 2: Negative check - :id: clv_2 - :links: clv_A, clv_B, clv_C - :status: [[check_linked_values('progress', 'status', 'in progress' )]] - :collapse: False - + :collapse: False **Example 3: Positive check thanks of used filter** status gets set to *progress*, because linked need *clv_C* is not part of the filter. - .. code-block:: jinja + .. need-example:: .. spec:: result 3: Positive check thanks of used filter :links: clv_A, clv_B, clv_C :status: [[check_linked_values('progress', 'status', 'in progress', 'type == "req" ' )]] - - .. spec:: result 3: Positive check thanks of used filter - :id: clv_3 - :links: clv_A, clv_B, clv_C - :status: [[check_linked_values('progress', 'status', 'in progress', 'type == "req" ' )]] - :collapse: False + :collapse: False **Example 4: Positive check thanks of one_hit option** @@ -305,32 +243,22 @@ def check_linked_values( That's because ``one_hit`` is used so that only one linked need must have the searched value. - .. code-block:: jinja + .. need-example:: .. spec:: result 4: Positive check thanks of one_hit option :links: clv_A, clv_B, clv_C :status: [[check_linked_values('progress', 'status', 'in progress', one_hit=True )]] - - .. spec:: result 4: Positive check thanks of one_hit option - :id: clv_4 - :links: clv_A, clv_B, clv_C - :status: [[check_linked_values('progress', 'status', 'in progress', one_hit=True )]] - :collapse: False + :collapse: False **Result 5: Two checks and a joint status** Two checks are performed and both are positive. So their results get joined. - .. code-block:: jinja + .. need-example:: .. spec:: result 5: Two checks and a joint status :links: clv_A, clv_B, clv_C :status: [[check_linked_values('progress', 'status', 'in progress', one_hit=True )]] [[check_linked_values('closed', 'status', 'closed', one_hit=True )]] - - .. spec:: result 5: Two checks and a joint status - :id: clv_5 - :links: clv_A, clv_B, clv_C - :status: [[check_linked_values('progress', 'status', 'in progress', one_hit=True )]] [[check_linked_values('closed', 'status', 'closed', one_hit=True )]] - :collapse: False + :collapse: False :param result: value, which gets returned if all linked needs have parsed the checks :param search_option: option name, which is used n linked needs for the search @@ -404,52 +332,38 @@ def calc_sum( **Example 2** - .. code-block:: jinja + .. need-example:: .. req:: Result 1 :amount: [[calc_sum("hours")]] - - .. req:: Result 1 - :amount: [[calc_sum("hours")]] - :collapse: False + :collapse: False **Example 2** - .. code-block:: jinja + .. need-example:: .. req:: Result 2 :amount: [[calc_sum("hours", "hours.isdigit() and float(hours) > 10")]] - - .. req:: Result 2 - :amount: [[calc_sum("hours", "hours.isdigit() and float(hours) > 10")]] - :collapse: False + :collapse: False **Example 3** - .. code-block:: jinja + .. need-example:: .. req:: Result 3 :links: sum_input_1; sum_input_3 :amount: [[calc_sum("hours", links_only="True")]] - - .. req:: Result 3 - :links: sum_input_1; sum_input_3 - :amount: [[calc_sum("hours", links_only="True")]] - :collapse: False + :collapse: False **Example 4** - .. code-block:: jinja + .. need-example:: .. req:: Result 4 :links: sum_input_1; sum_input_3 :amount: [[calc_sum("hours", "hours.isdigit() and float(hours) > 10", "True")]] - - .. req:: Result 4 - :links: sum_input_1; sum_input_3 - :amount: [[calc_sum("hours", "hours.isdigit() and float(hours) > 10", "True")]] - :collapse: False + :collapse: False :param option: Options, from which the numbers shall be taken :param filter: Filter string, which all needs must passed to get their value added.