[python] PyLint "Unable to import" error - how to set PYTHONPATH?

If you want to walk up from the current module/file that was handed to pylint looking for the root of the module, this will do it.

[MASTER]
init-hook=sys.path += [os.path.abspath(os.path.join(os.path.sep, *sys.argv[-1].split(os.sep)[:i])) for i, _ in enumerate(sys.argv[-1].split(os.sep)) if os.path.isdir(os.path.abspath(os.path.join(os.path.sep, *sys.argv[-1].split(os.sep)[:i], '.git')))][::-1]

If you have a python module ~/code/mymodule/, with a top-level directory layout like this

~/code/mymodule/
+-- .pylintrc
+-- mymodule/
¦   +-- src.py
+-- tests/
    +-- test_src.py

Then this will add ~/code/mymodule/ to your python path and allow for pylint to run in your IDE, even if you're importing mymodule.src in tests/test_src.py.

You could swap out a check for a .pylintrc instead but a git directory is usually what you want when it comes to the root of a python module.

Before you ask

The answers using import sys, os; sys.path.append(...) are missing something that justifies the format of my answer. I don't normally write code that way, but in this case you're stuck dealing with the limitations of the pylintrc config parser and evaluator. It literally runs exec in the context of the init_hook callback so any attempt to import pathlib, use multi-line statements, store something into variables, etc., won't work.

A less disgusting form of my code might look like this:

import os
import sys

def look_for_git_dirs(filename):
    has_git_dir = []
    filename_parts = filename.split(os.sep)
    for i, _ in enumerate(filename_parts):
        filename_part = os.path.abspath(os.path.join(os.path.sep, *filename_parts[:i]))
        if os.path.isdir(os.path.join(filename_part, '.git')):
            has_git_dir.append(filename_part)
    return has_git_dir[::-1]

# don't use .append() in case there's < 1 or > 1 matches found
sys.path += look_for_git_dirs(sys.argv[-1])

I wish I could have used pathlib.Path(filename).parents it would have made things much easier.

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to virtualenv

How to setup virtual environment for Python in VS Code? Conda version pip install -r requirements.txt --target ./lib What is the purpose of "pip install --user ..."? What is the difference between venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenv, etc? ImportError: No module named 'encodings' how to specify new environment location for conda create Use virtualenv with Python with Visual Studio Code in Ubuntu Is it ok having both Anacondas 2.7 and 3.5 installed in the same time? How to uninstall a package installed with pip install --user Unable to install boto3

Examples related to pylint

Pylint "unresolved import" error in Visual Studio Code Error message "Linter pylint is not installed" Is it possible to ignore one single specific line with Pylint? How do I disable "missing docstring" warnings at a file-level in Pylint? How do I disable a Pylint warning? PyLint "Unable to import" error - how to set PYTHONPATH? Pylint, PyChecker or PyFlakes? Python: avoiding pylint warnings about too many arguments

Examples related to pythonpath

sys.path different in Jupyter and Python - how to import own modules in Jupyter? Effect of using sys.path.insert(0, path) and sys.path(append) when loading modules PYTHONPATH on Linux How to configure custom PYTHONPATH with VM and PyCharm? How to get the PYTHONPATH in shell? adding directory to sys.path /PYTHONPATH set pythonpath before import statements Why use sys.path.append(path) instead of sys.path.insert(1, path)? Import Error: No module named django django import error - No module named core.management