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?

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.


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().


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

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"
}

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.


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()))"

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 :)


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.


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é.


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.)


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


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/")'

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)

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.


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).


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.


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'))"

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



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.


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)


-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 !!!!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.