pylint and pre-commit hook unable to import
Asked Answered
F

4

25

My project structure looks like this:

project/
   app/
      main.py
   venv/
   .pylintrc
   .pre-commit-config.yaml

When I am trying to edit project/app/main.py and it fails with

Unable to import 'psycopg2' (import-error)

But when I am trying to pylint this file directly, it works.

.pre-commit-config.yaml looks like this:

-   repo: https://github.com/PyCQA/pylint
    rev: pylint-2.4.2
    hooks:
    -   id: pylint
Fanciful answered 15/4, 2020 at 20:46 Comment(0)
D
34

not sure if this made it into pylint proper but there's a disclaimer on the bottom of pre-commit/mirrors-pylint

pre-commit runs pylint from an isolated virtualenv. Many of pylint's checks perform dynamic analysis which will fail there. You may find configuring pylint as a local hook more useful.

if you have very few dependencies, additional_dependencies might be enough to make it work, but using local hooks for things which need to (~essentially) import your code is probably your best bet


disclaimer: I'm the author of pre-commit

Defer answered 15/4, 2020 at 21:3 Comment(2)
The issue applies at least to flake8, pylint and mypy. If one takes these out of the pre-commit set of hooks they will likely ask themselves why to use pre-commit at all. I do not imply they should, just that current design limits its practical use considerably.Youngman
flake8 does not need your installed dependencies -- and it's fairly easy to get mypy working by explicitly listing your typed dependencies. I don't use pylint personally so I don't have any experience thereDefer
T
2

You can disable import error in pylint args. This should not conflict with other types:

- repo: https://github.com/pycqa/pylint
  rev: v2.17.5
  hooks:
    - id: pylint
      args: [src, --disable=import-error]
Tokharian answered 6/9, 2023 at 14:14 Comment(0)
C
0

I found (at least for me) a quite better solution.

I just looked at the official documentation: https://pylint.pycqa.org/en/latest/user_guide/installation/pre-commit-integration.html

My .pre-commit-config.yaml looks like the following:

repos:
-   repo: https://github.com/PyCQA/pylint
    rev: v3.0.3
    hooks:
    -   id: pylint
        language: system

If I understand this correctly the language: system defines that pylint will be executed from the system. Normally pre-commit creates an own environment to execute the hooks. In this environment your dependencies aren't installed, so you get an Unable to load import. You only must make sure you install pylint on your own into your environment along your dependencies.

Cagey answered 15/12, 2023 at 7:40 Comment(0)
Y
-2

One workaround that I used in the past was to force pre-commit to install current project. Be warned that while this works is not supported by the author of pre-commit in any way, in fact being actively discouraged, mainly because it prevents pre-commit from using immutable caches.

Once the virtualenv is created it will not be updated again and pre-commit does not have any command line option to tell to not trust local cache. If you get into errors your only option is to reset the entire pre-commit disk cache, this likely means removing gigabytes of data from ~/.cache./pre-commit when you run pre-commit clean. Doing that will slowdown running pre-commit on all other projects you have... :(

Ideally the tool should have an option to invalidate only the environments from the current project and not entire cache.

- repo: https://github.com/pre-commit/mirrors-pylint
  rev: v3.0.0a3
  hooks:
  - id: pylint
    additional_dependencies:
    - .  # <-- that makes it install current project
    - flaky
Youngman answered 29/6, 2021 at 8:34 Comment(1)
this does not work, . will install mirrors-pylint and not your projectDefer

© 2022 - 2024 — McMap. All rights reserved.