Bachmann1234 / diff_cover

Automatically find diff lines that need test coverage.
Apache License 2.0
710 stars 191 forks source link

7.7.0: pytest is failing in `tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist` unit #358

Open kloczek opened 1 year ago

kloczek commented 1 year ago

I'm packaging your module as an rpm package so I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.

pytest is failing with message that that flake8 is not installed despite fact that it is installed. First thing is why test suite is checking is that module installed? πŸ€” Here is pytest output:

```console + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-7.7.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-7.7.0-2.fc35.x86_64/usr/lib/python3.8/site-packages + /usr/bin/pytest -ra -m 'not network' ==================================================================================== test session starts ==================================================================================== platform linux -- Python 3.8.17, pytest-7.4.0, pluggy-1.2.0 rootdir: /home/tkloczko/rpmbuild/BUILD/diff_cover-7.7.0 configfile: pyproject.toml plugins: datadir-1.4.1, flake8-1.1.1, mock-3.11.1 collected 288 items tests/test_clover_violations_reporter.py . [ 0%] tests/test_config_parser.py ............... [ 5%] tests/test_diff_cover_main.py .. [ 6%] tests/test_diff_cover_tool.py ....... [ 8%] tests/test_diff_quality_main.py ............ [ 12%] tests/test_diff_reporter.py ....................................... [ 26%] tests/test_git_diff.py .......... [ 29%] tests/test_git_path.py ..... [ 31%] tests/test_integration.py ................................................ [ 48%] tests/test_java_violations_reporter.py .............. [ 53%] tests/test_report_generator.py .............................. [ 63%] tests/test_snippets.py ................... [ 70%] tests/test_util.py . [ 70%] tests/test_violations_reporter.py ...........................................F......................................... [100%] ========================================================================================= FAILURES ========================================================================================== __________________________________________________________________ TestFlake8QualityReporterTest.test_file_does_not_exist ___________________________________________________________________ self = @pytest.mark.disable_all_files_exist def test_file_does_not_exist(self): quality = QualityReporter(flake8_driver) file_paths = ["ajshdjlasdhajksdh.py"] # Expect that we get no results because that file does not exist for path in file_paths: > result = quality.violations(path) tests/test_violations_reporter.py:1120: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , src_path = 'ajshdjlasdhajksdh.py' def violations(self, src_path): """ Return a list of Violations recorded in `src_path`. """ if not any(src_path.endswith(ext) for ext in self.driver.supported_extensions): return [] if src_path not in self.violations_dict: if self.reports: self.violations_dict = self.driver.parse_reports(self.reports) else: if self.driver_tool_installed is None: self.driver_tool_installed = self.driver.installed() if not self.driver_tool_installed: > raise OSError(f"{self.driver.name} is not installed") E OSError: flake8 is not installed diff_cover/violationsreporters/base.py:160: OSError ================================================================================== short test summary info ================================================================================== FAILED tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist - OSError: flake8 is not installed ============================================================================== 1 failed, 287 passed in 10.18s =============================================================================== ```

Here is list of installed modules in build env

```console Package Version ----------------- ------- astroid 2.15.6 build 0.10.0 chardet 5.2.0 dill 0.3.7 distro 1.8.0 exceptiongroup 1.1.1 flake8 6.1.0 gpg 1.20.0 iniconfig 2.0.0 installer 0.7.0 isort 5.12.0 Jinja2 3.1.2 lazy-object-proxy 1.9.0 libcomps 0.1.19 MarkupSafe 2.1.3 mccabe 0.7.0 mock 5.1.0 packaging 23.1 platformdirs 3.10.0 pluggy 1.2.0 poetry-core 1.7.0 pycodestyle 2.11.0 pyflakes 3.1.0 Pygments 2.16.0 pylint 2.17.5 pyproject_hooks 1.0.0 pytest 7.4.0 pytest-datadir 1.4.1 pytest-flake8 1.1.1 pytest-mock 3.11.1 python-dateutil 2.8.2 six 1.16.0 tomli 2.0.1 tomlkit 0.12.1 typing_extensions 4.7.1 wheel 0.41.1 wrapt 1.14.1 ```
Bachmann1234 commented 1 year ago

So the most likely reason the suite is failing is that the command is not available on your path. Diff quality runs its commands via subprocess (since it does not assume the command are installed in the same python environment or are even python tools).

This error actually comes up on the command that checks for the tools existence.

kloczek commented 7 months ago

So the most likely reason the suite is failing is that the command is not available on your path. Diff quality runs its commands via subprocess (since it does not assume the command are installed in the same python environment or are even python tools).

This error actually comes up on the command that checks for the tools existence.

OK but which one command? πŸ€”

In mean time I've moved to python 3.9 and pytest 8.1.1 and now pytest fails in new units

Here is pytest output: ```console + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-8.0.3-2.fc36.x86_64/usr/lib64/python3.9/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-8.0.3-2.fc36.x86_64/usr/lib/python3.9/site-packages + /usr/bin/pytest -ra -m 'not network' ==================================================================================== test session starts ==================================================================================== platform linux -- Python 3.9.18, pytest-8.1.1, pluggy-1.4.0 rootdir: /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3 configfile: pyproject.toml plugins: flake8-1.1.1, mock-3.12.0, datadir-1.5.0 collected 288 items tests/test_clover_violations_reporter.py . [ 0%] tests/test_config_parser.py ............... [ 5%] tests/test_diff_cover_main.py .. [ 6%] tests/test_diff_cover_tool.py ....... [ 8%] tests/test_diff_quality_main.py ............ [ 12%] tests/test_diff_reporter.py ....................................... [ 26%] tests/test_git_diff.py .......... [ 29%] tests/test_git_path.py ..... [ 31%] tests/test_integration.py .............................FFF.......F.......F [ 48%] tests/test_java_violations_reporter.py .............. [ 53%] tests/test_report_generator.py .............................. [ 63%] tests/test_snippets.py ................... [ 70%] tests/test_util.py . [ 70%] tests/test_violations_reporter.py ...........................................F......................................... [100%] ========================================================================================= FAILURES ========================================================================================== __________________________________________________________________ TestDiffQualityIntegration.test_added_file_pylint_html ___________________________________________________________________ self = def test_added_file_pylint_html(self): > self._check_html_report( "git_diff_violations.txt", "pylint_violations_report.html", ["diff-quality", "--violations=pylint"], ) /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:446: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , git_diff_path = 'git_diff_violations.txt', expected_html_path = 'pylint_violations_report.html' tool_args = ['diff-quality', '--violations=pylint'], expected_status = 0, css_file = None def _check_html_report( self, git_diff_path, expected_html_path, tool_args, expected_status=0, css_file=None, ): """ Verify that the tool produces the expected HTML report. `git_diff_path` is a path to a fixture containing the (patched) output of the call to `git diff`. `expected_console_path` is a path to the fixture containing the expected HTML output of the tool. `tool_args` is a list of command line arguments to pass to the tool. You should include the name of the tool as the first argument. """ # Patch the output of `git diff` with open(git_diff_path, encoding="utf-8") as git_diff_file: self._set_git_diff_output(git_diff_file.read(), "") # Create a temporary directory to hold the output HTML report # Add a cleanup to ensure the directory gets deleted temp_dir = self.tmp_path / "dummy" temp_dir.mkdir() html_report_path = os.path.join(temp_dir, "diff_coverage.html") args = tool_args + ["--html-report", html_report_path] if css_file: css_file = os.path.join(temp_dir, css_file) args += ["--external-css-file", css_file] # Execute the tool if "diff-cover" in args[0]: code = diff_cover_tool.main(args) else: code = diff_quality_tool.main(args) > assert code == expected_status E assert 1 == 0 /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:111: AssertionError ------------------------------------------------------------------------------------- Captured log call ------------------------------------------------------------------------------------- ERROR diff_cover.diff_quality_tool:diff_quality_tool.py:379 Failure: 'pylint is not installed' ______________________________________________________________________ TestDiffQualityIntegration.test_fail_under_html ______________________________________________________________________ self = def test_fail_under_html(self): > self._check_html_report( "git_diff_violations.txt", "pylint_violations_report.html", ["diff-quality", "--violations=pylint", "--fail-under=80"], expected_status=1, ) /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:453: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:119: in _check_html_report html = self._clear_css(html) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , content = '' def _clear_css(self, content): """ The CSS is provided by pygments and changes fairly often. Im ok with simply saying "There was css" Perhaps I will eat these words """ clean_content = re.sub("r'", content, "", re.DOTALL) > assert len(content) > len(clean_content) E AssertionError: assert 0 > 0 E + where 0 = len('') E + and 0 = len('') /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:63: AssertionError ------------------------------------------------------------------------------------- Captured log call ------------------------------------------------------------------------------------- ERROR diff_cover.diff_quality_tool:diff_quality_tool.py:379 Failure: 'pylint is not installed' ___________________________________________________________________ TestDiffQualityIntegration.test_fail_under_pass_html ____________________________________________________________________ self = def test_fail_under_pass_html(self): > self._check_html_report( "git_diff_violations.txt", "pylint_violations_report.html", ["diff-quality", "--violations=pylint", "--fail-under=40"], expected_status=0, ) /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:461: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , git_diff_path = 'git_diff_violations.txt', expected_html_path = 'pylint_violations_report.html' tool_args = ['diff-quality', '--violations=pylint', '--fail-under=40'], expected_status = 0, css_file = None def _check_html_report( self, git_diff_path, expected_html_path, tool_args, expected_status=0, css_file=None, ): """ Verify that the tool produces the expected HTML report. `git_diff_path` is a path to a fixture containing the (patched) output of the call to `git diff`. `expected_console_path` is a path to the fixture containing the expected HTML output of the tool. `tool_args` is a list of command line arguments to pass to the tool. You should include the name of the tool as the first argument. """ # Patch the output of `git diff` with open(git_diff_path, encoding="utf-8") as git_diff_file: self._set_git_diff_output(git_diff_file.read(), "") # Create a temporary directory to hold the output HTML report # Add a cleanup to ensure the directory gets deleted temp_dir = self.tmp_path / "dummy" temp_dir.mkdir() html_report_path = os.path.join(temp_dir, "diff_coverage.html") args = tool_args + ["--html-report", html_report_path] if css_file: css_file = os.path.join(temp_dir, css_file) args += ["--external-css-file", css_file] # Execute the tool if "diff-cover" in args[0]: code = diff_cover_tool.main(args) else: code = diff_quality_tool.main(args) > assert code == expected_status E assert 1 == 0 /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:111: AssertionError ------------------------------------------------------------------------------------- Captured log call ------------------------------------------------------------------------------------- ERROR diff_cover.diff_quality_tool:diff_quality_tool.py:379 Failure: 'pylint is not installed' _________________________________________________________________ TestDiffQualityIntegration.test_added_file_pylint_console _________________________________________________________________ self = def test_added_file_pylint_console(self): console_report = "pylint_violations_console_report.txt" > self._check_console_report( "git_diff_violations.txt", console_report, ["diff-quality", "--violations=pylint"], ) /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:527: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , git_diff_path = 'git_diff_violations.txt' expected_console_path = 'pylint_violations_console_report.txt', tool_args = ['diff-quality', '--violations=pylint'], expected_status = 0 def _check_console_report( self, git_diff_path, expected_console_path, tool_args, expected_status=0 ): """ Verify that the tool produces the expected console report. `git_diff_path` is a path to a fixture containing the (patched) output of the call to `git diff`. `expected_console_path` is a path to the fixture containing the expected console output of the tool. `tool_args` is a list of command line arguments to pass to the tool. You should include the name of the tool as the first argument. """ # Patch the output of `git diff` with open(git_diff_path, encoding="utf-8") as git_diff_file: self._set_git_diff_output(git_diff_file.read(), "") # Capture stdout to a string buffer string_buffer = BytesIO() self._capture_stdout(string_buffer) # Execute the tool if "diff-cover" in tool_args[0]: code = diff_cover_tool.main(tool_args) else: code = diff_quality_tool.main(tool_args) > assert code == expected_status E assert 1 == 0 /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:156: AssertionError ------------------------------------------------------------------------------------- Captured log call ------------------------------------------------------------------------------------- ERROR diff_cover.diff_quality_tool:diff_quality_tool.py:379 Failure: 'pylint is not installed' ________________________________________________________________________ TestDiffQualityIntegration.test_quiet_mode _________________________________________________________________________ self = def test_quiet_mode(self): > self._check_console_report( "git_diff_violations.txt", "empty.txt", ["diff-quality", "--violations=pylint", "-q"], ) /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:618: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , git_diff_path = 'git_diff_violations.txt', expected_console_path = 'empty.txt' tool_args = ['diff-quality', '--violations=pylint', '-q'], expected_status = 0 def _check_console_report( self, git_diff_path, expected_console_path, tool_args, expected_status=0 ): """ Verify that the tool produces the expected console report. `git_diff_path` is a path to a fixture containing the (patched) output of the call to `git diff`. `expected_console_path` is a path to the fixture containing the expected console output of the tool. `tool_args` is a list of command line arguments to pass to the tool. You should include the name of the tool as the first argument. """ # Patch the output of `git diff` with open(git_diff_path, encoding="utf-8") as git_diff_file: self._set_git_diff_output(git_diff_file.read(), "") # Capture stdout to a string buffer string_buffer = BytesIO() self._capture_stdout(string_buffer) # Execute the tool if "diff-cover" in tool_args[0]: code = diff_cover_tool.main(tool_args) else: code = diff_quality_tool.main(tool_args) > assert code == expected_status E assert 1 == 0 /home/tkloczko/rpmbuild/BUILD/diff_cover-8.0.3/tests/test_integration.py:156: AssertionError ------------------------------------------------------------------------------------- Captured log call ------------------------------------------------------------------------------------- ERROR diff_cover.diff_quality_tool:diff_quality_tool.py:379 Failure: 'pylint is not installed' __________________________________________________________________ TestFlake8QualityReporterTest.test_file_does_not_exist ___________________________________________________________________ self = @pytest.mark.disable_all_files_exist def test_file_does_not_exist(self): quality = QualityReporter(flake8_driver) file_paths = ["ajshdjlasdhajksdh.py"] # Expect that we get no results because that file does not exist for path in file_paths: > result = quality.violations(path) tests/test_violations_reporter.py:1109: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , src_path = 'ajshdjlasdhajksdh.py' def violations(self, src_path): """ Return a list of Violations recorded in `src_path`. """ if not any(src_path.endswith(ext) for ext in self.driver.supported_extensions): return [] if src_path not in self.violations_dict: if self.reports: self.violations_dict = self.driver.parse_reports(self.reports) else: if self.driver_tool_installed is None: self.driver_tool_installed = self.driver.installed() if not self.driver_tool_installed: > raise OSError(f"{self.driver.name} is not installed") E OSError: flake8 is not installed diff_cover/violationsreporters/base.py:160: OSError ================================================================================== short test summary info ================================================================================== FAILED tests/test_integration.py::TestDiffQualityIntegration::test_added_file_pylint_html - assert 1 == 0 FAILED tests/test_integration.py::TestDiffQualityIntegration::test_fail_under_html - AssertionError: assert 0 > 0 FAILED tests/test_integration.py::TestDiffQualityIntegration::test_fail_under_pass_html - assert 1 == 0 FAILED tests/test_integration.py::TestDiffQualityIntegration::test_added_file_pylint_console - assert 1 == 0 FAILED tests/test_integration.py::TestDiffQualityIntegration::test_quiet_mode - assert 1 == 0 FAILED tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist - OSError: flake8 is not installed =============================================================================== 6 failed, 282 passed in 4.94s =============================================================================== ```
Bachmann1234 commented 7 months ago

@kloczek for pylint the command is pylint --version

Defined here https://github.com/Bachmann1234/diff_cover/blob/a2aa5f6a5ceb55f87c46c6daeadc0ab7c41e640e/diff_cover/violationsreporters/violations_reporter.py#L582

Based on the output that command is failing (returning a non zero code)

Bachmann1234 commented 7 months ago

To elaborate further. It really looks like whatever environment this is running in does not have pylint in its path

kloczek commented 7 months ago

Just tested new 9.0.0 with installed pylint and after that step indeed some units stopped failing however still have one failing unit

Here is pytest output: ```console + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib64/python3.10/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib/python3.10/site-packages + /usr/bin/pytest -ra -m 'not network' ==================================================================================== test session starts ==================================================================================== platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0 rootdir: /home/tkloczko/rpmbuild/BUILD/diff_cover-9.0.0 configfile: pyproject.toml plugins: datadir-1.5.0, flake8-1.1.1, mock-3.14.0 collected 288 items tests/test_clover_violations_reporter.py . [ 0%] tests/test_config_parser.py ............... [ 5%] tests/test_diff_cover_main.py .. [ 6%] tests/test_diff_cover_tool.py ....... [ 8%] tests/test_diff_quality_main.py ............ [ 12%] tests/test_diff_reporter.py ....................................... [ 26%] tests/test_git_diff.py .......... [ 29%] tests/test_git_path.py ..... [ 31%] tests/test_integration.py ................................................ [ 48%] tests/test_java_violations_reporter.py .............. [ 53%] tests/test_report_generator.py .............................. [ 63%] tests/test_snippets.py ................... [ 70%] tests/test_util.py . [ 70%] tests/test_violations_reporter.py ...........................................F......................................... [100%] ========================================================================================= FAILURES ========================================================================================== __________________________________________________________________ TestFlake8QualityReporterTest.test_file_does_not_exist ___________________________________________________________________ self = @pytest.mark.disable_all_files_exist def test_file_does_not_exist(self): quality = QualityReporter(flake8_driver) file_paths = ["ajshdjlasdhajksdh.py"] # Expect that we get no results because that file does not exist for path in file_paths: > result = quality.violations(path) tests/test_violations_reporter.py:1109: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , src_path = 'ajshdjlasdhajksdh.py' def violations(self, src_path): """ Return a list of Violations recorded in `src_path`. """ if not any(src_path.endswith(ext) for ext in self.driver.supported_extensions): return [] if src_path not in self.violations_dict: if self.reports: self.violations_dict = self.driver.parse_reports(self.reports) else: if self.driver_tool_installed is None: self.driver_tool_installed = self.driver.installed() if not self.driver_tool_installed: > raise OSError(f"{self.driver.name} is not installed") E OSError: flake8 is not installed diff_cover/violationsreporters/base.py:160: OSError ================================================================================== short test summary info ================================================================================== FAILED tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist - OSError: flake8 is not installed =============================================================================== 1 failed, 287 passed in 8.59s =============================================================================== ```

Error message does no match to actual situation because in build env is installed flake8

[tkloczko@pers-jacek SPECS]$ pip show flake8
Name: flake8
Version: 6.1.0
Summary: the modular source code checker: pep8 pyflakes and co
Home-page: https://github.com/pycqa/flake8
Author: Tarek Ziade
Author-email: tarek@ziade.org
License: MIT
Location: /usr/lib/python3.10/site-packages
Requires: mccabe, pycodestyle, pyflakes
Required-by: pytest-flake8
Bachmann1234 commented 7 months ago

Just tested new 9.0.0 with installed pylint and after that step indeed some units stopped failing however still have one failing unit

Here is pytest output: Error message does no match to actual situation because in build env is installed flake8

[tkloczko@pers-jacek SPECS]$ pip show flake8
Name: flake8
Version: 6.1.0
Summary: the modular source code checker: pep8 pyflakes and co
Home-page: https://github.com/pycqa/flake8
Author: Tarek Ziade
Author-email: tarek@ziade.org
License: MIT
Location: /usr/lib/python3.10/site-packages
Requires: mccabe, pycodestyle, pyflakes
Required-by: pytest-flake8

I dont really know what to tell you. That test failing implies the command flake8 --version is returning a non zero exit code. The most common reason for this is the command is not actually in the path. SO the library being installed is part of it but ultimately in whatever python running the test is having trouble running that check.

kloczek commented 7 months ago

I dont really know what to tell you. That test failing implies the command flake8 --version is returning a non zero exit code. The most common reason for this is the command is not actually in the path. SO the library being installed is part of it but ultimately in whatever python running the test is having trouble running that check.

[tkloczko@pers-jacek build]$ flake8 --version
6.1.0 (mccabe: 0.7.0, pycodestyle: 2.11.0, pyflakes: 3.1.0) CPython 3.10.14 on Linux
[tkloczko@pers-jacek build]$ echo $?
0

Problems happens .. you don't need ot say anything πŸ˜„

Do you have any propositions about what I can try to do to diagnose this effect? πŸ€” FYI: temporary I've added to --deselect list this unit assuming that more likely with testing procedure than tested code.

Bachmann1234 commented 6 months ago

I'll take another stab at reproducing this sometime this week. But at this point I think the only path would be putting a line in to log the exception and see how the command is failing

Bachmann1234 commented 6 months ago

@kloczek what does which flake8 show? IS that path accessible in whatever you are doing to run the tests?

Because im not convinced python3 -sBm build -w --no-isolation is installing dev dependencies.

I created a virtual env installed build and poetry then ran python3 -sBm build -w --no-isolation

❯ flake8
zsh: command not found: flake8

This is the output of pip --freeze

build==1.2.1
CacheControl==0.14.0
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
cleo==2.1.0
crashtest==0.4.1
distlib==0.3.8
dulwich==0.21.7
fastjsonschema==2.19.1
filelock==3.13.4
idna==3.7
installer==0.7.0
jaraco.classes==3.4.0
keyring==24.3.1
more-itertools==10.2.0
msgpack==1.0.8
packaging==24.0
pexpect==4.9.0
pkginfo==1.10.0
platformdirs==4.2.0
poetry==1.8.2
poetry-core==1.9.0
poetry-plugin-export==1.7.1
ptyprocess==0.7.0
pycparser==2.22
pyproject_hooks==1.0.0
rapidfuzz==3.8.1
requests==2.31.0
requests-toolbelt==1.0.0
shellingham==1.5.4
tomlkit==0.12.4
trove-classifiers==2024.4.10
urllib3==2.2.1
virtualenv==20.25.2
xattr==1.1.0
kloczek commented 6 months ago

@kloczek what does which flake8 show? IS that path accessible in whatever you are doing to run the tests?

I've already provided that details opening ticket

flake8            6.1.0

Because im not convinced python3 -sBm build -w --no-isolation is installing dev dependencies.

Of course it is not installing anything because that command is responsible for only build .whl archive. Nevertheless in this case it is issue not with building but with testing.

Bachmann1234 commented 6 months ago

@kloczek I don't see anything about the output of which flake8

I see that the library seems to be installed (and I admit last night I neglected to expand the details)

But it still may be interesting to know where in the build system that command is.

What procedure was used to install the quality tools? Simple pip install? Or something else?

kloczek commented 6 months ago

But it still may be interesting to know where in the build system that command is.

Hmm .. what you mean "where"? πŸ€”

What procedure was used to install the quality tools? Simple pip install? Or something else?

Full build, install and testing procedure is described on top of this ticket πŸ™„ πŸ˜‹ I'm installing all modules from rpm packages I'm not interested to test anything what is provided as .whl archives on pypi but only distribution resources on which I'm working. This is why build is performed with --no-isolation.

Bachmann1234 commented 6 months ago

But it still may be interesting to know where in the build system that command is.

Hmm .. what you mean "where"? πŸ€”

What procedure was used to install the quality tools? Simple pip install? Or something else?

Full build, install and testing procedure is described on top of this ticket πŸ™„ πŸ˜‹ I'm installing all modules from rpm packages I'm not interested to test anything what is provided as .whl archives on pypi but only distribution resources on which I'm working. This is why build is performed with --no-isolation.

The path! Running which will confirm the path of the command! So many times in Python builds executables end up in weird places

kloczek commented 6 months ago

The path! Running which will confirm the path of the command! So many times in Python builds executables end up in weird places

I'm building all packages in dedicated build envs created to build only one package. Inside build are installed only build dependencies. In distribution is only one python package which provides /usr/bin/python3 and it is ATM python 3.11.14. After finis build procedure build env is deleted. In other words .. in such env thee is no possibility to have multiple python binaries/versions.

Bachmann1234 commented 6 months ago

Clearly I don't know a lot about Linux packaging beyond basic user commands

But the test that's failing is running a command, not running a function that's imported from a lib. Your single package might be combining all the dependencies but it probably is not installing all the commands for the quality tools into some path that can be executed. But again, I know you are able to run it yourself.

So if your package does not have access to run the command then it will fail that test. This is why I keep asking you to run which to try and confirm where that command is. Because you have demonstrated that you can run it. So it's clearly in your users $PATH

But if that command exists in a place where in the context of the test it does not have access then it won't find the executable.

So that's why I keep asking. What does which pylint tell you. Because if pylint is somewhere the command does not see then it might as well not exist at all.

But honestly, I don't think it's likely that seeing where that command is will make it obvious what's going on. I suspect I'm gonna have to expose the underlying error so you can see specifically what's failing. May not be able to do that for a couple weeks though.

I just think the most likely cause is some kind of path error. In the context of the test, it can't find the pylint executable. I think when I expose the error it's going to be something boring like "command not found" and the question will become "but why?!"

kloczek commented 6 months ago

Clearly I don't know a lot about Linux packaging beyond basic user commands

reported issue has nothing to do with packaging so you don't need to know anything about that.

So that's why I keep asking. What does which pylint tell you. Because if pylint is somewhere the command does not see then it might as well not exist at all.

Please have look on provided output .. first time ever and/or one more time. Error message has nothing to do with pylint.

Why at all test using unis custom code checking "is module XXX installed" if for that can be used OOTB pytest calls? πŸ€”

Again flake8 is installed in build env and it works in casesof other modules build procedures

[tkloczko@pers-jacek SPECS]$ grep "BuildRequires:.*python3dist(flake8)" *
crypto-policies.spec:BuildRequires:     python3dist(flake8)
python-diff-cover.spec:BuildRequires:   python3dist(flake8)
python-flake8-bugbear.spec:BuildRequires:       python3dist(flake8)     >= 3.0.0
python-flake8-dunder-all.spec:BuildRequires:    python3dist(flake8)
python-flake8-pyi.spec:BuildRequires:   python3dist(flake8)     >= 3.2.1
python-mypy.spec:BuildRequires: python3dist(flake8)
python-pytest-flake8.spec:BuildRequires:        python3dist(flake8)     >= 3.5

As you see in above is literally flake8 is listed in case of this module. With installed that module in build it is not possible to start build. pip show that flake8 is installed but code of that unit for some reason is not able to find it.

Bachmann1234 commented 6 months ago

I swear im not trying to be difficult here. I know my mixing up of the specific quality tool is not helping. Ive been responding in the morning and at night while juggling other things and thats my bad. But the theory is the same.

Here is a screenshot from your output

Screenshot 2024-04-17 at 12 57 22β€―PM

The test is an integration test, it executes flake8 --version as a subprocess command and if that command fails it catches the failure and returns that output 'flake8 is not installed.

Now I know you can run this command yourself, you demonstrated it. And I know flake8 is technically installed. But the point is the subprocess is failing to run it one way or another.

I suspect thats because the library is being installed but the executable for said library is not accessable when running the test and I dont know why.

So you have two options to figure this out.

  1. Put some print statement around here to spit out the actual output of the subprocess command (basically capture the stdout, stdin that is currently ignored and print it) [The docs for communicate] (https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate) I would replace this with
stdin, stdout = process.communicate()
print(stdin)
print(stdout)

that should tell you exactly why the subprocess command is failing. Though again, I suspect its gonna be a path failure of some kind. Where it says the command does not exist despite being installed.

  1. wait for me to find time to think of a way to expose it and release a version with that. Probably do something similar what the main execute function is doing. Though that will be a bit as I am not in a position to do work on diff cover right now.
kloczek commented 6 months ago

I've modified my spec file %check to:

%check
echo; pip show flake8; echo
%pytest tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist
%pytest %{!?with_failing_tests: \
        --deselect tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist \
}

and added pip to build dependencies (normally it is not needed) I've send that spec as test build request (each build is performed in build env created from scratch and after build such build env is deleted).

Here is result literally taken from build log of the rpm %check (test suite execution):

```console Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.dxRdmQ + umask 022 + cd /home/tkloczko/rpmbuild/BUILD + '[' /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64 '!=' / ']' + rm -rf /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64 + cd diff_cover-9.0.0 + /usr/bin/python3 -sBm installer dist/diff_cover-9.0.0-py3-none-any.whl --destdir /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64 + /usr/bin/rm -rfv /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/bin/__pycache__ + for distinfo in /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib/python3.10/site-packages/*.dist-info /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib64/python3.10/site-packages/*.dist-info + '[' -f /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib/python3.10/site-packages/diff_cover-9.0.0.dist-info/direct_url.json ']' + for distinfo in /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib/python3.10/site-packages/*.dist-info /home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib64/python3.10/site-packages/*.dist-info + '[' -f '/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib64/python3.10/site-packages/*.dist-info/direct_url.json' ']' + /usr/bin/find-debuginfo -j48 --strict-build-id -m -i --build-id-seed 9.0.0-2.fc37 --unique-debug-suffix -9.0.0-2.fc37.x86_64 --unique-debug-src-base python-diff-cover-9.0.0-2.fc37.x86_64 --run-dwz --dwz-low-mem-die-limit none --dwz-max-die-limit 110000000 -S debugsourcefiles.list /home/tkloczko/rpmbuild/BUILD/diff_cover-9.0.0 find-debuginfo: starting Extracting debug info from 0 files Creating .debug symlinks for symlinks to ELF files find: β€˜debug’: No such file or directory find-debuginfo: done + /usr/lib/rpm/check-buildroot + /usr/lib/rpm/redhat/brp-ldconfig + /usr/lib/rpm/brp-compress + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip + /usr/lib/rpm/check-rpaths + /usr/lib/rpm/redhat/brp-mangle-shebangs Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.KOoawZ + umask 022 + cd /home/tkloczko/rpmbuild/BUILD + cd diff_cover-9.0.0 + echo + pip show flake8 Name: flake8 Version: 6.1.0 Summary: the modular source code checker: pep8 pyflakes and co Home-page: https://github.com/pycqa/flake8 Author: Tarek Ziade Author-email: tarek@ziade.org License: MIT Location: /usr/lib/python3.10/site-packages Requires: mccabe, pycodestyle, pyflakes Required-by: pytest-flake8 + echo + ASMFLAGS='-m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -O2 -g -grecord-gcc-switches -pipe -mtls-dialect=gnu2 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fdata-sections -ffunction-sections -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -flto=auto -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -Wall -Werror=format-security' + CFLAGS='-m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -O2 -g -grecord-gcc-switches -pipe -mtls-dialect=gnu2 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fdata-sections -ffunction-sections -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -flto=auto -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -Wall -Werror=format-security' + CXXFLAGS='-m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -O2 -g -grecord-gcc-switches -pipe -mtls-dialect=gnu2 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fdata-sections -ffunction-sections -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -flto=auto -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -Wall -Werror=format-security' + FFLAGS='-m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -O2 -g -grecord-gcc-switches -pipe -mtls-dialect=gnu2 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fdata-sections -ffunction-sections -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -flto=auto -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -Wall -Werror=format-security -I/usr/lib64/gfortran/modules' + FCFLAGS='-m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -O2 -g -grecord-gcc-switches -pipe -mtls-dialect=gnu2 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fdata-sections -ffunction-sections -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -flto=auto -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -Wall -Werror=format-security -I/usr/lib64/gfortran/modules' + LDFLAGS='-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--gc-sections -Wl,--as-needed -Wl,--build-id=sha1 -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-z,pack-relative-relocs -flto=auto -fuse-linker-plugin' + RUSTFLAGS='-C codegen-units=1 -C debuginfo=2 -C opt-level=2 -C link-arg=-Wl,--as-needed -C link-arg=-Wl,--build-id=sha1 -C link-arg=-Wl,-z,now -C link-arg=-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -C link-arg=-Wl,-z,pack-relative-relocs -C link-arg=-Wl,-z,relro -C link-arg=-flto=auto --cap-lints=warn' + VALAFLAGS=-g + CC=/usr/bin/gcc + CXX=/usr/bin/g++ + FC=/usr/bin/gfortran + AR=/usr/bin/gcc-ar + NM=/usr/bin/gcc-nm + RANLIB=/usr/bin/gcc-ranlib + export ASMFLAGS CFLAGS CXXFLAGS FFLAGS FCFLAGS LDFLAGS VALAFLAGS CC CXX FC AR NM RANLIB RUSTFLAGS VALAFLAGS + PATH=/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/bin:/usr/bin:/usr/sbin:/usr/local/sbin + LD_LIBRARY_PATH=/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib64 + PYTHONDONTWRITEBYTECODE=1 + PDM_BUILD_SCM_VERSION=9.0.0 + PBR_VERSION=9.0.0 + SETUPTOOLS_SCM_PRETEND_VERSION=9.0.0 + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib64/python3.10/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/lib/python3.10/site-packages + /usr/bin/pytest -ra -m 'not network' tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist ============================= test session starts ============================== platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0 benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000) rootdir: /home/tkloczko/rpmbuild/BUILD/diff_cover-9.0.0 configfile: pyproject.toml plugins: forked-1.6.0, hypothesis-6.100.0, mock-3.14.0, benchmark-4.0.0, timeout-2.3.1, flaky-3.8.1, subprocess-1.5.0, flake8-1.1.1, datadir-1.5.0 collected 1 item tests/test_violations_reporter.py F [100%] =================================== FAILURES =================================== ____________ TestFlake8QualityReporterTest.test_file_does_not_exist ____________ self = @pytest.mark.disable_all_files_exist def test_file_does_not_exist(self): quality = QualityReporter(flake8_driver) file_paths = ["ajshdjlasdhajksdh.py"] # Expect that we get no results because that file does not exist for path in file_paths: > result = quality.violations(path) tests/test_violations_reporter.py:1109: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = src_path = 'ajshdjlasdhajksdh.py' def violations(self, src_path): """ Return a list of Violations recorded in `src_path`. """ if not any(src_path.endswith(ext) for ext in self.driver.supported_extensions): return [] if src_path not in self.violations_dict: if self.reports: self.violations_dict = self.driver.parse_reports(self.reports) else: if self.driver_tool_installed is None: self.driver_tool_installed = self.driver.installed() if not self.driver_tool_installed: > raise OSError(f"{self.driver.name} is not installed") E OSError: flake8 is not installed diff_cover/violationsreporters/base.py:160: OSError =========================== short test summary info ============================ FAILED tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist ============================== 1 failed in 1.10s =============================== ```

As you see pip shows tat flake8 is present and your cede that it is not. Can you explain that? πŸ€”

Just humble question one more time: why at all this module test procedure needs to check is flake8 installed? πŸ€”

flake8 as many other modules never should be executed as module over python -m foo because when pyton is executed with -m it adds current directory to sys.path which messes with many such modules. This is why flake, pytest and many more provides wrapper script like

[tkloczko@pers-jacek SPECS]$ cat /usr/bin/flake8
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from flake8.main.cli import main
if __name__ == "__main__":
    sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0])
    sys.exit(main())

In other words if on testing is needed flake8 it shoulder be blindly executed as command and not checked as module. Am I right or not? πŸ€”

Bachmann1234 commented 6 months ago
Just humble question one more time: why at all this module test procedure needs to check is flake8 installed? 

I mean we are talking about code that was written potentially over a decade ago... and I dont even remember what parts were originally me.... but if im remembering correctly the idea is that diffcover/diffquality does not assume its bundled with anything. All it cares about is the tool it needs to run can be run over the code. So the python that runs diff cover does not need to be the same python that runs flake8 or any of the related tools (hell, some of the tools are not even python tools). so im not confident the python -m foo procedure makes sense in this context.

If this tool was written today it may have been written differently but who knows!.

The check to see if its installed is just running a simple version of the command. Feel free to remove the install check. I dont think it will help you because the main command will fail... likely for the same cause.

As you see pip shows tat flake8 is present and your cede that it is not. Can you explain that? 

I feel like ive tried to explain it. The command is failing, for some reason or another. If the basic --version command fails the code assumes its not installed and throws an os error and says its not installed. The error message is likely misleading. Ive told you what you could do to get a more specific error message but that would involve editing the code to see whats going on.

In other words if on testing is needed flake8 it shoulder be blindly executed as command and not checked as module.
Am I right or not? πŸ€”

Again, the "check" being run is blindly executing flake8. Executing flake8 is failing and the error the code throws says its not installed. But clearly the language is misleading/wrong because clearly its installed. But for some reason the subprocess command is failing.

kloczek commented 6 months ago

I mean we are talking about code that was written potentially over a decade ago... and I dont even remember what parts were originally me.

Please don't get me wrong. I'm not trying to blame/accuse anything or anyone. I'm only b*dy messenger πŸ˜‹ "Shit happens .. sometimes" πŸ˜„

I feel like ive tried to explain it. The command is failing, for some reason or another. If the basic --version command fails the code assumes its not installed and throws an os error and says its not installed.

Just made another test

+ strace -e trace=execve,fork /usr/bin/pytest -ra -m 'not network' tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist
execve("/usr/bin/pytest", ["/usr/bin/pytest", "-ra", "-m", "not network", "tests/test_violations_reporter.p"...], 0x7fff283d7630 /* 63 vars */) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=35604, si_uid=1000, si_status=128, si_utime=0, si_stime=0} ---
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=35605, si_uid=1000, si_status=255, si_utime=0, si_stime=0} ---
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=35606, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
==================================================================================== test session starts ====================================================================================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /home/tkloczko/rpmbuild/BUILD/diff_cover-9.0.0
configfile: pyproject.toml
plugins: forked-1.6.0, hypothesis-6.100.0, mock-3.14.0, benchmark-4.0.0, timeout-2.3.1, flaky-3.8.1, subprocess-1.5.0, flake8-1.1.1, datadir-1.5.0
collected 1 item

tests/test_violations_reporter.py --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=33582, si_uid=1000, si_status=1, si_utime=13 /* 0.13 s */, si_stime=2 /* 0.02 s */} ---
F                                                                                                                                                   [100%]

========================================================================================= FAILURES ==========================================================================================
__________________________________________________________________ TestFlake8QualityReporterTest.test_file_does_not_exist ___________________________________________________________________

self = <tests.test_violations_reporter.TestFlake8QualityReporterTest object at 0x7fb3bbd00940>

    @pytest.mark.disable_all_files_exist
    def test_file_does_not_exist(self):
        quality = QualityReporter(flake8_driver)
        file_paths = ["ajshdjlasdhajksdh.py"]
        # Expect that we get no results because that file does not exist
        for path in file_paths:
>           result = quality.violations(path)

tests/test_violations_reporter.py:1109:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <diff_cover.violationsreporters.base.QualityReporter object at 0x7fb3bbd009a0>, src_path = 'ajshdjlasdhajksdh.py'

    def violations(self, src_path):
        """
        Return a list of Violations recorded in `src_path`.
        """
        if not any(src_path.endswith(ext) for ext in self.driver.supported_extensions):
            return []
        if src_path not in self.violations_dict:
            if self.reports:
                self.violations_dict = self.driver.parse_reports(self.reports)
            else:
                if self.driver_tool_installed is None:
                    self.driver_tool_installed = self.driver.installed()
                if not self.driver_tool_installed:
>                   raise OSError(f"{self.driver.name} is not installed")
E                   OSError: flake8 is not installed

diff_cover/violationsreporters/base.py:160: OSError
================================================================================== short test summary info ==================================================================================
FAILED tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist - OSError: flake8 is not installed
===================================================================================== 1 failed in 1.61s =====================================================================================
+++ exited with 1 +++

As you see strace does not show any traces of execve() after pytest execution calls πŸ€”

kloczek commented 6 months ago

Corrected test. I forgot about -f in strace params (trace in forked processes. Now it shows:

```console + strace -fe trace=execve /usr/bin/pytest -ra -m 'not network' tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist execve("/usr/bin/pytest", ["/usr/bin/pytest", "-ra", "-m", "not network", "tests/test_violations_reporter.p"...], 0x7ffcef4cf390 /* 63 vars */) = 0 strace: Process 36146 attached [pid 36146] execve("/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/bin/git", ["git", "rev-parse", "--git-dir"], 0x7ffd15933650 /* 63 vars */) = -1 ENOENT (No such file or directory) [pid 36146] execve("/usr/bin/git", ["git", "rev-parse", "--git-dir"], 0x7ffd15933650 /* 63 vars */) = 0 [pid 36146] +++ exited with 128 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=36146, si_uid=1000, si_status=128, si_utime=0, si_stime=0} --- strace: Process 36147 attached [pid 36147] execve("/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/bin/hg", ["hg", "path", "default"], 0x7ffd15933650 /* 63 vars */) = -1 ENOENT (No such file or directory) [pid 36147] execve("/usr/bin/hg", ["hg", "path", "default"], 0x7ffd15933650 /* 63 vars */) = -1 ENOENT (No such file or directory) [pid 36147] execve("/usr/sbin/hg", ["hg", "path", "default"], 0x7ffd15933650 /* 63 vars */) = -1 ENOENT (No such file or directory) [pid 36147] execve("/usr/local/sbin/hg", ["hg", "path", "default"], 0x7ffd15933650 /* 63 vars */) = -1 ENOENT (No such file or directory) [pid 36147] +++ exited with 255 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=36147, si_uid=1000, si_status=255, si_utime=0, si_stime=0} --- strace: Process 36148 attached [pid 36148] execve("/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/bin/file", ["file", "-b", "/usr/bin/python"], 0x55f6303ae080 /* 64 vars */) = -1 ENOENT (No such file or directory) [pid 36148] execve("/usr/bin/file", ["file", "-b", "/usr/bin/python"], 0x55f6303ae080 /* 64 vars */) = 0 [pid 36148] +++ exited with 0 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=36148, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- ==================================================================================== test session starts ==================================================================================== platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0 benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000) rootdir: /home/tkloczko/rpmbuild/BUILD/diff_cover-9.0.0 configfile: pyproject.toml plugins: forked-1.6.0, hypothesis-6.100.0, mock-3.14.0, benchmark-4.0.0, timeout-2.3.1, flaky-3.8.1, subprocess-1.5.0, flake8-1.1.1, datadir-1.5.0 collected 1 item tests/test_violations_reporter.py strace: Process 36149 attached [pid 36149] execve("/home/tkloczko/rpmbuild/BUILDROOT/python-diff-cover-9.0.0-2.fc37.x86_64/usr/bin/flake8", ["flake8", "--version"], 0x55f6303c2c70 /* 64 vars */) = -1 ENOENT (No such file or directory) [pid 36149] execve("/usr/bin/flake8", ["flake8", "--version"], 0x55f6303c2c70 /* 64 vars */) = 0 [pid 36149] +++ exited with 1 +++ --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=36149, si_uid=1000, si_status=1, si_utime=21 /* 0.21 s */, si_stime=4 /* 0.04 s */} --- F [100%] ========================================================================================= FAILURES ========================================================================================== __________________________________________________________________ TestFlake8QualityReporterTest.test_file_does_not_exist ___________________________________________________________________ self = @pytest.mark.disable_all_files_exist def test_file_does_not_exist(self): quality = QualityReporter(flake8_driver) file_paths = ["ajshdjlasdhajksdh.py"] # Expect that we get no results because that file does not exist for path in file_paths: > result = quality.violations(path) tests/test_violations_reporter.py:1109: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , src_path = 'ajshdjlasdhajksdh.py' def violations(self, src_path): """ Return a list of Violations recorded in `src_path`. """ if not any(src_path.endswith(ext) for ext in self.driver.supported_extensions): return [] if src_path not in self.violations_dict: if self.reports: self.violations_dict = self.driver.parse_reports(self.reports) else: if self.driver_tool_installed is None: self.driver_tool_installed = self.driver.installed() if not self.driver_tool_installed: > raise OSError(f"{self.driver.name} is not installed") E OSError: flake8 is not installed diff_cover/violationsreporters/base.py:160: OSError ================================================================================== short test summary info ================================================================================== FAILED tests/test_violations_reporter.py::TestFlake8QualityReporterTest::test_file_does_not_exist - OSError: flake8 is not installed ===================================================================================== 1 failed in 2.11s ===================================================================================== +++ exited with 1 +++ ```

No traces of executing flake8 and why this unit is trying to execute git, hg and file is another mystery πŸ˜‹ πŸ™„

kloczek commented 6 months ago

Ops .. sorry ..

[pid 36149] execve("/usr/bin/flake8", ["flake8", "--version"], 0x55f6303c2c70 /* 64 vars */) = 0

but this execution returns 0 exit code πŸ€”

Bachmann1234 commented 6 months ago

git, hg, and file could be any of a bunch of setup and fixture stuff...

Now the flake8 --version call returning 0 is very interesting.... and surprising

So we know flake8 is a regex based driver (so no custom stuff going on)

https://github.com/Bachmann1234/diff_cover/blob/57926a03c691b188c946aedcbcad228aa60923c7/diff_cover/violationsreporters/violations_reporter.py#L456-L467

This is the function being called there

https://github.com/Bachmann1234/diff_cover/blob/57926a03c691b188c946aedcbcad228aa60923c7/diff_cover/violationsreporters/base.py#L247

That function is pretty simple.. if the process return code is 0 then I feel like that must mean this branch got hit, otherwise it would have returned process.returncode would have returned 0

https://github.com/Bachmann1234/diff_cover/blob/57926a03c691b188c946aedcbcad228aa60923c7/diff_cover/command_runner.py#L62

But ill try and find some time tonight to look closer at this test to verify my assumptions about how this traces out are correct.

kloczek commented 6 months ago

Am I right thar you are suggesting that to run this test it needs to b installed some flake8 extension? πŸ€”

My questions about why at all this needs to be executed seem still is valid. What do you think about that? πŸ™„

Bachmann1234 commented 6 months ago

you should not need anything thats not already defined in the toml. You can see githubs action run this build regularly.

flake8 is executed because this is an integration test and mocks would make assumptions about how the tool runs that could be changed over time as versions shift.

If you really wanna dig into whats happening here I suggest editing the lines I suggested in the installed lib and running the test. That way you can see if there is a better error

kloczek commented 6 months ago

Again .. executed flake8 script returns 0 status.

Bachmann1234 commented 6 months ago

Again .. executed flake8 script returns 0 status.

I understand that block of code is either hitting a filenotfound exception or something else is happening.

Whatever is happening is in that block of code and the only way I know to move forward on this is to print stuff in there and see what comes out

Bachmann1234 commented 6 months ago

Because despite what your test did that function returned 1 at least that's what the test output is implying

Bachmann1234 commented 6 months ago

Because despite what your test did that function returned 1 at least that's what the test output is implying

kloczek commented 6 months ago

If you have any propositions of some diagnostics please let mi know.

Bachmann1234 commented 6 months ago

If you have any propositions of some diagnostics please let mi know.

Earlier I suggested sticking a couple of print lines in that function. So that and remove the catch of the filenotfound exception.

That should print out any output from running the command (if any) and if the exception being thrown (which at this point seems more likely)maybe it will provide more context on why.

kloczek commented 6 months ago

Honestly .. I have no idea where I can put those lines 😞

Bachmann1234 commented 6 months ago

I traced though the code path earlier

Take this function

https://github.com/Bachmann1234/diff_cover/blob/57926a03c691b188c946aedcbcad228aa60923c7/diff_cover%2Fcommand_runner.py#L51-L64

And replace it with this version

def run_command_for_code(command):
    """
    Returns command's exit code.
    """
    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()
    print(stdin)
    print(stout)
    return process.returncode

See if the failure output is more interesting

ancieg commented 1 week ago

This is because .flake8 config file is ill-formed - it contains inline comments (see: https://flake8.pycqa.org/en/latest/user/configuration.html). I suggest to fix the config via the following patch:

diff --git a/.flake8 b/.flake8
index 2ef7b1b..e934134 100644
--- a/.flake8
+++ b/.flake8
@@ -1,13 +1,18 @@
 [flake8]
 max-line-length=100
 select=
-    C901,  # flake8-mccabe
-    E,  # flake8-pycodestyle
-    F,  # flake8-pyflakes
-    W,  # flake8-pycodestyle
+    # flake8-mccabe
+    C901,
+    # flake8-pycodestyle
+    E,
+    # flake8-pyflakes
+    F,
+    # flake8-pycodestyle
+    W,
 ignore =
-    W503,E203,  # conflict with black formatter
+    # conflict with black formatter
+    W503,E203,
 per-file-ignores =
     # supression for __init__
     diff_cover/tests/*: E501
-    diff_cover/tests/fixtures/*: E,F,W
\ No newline at end of file
+    diff_cover/tests/fixtures/*: E,F,W
ancieg commented 1 week ago

This is because .flake8 config file is ill-formed - it contains inline comments (see: https://flake8.pycqa.org/en/latest/user/configuration.html). I suggest to fix the config via the following patch:


Following the recommended settings for Python’s configparser, Flake8 does not support inline comments for any of the keys. So while this is fine:

[flake8]
per-file-ignores =
    # imported but unused
    __init__.py: F401

this is not:

[flake8]
per-file-ignores =
    __init__.py: F401 # imported but unused
kloczek commented 1 week ago

Why nor switch from flake8 to ruff? πŸ€”

ancieg commented 1 week ago

Why nor switch from flake8 to ruff? πŸ€”

I think you should open new issue with this question.

Bachmann1234 commented 1 week ago

I'll take a look at this in the next few days when things calm down for me.

As for switching to ruff. I'm not against it. But it's not high on my list of priorities. I hear it's great though

Bachmann1234 commented 1 week ago

https://github.com/Bachmann1234/diff_cover/pull/423 should fix this so next time I do a release (Im not confident this change merits one) it should be addressed.