PyCQA / PyCQA/flake8

option_manager.add_option ignores action when reading from config

Open
#1,770 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
3.8k
Forks
356
PR merge metrics
No merged PRs in 30d

Description

how did you install flake8?
pip install flake8

also when cloned from github master

unmodified output of flake8 --bug-report
{
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.10.8",
    "system": "Linux"
  },
  "plugins": [
    {
      "plugin": "mccabe",
      "version": "0.7.0"
    },
    {
      "plugin": "pycodestyle",
      "version": "2.10.0"
    },
    {
      "plugin": "pyflakes",
      "version": "3.0.1"
    }
  ],
  "version": "6.0.0"
}
describe the problem
what I expected to happen

my argparse.Action to be called regardless of if the parameter is specified on the command line or in the config

sample code

I implemented a test that reproduces the error. The first one passes, the second one doesn't.

from collections.abc import Sequence
from flake8.options import config

# always sets the value to bar regardless of what `values` is
class MyAction(argparse.Action):
    def __call__(
        self,
        parser: argparse.ArgumentParser,
        namespace: argparse.Namespace,
        values: Sequence[str] | None,
        option_string: str | None = None,
    ) -> None:
        setattr(namespace, self.dest, "bar")


def test_action_cmdline(optmanager):
    optmanager.add_option(
        "--my-option",
        parse_from_config=True,
        required=False,
        action=MyAction,
    )
    options = optmanager.parse_args(["--my-option", "foo"])
    assert options.my_option == 'bar'

def test_action_config(tmpdir):
    tmpdir.join("setup.cfg").write("[flake8]\nmy-option=foo\n")

    with tmpdir.as_cwd():
        cfg, cfg_dir = config.load_config(None, [], isolated=False)

    assert cfg.get("flake8", "my-option") == "bar"
commands ran
$ pytest -k test_action_ 
===================================== test session starts =====================================
platform linux -- Python 3.10.8, pytest-7.2.0, pluggy-1.0.0
rootdir: /home/h/Git/flake8, configfile: pytest.ini
collected 465 items / 463 deselected / 2 selected                                             

tests/unit/test_option_manager.py .F                                                    [100%]

========================================== FAILURES ===========================================
_____________________________________ test_action_config ______________________________________

tmpdir = local('/tmp/pytest-of-h/pytest-62/test_action_config0')

    def test_action_config(tmpdir):
        tmpdir.join("setup.cfg").write("[flake8]\nmy-option=foo\n")
    
        with tmpdir.as_cwd():
            cfg, cfg_dir = config.load_config(None, [], isolated=False)
    
>       assert cfg.get("flake8", "my-option") == "bar"
E       AssertionError: assert 'foo' == 'bar'
E         - bar
E         + foo

tests/unit/test_option_manager.py:243: AssertionError
========================= 1 failed, 1 passed, 463 deselected in 0.26s =========================

The value is foo, which it would be if there's no action specified, but it completely sidesteps calling the action completely.

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 with tests/unit/test_option_manager.py, especially test_action_cmdline and test_action_config, and trace how option_manager.add_option handles parse_from_config through config.load_config. Done means the configured value invokes the argparse.Action just like the command-line value and the regression test passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.