mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-01 19:36:54 +00:00
Add warnings when --jobs is invalid
Some platforms and options are not compatible with the --jobs option. For example, it is not valid on Windows. Nor is it compatible with the --diff option. This adds warnings when the --jobs option is supplied but is not allowed.
This commit is contained in:
parent
a9f375aa93
commit
c3f5d144bc
3 changed files with 203 additions and 0 deletions
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import platform
|
||||
import warnings
|
||||
|
||||
import pep8
|
||||
|
||||
|
|
@ -123,6 +124,21 @@ def get_style_guide(**kwargs):
|
|||
for options_hook in options_hooks:
|
||||
options_hook(options)
|
||||
|
||||
if options.jobs and options.jobs.isdigit() and int(options.jobs) > 1:
|
||||
if not multiprocessing:
|
||||
warnings.warn("The multiprocessing module is not available. "
|
||||
"Ignoring --jobs arguments.")
|
||||
if is_windows():
|
||||
warnings.warn("The --jobs option is not available on Windows. "
|
||||
"Ignoring --jobs arguments.")
|
||||
if is_using_stdin(styleguide.paths):
|
||||
warnings.warn("The --jobs option is not compatible with supplying "
|
||||
"input using - . Ignoring --jobs arguments.")
|
||||
if options.diff:
|
||||
warnings.warn("The --diff option was specified with --jobs but "
|
||||
"they are not compatible. Ignoring --jobs arguments."
|
||||
)
|
||||
|
||||
if options.diff:
|
||||
options.jobs = None
|
||||
|
||||
|
|
|
|||
184
flake8/tests/toast_warnings.py
Normal file
184
flake8/tests/toast_warnings.py
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
"""
|
||||
toast_warnings.py
|
||||
|
||||
Tests for the warnings that are emitted by flake8.
|
||||
|
||||
This module is named toast_warnings instead of test_warnings so that a
|
||||
normal nosetests run does not collect it. The tests in this module pass
|
||||
when they are run alone, but they fail when they are run along with other
|
||||
tests (nosetests --with-isolation doesn't help).
|
||||
|
||||
In tox.ini, these tests are run separately.
|
||||
"""
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
import os
|
||||
import warnings
|
||||
import unittest
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock # < PY33
|
||||
|
||||
from flake8 import engine
|
||||
from flake8.util import is_windows
|
||||
|
||||
|
||||
class IntegrationTestCaseWarnings(unittest.TestCase):
|
||||
"""Integration style tests to check that warnings are issued properly for
|
||||
different command line options."""
|
||||
|
||||
def this_file(self):
|
||||
"""Return the real path of this file."""
|
||||
this_file = os.path.realpath(__file__)
|
||||
if this_file.endswith("pyc"):
|
||||
this_file = this_file[:-1]
|
||||
return this_file
|
||||
|
||||
@staticmethod
|
||||
def get_style_guide_with_warnings(engine, *args, **kwargs):
|
||||
"""
|
||||
Return a style guide object (obtained by calling
|
||||
engine.get_style_guide) and a list of the warnings that were raised in
|
||||
the process.
|
||||
|
||||
Note: not threadsafe
|
||||
"""
|
||||
|
||||
# Note
|
||||
# https://docs.python.org/2/library/warnings.html
|
||||
#
|
||||
# The catch_warnings manager works by replacing and then later
|
||||
# restoring the module's showwarning() function and internal list of
|
||||
# filter specifications. This means the context manager is modifying
|
||||
# global state and therefore is not thread-safe
|
||||
|
||||
with warnings.catch_warnings(record=True) as collected_warnings:
|
||||
# Cause all warnings to always be triggered.
|
||||
warnings.simplefilter("always")
|
||||
|
||||
# Get the style guide
|
||||
style_guide = engine.get_style_guide(*args, **kwargs)
|
||||
|
||||
# Now that the warnings have been collected, return the style guide and
|
||||
# the
|
||||
# warnings.
|
||||
return (style_guide, collected_warnings)
|
||||
|
||||
def verify_warnings(self, collected_warnings, expected_warnings=None):
|
||||
"""
|
||||
Verifies that collected_warnings is a sequence that contains user
|
||||
warnings that match the sequence of string values passed in as
|
||||
expected_warnings.
|
||||
"""
|
||||
if expected_warnings is None:
|
||||
expected_warnings = []
|
||||
|
||||
collected_user_warnings = [w for w in collected_warnings
|
||||
if issubclass(w.category, UserWarning)]
|
||||
|
||||
self.assertEqual(len(collected_user_warnings),
|
||||
len(expected_warnings))
|
||||
|
||||
collected_warnings_set = set(str(warning.message)
|
||||
for warning
|
||||
in collected_user_warnings)
|
||||
expected_warnings_set = set(expected_warnings)
|
||||
self.assertEqual(collected_warnings_set, expected_warnings_set)
|
||||
|
||||
def check_files_collect_warnings(self,
|
||||
arglist=[],
|
||||
explicit_stdin=False,
|
||||
count=0):
|
||||
"""Call check_files and collect any warnings that are issued."""
|
||||
if explicit_stdin:
|
||||
target_file = "-"
|
||||
else:
|
||||
target_file = self.this_file()
|
||||
argv = ['flake8'] + arglist + [target_file]
|
||||
with mock.patch("sys.argv", argv):
|
||||
(style_guide,
|
||||
collected_warnings,
|
||||
) = self.get_style_guide_with_warnings(engine,
|
||||
parse_argv=True)
|
||||
report = style_guide.check_files()
|
||||
self.assertEqual(report.total_errors, count)
|
||||
return style_guide, report, collected_warnings
|
||||
|
||||
def check_files_no_warnings_allowed(self,
|
||||
arglist=[],
|
||||
explicit_stdin=False,
|
||||
count=0):
|
||||
"""Call check_files, and assert that there were no warnings issued."""
|
||||
(style_guide,
|
||||
report,
|
||||
collected_warnings,
|
||||
) = self.check_files_collect_warnings(arglist=arglist,
|
||||
explicit_stdin=explicit_stdin,
|
||||
count=count)
|
||||
self.verify_warnings(collected_warnings)
|
||||
return style_guide, report
|
||||
|
||||
def test_no_args_no_warnings(self):
|
||||
# assert there are no reported errors or warnings
|
||||
self.check_files_no_warnings_allowed()
|
||||
|
||||
def _job_tester(self, jobs):
|
||||
# mock stdout.flush so we can count the number of jobs created
|
||||
with mock.patch('sys.stdout.flush') as mocked:
|
||||
(guide,
|
||||
report,
|
||||
collected_warnings,
|
||||
) = self.check_files_collect_warnings(arglist=['--jobs=%s'
|
||||
% jobs])
|
||||
|
||||
expected_warings = []
|
||||
if is_windows():
|
||||
expected_warings.append("The --jobs option is not "
|
||||
"available on Windows. Ignoring "
|
||||
"--jobs arguments.")
|
||||
|
||||
# The code path where guide.options.jobs gets converted to an
|
||||
# int is not run on windows. So, do the int conversion here.
|
||||
self.assertEqual(int(guide.options.jobs), jobs)
|
||||
# On windows, call count is always zero.
|
||||
self.assertEqual(mocked.call_count, 0)
|
||||
else:
|
||||
self.assertEqual(guide.options.jobs, jobs)
|
||||
self.assertEqual(mocked.call_count, jobs)
|
||||
self.verify_warnings(collected_warnings, expected_warings)
|
||||
|
||||
def test_jobs(self):
|
||||
self._job_tester(2)
|
||||
self._job_tester(10)
|
||||
|
||||
def test_stdin_jobs_warning(self):
|
||||
self.count = 0
|
||||
|
||||
def fake_stdin():
|
||||
self.count += 1
|
||||
with open(self.this_file(), "r") as f:
|
||||
return f.read()
|
||||
|
||||
with mock.patch("pep8.stdin_get_value", fake_stdin):
|
||||
(style_guide,
|
||||
report,
|
||||
collected_warnings,
|
||||
) = self.check_files_collect_warnings(
|
||||
arglist=['--jobs=4'],
|
||||
explicit_stdin=True)
|
||||
|
||||
expected_warings = ["The --jobs option is not compatible with "
|
||||
"supplying input using - . Ignoring --jobs "
|
||||
"arguments."]
|
||||
if is_windows():
|
||||
expected_warings.append("The --jobs option is not "
|
||||
"available on Windows. Ignoring "
|
||||
"--jobs arguments.")
|
||||
self.verify_warnings(collected_warnings, expected_warings)
|
||||
self.assertEqual(self.count, 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
3
tox.ini
3
tox.ini
|
|
@ -6,9 +6,12 @@ envlist =
|
|||
[testenv]
|
||||
usedevelop = True
|
||||
deps =
|
||||
nose
|
||||
mock
|
||||
commands =
|
||||
python setup.py test -q
|
||||
python setup.py flake8
|
||||
nosetests flake8.tests.toast_warnings
|
||||
|
||||
[testenv:py27-flake8]
|
||||
basepython = python2.7
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue