pytest-dev / pytest-dev/pytest

`'store_true'` does not work correctly in parser.addoption

Open
#9,303 15 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

topic: config type: bug
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

One more from https://github.com/conda-forge/staged-recipes/pull/16888, where (after patching in workarounds for #9300 & #9301), the test suite failed with

==================================== ERRORS ====================================
________________ ERROR at setup of test_serialization[cpu-gelu] ________________

self = <_pytest.config.Config object at 0x7fc1975d41c0>
name = 'skip_custom_ops', default = <NOTSET>, skip = False

    def getoption(self, name: str, default=notset, skip: bool = False):
        """Return command line option value.
    
        :param name: Name of the option.  You may also specify
            the literal ``--OPT`` option instead of the "dest" option name.
        :param default: Default value if no option of that name exists.
        :param skip: If True, raise pytest.skip if option does not exists
            or has a None value.
        """
        name = self._opt2dest.get(name, name)
        try:
>           val = getattr(self.option, name)
E           AttributeError: 'Namespace' object has no attribute 'skip_custom_ops'

../[...]/_pytest/config/__init__.py:1463: AttributeError

The above exception was the direct cause of the following exception:

request = <SubRequest 'set_global_variables' for <Function test_serialization[cpu-gelu]>>

    @pytest.fixture(scope="session", autouse=True)
    def set_global_variables(request):
>       if request.config.getoption("--skip-custom-ops"):
E       ValueError: no option named 'skip_custom_ops

So from that, it looks like something is going wrong with skip_custom_ops. Chasing around the upstream repo I find that this option is added here as follows:

def pytest_addoption(parser):
    parser.addoption(
        "--skip-custom-ops",
        action="store_true",
        help="When a custom op is being loaded in a test, skip this test.",
    )

The pytest docs for parser.addoption say that this works like argparse, where the linked docs say:

'store_true' and 'store_false' - These are special cases of 'store_const' used for storing the values True and False respectively. In addition, they create default values of False and True respectively.

What caught my eye in the stack trace was the default = <NOTSET>, which is clearly at odds with that documentation. To verify this hypothesis, I added the following patch

diff --git a/tensorflow_addons/utils/test_utils.py b/tensorflow_addons/utils/test_utils.py
index 9d1dec0..0efd707 100644
--- a/tensorflow_addons/utils/test_utils.py
+++ b/tensorflow_addons/utils/test_utils.py
@@ -134,7 +134,8 @@ def set_seeds():
 def pytest_addoption(parser):
     parser.addoption(
         "--skip-custom-ops",
-        action="store_true",
+        action="store",
+        default=True,
         help="When a custom op is being loaded in a test, skip this test.",
     )

and voilà, it works.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing parser.addoption and Config.getoption, using the tensorflow_addons/utils/test_utils.py pytest_addoption example and its store_true option. Reproduce the missing skip_custom_ops behavior with a focused test, then verify that store_true supplies the expected default and that the reported getoption call succeeds.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.