From a8a44cc39747c7e2987356a0ca1cf722c0cf0ab2 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Sat, 15 Oct 2022 08:55:21 +0200 Subject: [PATCH] Skip invalid TOML and improve test coverage --- src/flake8_requirements/checker.py | 6 +++--- test/test_checker.py | 23 +++++++++++++++++++---- test/test_pep621.py | 5 +++++ test/test_setup.py | 21 +++++++++++++++++++++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/flake8_requirements/checker.py b/src/flake8_requirements/checker.py index 274f529..09a7cd4 100644 --- a/src/flake8_requirements/checker.py +++ b/src/flake8_requirements/checker.py @@ -196,13 +196,13 @@ def setup(**kw): '__file__': os.path.join(cwd, "setup.py"), '__f8r_setup': setup, }) - except Exception as e: + except BaseException as e: # XXX: Exception during setup.py evaluation might not necessary # mean "fatal error". This exception might occur if e.g. # we have hijacked local setup() function (due to matching # heuristic for function arguments). Anyway, we shall not # break flake8 execution due to our eval() usage. - LOG.exception("Couldn't evaluate setup.py: %s", e) + LOG.error("Couldn't evaluate setup.py: %r", e) self.redirected = False # Restore import search path. @@ -548,7 +548,7 @@ def get_pyproject_toml(cls): try: with open(os.path.join(cls.root_dir, "pyproject.toml")) as f: return toml.loads(f.read()) - except IOError as e: + except (IOError, toml.TomlDecodeError) as e: LOG.debug("Couldn't load project setup: %s", e) return {} diff --git a/test/test_checker.py b/test/test_checker.py index 17ee829..b0483c0 100644 --- a/test/test_checker.py +++ b/test/test_checker.py @@ -32,6 +32,12 @@ def processing_setup_py(self): return self.filename == "setup.py" +class Flake8OptionManagerMock(dict): + + def add_option(self, name, **kw): + self[name] = kw + + class Flake8Options: known_modules = "" requirements_file = None @@ -49,6 +55,15 @@ def check(code, filename="", options=None): class Flake8CheckerTestCase(unittest.TestCase): + def test_add_options(self): + manager = Flake8OptionManagerMock() + Flake8Checker.add_options(manager) + self.assertEqual( + sorted(manager.keys()), + ['--known-modules', '--requirements-file', + '--requirements-max-depth', '--scan-host-site-packages'], + ) + def test_stdlib(self): errors = check("import os\nfrom unittest import TestCase") self.assertEqual(len(errors), 0) @@ -121,10 +136,10 @@ class Options(Flake8Options): type(Flake8Checker.known_host_3rd_parties), dict, ) - # Since flake8-requirements (this package) is a plugin for flake8, - # it is very likely that onc will have flake8 installed in the host - # site-packages. However, that is not the case for all our GitHub - # Actions runners, so we can not enforce this assertion. + # Since flake8-requirements (this package) is a plugin for flake8, it + # is very likely that one will have flake8 installed in the host + # site-packages. However, that is not the case for our GitHub Actions + # runners, so we can not enforce this assertion. if 'flake8' in Flake8Checker.known_host_3rd_parties: self.assertEqual( Flake8Checker.known_host_3rd_parties['flake8'], diff --git a/test/test_pep621.py b/test/test_pep621.py index fd96592..cf0a52a 100644 --- a/test/test_pep621.py +++ b/test/test_pep621.py @@ -57,6 +57,11 @@ def test_get_pyproject_toml_pep621(self): } self.assertDictEqual(pep621, expected) + def test_get_pyproject_toml_invalid(self): + content = self.content + "invalid" + with mock.patch(builtins_open, mock.mock_open(read_data=content)): + self.assertDictEqual(Flake8Checker.get_pyproject_toml_pep621(), {}) + def test_1st_party(self): with mock.patch(builtins_open, mock.mock_open()) as m: m.side_effect = ( diff --git a/test/test_setup.py b/test/test_setup.py index cf49d2b..83dc89f 100644 --- a/test/test_setup.py +++ b/test/test_setup.py @@ -55,6 +55,27 @@ def test_detect_setup(self): setup = SetupVisitor(ast.parse(code), "") self.assertEqual(setup.redirected, False) + def test_detect_setup_wrong_num_of_args(self): + setup = SetupVisitor(ast.parse("setup(name='A')"), "") + self.assertEqual(setup.redirected, False) + + def test_detect_setup_wrong_function(self): + setup = SetupVisitor(ast.parse("setup(1, name='A')"), "") + self.assertEqual(setup.redirected, False) + + def test_detect_setup_oops(self): + setup = SetupVisitor(ast.parse("\n".join(( + "from .myModule import setup", + "setup({})".format(",".join(( + "name='A'", + "version='1'", + "author='A'", + "packages=['']", + "url='URL'", + ))), + ))), "") + self.assertEqual(setup.redirected, False) + def test_get_requirements(self): setup = SetupVisitor(ast.parse("setup(**{})".format(str({ 'name': 'A',