How pylint-pytest throws F6401 Can-enumerate-pytest-fixtures - python

Can you explain the prompt 'F6401' when I run pylint pylint-pytest plugin cannot enumerate and collect pytest fixtures. Please run `pytest --fixtures --collect-only path/to/current/module.py` and resolve any potential syntax error or package dependency issues (Can-enumerate-pytest-fixtures) is the reason?
I would like to know how it works, or why it appears, and sometimes has different outputs. The same code, sometimes two, sometimes more. I was depressed.
I did run pytest --fixtures --collect-only without any unusual hints and my tests were normal.
Description:
After I fine-tune my existing code, including running pylint, pytest, and isort, everything works. I added a new package executor with three modules, one is the abstract module of base.py, two are corresponding to different implementation modules(local.py, docker.py).
Then I run isort, and pylint works fine
Then I import the base class and two implementation classes in the module's __init__.py file, and add a factory method.
When I run pylint again, the input tells me that some of the test modules have problems with F6401.
Again, I want to emphasize that everything was fine until I added this module. But now I just added the source code of this module, this exception will appear.
What makes it even more confusing to me is that the module I'm prompted doesn't include any fixtures. I ran pylint again and found that F6401 has more test modules (several times more than last time).
I've been using PyLint for a new project to check for a mode-by-module migration, and when I migrate to this module, I can't continue.
OS env
python 3.7
os: Deepin(base Debian)
IDE: Pycharm
Package versions
pylint 3.0.0a3
pylint-pytest 1.1.2
pyparsing 2.4.7
pytest 6.2.3
pytest-asyncio 0.14.0
pytest-cov 2.11.1
pytest-mock 3.5.1
ISSUE about this question.

After debugging the source code, I found out that the cause of my problems was an error in pylint-pytest when running pytest to collect fixtures from source code, and then pylint-pytest passed the error to PyLint.
My source code had a type annotation error that caused pytest to look for a fixture from that module that was wrong, and the error was passed to pylint. But why there is a different output is not clear to me.
From debugging the source code, we know that pylint-pytest registers itself with pylint, and when pylint checks all files, it passes the files to pylint-pytest's FixtureChecker.
https://github.com/reverbc/pylint-pytest/blob/62676386f80989cc0373d77bc5dc74acc635fd7a/pylint_pytest/checkers/fixture.py#L92-L142
The visit_module method in the FixtureChecker passes the file to pytest, running pytest <module_file> --fixtures --collect-only, At the same time load the FixtureCollector plug-in into pytest.
https://github.com/reverbc/pylint-pytest/blob/62676386f80989cc0373d77bc5dc74acc635fd7a/pylint_pytest/checkers/fixture.py#L125-L131
In pytest_collectreport , if an error is reported by pytest, it is logged and the error information is passed to pytest.
https://github.com/reverbc/pylint-pytest/blob/62676386f80989cc0373d77bc5dc74acc635fd7a/pylint_pytest/checkers/fixture.py#L24-L34
I don't think this logic makes sense. Pytest should only collect fixtures from the test modules, and instead of collecting fixtures from all modules, Pylint-Pytest should filter out the source code when PyLint checks.
At this point, my doubts have disappeared. Thanks.

Related

Why am getting pylint import and no member errors when I didn't before?

Hi I've been working on this code for months without any of the pylint errors that have suddenly appeared? How do I fix this?
You need pandas and torch installed in the same environment than the one you run pylint.
From the documentation at https://pylint.pycqa.org/en/latest/user_guide/messages/error/no-member.html:
If you are getting the dreaded no-member error, there is a possibility that either:
pylint found a bug in your code
You're launching pylint without the dependencies installed in its environment.
pylint would need to lint a C extension module and is refraining to do so.
Linting C extension modules is not supported out of the box, especially since pylint has no way to get an AST object out of the extension module.
But pylint actually has a mechanism which you might use in case you want to analyze C extensions. Pylint has a flag, called extension-pkg-allow-list (formerly extension-pkg-whitelist), through which you can tell it to import that module and to build an AST from that imported module:
pylint --extension-pkg-allow-list=your_c_extension
Be aware though that using this flag means that extensions are loaded into the active Python interpreter and may run arbitrary code, which you may not want. This is the reason why we disable by default loading C extensions. In case you do not want the hassle of passing C extensions module with this flag all the time, you can enable unsafe-load-any-extension in your configuration file, which will build AST objects from all the C extensions that pylint encounters:
pylint --unsafe-load-any-extension=y
Alternatively, since pylint emits a separate error for attributes that cannot be found in C extensions, c-extension-no-member, you can disable this error for your project.

Coverage "No source for code" with pytest

I am trying to measure code coverage by my pytest tests. I tried following the quick start guide of coverage (https://coverage.readthedocs.io/en/6.4.1/)
When I run my test with the following command, everything seems fine
coverage run -m pytest tests/
===================================== test session starts ======================================
platform linux -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0
rootdir: /home/arnaud/Documents/Github/gotcha
collected 4 items
tests/preprocessing/test_preprocessing.py .... [100%]
====================================== 4 passed in 0.30s =======================================
However, when I try to access the report with either of those commands,
coverage report
coverage html
I get the following message:
No source for code: '<project_directory>/config-3.py'.
I did not find an appropriate solution to this problem so far
It is possible to ignore errors using the command
coverage html -i
which solved my issue
This issue is usually caused by older coverage result files, so you can either:
remove the old coverage results files or...
run coverage command with -i flag in order to ignore the errors - you can read more about that in coverage official docs: https://coverage.readthedocs.io/en/6.4.1/cmd.html#reporting
Another possible solution is to specify the source attribute. In my case, rather than the whole project (source = .), I specified the actual source folder (e.g. src). This can either be done on the commandline:
coverage run --source=src
or include it in your .coveragerc file:
[run]
source = src
...
I was getting this same issue because of a specific library I was importing*, but I never figured out why that library affected coverage, and others didn't.
Though this might just be a workaround, it makes sense to just check your source folder, and ignoring all errors (with -i) isn't much better.
* The library uses opencv-python-headless, which I think has the root cause of this issue.

Python PDM + pre-commit using pylint: imports cannot be found

Background
I am wrangling some legacy code into shape.
I use PDM to manage dependencies, which places all dependent packages in a __pypackages__ folder directly under the repo root level. PDM also uses the relatively new pyproject.toml package config file.
I am trying to adopt pre-commit Git hooks so that I can have automated checks for formatting and style before trying to commit, merge, and/or create PRs.
I am asking pre-commit to use only a few Python tools for now: pylint and black.
Issue
Most of that toolset works great together. However, pylint cannot find any of the modules that are stored in the __pypackages__ folder. Most of what I have read suggests that I alter my $PYTHONPATH to find the modules.
This solution seems very outdated. But also, I am not sure how I can do this in a robust way across the team. I can alter the Git hooks, but the $PYTHONPATH may be different for each engineer, so this will only work for my machine.
I would like to be able to add something in the pyproject.toml file to have pylint find it. I am not sure what to write, though, so that it generically works across the whole team. Something like
[tools.pylint]
pypackages = "./__pypackages__"
Any ideas how I can do this?
Details
I am not sure more details are needed, but here it is:
My actions:
> pre-commit run --all-files # The --all-files flag is just to allow me to test without a commit
Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check Yaml...........................................(no files to check)Skipped
Check for added large files..............................................Passed
black....................................................................Passed
pylint...................................................................Failed
- hook id: pylint
- exit code: 30
************* Module testfile
testfile.py:18:0: E0401: Unable to import 'boto3' (import-error)
boto3 is in the __pypackages__ mentioned above. None of the modules can be imported, but I limited the output for clarity.
I can pdm run ... everything correctly and VS Code sees the modules fine. But pylint is not finding it because it cannot find this __pypackages__ folder.
You can get around this by updating the PYTHONPATH environment variable used by the extension, by creating a file named .env in your workspace (project folder) and adding the following entry:
PYTHONPATH=D:/commonScripts
Note: Relative paths are also supported.
Further info on .env files can be found here https://code.visualstudio.com/docs/python/environments#_environment-variable-definitions-file

Skipping import modules in pytest from the command line

The documentation for pytest suggests you can skip certain imports:
https://docs.pytest.org/en/latest/skipping.html#skipping-on-a-missing-import-dependency
We are trying to run pylint under pytest and in some cases importing tensorflow causes issues because of system dependencies. The documentation shows a way of skipping the import in code, is it possible to skip imports like this from the command line of pytest?
There is no such feature in pytest, so you should do this directly in code (usually in a conftest.py).
A hacky workaround to do the same directly at the command line woud be:
python -c "import pytest; pytest.importorskip('tensorflow'); pytest.main()"
Better would be to use one of the existing hooks to add your own command-line option to pytest, so it can be specified clearly like --no-tensorflow or whatever.

Pylint not working when used as pre-commit hook in github

I am trying to use the following pre-commit hook to check my code quality.
https://github.com/sebdah/git-pylint-commit-hook
I followed the instruction and installed it but it's displaying me a 0 score for all file. ex.
Running pylint on make_postreq.py (file 5/15).. 0/10.00 FAILED ************* Module make_postreq
Whereas if I run pylint from the console, I get a decent score.
Global evaluation
Your code has been rated at 8.75/10 (previous run: 8.75/10, +0.00)
I feel it might be a configuration issue, but can't seem to make it work.
Or is there some other way we can check our Python code quality before committing in GitHub?
This issue may be caused by setting the files-output parameter in your pylintrc to yes. I just ran into this where I transferred a configuration file over. The result processing in git-pylint-commit-hook requires that pylint print the final status to stdout, which is suppressed with files-output.
Try to
set 'reports=yes' in [REPORTS] section
don't disable 'RP0004'

Categories