Skip to content

pytest.Config.getoption default argument not working as expected #10558

@ryancausey

Description

@ryancausey
  • a detailed description of the bug or problem you are having
  • output of pip list from the virtual environment you are using
  • pytest and operating system versions
  • minimal example if possible

I'm running into an issue where the default argument to pytest.Config.getoption is not working as expected, or at least not as it is documented.

Reproduction steps

  1. define the pytest_generate_tests hook in a conftest.py file.
  2. use the metafunc argument to access the pytest.Config object via metafunc.config.
  3. try to call getoption on an option that was not passed while specifying a default, E.G. metafunc.config.getoption(name="foobaz", default={})

Exepected behavior

The empty dictionary is returned as it is set as the default.

Actual behavior

None is returned instead.

Possible fix

The issue appears to be the check inside getoption on line 1541:

(Pdb) ll
1529        def getoption(self, name: str, default=notset, skip: bool = False):
1530            """Return command line option value.
1531
1532            :param name: Name of the option.  You may also specify
1533                the literal ``--OPT`` option instead of the "dest" option name.
1534            :param default: Default value if no option of that name exists.
1535            :param skip: If True, raise pytest.skip if option does not exists
1536                or has a None value.
1537            """
1538            name = self._opt2dest.get(name, name)
1539            try:
1540                val = getattr(self.option, name)
1541 ->             if val is None and skip:
1542                    raise AttributeError(name)
1543                return val
1544            except AttributeError as e:
1545                if default is not notset:
1546                    return default
1547                if skip:
1548                    import pytest
1549
1550                    pytest.skip(f"no {name!r} option found")
1551                raise ValueError(f"no option named {name!r}") from e
(Pdb) print(val)
None
(Pdb) print(skip)
False
(Pdb)

Since skip is not passed, it defaults to False which means even if a default is set to something other than notset, that default value will never be returned unless skip is also set to True. I believe the fix is to change line 1541 to:

if val is None:

This will be a breaking change, however, as it would mean not passing default would lead to a ValueError being raised when skip is False.

Minimal reproduction example

# conftest.py
def pytest_generate_tests(metafunc):
    my_cool_option = metafunc.config.getoption(name="foobaz", default={})
    assert my_cool_option is not None

Pip list

Actually it's `poetry show`

$ poetry show
astroid               2.12.10   An abstract syntax tree for Python with inference support.
attrs                 22.1.0    Classes Without Boilerplate
aws-xray-sdk          2.10.0    The AWS X-Ray SDK for Python (the SDK) enables Python developers to record and emit information from within their applications to the AWS X-Ray se...
awscrt                0.14.0    A common runtime for AWS Python projects
backoff               2.1.2     Function decoration for backoff and retry
black                 22.8.0    The uncompromising code formatter.
boto3                 1.26.6    The AWS SDK for Python
botocore              1.29.6    Low-level, data-driven core of boto 3.
certifi               2022.9.24 Python package for providing Mozilla's CA Bundle.
cfgv                  3.3.1     Validate configuration and produce human readable error messages.
charset-normalizer    2.1.1     The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
click                 8.1.3     Composable command line interface toolkit
click-log             0.4.0     Logging integration for Click
cloup                 1.0.2     Adds features to Click: option groups, constraints, subcommand sections and help themes.
coverage              6.4.4     Code coverage measurement for Python
dill                  0.3.5.1   serialize all of python
distlib               0.3.6     Distribution utilities
dodgy                 0.2.1     Dodgy: Searches for dodgy looking lines in Python code
exceptiongroup        1.0.4     Backport of PEP 654 (exception groups)
execnet               1.9.0     execnet: rapid multi-Python deployment
faunadb               4.3.1     FaunaDB Python driver
filelock              3.8.0     A platform independent file lock.
flake8                2.3.0     the modular source code checker: pep8, pyflakes and co
flake8-polyfill       1.0.2     Polyfill package for Flake8 plugins
fluctuate             1.0.1     A simple migration utility for Fauna DB.
future                0.18.2    Clean single-source support for Python 3 and 2
h2                    2.6.2     HTTP/2 State-Machine based protocol implementation
hpack                 3.0.0     Pure-Python HPACK header compression
hyper                 0.7.0     HTTP/2 Client for Python
hyperframe            3.2.0     HTTP/2 framing layer for Python
identify              2.5.6     File identification library for Python
idna                  3.4       Internationalized Domain Names in Applications (IDNA)
iniconfig             1.1.1     iniconfig: brain-dead simple config-ini parsing
iso8601               1.0.2     Simple module to parse ISO 8601 dates
isort                 5.10.1    A Python utility / library to sort Python imports.
jmespath              1.0.1     JSON Matching Expressions
lazy-object-proxy     1.7.1     A fast and thorough lazy object proxy.
mccabe                0.6.1     McCabe checker, plugin for flake8
mypy-extensions       0.4.3     Experimental type system extensions for programs checked with the mypy typechecker.
nodeenv               1.7.0     Node.js virtual environment builder
packaging             21.3      Core utilities for Python packages
pathspec              0.10.1    Utility library for gitignore style pattern matching of file paths.
pep8                  1.7.1     Python style guide checker
pep8-naming           0.10.0    Check PEP-8 naming conventions, plugin for flake8
platformdirs          2.5.2     A small Python module for determining appropriate platform-specific dirs, e.g. a "user data dir".
pluggy                1.0.0     plugin and hook calling mechanisms for python
pre-commit            2.20.0    A framework for managing and maintaining multi-language pre-commit hooks.
prospector            1.7.7
py                    1.11.0    library with cross-python path, ini-parsing, io, code, log facilities
pycodestyle           2.8.0     Python style guide checker
pydocstyle            6.1.1     Python docstring style checker
pyflakes              2.5.0     passive checker of Python programs
pylint                2.15.3    python code static checker
pylint-celery         0.3       pylint-celery is a Pylint plugin to aid Pylint in recognising and understandingerrors caused when using the Celery library
pylint-django         2.5.3     A Pylint plugin to help Pylint understand the Django web framework
pylint-flask          0.6       pylint-flask is a Pylint plugin to aid Pylint in recognizing and understanding errors caused when using Flask
pylint-plugin-utils   0.7       Utilities and helpers for writing Pylint plugins
pyparsing             3.0.9     pyparsing module - Classes and methods to define and execute parsing grammars
pytest                7.2.0     pytest: simple powerful testing with Python
pytest-cov            3.0.0     Pytest plugin for measuring coverage.
pytest-env            0.6.2     py.test plugin that allows you to add environment variables.
pytest-forked         1.4.0     run tests in isolated forked subprocesses
pytest-xdist          2.5.0     pytest xdist plugin for distributed testing and loop-on-failing modes
python-dateutil       2.8.2     Extensions to the standard Python datetime module
python-decouple       3.6       Strict separation of settings from code.
PyYAML                6.0       YAML parser and emitter for Python
requests              2.28.1    Python HTTP for Humans.
requirements-detector 0.7       Python tool to find and list requirements of a Python project
s3transfer            0.6.0     An Amazon S3 Transfer Manager
sentry-sdk            1.9.9     Python client for Sentry (https://sentry.io)
setoptconf-tmp        0.3.1     A module for retrieving program settings from various sources in a consistant method.
setuptools            65.5.0    Easily download, build, install, upgrade, and uninstall Python packages
six                   1.16.0    Python 2 and 3 compatibility utilities
snowballstemmer       2.2.0     This package provides 29 stemmers for 28 languages generated from Snowball algorithms.
toml                  0.10.2    Python Library for Tom's Obvious, Minimal Language
tomli                 2.0.1     A lil' TOML parser
tomlkit               0.11.4    Style preserving TOML library
typing-extensions     4.3.0     Backported and Experimental Type Hints for Python 3.7+
urllib3               1.26.12   HTTP library with thread-safe connection pooling, file post, and more.
virtualenv            20.16.5   Virtual Python Environment builder
wrapt                 1.14.1    Module for decorators, wrappers and monkey patching.

pytest and OS versions

$ poetry show pytest
 name         : pytest
 version      : 7.2.0
 description  : pytest: simple powerful testing with Python

dependencies
 - attrs >=19.2.0
 - colorama *
 - exceptiongroup >=1.0.0rc8
 - iniconfig *
 - packaging *
 - pluggy >=0.12,<2.0
 - tomli >=1.0.0

required by
 - pytest-cov >=4.6
 - pytest-env >=2.6.0
 - pytest-forked >=3.10
 - pytest-xdist >=6.2.0

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
Codename:       jammy

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: configrelated to config handling, argument parsing and config filetype: bugproblem that needs to be addressed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions