web-dev-qa-db-fra.com

Py_Initialize échoue - impossible de charger le codec du système de fichiers

Je tente de mettre sur pied un projet de test c ++ simple qui utilise python 3.2. Le projet se construit bien, mais Py_Initialize génère une erreur fatale:

Fatal Python error: Py_Initialize: unable to load the file system codec
LookupError: no codec search functions registered: can't find encoding

Code minimal:

#include <Python.h>

int main (int, char**)
{
  Py_Initialize ();
  Py_Finalize ();
  return 0;
}

Le système d'exploitation est Vista 32 bits.

La version python utilisée est une version de débogage python 3.2), construite à partir de sources utilisant VC++ 10.

Le fichier python_d.exe de la même génération s’exécute sans problème.

Quelqu'un pourrait-il expliquer le problème et comment le résoudre? Mon propre google-fu me fait défaut.

EDIT 1

Après avoir parcouru le code source python), j'ai constaté que, comme le dit l'erreur, aucune fonction de recherche de codec n'avait été enregistrée. codec_register Et PyCodec_Register Sont comme il se doit. C'est juste que nulle part dans le code aucune de ces fonctions n'est appelée.

Je ne sais pas vraiment ce que cela signifie, car je ne sais toujours pas quand et d'où ces fonctions auraient dû être appelées. Le code qui génère l'erreur est entièrement absent du code source de mon autre python build (3.1.3).

EDIT 2

Répondu à ma propre question ci-dessous.

56
Anton

Ainsi, pour une raison quelconque, la dll python dll ne parvient pas à localiser le module d’encodage. L’exécutable python.exe le trouve apparemment car il possède le chemin relatif attendu. La modification du chemin de recherche fonctionne.

La raison de tout ça? Je ne sais pas mais au moins ça marche. Je soupçonne fortement une faute de frappe de ma part quelque part, c'est généralement la raison pour laquelle certains bugs étranges semblent être.

2
Anton

Vérifiez les variables d’environnement PYTHONPATH et PYTHONHOME et assurez-vous qu’elles ne pointent pas vers Python 2.x.

http://bugs.python.org/issue11288

41
Troydm

Certaines parties de cela ont déjà été mentionnées, mais en résumé, c’est ce qui a fonctionné pour mon environnement où j’ai plusieurs Python est installé et mon environnement global de système d’exploitation configuré pour pointer vers un différent installer que celui que je tente de travailler lorsque je rencontre le problème.

Assurez-vous que votre environnement (local ou global) est entièrement configuré pour pointer vers l'installation avec laquelle vous souhaitez travailler, par exemple. vous avez deux (ou plus) installations de, disons un python27 et un python33 (désolé, il s’agit de chemins Windows, mais les suivants devraient être valables pour les chemins équivalents de style UNIX, veuillez me faire savoir tout ce qui me manque ici ( probablement le chemin des DLL peut être différent)):

C:\python27_x86

C:\python33_x64

Maintenant, si vous avez l’intention de travailler avec votre installation python33 mais que votre environnement global pointe vers python27, veillez à mettre votre environnement à jour en tant que tel (alors que PATH et PYTHONHOMEmay = être optionnel (par exemple si vous travaillez temporairement dans un Shell local)):

PATH="C:\python33_x64;%PATH%"

PYTHONPATH="C:\python33_x64\DLLs;C:\python33_x64\Lib;C:\python33_x64\Lib\site-packages"

PYTHONHOME=C:\python33_x64

Notez que vous devrez peut-être/voudrez ajouter d’autres chemins de bibliothèque à votre PYTHONPATH si votre environnement de développement le demande, mais en ayant votre DLLs, Lib et site-packages une installation correcte est d’une importance primordiale.

J'espère que cela t'aides.

29
bossi

La raison principale est assez simple: Python ne trouve pas son répertoire de modules, il ne peut donc bien sûr pas charger encodings

Le document Python sur l'incorporation dit "Py_Initialize()" calcule le chemin de recherche du module en fonction de sa meilleure estimation "..." Il recherche notamment un répertoire nommé lib/pythonX.Y "

Pourtant, si les modules sont installés dans (seulement) lib - par rapport à python binaire - devinez ci-dessus est faux.

Bien que docs indique que PYTHONHOME et PYTHONPATH sont considérés, nous avons observé que ce n'était pas le cas; leur présence ou leur contenu étaient totalement hors de propos.

La seule chose qui a eu un effet a été un appel à Py_SetPath() avec par ex. [path-to]\lib Comme argument avant Py_Initialize().

Bien sûr, il ne s’agit là que d’une option pour un scénario d’incorporation dans lequel l’utilisateur a un accès direct au code et le contrôle; avec une solution toute faite, des étapes spéciales peuvent être nécessaires pour résoudre le problème.

8
Semanino

J'ai essayé la même chose en essayant d'installer python3 de brew sous Mac OS! Le problème ici est que, sous Mac OS, l’homebrew place le "vrai" python tout un calque plus profond que vous ne le pensez. Vous penseriez, d'après la sortie de l'homebrew

$ echo $PYTHONHOME
/usr/local/Cellar/python3/3.6.2/
$ echo $PYTHONPATH
/usr/local/Cellar/python3/3.6.2/bin

serait correct, mais l’appel de $ PYTHONPATH/python3 plante immédiatement après l’abandon 6 "ne trouve pas les encodages." En effet, bien que $ PYTHONHOME ressemble à une installation complète, avec un bac, une bibliothèque, etc., il ne s'agit PAS du Python lui-même, qui se trouve dans un "Framework" Mac OS. Faire ceci:

PYTHONHOME=/usr/local/Cellar/python3/3.x.y/Frameworks/Python.framework/Versions/3.x
PYTHONPATH=$PYTHONHOME/bin

(en substituant les numéros de version, le cas échéant) et cela fonctionnera bien.

5
user405

Je viens de rencontrer exactement le même problème (idem Python, système d'exploitation, code, etc.).

Il vous suffit de copier le répertoire Lib/de Python dans le répertoire de travail de votre programme (on VC c'est le répertoire où se trouve le fichier .vcproj)

4
Calvin1602

À partir de python3k, le démarrage a besoin du module de codage, disponible dans le répertoire PYTHONHOME\Lib. En fait, les API Py_Initialize () font l'init et importent le module d'encodages. Assurez-vous que PYTHONHOME\Lib est dans sys.path et vérifiez que le module de codage est présent.

4
tempbottle

J'ai eu ce problème avec python 3.5, anaconda 3, windows 7 32 bits. Je l'ai résolu en déplaçant mes fichiers pythonX.lib et pythonX.dll dans mon répertoire de travail et en appelant

Py_SetPythonHome(L"C:\\Path\\To\\My\\Python\\Installation");

avant de l'initialiser afin qu'il puisse trouver les en-têtes dont il avait besoin, où mon chemin était "...\Anaconda3 \". L’étape supplémentaire d’appel de Py_SetPythonHome s’est avérée nécessaire pour éviter d’autres erreurs étranges: python fichiers d’importation).

4
aquirdturtle

Il semble y avoir un problème avec la version de la version, soit en ne intégrant pas les codecs appropriés, soit en identifiant de manière erronée le codec à utiliser pour les API système. Puisque l'exécutable python_d Fonctionne, que retourne-t-il pour os.getfsencoding()? (Utilisez l’API C pour l’appeler entre vos appels Initialize/Finalize)

3
ncoghlan

J'avais le problème et je bricolais avec les différentes solutions mentionnées ici. Comme j’exécutais mon projet à partir de Visual Studio, il me fallait apparemment définir le chemin de l’environnement dans Visual Studio et non le chemin du système.

L'ajout d'un simple PYTHONHOME = PATH\TO\PYTHON\DIR dans la solution du projet\properties\environment a résolu le problème.

2
user1538653

J'ai eu le même problème et trouvé cette question. Cependant, d'après les réponses fournies, je n'ai pas pu résoudre mon problème. J'ai commencé à déboguer le code cpython et j'ai pensé qu'un bogue pourrait être découvert. Par conséquent, j’ai ouvert un problème sur le traqueur de problèmes python.

Mon erreur est que je n'ai pas compris que Py_SetPath Efface tous les chemins inférés. Il faut donc définir tous les chemins lors de l’appel de cette fonction.

Pour terminer, j'ai également copié la partie la plus importante de la conversation ci-dessous.


Mon texte de publication original

J'ai compilé moi-même les sources de CPython 3.7.3 sous Windows avec Visual Studio 2017, ainsi que des packages tels que numpy, par exemple. Lorsque je lance l’interprète Python, je peux importer et utiliser numpy. Toutefois, lorsque j’exécute le même script via C-API, j’obtiens un ModuleNotFoundError.

Donc, la première chose que j'ai faite a été de vérifier si numpy se trouve dans le répertoire de mon site paquets et effectivement, il existe un dossier nommé numpy-1.16.2-py3.7-win-AMD64.Egg. (Cela a du sens parce que l’interprète python peut trouver numpy)

La prochaine chose que j'ai faite a été d'obtenir des informations sur la variable sys.path créée lors de l'exécution du script via C-API.

#### sys.path content ####
C:\Work\build\product\python37.Zip
C:\Work\build\product\DLLs
C:\Work\build\product\lib
C:\PROGRAM FILES (X86)\Microsoft VISUAL STUDIO\2017\PROFESSIONAL\COMMON7\IDE\EXTENSIONS\TESTPLATFORM
C:\Users\rvq\AppData\Roaming\Python\Python37\site-packages

En examinant le contenu de sys.path, j'ai remarqué deux choses.

  1. C:\Work\build\product\python37.Zip A le bon chemin 'C:\Work\build\product\'. Il n'y avait tout simplement pas de fichier Zip. Tous mes fichiers et répertoire ont été décompressés. J'ai donc compressé les fichiers dans une archive nommée python37.Zip, ce qui a résolu l'erreur d'importation.

  2. C:\Users\rvq\AppData\Roaming\Python\Python37\site-packages Est faux, cela devrait être C:\Work\build\product\Lib\site-packages Mais je ne sais pas comment ce mauvais chemin est créé.

La prochaine chose que j'ai essayée était d'utiliser Py_SetPath(L"C:/Work/build/product/Lib/site-packages") avant d'appeler Py_Initialize(). Cela a mené à

Fatal Python Erreur "Impossible de charger le codage du système de fichiers" ModuleNotFoundError: Aucun module nommé "codages".

J'ai créé un projet minimal c ++ avec exactement ces deux appels et commencé à déboguer Cpython.

int main()
{
  Py_SetPath(L"C:/Work/build/product/Lib/site-packages");
  Py_Initialize();
}

J'ai suivi l'appel de Py_Initialize() jusqu'à l'appel de

static int
zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)

à l'intérieur de zipimport.c

Le commentaire au-dessus de cette fonction indique ce qui suit:

Créez une nouvelle instance de zipimporter. 'archivepath' doit être un objet ressemblant à un chemin d'accès à un fichier zip ou à un chemin spécifique à l'intérieur d'un fichier zip. Par exemple, il peut s'agir de "/tmp/myimport.Zip" ou de "/tmp/myimport.Zip/mydirectory", si mydirectory est un répertoire valide à l'intérieur de l'archive. 'ZipImportError' est déclenché si 'archivepath' ne pointe pas vers une archive Zip valide. L'attribut 'archive' de l'objet zipimporter contient le nom du fichier zip ciblé.

Donc, pour moi, il semble que la C-API s'attend à ce que le chemin défini avec Py_SetPath soit le chemin d'un fichier zip. Est ce comportement attendu ou est-ce un bug? Si ce n'est pas un bogue, y a-t-il moyen de changer cela pour qu'il puisse également détecter les répertoires?

PS: ModuleNotFoundError ne s’est pas produit lors de l’utilisation de Python 3.5.2+, version utilisée auparavant dans mon projet. J'ai également vérifié si j'avais défini des variables d'environnement PYTHONHOME ou PYTHONPATH. mais je n'ai pas vu l'un d'entre eux sur mon système.


Réponse

C'est probablement un échec de la documentation plus que toute autre chose. Nous sommes cependant en train de redéfinir l'initialisation, c'est donc un bon moment pour contribuer à ce retour.

La réponse courte est que vous devez vous assurer que Python peut trouver le répertoire Lib/encodings, Généralement en plaçant la bibliothèque standard dans sys.path. Py_SetPath efface tous les chemins inférés, vous devez donc spécifier tous les endroits Python devrait ressembler. (Les règles pour où Python semble automatiquement sont compliquées et varient selon la plateforme , ce que je tiens à corriger.)

Les chemins qui n'existent pas sont acceptables, et c'est le fichier Zip. Vous pouvez choisir de placer stdlib dans un fichier Zip. Il se trouvera automatiquement si vous le nommez chemin par défaut, mais vous pouvez également le laisser décompressé et référencer le répertoire.

Une procédure complète d’inclusion est plus que ce que je suis disposé à taper sur mon téléphone. Espérons que cela suffira pour vous aider pour le moment.

2
R_Valdez

Pour moi, cela s'est passé lorsque j'ai mis à jour Python 64 bits de .6.4 à .6.5. Il a renvoyé une erreur comme "impossible d'extraire python.dll. Avez-vous des autorisations."

Pycharm n'a également pas réussi à charger l'interprète, même si je l'ai rechargé dans les paramètres. L'exécution de la commande python a donné la même erreur, avec et sans mode administrateur.

Raison

Une erreur s’est produite lors de l’installation de Python, le dossier include dans python --- C:\Utilisateurs\NOMUTILISATEUR\AppData\Local\Programmes\Python\Python36 était manquant

Réinstallation Python a également résoudre le problème. (Pas de suppression ni d’installation))

Solution

Désinstallez Python et installez à nouveau Python.

Parce que le programme d'installation en cours d'extraction ne faisait qu'extraire les mêmes fichiers à l'exception du dossier d'inclusion

2
Prateek

Dans mon cas, pour Windows, si vous avez plusieurs python installées, si PYTHONPATH pointe sur une version, les autres ne fonctionnent pas. Je découvrais que si vous supprime PYTHONPATH, ils fonctionnent tous bien

1
AmitE