Skip to content

Commit

Permalink
Merge pull request #1739 from PyCQA/remove-optparse
Browse files Browse the repository at this point in the history
remove optparse support
  • Loading branch information
asottile committed Nov 16, 2022
2 parents 1a92561 + 88457a0 commit 16c371d
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 199 deletions.
112 changes: 4 additions & 108 deletions src/flake8/options/manager.py
Expand Up @@ -7,7 +7,6 @@
import logging
from typing import Any
from typing import Callable
from typing import Mapping
from typing import Sequence

from flake8 import utils
Expand All @@ -20,55 +19,6 @@
_ARG = enum.Enum("_ARG", "NO")


_optparse_callable_map: dict[str, type[Any] | _ARG] = {
"int": int,
"long": int,
"string": str,
"float": float,
"complex": complex,
"choice": _ARG.NO,
# optparse allows this but does not document it
"str": str,
}


class _CallbackAction(argparse.Action):
"""Shim for optparse-style callback actions."""

def __init__(
self,
*args: Any,
callback: Callable[..., Any],
callback_args: Sequence[Any] = (),
callback_kwargs: dict[str, Any] | None = None,
**kwargs: Any,
) -> None:
self._callback = callback
self._callback_args = callback_args
self._callback_kwargs = callback_kwargs or {}
super().__init__(*args, **kwargs)

def __call__(
self,
parser: argparse.ArgumentParser,
namespace: argparse.Namespace,
values: Sequence[str] | str | None,
option_string: str | None = None,
) -> None:
if not values:
values = None
elif isinstance(values, list) and len(values) > 1:
values = tuple(values)
self._callback(
self,
option_string,
values,
parser,
*self._callback_args,
**self._callback_kwargs,
)


def _flake8_normalize(
value: str,
*args: str,
Expand All @@ -95,21 +45,16 @@ def __init__(
self,
short_option_name: str | _ARG = _ARG.NO,
long_option_name: str | _ARG = _ARG.NO,
# Options below here are taken from the optparse.Option class
# Options below are taken from argparse.ArgumentParser.add_argument
action: str | type[argparse.Action] | _ARG = _ARG.NO,
default: Any | _ARG = _ARG.NO,
type: str | Callable[..., Any] | _ARG = _ARG.NO,
type: Callable[..., Any] | _ARG = _ARG.NO,
dest: str | _ARG = _ARG.NO,
nargs: int | str | _ARG = _ARG.NO,
const: Any | _ARG = _ARG.NO,
choices: Sequence[Any] | _ARG = _ARG.NO,
help: str | _ARG = _ARG.NO,
metavar: str | _ARG = _ARG.NO,
# deprecated optparse-only options
callback: Callable[..., Any] | _ARG = _ARG.NO,
callback_args: Sequence[Any] | _ARG = _ARG.NO,
callback_kwargs: Mapping[str, Any] | _ARG = _ARG.NO,
# Options below are taken from argparse.ArgumentParser.add_argument
required: bool | _ARG = _ARG.NO,
# Options below here are specific to Flake8
parse_from_config: bool = False,
Expand Down Expand Up @@ -150,21 +95,9 @@ def __init__(
:param type:
A callable to normalize the type (as is the case in
:mod:`argparse`). Deprecated: you can also pass through type
strings such as ``'int'`` which are handled by :mod:`optparse`.
:mod:`argparse`).
:param action:
Any action allowed by :mod:`argparse`. Deprecated: this also
understands the ``action='callback'`` action from :mod:`optparse`.
:param callback:
Callback used if the action is ``"callback"``. Deprecated: please
use ``action=`` instead.
:param callback_args:
Additional positional arguments to the callback callable.
Deprecated: please use ``action=`` instead (probably with
``functools.partial``).
:param callback_kwargs:
Keyword arguments to the callback callable. Deprecated: please
use ``action=`` instead (probably with ``functools.partial``).
Any action allowed by :mod:`argparse`.
The following parameters are for Flake8's option handling alone.
Expand All @@ -184,37 +117,6 @@ def __init__(
):
short_option_name, long_option_name = _ARG.NO, short_option_name

# optparse -> argparse `%default` => `%(default)s`
if help is not _ARG.NO and "%default" in help:
LOG.warning(
"option %s: please update `help=` text to use %%(default)s "
"instead of %%default -- this will be an error in the future",
long_option_name,
)
help = help.replace("%default", "%(default)s")

# optparse -> argparse for `callback`
if action == "callback":
LOG.warning(
"option %s: please update from optparse `action='callback'` "
"to argparse action classes -- this will be an error in the "
"future",
long_option_name,
)
action = _CallbackAction
if type is _ARG.NO:
nargs = 0

# optparse -> argparse for `type`
if isinstance(type, str):
LOG.warning(
"option %s: please update from optparse string `type=` to "
"argparse callable `type=` -- this will be an error in the "
"future",
long_option_name,
)
type = _optparse_callable_map[type]

# flake8 special type normalization
if comma_separated_list or normalize_paths:
type = functools.partial(
Expand All @@ -237,9 +139,6 @@ def __init__(
self.nargs = nargs
self.const = const
self.choices = choices
self.callback = callback
self.callback_args = callback_args
self.callback_kwargs = callback_kwargs
self.help = help
self.metavar = metavar
self.required = required
Expand All @@ -251,9 +150,6 @@ def __init__(
"nargs": self.nargs,
"const": self.const,
"choices": self.choices,
"callback": self.callback,
"callback_args": self.callback_args,
"callback_kwargs": self.callback_kwargs,
"help": self.help,
"metavar": self.metavar,
"required": self.required,
Expand Down
91 changes: 0 additions & 91 deletions tests/unit/test_option_manager.py
Expand Up @@ -3,7 +3,6 @@

import argparse
import os
from unittest import mock

import pytest

Expand Down Expand Up @@ -170,96 +169,6 @@ def test_extend_default_ignore(optmanager):
assert optmanager.extended_default_ignore == ["T100", "T101", "T102"]


def test_optparse_normalize_callback_option_legacy(optmanager):
"""Test the optparse shim for `callback=`."""
callback_foo = mock.Mock()
optmanager.add_option(
"--foo",
action="callback",
callback=callback_foo,
callback_args=(1, 2),
callback_kwargs={"a": "b"},
)
callback_bar = mock.Mock()
optmanager.add_option(
"--bar",
action="callback",
type="string",
callback=callback_bar,
)
callback_baz = mock.Mock()
optmanager.add_option(
"--baz",
action="callback",
type="string",
nargs=2,
callback=callback_baz,
)

optmanager.parse_args(["--foo", "--bar", "bararg", "--baz", "1", "2"])

callback_foo.assert_called_once_with(
mock.ANY, # the option / action instance
"--foo",
None,
mock.ANY, # the OptionParser / ArgumentParser
1,
2,
a="b",
)
callback_bar.assert_called_once_with(
mock.ANY, # the option / action instance
"--bar",
"bararg",
mock.ANY, # the OptionParser / ArgumentParser
)
callback_baz.assert_called_once_with(
mock.ANY, # the option / action instance
"--baz",
("1", "2"),
mock.ANY, # the OptionParser / ArgumentParser
)


@pytest.mark.parametrize(
("type_s", "input_val", "expected"),
(
("int", "5", 5),
("long", "6", 6),
("string", "foo", "foo"),
("float", "1.5", 1.5),
("complex", "1+5j", 1 + 5j),
# optparse allows this but does not document it
("str", "foo", "foo"),
),
)
def test_optparse_normalize_types(optmanager, type_s, input_val, expected):
"""Test the optparse shim for type="typename"."""
optmanager.add_option("--foo", type=type_s)
opts = optmanager.parse_args(["--foo", input_val])
assert opts.foo == expected


def test_optparse_normalize_choice_type(optmanager):
"""Test the optparse shim for type="choice"."""
optmanager.add_option("--foo", type="choice", choices=("1", "2", "3"))
opts = optmanager.parse_args(["--foo", "1"])
assert opts.foo == "1"
# fails to parse
with pytest.raises(SystemExit):
optmanager.parse_args(["--foo", "4"])


def test_optparse_normalize_help(optmanager, capsys):
"""Test the optparse shim for %default in help text."""
optmanager.add_option("--foo", default="bar", help="default: %default")
with pytest.raises(SystemExit):
optmanager.parse_args(["--help"])
out, err = capsys.readouterr()
output = out + err
assert "default: bar" in output


@pytest.mark.parametrize(
("s", "is_auto", "n_jobs"),
(
Expand Down

0 comments on commit 16c371d

Please sign in to comment.