summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Sottile <asottile@umich.edu>2020-05-13 20:29:34 +0000
committerAnthony Sottile <asottile@umich.edu>2020-05-13 20:29:34 +0000
commitc8494e7ac0d017d032edc0a402c569b2fddb8a7f (patch)
treeb4f42b855dfd87a0d4a0f4e6f6ab306da6ccc805
parent666be736e0a8632c217997201ef1117babf47c75 (diff)
parent45573570cf706f8490cd631ee6f6a58bc41f8130 (diff)
downloadflake8-c8494e7ac0d017d032edc0a402c569b2fddb8a7f.tar.gz
Merge branch 'master' into 'master'
Parse --jobs as a custom argparse type. Fixes #567 Closes #567 See merge request pycqa/flake8!428
-rw-r--r--src/flake8/checker.py11
-rw-r--r--src/flake8/main/options.py22
-rw-r--r--tests/unit/test_checker_manager.py3
-rw-r--r--tests/unit/test_option_manager.py30
4 files changed, 56 insertions, 10 deletions
diff --git a/src/flake8/checker.py b/src/flake8/checker.py
index 36a4735..d993cb9 100644
--- a/src/flake8/checker.py
+++ b/src/flake8/checker.py
@@ -137,19 +137,12 @@ class Manager(object):
return 0
jobs = self.options.jobs
- if jobs != "auto" and not jobs.isdigit():
- LOG.warning(
- '"%s" is not a valid parameter to --jobs. Must be one '
- 'of "auto" or a numerical value, e.g., 4.',
- jobs,
- )
- return 0
# If the value is "auto", we want to let the multiprocessing library
# decide the number based on the number of CPUs. However, if that
# function is not implemented for this particular value of Python we
# default to 1
- if jobs == "auto":
+ if jobs.is_auto:
try:
return multiprocessing.cpu_count()
except NotImplementedError:
@@ -157,7 +150,7 @@ class Manager(object):
# Otherwise, we know jobs should be an integer and we can just convert
# it to an integer
- return int(jobs)
+ return jobs.n_jobs
def _handle_results(self, filename, results):
style_guide = self.style_guide
diff --git a/src/flake8/main/options.py b/src/flake8/main/options.py
index ba1f1c2..f4588e8 100644
--- a/src/flake8/main/options.py
+++ b/src/flake8/main/options.py
@@ -62,6 +62,27 @@ def register_preliminary_options(parser):
)
+class JobsArgument:
+ """Type callback for the --jobs argument."""
+
+ def __init__(self, arg): # type: (str) -> None
+ """Parse and validate the --jobs argument.
+
+ :param str arg:
+ The argument passed by argparse for validation
+ """
+ self.is_auto = False
+ self.n_jobs = -1
+ if arg == "auto":
+ self.is_auto = True
+ elif arg.isdigit():
+ self.n_jobs = int(arg)
+ else:
+ raise argparse.ArgumentTypeError(
+ "{!r} must be 'auto' or an integer.".format(arg),
+ )
+
+
def register_default_options(option_manager):
"""Register the default options on our OptionManager.
@@ -293,6 +314,7 @@ def register_default_options(option_manager):
"--jobs",
default="auto",
parse_from_config=True,
+ type=JobsArgument,
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."
diff --git a/tests/unit/test_checker_manager.py b/tests/unit/test_checker_manager.py
index 1d7e547..d3e7e61 100644
--- a/tests/unit/test_checker_manager.py
+++ b/tests/unit/test_checker_manager.py
@@ -5,13 +5,14 @@ import mock
import pytest
from flake8 import checker
+from flake8.main.options import JobsArgument
def style_guide_mock():
"""Create a mock StyleGuide object."""
return mock.MagicMock(**{
'options.diff': False,
- 'options.jobs': '4',
+ 'options.jobs': JobsArgument("4"),
})
diff --git a/tests/unit/test_option_manager.py b/tests/unit/test_option_manager.py
index f2ee4f9..3a63db9 100644
--- a/tests/unit/test_option_manager.py
+++ b/tests/unit/test_option_manager.py
@@ -6,6 +6,7 @@ import mock
import pytest
from flake8 import utils
+from flake8.main.options import JobsArgument
from flake8.options import manager
TEST_VERSION = '3.0.0b1'
@@ -343,3 +344,32 @@ def test_optmanager_group(optmanager, capsys):
out, err = capsys.readouterr()
output = out + err
assert '\ngroupname:\n' in output
+
+
+@pytest.mark.parametrize(
+ ("s", "is_auto", "n_jobs"),
+ (
+ ("auto", True, -1),
+ ("4", False, 4),
+ ),
+)
+def test_parse_valid_jobs_argument(s, is_auto, n_jobs):
+ """Test that --jobs properly parses valid arguments."""
+ jobs_opt = JobsArgument(s)
+ assert is_auto == jobs_opt.is_auto
+ assert n_jobs == jobs_opt.n_jobs
+
+
+def test_parse_invalid_jobs_argument(optmanager, capsys):
+ """Test that --jobs properly rejects invalid arguments."""
+ namespace = argparse.Namespace()
+ optmanager.add_option("--jobs", type=JobsArgument)
+ with pytest.raises(SystemExit):
+ optmanager.parse_args(["--jobs=foo"], namespace)
+ out, err = capsys.readouterr()
+ output = out + err
+ expected = (
+ "\nflake8: error: argument --jobs: "
+ "'foo' must be 'auto' or an integer.\n"
+ )
+ assert expected in output