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

165

J'exécute PyLint depuis 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, ie.

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

À l'intérieur, two.pyj'ai import oneet cela fonctionne bien au moment de l'exécution, car le répertoire de niveau supérieur (à partir duquel myapp.pyest exécuté) se trouve dans le chemin Python. Cependant, lorsque j'exécute PyLint sur two.py, cela me donne une erreur:

F0401: Unable to import 'one'

Comment puis-je réparer ça?

EMP
la source

Réponses:

145

Je connais deux options.

Premièrement, modifiez la PYTHONPATHvariable d'environnement pour inclure le répertoire au-dessus de votre module.

Sinon, modifiez ~/.pylintrcpour 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, le hook init vous oblige à changer [General] en [MASTER])

Ces deux options devraient fonctionner.

J'espère que cela pourra aider.

Brian M. Hunt
la source
8
Ce crochet pylint est actuellement le meilleur moyen de VScode car PYTHONPATH n'est pas encore pris en charge pour son utilisation intégrée de linter.
Danny Staple
2
J'ai le même problème en utilisant MacVim avec syntastic. Comment puis-je configurer Prosector pour corriger l'erreur d'importation?
Laurent
Article de blog connexe avec quelques détails supplémentaires.
Christian Long
~/.pylintrca travaillé pour moi sur OSX, l'autre n'a pas fonctionné
Miquel
Je ne sais pas pourquoi ce n'est pas la réponse acceptée - également, il convient de mentionner pour ceux qui trébuchent sur cela, que vous devez le faire export PYTHONPATHpour qu'il pylintle voie (au moins, dans bash / zsh)
Marco Massenzio
43

La solution pour modifier le chemin init-hookest bonne, mais je n'aime pas le fait que j'ai dû y ajouter un chemin absolu, par conséquent je ne peux pas partager ce fichier pylintrc entre les développeurs du projet. Cette solution utilisant un chemin relatif vers le 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 qu'il pylint.config.PYLINTRCexiste également et a la même valeur que find_pylintrc().

alex_koval
la source
1
Confirmer que cela a vraiment fourni la solution pour les erreurs de pylint E0611 et E0401. Pour les utilisateurs de VSCode: Il est important que le dossier ouvert soit le "dossier racine python" et que le .pylintrc se trouve dans ce dossier.
np8
aussi, assurez-vous qu'aucun de vos noms de répertoire de module ne commence par .(point).
Saw-mon and Natalie
2
si vous voulez ajouter un sous-dossier spécifique (ie app) vous pouvez utiliserfrom pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.join(os.path.dirname(find_pylintrc()), 'app'))
chachan
27

1) sys.path est une liste.

2) Le problème est parfois que sys.path n'est pas votre virtualenv.path et que vous souhaitez 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
macm
la source
8
J'ai semblé avoir corrigé cela en installant pylintdans mon virtualenv selon ce conseil: plaidzooks.tumblr.com/post/36813101879
Matt
3
Cela fonctionne très bien et devrait être la meilleure réponse. Si vous n'avez pas défini .pylintrc, assurez-vous simplement de faire un rapide pylint --generate-rcfile > .pylintrcdans votre dossier de départ.
reka18
26

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"
}
jeanerpp
la source
2
Pour Windows, c'est { "python.pythonPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath": "${workspaceFolder}\\.venv\\Scripts\\pylint.exe" } juste pour être complet.
Roy2511
La question ne demande pas cet éditeur.
Ivailo Bardarov le
VSCode affiche maintenant ce message: The setting "python.pythonPath" defined in your settings.json is now deprecated. si je supprime la python.pythonPathligne, cela semble toujours fonctionner.
Jesse Aldridge le
23

Avez-vous un __init__.pyfichier vide dans les deux répertoires pour faire savoir à python que les répertoires sont des modules?

Le plan de base lorsque vous ne courez pas à partir du dossier (c'est-à-dire peut-être de pylint, bien que je ne l'utilise pas) est:

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

C'est ainsi que l'interpréteur python est conscient du module sans référence au répertoire courant, donc si pylint s'exécute à partir de son propre chemin absolu, il pourra accéder en functions_etc.pytant que topdir.functions_etcou topdir.subdir.other_functions, à condition qu'il topdirsoit sur le PYTHONPATH.

MISE À JOUR: Si le problème n'est pas le __init__.pyfichier, essayez peut-être de copier ou de déplacer votre module vers c:\Python26\Lib\site-packages- c'est un endroit courant pour mettre des paquets supplémentaires, et sera certainement sur votre chemin python. Si vous savez comment créer des liens symboliques Windows ou l'équivalent (je ne sais pas!), Vous pouvez le faire à la place. Il y a beaucoup plus d'options ici: http://docs.python.org/install/index.html , y compris l'option d'ajouter sys.path avec le répertoire de niveau utilisateur de votre code de développement, mais en pratique, je lie généralement symboliquement mon répertoire de développement local vers les packages de site - le copier a le même effet.

démonté
la source
1
Oui, je l'ai __init__.pydans les deux répertoires. Je pense que le problème est que le répertoire supérieur n'est PAS dans PYTHONPATH lorsque PyLint s'exécute et je ne sais pas comment résoudre ce problème.
EMP
Le lien symbolique est une bonne idée, mais il n'est pris en charge qu'à partir de Windows Vista et j'utilise XP. Je suppose que je pourrais essayer de le lier en dur ...
EMP
re hardlinking: Non, vous feriez mieux de ne pas le faire. J'ai joué avec et, bien que cela fonctionne certainement (d'une certaine manière), cela ne fonctionnera pas comme prévu.
shylent
Les liens symboliques ne sont pas une bonne idée. Cela résout uniquement le problème sur votre machine - lorsque quelqu'un d'autre vérifie le projet, il sera cassé pour eux.
Jonathan Hartley
12

réponse générale à cette question que j'ai trouvée sur cette page VEUILLEZ NE PAS OUVRIR, LE SITE EST BOGUE

créer .pylintrcet ajouter

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

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 est le chemin. Cela pourrait être utile pour quelqu'un :)

Simon
la source
4

J'ai dû mettre à jour la PYTHONPATHvariable système pour ajouter mon chemin App Engine. Dans mon cas, je devais juste éditer mon ~/.bashrcfichier et ajouter la ligne suivante:

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

En fait, j'ai essayé de définir le init-hookpremier 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.

Brian Moeskau
la source
3

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

EMP
la source
Super; Comment?
Cees Timmerman
1
@CeesTimmerman Exécuter à pylint ... dirpartir du dossier parent. Cela nécessite __init__.pyd'être présent dans chaque sous-dossier avec des .pyfichiers.
yugr
3

Essayer

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

Notez que dans Python 3, la syntaxe de la partie de la elseclause 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é en tant que module principal, mais ce n'est pas le cas. Et compte tenu des différences dans la manière dont Python 2.6 (sans importer absolute_importdepuis__future__ ) et Python 3.x gèrent les importations, vous n'auriez pas besoin de le faire pour Python 2.6 de toute façon, je ne pense pas.

Néanmoins, si vous passez éventuellement à Python 3 et que vous prévoyez d'utiliser un module à la fois comme module de package et comme script autonome à l'intérieur du package, il peut être judicieux de conserver quelque chose comme

if __name__ == '__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 réel. Exécutez PyLint à partir du répertoire contenant votre onemodule (via la ligne de commande, peut-être), ou placez 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)

Fondamentalement, au lieu de jouer avec PYTHONPATH, assurez-vous simplement que le répertoire de travail actuel est le répertoire contenant one.pylorsque 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 ajouter sys.pathce qu'il fait, ce qui est légèrement plus élégant que ma solution.)

COUP
la source
2

La clé est d'ajouter votre répertoire de projet sys.pathsans tenir compte de la variable env.

Pour quelqu'un qui utilise VSCode, voici une solution en une ligne pour vous 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)'

Laissez-moi vous expliquer un peu:

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

  • os.path.join(os.getcwd(), base_dir): ajouter cwdà sys.pathpour répondre à l'environnement de ligne de commande


Pour info, voici mon .pylintrc:

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

chuyik
la source
2

J'ai eu ce même problème et je l'ai résolu en installant pylint dans mon virtualenv, puis en ajoutant un fichier .pylintrc à mon répertoire de projet avec ce qui suit dans le fichier:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
Nate
la source
Je dois confirmer que cela élimine les erreurs de pylint E0611, mais les erreurs E0401 restent.
np8
1

Peut-être en ajoutant manuellement le répertoire dans le PYTHONPATH?

sys.path.append(dirname)
Mario Mikić
la source
Hmm, mais où mettriez-vous ce code? En haut de chaque fichier? Je suppose que cela fonctionnerait, mais c'est tout un truc juste pour faire fonctionner PyLint.
EMP
@Evgeny: Voir la réponse que Brian M. Hunt a récemment publiée.
JAB
Et l'ajout de ceci en haut de chaque fichier ne fonctionne pas pour une raison quelconque - PyLint semble parfaitement content d'ignorer toutes les modifications apportées à sys.path à partir des modules qu'il analyse. Je n'ai pas pris la peine de rechercher pourquoi, cependant ...
javawizard
1

J'ai eu le même problème et comme je n'ai pas pu trouver de réponse, j'espère que cela pourra aider toute personne ayant un problème similaire.

J'utilise flymake avec epylint. Fondamentalement, j'ai ajouté un hook en mode dired 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 package 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.

user2826500
la source
1

Si quelqu'un cherche un moyen d'exécuter 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 je l'ai résolu:

  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 utiliser pylint du répertoire de l'interpréteur python: $PyInterpreterDirectory$/pylint
  3. Définissez vos autres paramètres dans le champ Paramètres, comme: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Définissez votre répertoire de travail sur $FileDir$

Maintenant, utiliser pylint comme outil externe exécutera pylint sur n'importe quel répertoire que vous avez sélectionné en utilisant un fichier de configuration commun et utilisera n'importe quel interpréteur configuré pour votre projet (qui est probablement votre interpréteur virtualenv).

tterry
la source
1

Ceci est une vieille question mais n'a pas de réponse acceptée, donc je suggère ceci: changez l'instruction d'importation dans two.py pour lire:

from .. import one

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

Mike C
la source
1

J'ai trouvé une bonne réponse . Modifiez votre pylintrc et ajoutez ce qui suit dans master

init-hook="import imp, os; from pylint.config import find_pylintrc; imp.load_source('import_hook', os.path.join(os.path.dirname(find_pylintrc()), 'import_hook.py'))"
Devguru
la source
1

Lorsque vous installez Python, vous pouvez configurer le chemin. Si le chemin est déjà défini, ce que vous pouvez faire est dans VS Code, appuyez sur Ctrl + Maj + P et tapez Python: Sélectionnez Interpreter et sélectionnez la version mise à jour de Python. Suivez ce lien pour plus d'informations, https://code.visualstudio.com/docs/python/environments

Nadeem
la source
0

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

Vikas Bhutani
la source
Également avec le code VS, il semble y avoir des problèmes potentiels avec le point dans les noms de dossier: github.com/PyCQA/pylint/issues/2182
Eric Burel
0

Si vous utilisez Cython sous Linux, j'ai résolu la suppression de module.cpython-XXm-X-linux-gnu.sofichiers dans le répertoire cible de mon projet.

M. Andrade
la source
0

ajoutez simplement ce code dans le fichier .vscode / settings.json

, "python.linting.pylintPath": "venv / bin / pylint"

Cela notifiera l'emplacement de pylint (qui est un vérificateur d'erreurs pour python)

user3395246
la source
-1

Bonjour, j'ai pu importer les packages à partir de différents répertoires. Je viens de faire ce qui suit: Remarque: j'utilise VScode

Étapes pour créer un package Python Travailler avec des packages Python est vraiment simple. Tout ce que vous devez faire est:

Créez un répertoire et donnez-lui le nom de votre package. Mettez vos cours dedans. Créez un fichier init .py dans le répertoire

Par exemple: vous avez un dossier appelé Framework dans lequel vous conservez toutes les classes personnalisées et votre travail consiste simplement à créer un fichier init .py dans le dossier nommé Framework.

Et lors de l'importation, vous devez importer de cette manière --->

depuis la base d'importation du Framework

donc l'erreur E0401 disparaît. Framework est le dossier dans lequel vous venez de créer init .py et base est votre module personnalisé dans lequel vous devez importer et travailler dessus J'espère que ça aide !!!!

SUNEEL KAUSHIK S
la source