diff options
| -rw-r--r-- | flake8/engine.py | 22 | ||||
| -rw-r--r-- | flake8/tests/test_engine.py | 24 |
2 files changed, 45 insertions, 1 deletions
diff --git a/flake8/engine.py b/flake8/engine.py index 0f440c1..6587667 100644 --- a/flake8/engine.py +++ b/flake8/engine.py @@ -17,6 +17,26 @@ _flake8_noqa = re.compile(r'\s*# flake8[:=]\s*noqa', re.I).search EXTRA_EXCLUDE = ['.tox', '.eggs', '*.egg'] +def _load_entry_point(entry_point, verify_requirements): + """Based on the version of setuptools load an entry-point correctly. + + setuptools 11.3 deprecated `require=False` in the call to EntryPoint.load. + To load entry points correctly after that without requiring all + dependencies be present, the proper way is to call EntryPoint.resolve. + + This function will provide backwards compatibility for older versions of + setuptools while also ensuring we do the right thing for the future. + """ + if hasattr(entry_point, 'resolve') and hasattr(entry_point, 'require'): + if verify_requirements: + entry_point.require() + plugin = entry_point.resolve() + else: + plugin = entry_point.load(require=verify_requirements) + + return plugin + + def _register_extensions(): """Register all the extensions.""" extensions = util.OrderedSet() @@ -31,7 +51,7 @@ def _register_extensions(): else: for entry in iter_entry_points('flake8.extension'): # Do not verify that the requirements versions are valid - checker = entry.load(require=False) + checker = _load_entry_point(entry, verify_requirements=False) pep8.register_check(checker, codes=[entry.name]) extensions.add((checker.name, checker.version)) if hasattr(checker, 'add_options'): diff --git a/flake8/tests/test_engine.py b/flake8/tests/test_engine.py index a6faab5..f6c0e5e 100644 --- a/flake8/tests/test_engine.py +++ b/flake8/tests/test_engine.py @@ -113,6 +113,30 @@ class TestEngine(unittest.TestCase): sg = engine.StyleGuide(parser=parser) assert 'X' not in sg.options.ignore + def test_load_entry_point_verifies_requirements(self): + entry_point = mock.Mock(spec=['require', 'resolve', 'load']) + + engine._load_entry_point(entry_point, verify_requirements=True) + entry_point.require.assert_called_once_with() + entry_point.resolve.assert_called_once_with() + + def test_load_entry_point_does_not_verify_requirements(self): + entry_point = mock.Mock(spec=['require', 'resolve', 'load']) + + engine._load_entry_point(entry_point, verify_requirements=False) + self.assertFalse(entry_point.require.called) + entry_point.resolve.assert_called_once_with() + + def test_load_entry_point_passes_require_argument_to_load(self): + entry_point = mock.Mock(spec=['load']) + + engine._load_entry_point(entry_point, verify_requirements=True) + entry_point.load.assert_called_once_with(require=True) + entry_point.reset_mock() + + engine._load_entry_point(entry_point, verify_requirements=False) + entry_point.load.assert_called_once_with(require=False) + def oserror_generator(error_number, message='Ominous OSError message'): def oserror_side_effect(*args, **kwargs): |
