web-dev-qa-db-fra.com

Erreur PyLint "Impossible d'importer" - comment définir PYTHONPATH?

J'utilise PyLint à partir de Wing IDE sous Windows. J'ai un sous-répertoire (package) dans mon projet et à l'intérieur du package, j'importe un module du niveau supérieur, c'est-à-dire.

__init__.py
myapp.py
one.py
subdir\
    __init__.py
    two.py

Inside two.py J'ai import one et cela fonctionne bien à l'exécution, car le répertoire de niveau supérieur (à partir duquel myapp.py est exécuté) se trouve dans le chemin Python. Cependant, quand je lance PyLint sur two.py, cela me donne une erreur:

F0401: Unable to import 'one'

Comment puis-je réparer ça?

112
EMP

Je suis conscient de deux options.

Tout d'abord, modifiez la variable d'environnement PYTHONPATH pour inclure le répertoire situé au-dessus de votre module.

Sinon, éditez ~/.pylintrc pour inclure le répertoire au-dessus de votre module, comme ceci:

[MASTER]
init-hook='import sys; sys.path.append("/path/to/root")'

(Ou dans une autre version de pylint, l'init-hook nécessite de changer [Général] en [MAÎTRE])

Ces deux options devraient fonctionner.

J'espère que cela pourra aider.

100
Brian M. Hunt

1) sys.path est une liste. 

2) Le problème est que parfois sys.path n’est pas votre virtualenv.path et que vous voulez utiliser pylint dans votre virtualenv

3) Donc, comme dit, utilisez init-hook (faites attention dans 'et "l'analyse de pylint est stricte)

[Master]
init-hook='sys.path = ["/path/myapps/bin/", "/path/to/myapps/lib/python3.3/site-packages/", ... many paths here])'

ou

[Master]
init-hook='sys.path = list(); sys.path.append("/path/to/foo")'

.. et 

pylint --rcfile /path/to/pylintrc /path/to/module.py
20
macm

La solution pour modifier le chemin dans init-hook est bonne, mais je n'aime pas le fait que je devais ajouter un chemin absolu, car je ne peux pas partager ce fichier pylintrc entre les développeurs du projet. Cette solution utilisant le chemin relatif au fichier pylintrc fonctionne mieux pour moi:

[MASTER]
init-hook="from pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"

Notez que pylint.config.PYLINTRC existe également et a la même valeur que find_pylintrc().

19
alex_koval

Avez-vous un fichier __init__.py vide dans les deux répertoires pour indiquer à python que les répertoires sont des modules?

Le schéma de base lorsque vous n’exécutez pas à partir du dossier (c’est-à-dire peut-être de pylint, bien que je ne l’aie pas utilisé) est le suivant:

topdir\
  __init__.py
  functions_etc.py
  subdir\
    __init__.py
    other_functions.py

C’est ainsi que l’interprète python connaît le module sans faire référence au répertoire en cours. Ainsi, si pylint est exécuté à partir de son propre chemin absolu, il pourra accéder à functions_etc.py en tant que topdir.functions_etc ou topdir.subdir.other_functions, à condition que topdir soit sur PYTHONPATH.

UPDATE: Si le problème ne vient pas du fichier __init__.py, essayez peut-être simplement de copier ou de déplacer votre module vers c:\Python26\Lib\site-packages - il s'agit d'un emplacement courant pour mettre des packages supplémentaires et se trouvera définitivement sur votre chemin python. Si vous savez faire des liens symboliques Windows ou l’équivalent (je ne le fais pas!), Vous pouvez le faire à la place. Il y a beaucoup plus d'options ici: http://docs.python.org/install/index.html , y compris la possibilité d'ajouter sys.path avec le répertoire de niveau utilisateur de votre code de développement, mais en pratique, je Habituellement, reliez simplement symboliquement mon répertoire de développement local à des packages de site. La copie de ce répertoire a le même effet.

15
unmounted

Je ne sais pas comment cela fonctionne avec WingIDE, mais pour utiliser PyLint avec Geany, j'ai défini ma commande externe sur:

PYTHONPATH=${PYTHONPATH}:$(dirname %d) pylint --output-format=parseable --reports=n "%f"

où% f est le nom du fichier et% d le chemin. Pourrait être utile pour quelqu'un :)

5
simon

Le problème peut être résolu en configurant le chemin pylint sous venv: $ Cat .vscode/settings.json 

{
    "python.pythonPath": "venv/bin/python",
    "python.linting.pylintPath": "venv/bin/pylint"
}
4
jeanerpp

J'ai dû mettre à jour la variable système PYTHONPATH pour ajouter mon chemin d'accès à App Engine. Dans mon cas, je viens de modifier mon fichier ~/.bashrc et d’ajouter la ligne suivante:

export PYTHONPATH=$PYTHONPATH:/path/to/google_appengine_folder

En fait, j'ai d'abord essayé de définir le init-hook mais cela n'a pas résolu le problème de manière cohérente dans ma base de code (je ne sais pas pourquoi). Une fois que je l'ai ajouté au chemin du système (probablement une bonne idée en général), mes problèmes ont disparu.

4
Brian Moeskau

J'ai eu le même problème et je l'ai corrigé en installant pylint dans mon virtualenv puis en ajoutant un fichier .pylintrc à mon répertoire de projet avec les éléments suivants dans le fichier:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
2
Nate

Une solution de contournement que je viens de découvrir consiste à exécuter PyLint pour l'ensemble du package plutôt que pour un seul fichier. D'une certaine manière, il parvient à trouver le module importé ensuite.

2
EMP

Essayer

if __== '__main__':
    from [whatever the name of your package is] import one
else:
    import one

Notez que dans Python 3, la syntaxe de la partie dans la clause else serait

from .. import one

À la réflexion, cela ne résoudra probablement pas votre problème spécifique. J'ai mal compris la question et j'ai pensé que Two.py était exécuté comme module principal, mais ce n'est pas le cas. Et compte tenu des différences entre Python 2.6 (sans importer absolute_import à partir de __future__) et Python 3.x, vous n'avez pas besoin de gérer faire ceci pour Python 2.6 de toute façon, je ne pense pas.

Néanmoins, si vous passez finalement à Python 3 et envisagez d'utiliser un module à la fois comme module de package et comme script autonome dans le package, il peut être judicieux de conserver un élément tel que

if __== '__main__':
    from [whatever the name of your package is] import one   # assuming the package is in the current working directory or a subdirectory of PYTHONPATH
else:
    from .. import one

à l'esprit.

EDIT: Et maintenant pour une solution possible à votre problème actuel. Exécutez PyLint à partir du répertoire contenant votre module one (via la ligne de commande, par exemple), ou insérez le code suivant quelque part lors de l’exécution de PyLint:

import os

olddir = os.getcwd()
os.chdir([path_of_directory_containing_module_one])
import one
os.chdir(olddir)

Au lieu de jouer avec PYTHONPATH, assurez-vous simplement que le répertoire de travail actuel est le répertoire contenant one.py lorsque vous effectuez l'importation.

(En regardant la réponse de Brian, vous pourriez probablement attribuer le code précédent à init_hook, mais si vous voulez le faire, vous pouvez simplement faire l'ajout à sys.path qu'il fait, ce qui est légèrement plus élégant que ma solution.)

2
JAB

La clé consiste à ajouter votre répertoire de projet à sys.path sans prendre en compte la variable env.

Pour les utilisateurs de VSCode, voici une solution monoligne s’il existe un répertoire de base de votre projet:

[MASTER]
init-hook='base_dir="my_spider"; import sys,os,re; _re=re.search(r".+\/" + base_dir, os.getcwd()); project_dir = _re.group() if _re else os.path.join(os.getcwd(), base_dir); sys.path.append(project_dir)'

Permettez-moi de l'expliquer un peu:

  • re.search(r".+\/" + base_dir, os.getcwd()).group(): recherche le répertoire de base en fonction du fichier d'édition

  • os.path.join(os.getcwd(), base_dir): ajoutez cwd à sys.path pour respecter l'environnement de ligne de commande


Pour votre information, voici mon .pylintrc:

https://Gist.github.com/chuyik/f0ffc41a6948b6c87c7160151ffe8c2f

2
chuyik

J'ai eu le même problème et comme je ne pouvais pas trouver de réponse, j'espère que cela pourra aider n'importe qui avec un problème similaire. 

J'utilise flymake avec epylint. Fondamentalement, ce que j’ai fait a été d’ajouter un dired-mode-hook qui vérifie si le répertoire dired est un répertoire de package python. Si c'est le cas, je l'ajoute au PYTHONPATH. Dans mon cas, je considère un répertoire comme un paquet python s'il contient un fichier nommé "setup.py".

;;;;;;;;;;;;;;;;;
;; PYTHON PATH ;;
;;;;;;;;;;;;;;;;;

(defun python-expand-path ()
  "Append a directory to the PYTHONPATH."
  (interactive
   (let ((string (read-directory-name 
          "Python package directory: " 
          nil 
          'my-history)))
     (setenv "PYTHONPATH" (concat (expand-file-name string)
                  (getenv ":PYTHONPATH"))))))

(defun pythonpath-dired-mode-hook ()
  (let ((setup_py (concat default-directory "setup.py"))
    (directory (expand-file-name default-directory)))
    ;;   (if (file-exists-p setup_py)
    (if (is-python-package-directory directory)
    (let ((pythonpath (concat (getenv "PYTHONPATH") ":" 
                  (expand-file-name directory))))
      (setenv "PYTHONPATH" pythonpath)
      (message (concat "PYTHONPATH=" (getenv "PYTHONPATH")))))))

(defun is-python-package-directory (directory)
  (let ((setup_py (concat directory "setup.py")))
    (file-exists-p setup_py)))

(add-hook 'dired-mode-hook 'pythonpath-dired-mode-hook)

J'espère que cela t'aides.

1
user2826500

Peut-être en ajoutant manuellement le répertoire à l'intérieur du PYTHONPATH?

sys.path.append(dirname)
1
Mario Mikić

Si quelqu'un cherche un moyen d'utiliser pylint en tant qu'outil externe dans PyCharm et de le faire fonctionner avec ses environnements virtuels (pourquoi je suis venu à cette question), voici comment j'ai résolu le problème:

  1. Dans PyCharm> Préférences> Outils> Outils externes, ajoutez ou modifiez un élément pour pylint.
  2. Dans les paramètres de l'outil de la boîte de dialogue Modifier l'outil, définissez Programme pour qu'il utilise pylint à partir du répertoire d'interpréteur python: $PyInterpreterDirectory$/pylint
  3. Définissez vos autres paramètres dans le champ Paramètres, par exemple: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Définissez votre répertoire de travail sur $FileDir$

Maintenant, utiliser pylint comme outil externe lancera pylint sur le répertoire que vous avez sélectionné en utilisant un fichier de configuration commun et utilisera l’interpréteur configuré pour votre projet (qui est vraisemblablement votre interprète virtualenv).

1
tterry

C'est une vieille question, mais qui n'a pas de réponse acceptée, je vais donc suggérer ceci: changez la déclaration d'importation en deux.py comme suit:

from .. import one

Dans mon environnement actuel (Python 3.6, VSCode utilisant pylint 2.3.1), cela efface l'instruction marquée.

0
Mike C

si vous utilisez vscode, assurez-vous que votre répertoire de paquet est en dehors du répertoire _pychache__.

0
Vikas Bhutani