mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-01 03:26:52 +00:00
move from optparse to argparse
This commit is contained in:
parent
03cb85f556
commit
b66ebd7034
30 changed files with 462 additions and 302 deletions
|
|
@ -3,6 +3,7 @@
|
|||
Previously, users would import :func:`get_style_guide` from ``flake8.engine``.
|
||||
In 3.0 we no longer have an "engine" module but we maintain the API from it.
|
||||
"""
|
||||
import argparse
|
||||
import logging
|
||||
import os.path
|
||||
|
||||
|
|
@ -72,10 +73,10 @@ class StyleGuide(object):
|
|||
self._file_checker_manager = application.file_checker_manager
|
||||
|
||||
@property
|
||||
def options(self):
|
||||
def options(self): # type: () -> argparse.Namespace
|
||||
"""Return application's options.
|
||||
|
||||
An instance of :class:`optparse.Values` containing parsed options.
|
||||
An instance of :class:`argparse.Namespace` containing parsed options.
|
||||
"""
|
||||
return self._application.options
|
||||
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ class FileChecker(object):
|
|||
:param options:
|
||||
Parsed option values from config and command-line.
|
||||
:type options:
|
||||
optparse.Values
|
||||
argparse.Namespace
|
||||
"""
|
||||
self.options = options
|
||||
self.filename = filename
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""The base class and interface for all formatting plugins."""
|
||||
from __future__ import print_function
|
||||
|
||||
import optparse
|
||||
import argparse
|
||||
from typing import IO, List, Optional, Tuple
|
||||
|
||||
if False: # `typing.TYPE_CHECKING` was introduced in 3.5.2
|
||||
|
|
@ -32,13 +32,13 @@ class BaseFormatter(object):
|
|||
"""
|
||||
|
||||
def __init__(self, options):
|
||||
# type: (optparse.Values) -> None
|
||||
# type: (argparse.Namespace) -> None
|
||||
"""Initialize with the options parsed from config and cli.
|
||||
|
||||
This also calls a hook, :meth:`after_init`, so subclasses do not need
|
||||
to call super to call this method.
|
||||
|
||||
:param optparse.Values options:
|
||||
:param argparse.Namespace options:
|
||||
User specified configuration parsed from both configuration files
|
||||
and the command-line interface.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
"""Module containing the application logic for Flake8."""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import optparse
|
||||
import sys
|
||||
import time
|
||||
from typing import Dict, List, Optional, Set
|
||||
|
|
@ -52,8 +52,8 @@ class Application(object):
|
|||
)
|
||||
options.register_default_options(self.option_manager)
|
||||
#: The preliminary options parsed from CLI before plugins are loaded,
|
||||
#: into a :class:`optparse.Values` instance
|
||||
self.prelim_opts = None # type: optparse.Values
|
||||
#: into a :class:`argparse.Namespace` instance
|
||||
self.prelim_opts = None # type: argparse.Namespace
|
||||
#: The preliminary arguments parsed from CLI before plugins are loaded
|
||||
self.prelim_args = None # type: List[str]
|
||||
#: The instance of :class:`flake8.options.config.ConfigFileFinder`
|
||||
|
|
@ -77,8 +77,8 @@ class Application(object):
|
|||
self.file_checker_manager = None # type: checker.Manager
|
||||
|
||||
#: The user-supplied options parsed into an instance of
|
||||
#: :class:`optparse.Values`
|
||||
self.options = None # type: optparse.Values
|
||||
#: :class:`argparse.Namespace`
|
||||
self.options = None # type: argparse.Namespace
|
||||
#: The left over arguments that were not parsed by
|
||||
#: :attr:`option_manager`
|
||||
self.args = None # type: List[str]
|
||||
|
|
@ -117,7 +117,7 @@ class Application(object):
|
|||
# printing the version until we aggregate options from config files
|
||||
# and the command-line. First, let's clone our arguments on the CLI,
|
||||
# then we'll attempt to remove ``--version`` so that we can avoid
|
||||
# triggering the "version" action in optparse. If it's not there, we
|
||||
# triggering the "version" action in argparse. If it's not there, we
|
||||
# do not need to worry and we can continue. If it is, we successfully
|
||||
# defer printing the version until just a little bit later.
|
||||
# Similarly we have to defer printing the help text until later.
|
||||
|
|
|
|||
|
|
@ -1,41 +1,38 @@
|
|||
"""Module containing the logic for our debugging logic."""
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import platform
|
||||
|
||||
import entrypoints
|
||||
|
||||
|
||||
def print_information(
|
||||
option, option_string, value, parser, option_manager=None
|
||||
):
|
||||
"""Print debugging information used in bug reports.
|
||||
class DebugAction(argparse.Action):
|
||||
"""argparse action to print debug information."""
|
||||
|
||||
:param option:
|
||||
The optparse Option instance.
|
||||
:type option:
|
||||
optparse.Option
|
||||
:param str option_string:
|
||||
The option name
|
||||
:param value:
|
||||
The value passed to the callback parsed from the command-line
|
||||
:param parser:
|
||||
The optparse OptionParser instance
|
||||
:type parser:
|
||||
optparse.OptionParser
|
||||
:param option_manager:
|
||||
The Flake8 OptionManager instance.
|
||||
:type option_manager:
|
||||
flake8.options.manager.OptionManager
|
||||
"""
|
||||
if not option_manager.registered_plugins:
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the action.
|
||||
|
||||
This takes an extra `option_manager` keyword argument which will be
|
||||
used to delay response.
|
||||
"""
|
||||
self._option_manager = kwargs.pop("option_manager")
|
||||
super(DebugAction, self).__init__(*args, **kwargs)
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
"""Perform the argparse action for printing debug information."""
|
||||
# NOTE(sigmavirus24): Flake8 parses options twice. The first time, we
|
||||
# will not have any registered plugins. We can skip this one and only
|
||||
# take action on the second time we're called.
|
||||
return
|
||||
print(json.dumps(information(option_manager), indent=2, sort_keys=True))
|
||||
raise SystemExit(False)
|
||||
if not self._option_manager.registered_plugins:
|
||||
return
|
||||
print(
|
||||
json.dumps(
|
||||
information(self._option_manager), indent=2, sort_keys=True
|
||||
)
|
||||
)
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
def information(option_manager):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Contains the logic for all of the default options for Flake8."""
|
||||
import functools
|
||||
|
||||
from flake8 import defaults
|
||||
from flake8.main import debug
|
||||
from flake8.main import vcs
|
||||
|
|
@ -83,7 +85,7 @@ def register_default_options(option_manager):
|
|||
parse_from_config=True,
|
||||
normalize_paths=True,
|
||||
help="Comma-separated list of files or directories to exclude."
|
||||
" (Default: %default)",
|
||||
" (Default: %(default)s)",
|
||||
)
|
||||
|
||||
add_option(
|
||||
|
|
@ -103,7 +105,7 @@ def register_default_options(option_manager):
|
|||
parse_from_config=True,
|
||||
comma_separated_list=True,
|
||||
help="Only check for filenames matching the patterns in this comma-"
|
||||
"separated list. (Default: %default)",
|
||||
"separated list. (Default: %(default)s)",
|
||||
)
|
||||
|
||||
add_option(
|
||||
|
|
@ -111,7 +113,7 @@ def register_default_options(option_manager):
|
|||
default="stdin",
|
||||
help="The name used when reporting errors from code passed via stdin."
|
||||
" This is useful for editors piping the file contents to flake8."
|
||||
" (Default: %default)",
|
||||
" (Default: %(default)s)",
|
||||
)
|
||||
|
||||
# TODO(sigmavirus24): Figure out --first/--repeat
|
||||
|
|
@ -142,7 +144,7 @@ def register_default_options(option_manager):
|
|||
parse_from_config=True,
|
||||
comma_separated_list=True,
|
||||
help="Comma-separated list of errors and warnings to ignore (or skip)."
|
||||
" For example, ``--ignore=E4,E51,W234``. (Default: %default)",
|
||||
" For example, ``--ignore=E4,E51,W234``. (Default: %(default)s)",
|
||||
)
|
||||
|
||||
add_option(
|
||||
|
|
@ -168,22 +170,22 @@ def register_default_options(option_manager):
|
|||
|
||||
add_option(
|
||||
"--max-line-length",
|
||||
type="int",
|
||||
type=int,
|
||||
metavar="n",
|
||||
default=defaults.MAX_LINE_LENGTH,
|
||||
parse_from_config=True,
|
||||
help="Maximum allowed line length for the entirety of this run. "
|
||||
"(Default: %default)",
|
||||
"(Default: %(default)s)",
|
||||
)
|
||||
|
||||
add_option(
|
||||
"--max-doc-length",
|
||||
type="int",
|
||||
type=int,
|
||||
metavar="n",
|
||||
default=None,
|
||||
parse_from_config=True,
|
||||
help="Maximum allowed doc line length for the entirety of this run. "
|
||||
"(Default: %default)",
|
||||
"(Default: %(default)s)",
|
||||
)
|
||||
|
||||
add_option(
|
||||
|
|
@ -193,7 +195,7 @@ def register_default_options(option_manager):
|
|||
parse_from_config=True,
|
||||
comma_separated_list=True,
|
||||
help="Comma-separated list of errors and warnings to enable."
|
||||
" For example, ``--select=E4,E51,W234``. (Default: %default)",
|
||||
" For example, ``--select=E4,E51,W234``. (Default: %(default)s)",
|
||||
)
|
||||
|
||||
add_option(
|
||||
|
|
@ -227,7 +229,6 @@ def register_default_options(option_manager):
|
|||
default="",
|
||||
parse_from_config=True,
|
||||
comma_separated_list=True,
|
||||
type="string",
|
||||
help="Enable plugins and extensions that are otherwise disabled "
|
||||
"by default",
|
||||
)
|
||||
|
|
@ -240,10 +241,8 @@ def register_default_options(option_manager):
|
|||
|
||||
add_option(
|
||||
"--install-hook",
|
||||
action="callback",
|
||||
type="choice",
|
||||
action=vcs.InstallAction,
|
||||
choices=vcs.choices(),
|
||||
callback=vcs.install,
|
||||
help="Install a hook that is run prior to a commit for the supported "
|
||||
"version control system.",
|
||||
)
|
||||
|
|
@ -251,21 +250,18 @@ def register_default_options(option_manager):
|
|||
add_option(
|
||||
"-j",
|
||||
"--jobs",
|
||||
type="string",
|
||||
default="auto",
|
||||
parse_from_config=True,
|
||||
help="Number of subprocesses to use to run checks in parallel. "
|
||||
'This is ignored on Windows. The default, "auto", will '
|
||||
"auto-detect the number of processors available to use."
|
||||
" (Default: %default)",
|
||||
" (Default: %(default)s)",
|
||||
)
|
||||
|
||||
add_option(
|
||||
"--output-file",
|
||||
default=None,
|
||||
type="string",
|
||||
parse_from_config=True,
|
||||
# callback=callbacks.redirect_stdout,
|
||||
help="Redirect report to a file.",
|
||||
)
|
||||
|
||||
|
|
@ -316,8 +312,9 @@ def register_default_options(option_manager):
|
|||
|
||||
add_option(
|
||||
"--bug-report",
|
||||
action="callback",
|
||||
callback=debug.print_information,
|
||||
callback_kwargs={"option_manager": option_manager},
|
||||
action=functools.partial(
|
||||
debug.DebugAction, option_manager=option_manager
|
||||
),
|
||||
nargs=0,
|
||||
help="Print information necessary when preparing a bug report",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""Module containing some of the logic for our VCS installation logic."""
|
||||
import argparse
|
||||
|
||||
from flake8 import exceptions as exc
|
||||
from flake8.main import git
|
||||
from flake8.main import mercurial
|
||||
|
|
@ -11,24 +13,23 @@ from flake8.main import mercurial
|
|||
_INSTALLERS = {"git": git.install, "mercurial": mercurial.install}
|
||||
|
||||
|
||||
def install(option, option_string, value, parser):
|
||||
"""Determine which version control hook to install.
|
||||
class InstallAction(argparse.Action):
|
||||
"""argparse action to run the hook installation."""
|
||||
|
||||
For more information about the callback signature, see:
|
||||
https://docs.python.org/3/library/optparse.html#optparse-option-callbacks
|
||||
"""
|
||||
installer = _INSTALLERS[value]
|
||||
errored = False
|
||||
successful = False
|
||||
try:
|
||||
successful = installer()
|
||||
except exc.HookInstallationError as hook_error:
|
||||
print(str(hook_error))
|
||||
errored = True
|
||||
def __call__(self, parser, namespace, value, option_string=None):
|
||||
"""Perform the argparse action for installing vcs hooks."""
|
||||
installer = _INSTALLERS[value]
|
||||
errored = False
|
||||
successful = False
|
||||
try:
|
||||
successful = installer()
|
||||
except exc.HookInstallationError as hook_error:
|
||||
print(str(hook_error))
|
||||
errored = True
|
||||
|
||||
if not successful:
|
||||
print("Could not find the {0} directory".format(value))
|
||||
raise SystemExit(not successful and errored)
|
||||
if not successful:
|
||||
print("Could not find the {0} directory".format(value))
|
||||
raise SystemExit(not successful and errored)
|
||||
|
||||
|
||||
def choices():
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ def aggregate_options(manager, config_finder, arglist=None, values=None):
|
|||
The list of arguments to pass to ``manager.parse_args``. In most cases
|
||||
this will be None so ``parse_args`` uses ``sys.argv``. This is mostly
|
||||
available to make testing easier.
|
||||
:param optparse.Values values:
|
||||
:param argparse.Namespace values:
|
||||
Previously parsed set of parsed options.
|
||||
:returns:
|
||||
Tuple of the parsed options and extra arguments returned by
|
||||
``manager.parse_args``.
|
||||
:rtype:
|
||||
tuple(optparse.Values, list)
|
||||
tuple(argparse.Namespace, list)
|
||||
"""
|
||||
# Get defaults from the option parser
|
||||
default_values, _ = manager.parse_args([], values=values)
|
||||
|
|
|
|||
|
|
@ -167,9 +167,6 @@ class MergedConfigParser(object):
|
|||
dictionaries with the parsed values.
|
||||
"""
|
||||
|
||||
#: Set of types that should use the
|
||||
#: :meth:`~configparser.RawConfigParser.getint` method.
|
||||
GETINT_TYPES = {"int", "count"}
|
||||
#: Set of actions that should use the
|
||||
#: :meth:`~configparser.RawConfigParser.getbool` method.
|
||||
GETBOOL_ACTIONS = {"store_true", "store_false"}
|
||||
|
|
@ -216,10 +213,7 @@ class MergedConfigParser(object):
|
|||
|
||||
# Use the appropriate method to parse the config value
|
||||
method = config_parser.get
|
||||
if (
|
||||
option.type in self.GETINT_TYPES
|
||||
or option.action in self.GETINT_TYPES
|
||||
):
|
||||
if option.type is int or option.action == "count":
|
||||
method = config_parser.getint
|
||||
elif option.action in self.GETBOOL_ACTIONS:
|
||||
method = config_parser.getboolean
|
||||
|
|
|
|||
|
|
@ -1,55 +1,100 @@
|
|||
"""Option handling and Option management logic."""
|
||||
import argparse
|
||||
import collections
|
||||
import functools
|
||||
import logging
|
||||
import optparse # pylint: disable=deprecated-module
|
||||
from typing import Dict, List, Optional, Set
|
||||
from typing import Any, Dict, List, Optional, Set
|
||||
|
||||
from flake8 import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
_NOARG = object()
|
||||
|
||||
|
||||
class _CallbackAction(argparse.Action):
|
||||
"""Shim for optparse-style callback actions."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._callback = kwargs.pop("callback")
|
||||
self._callback_args = kwargs.pop("callback_args", ())
|
||||
self._callback_kwargs = kwargs.pop("callback_kwargs", {})
|
||||
super(_CallbackAction, self).__init__(*args, **kwargs)
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=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, *args, **kwargs):
|
||||
comma_separated_list = kwargs.pop("comma_separated_list", False)
|
||||
normalize_paths = kwargs.pop("normalize_paths", False)
|
||||
if kwargs:
|
||||
raise TypeError("Unexpected keyword args: {}".format(kwargs))
|
||||
|
||||
if comma_separated_list and isinstance(value, utils.string_types):
|
||||
value = utils.parse_comma_separated_list(value)
|
||||
|
||||
if normalize_paths:
|
||||
if isinstance(value, list):
|
||||
value = utils.normalize_paths(value, *args)
|
||||
else:
|
||||
value = utils.normalize_path(value, *args)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class Option(object):
|
||||
"""Our wrapper around an optparse.Option object to add features."""
|
||||
"""Our wrapper around an argparse argument parsers to add features."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
short_option_name=None,
|
||||
long_option_name=None,
|
||||
short_option_name=_NOARG,
|
||||
long_option_name=_NOARG,
|
||||
# Options below here are taken from the optparse.Option class
|
||||
action=None,
|
||||
default=None,
|
||||
type=None,
|
||||
dest=None,
|
||||
nargs=None,
|
||||
const=None,
|
||||
choices=None,
|
||||
callback=None,
|
||||
callback_args=None,
|
||||
callback_kwargs=None,
|
||||
help=None,
|
||||
metavar=None,
|
||||
action=_NOARG,
|
||||
default=_NOARG,
|
||||
type=_NOARG,
|
||||
dest=_NOARG,
|
||||
nargs=_NOARG,
|
||||
const=_NOARG,
|
||||
choices=_NOARG,
|
||||
help=_NOARG,
|
||||
metavar=_NOARG,
|
||||
# deprecated optparse-only options
|
||||
callback=_NOARG,
|
||||
callback_args=_NOARG,
|
||||
callback_kwargs=_NOARG,
|
||||
# Options below are taken from argparse.ArgumentParser.add_argument
|
||||
required=_NOARG,
|
||||
# Options below here are specific to Flake8
|
||||
parse_from_config=False,
|
||||
comma_separated_list=False,
|
||||
normalize_paths=False,
|
||||
):
|
||||
"""Initialize an Option instance wrapping optparse.Option.
|
||||
"""Initialize an Option instance.
|
||||
|
||||
The following are all passed directly through to optparse.
|
||||
The following are all passed directly through to argparse.
|
||||
|
||||
:param str short_option_name:
|
||||
The short name of the option (e.g., ``-x``). This will be the
|
||||
first argument passed to :class:`~optparse.Option`.
|
||||
first argument passed to ``ArgumentParser.add_argument``
|
||||
:param str long_option_name:
|
||||
The long name of the option (e.g., ``--xtra-long-option``). This
|
||||
will be the second argument passed to :class:`~optparse.Option`.
|
||||
:param str action:
|
||||
Any action allowed by :mod:`optparse`.
|
||||
will be the second argument passed to
|
||||
``ArgumentParser.add_argument``
|
||||
:param default:
|
||||
Default value of the option.
|
||||
:param type:
|
||||
Any type allowed by :mod:`optparse`.
|
||||
:param dest:
|
||||
Attribute name to store parsed option value as.
|
||||
:param nargs:
|
||||
|
|
@ -59,16 +104,33 @@ class Option(object):
|
|||
conjuntion with ``action="store_const"``.
|
||||
:param iterable choices:
|
||||
Possible values for the option.
|
||||
:param callable callback:
|
||||
Callback used if the action is ``"callback"``.
|
||||
:param iterable callback_args:
|
||||
Additional positional arguments to the callback callable.
|
||||
:param dictionary callback_kwargs:
|
||||
Keyword arguments to the callback callable.
|
||||
:param str help:
|
||||
Help text displayed in the usage information.
|
||||
:param str metavar:
|
||||
Name to use instead of the long option name for help text.
|
||||
:param bool required:
|
||||
Whether this option is required or not.
|
||||
|
||||
The following options may be passed directly through to :mod:`argparse`
|
||||
but may need some massaging.
|
||||
|
||||
: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`.
|
||||
:param str action:
|
||||
Any action allowed by :mod:`argparse`. Deprecated: this also
|
||||
understands the ``action='callback'`` action from :mod:`optparse`.
|
||||
:param callable callback:
|
||||
Callback used if the action is ``"callback"``. Deprecated: please
|
||||
use ``action=`` instead.
|
||||
:param iterable callback_args:
|
||||
Additional positional arguments to the callback callable.
|
||||
Deprecated: please use ``action=`` instead (probably with
|
||||
``functools.partial``).
|
||||
:param dictionary callback_kwargs:
|
||||
Keyword arguments to the callback callable. Deprecated: please
|
||||
use ``action=`` instead (probably with ``functools.partial``).
|
||||
|
||||
The following parameters are for Flake8's option handling alone.
|
||||
|
||||
|
|
@ -81,16 +143,66 @@ class Option(object):
|
|||
Whether the option is expecting a path or list of paths and should
|
||||
attempt to normalize the paths to absolute paths.
|
||||
"""
|
||||
if long_option_name is _NOARG and short_option_name.startswith("--"):
|
||||
short_option_name, long_option_name = _NOARG, short_option_name
|
||||
|
||||
# optparse -> argparse `%default` => `%(default)s`
|
||||
if help is not _NOARG 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 _NOARG:
|
||||
nargs = 0
|
||||
|
||||
# optparse -> argparse for `type`
|
||||
if isinstance(type, utils.string_types):
|
||||
LOG.warning(
|
||||
"option %s: please update from optparse string `type=` to "
|
||||
"argparse callable `type=` -- this will be an error in the "
|
||||
"future"
|
||||
)
|
||||
type = {
|
||||
"int": int,
|
||||
"long": int,
|
||||
"string": str,
|
||||
"float": float,
|
||||
"complex": complex,
|
||||
"choice": _NOARG,
|
||||
}[type]
|
||||
|
||||
# flake8 special type normalization
|
||||
if comma_separated_list or normalize_paths:
|
||||
type = functools.partial(
|
||||
_flake8_normalize,
|
||||
comma_separated_list=comma_separated_list,
|
||||
normalize_paths=normalize_paths,
|
||||
)
|
||||
|
||||
self.short_option_name = short_option_name
|
||||
self.long_option_name = long_option_name
|
||||
self.option_args = [
|
||||
x for x in (short_option_name, long_option_name) if x is not None
|
||||
x
|
||||
for x in (short_option_name, long_option_name)
|
||||
if x is not _NOARG
|
||||
]
|
||||
self.option_kwargs = {
|
||||
"action": action,
|
||||
"default": default,
|
||||
"type": type,
|
||||
"dest": self._make_dest(dest),
|
||||
"dest": dest,
|
||||
"nargs": nargs,
|
||||
"const": const,
|
||||
"choices": choices,
|
||||
|
|
@ -111,7 +223,7 @@ class Option(object):
|
|||
|
||||
self.config_name = None # type: Optional[str]
|
||||
if parse_from_config:
|
||||
if not long_option_name:
|
||||
if long_option_name is _NOARG:
|
||||
raise ValueError(
|
||||
"When specifying parse_from_config=True, "
|
||||
"a long_option_name must also be specified."
|
||||
|
|
@ -120,25 +232,20 @@ class Option(object):
|
|||
|
||||
self._opt = None
|
||||
|
||||
@property
|
||||
def filtered_option_kwargs(self): # type: () -> Dict[str, Any]
|
||||
"""Return any actually-specified arguments."""
|
||||
return {
|
||||
k: v for k, v in self.option_kwargs.items() if v is not _NOARG
|
||||
}
|
||||
|
||||
def __repr__(self): # noqa: D105
|
||||
return (
|
||||
"Option({0}, {1}, action={action}, default={default}, "
|
||||
"dest={dest}, type={type}, callback={callback}, help={help},"
|
||||
" callback={callback}, callback_args={callback_args}, "
|
||||
"callback_kwargs={callback_kwargs}, metavar={metavar})"
|
||||
).format(
|
||||
self.short_option_name,
|
||||
self.long_option_name,
|
||||
**self.option_kwargs
|
||||
)
|
||||
|
||||
def _make_dest(self, dest):
|
||||
if dest:
|
||||
return dest
|
||||
|
||||
if self.long_option_name:
|
||||
return self.long_option_name[2:].replace("-", "_")
|
||||
return self.short_option_name[1]
|
||||
parts = []
|
||||
for arg in self.option_args:
|
||||
parts.append(arg)
|
||||
for k, v in self.filtered_option_kwargs.items():
|
||||
parts.append("{}={!r}".format(k, v))
|
||||
return "Option({})".format(", ".join(parts))
|
||||
|
||||
def normalize(self, value, *normalize_args):
|
||||
"""Normalize the value based on the option configuration."""
|
||||
|
|
@ -158,11 +265,11 @@ class Option(object):
|
|||
def normalize_from_setuptools(self, value):
|
||||
"""Normalize the value received from setuptools."""
|
||||
value = self.normalize(value)
|
||||
if self.type == "int" or self.action == "count":
|
||||
if self.type is int or self.action == "count":
|
||||
return int(value)
|
||||
elif self.type == "float":
|
||||
elif self.type is float:
|
||||
return float(value)
|
||||
elif self.type == "complex":
|
||||
elif self.type is complex:
|
||||
return complex(value)
|
||||
if self.action in ("store_true", "store_false"):
|
||||
value = str(value).upper()
|
||||
|
|
@ -172,13 +279,14 @@ class Option(object):
|
|||
return False
|
||||
return value
|
||||
|
||||
def to_argparse(self):
|
||||
"""Convert a Flake8 Option to argparse ``add_argument`` arguments."""
|
||||
return self.option_args, self.filtered_option_kwargs
|
||||
|
||||
@property
|
||||
def to_optparse(self):
|
||||
"""Convert a Flake8 Option to an optparse Option."""
|
||||
if self._opt is None:
|
||||
self._opt = optparse.Option(
|
||||
*self.option_args, **self.option_kwargs
|
||||
)
|
||||
return self._opt
|
||||
"""No longer functional."""
|
||||
raise AttributeError("to_optparse: flake8 now uses argparse")
|
||||
|
||||
|
||||
PluginVersion = collections.namedtuple(
|
||||
|
|
@ -190,7 +298,10 @@ class OptionManager(object):
|
|||
"""Manage Options and OptionParser while adding post-processing."""
|
||||
|
||||
def __init__(
|
||||
self, prog=None, version=None, usage="%prog [options] file file ..."
|
||||
self,
|
||||
prog=None,
|
||||
version=None,
|
||||
usage="%(prog)s [options] file file ...",
|
||||
):
|
||||
"""Initialize an instance of an OptionManager.
|
||||
|
||||
|
|
@ -201,9 +312,11 @@ class OptionManager(object):
|
|||
:param str usage:
|
||||
Basic usage string used by the OptionParser.
|
||||
"""
|
||||
self.parser = optparse.OptionParser(
|
||||
prog=prog, version=version, usage=usage
|
||||
self.parser = argparse.ArgumentParser(prog=prog, usage=usage)
|
||||
self.version_action = self.parser.add_argument(
|
||||
"--version", action="version", version=version
|
||||
)
|
||||
self.parser.add_argument("filenames", nargs="*", metavar="filename")
|
||||
self.config_options_dict = {} # type: Dict[str, Option]
|
||||
self.options = [] # type: List[Option]
|
||||
self.program_name = prog
|
||||
|
|
@ -226,12 +339,11 @@ class OptionManager(object):
|
|||
.. note::
|
||||
|
||||
``short_option_name`` and ``long_option_name`` may be specified
|
||||
positionally as they are with optparse normally.
|
||||
positionally as they are with argparse normally.
|
||||
"""
|
||||
if len(args) == 1 and args[0].startswith("--"):
|
||||
args = (None, args[0])
|
||||
option = Option(*args, **kwargs)
|
||||
self.parser.add_option(option.to_optparse())
|
||||
option_args, option_kwargs = option.to_argparse()
|
||||
self.parser.add_argument(*option_args, **option_kwargs)
|
||||
self.options.append(option)
|
||||
if option.parse_from_config:
|
||||
name = option.config_name
|
||||
|
|
@ -289,12 +401,8 @@ class OptionManager(object):
|
|||
|
||||
def update_version_string(self):
|
||||
"""Update the flake8 version string."""
|
||||
self.parser.version = (
|
||||
self.version
|
||||
+ " ("
|
||||
+ self.generate_versions()
|
||||
+ ") "
|
||||
+ utils.get_python_version()
|
||||
self.version_action.version = "{} ({}) {}".format(
|
||||
self.version, self.generate_versions(), utils.get_python_version()
|
||||
)
|
||||
|
||||
def generate_epilog(self):
|
||||
|
|
@ -304,18 +412,13 @@ class OptionManager(object):
|
|||
plugin_version_format
|
||||
)
|
||||
|
||||
def _normalize(self, options):
|
||||
for option in self.options:
|
||||
old_value = getattr(options, option.dest)
|
||||
setattr(options, option.dest, option.normalize(old_value))
|
||||
|
||||
def parse_args(self, args=None, values=None):
|
||||
"""Proxy to calling the OptionParser's parse_args method."""
|
||||
self.generate_epilog()
|
||||
self.update_version_string()
|
||||
options, xargs = self.parser.parse_args(args, values)
|
||||
self._normalize(options)
|
||||
return options, xargs
|
||||
args = self.parser.parse_args(args, values)
|
||||
# TODO: refactor callers to not need this
|
||||
return args, args.filenames
|
||||
|
||||
def parse_known_args(self, args=None, values=None):
|
||||
"""Parse only the known arguments from the argument values.
|
||||
|
|
@ -325,33 +428,8 @@ class OptionManager(object):
|
|||
"""
|
||||
self.generate_epilog()
|
||||
self.update_version_string()
|
||||
# Taken from optparse.OptionParser.parse_args
|
||||
rargs = self.parser._get_args(args)
|
||||
if values is None:
|
||||
values = self.parser.get_default_values()
|
||||
|
||||
self.parser.rargs = rargs
|
||||
largs = [] # type: List[str]
|
||||
self.parser.values = values
|
||||
|
||||
while rargs:
|
||||
# NOTE(sigmavirus24): If we only care about *known* options, then
|
||||
# we should just shift the bad option over to the largs list and
|
||||
# carry on.
|
||||
# Unfortunately, we need to rely on a private method here.
|
||||
try:
|
||||
self.parser._process_args(largs, rargs, values)
|
||||
except (
|
||||
optparse.BadOptionError,
|
||||
optparse.OptionValueError,
|
||||
) as err:
|
||||
# TODO: https://gitlab.com/pycqa/flake8/issues/541
|
||||
largs.append(err.opt_str) # type: ignore
|
||||
|
||||
args = largs + rargs
|
||||
options, xargs = self.parser.check_values(values, args)
|
||||
self._normalize(options)
|
||||
return options, xargs
|
||||
args, rest = self.parser.parse_known_args(args, values)
|
||||
return args, rest
|
||||
|
||||
def register_plugin(self, name, version, local=False):
|
||||
"""Register a plugin relying on the OptionManager.
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ class FlakesChecker(pyflakes.checker.Checker):
|
|||
comma_separated_list=True,
|
||||
normalize_paths=True,
|
||||
help="Run doctests only on these files",
|
||||
type="string",
|
||||
)
|
||||
parser.add_option(
|
||||
"--exclude-from-doctest",
|
||||
|
|
@ -128,7 +127,6 @@ class FlakesChecker(pyflakes.checker.Checker):
|
|||
comma_separated_list=True,
|
||||
normalize_paths=True,
|
||||
help="Skip these files when running doctests",
|
||||
type="string",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ class StyleGuideManager(object):
|
|||
:param options:
|
||||
The original options parsed from the CLI and config file.
|
||||
:type options:
|
||||
:class:`~optparse.Values`
|
||||
:class:`~argparse.Namespace`
|
||||
:returns:
|
||||
A copy of the default style guide with overridden values.
|
||||
:rtype:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue