web-dev-qa-db-ja.com

Py_Initializeが失敗する-ファイルシステムコーデックをロードできません

python 3.2。を使用する単純なc ++テストプロジェクトをまとめようとしています。プロジェクトは正常にビルドされますが、Py_Initializeは致命的なエラーを発生させます。

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

最小コード:

#include <Python.h>

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

OSは32ビットVistaです。

python使用されるバージョンはpython 3.2デバッグビルドで、VC++ 10を使用してソースからビルドされます。

同じビルドのpython_d.exeファイルは問題なく実行されます。

誰かが問題とその修正方法を説明できますか?自分のgoogle-fuが失敗します。

編集1

pythonソースコードを調べた後、エラーが示すように、コーデック検索関数が登録されていないことがわかりました。両方のcodec_registerおよびPyCodec_Registerはあるべき姿です。これらの関数は、コードのどこにも呼び出されないだけです。

これらの関数がいつどこから呼び出されるべきかまだわからないので、これが何を意味するのか本当にわかりません。エラーを発生させるコードは、他のpython build(3.1.3)のソースから完全に欠落しています。

編集2

以下の私の質問に答えました。

56
Anton

そのため、何らかの理由でpython dllはencodingsモジュールを見つけることができません。予想される相対パスがあるため、python.exe実行可能ファイルは見かけ上それを見つけます。検索パスの変更は機能します。

このすべての理由は?わかりませんが、少なくとも機能します。私はどこかでタイプミスをしているのではないかと強く疑っています。それが通常奇妙なバグの理由です。

2
Anton

PYTHONPATHおよびPYTHONHOME環境変数を確認し、それらがPython 2.x.

http://bugs.python.org/issue11288

41
Troydm

これについては以前にも言及しましたが、簡単に言えば、これは複数のPythonインストールと、グローバルOS環境がdifferent問題が発生したときに作業しようとするものよりもインストールします。

(ローカルまたはグローバル)環境が完全セットアップであることを確認してください。 python27とpython33の2つ(またはそれ以上)のインストールがあるとします(これらはWindowsパスですが、同等のUNIXスタイルのパスでも以下が有効である必要があります。ここで不足しているものについて教えてください(おそらくDLLのパスが異なる場合があります)):

C:\python27_x86

C:\python33_x64

Python33インストールで作業するつもりで、グローバル環境がpython27を指している場合は、環境をそのように更新してください(PATHおよびPYTHONHOMEmay =オプション(たとえば、ローカルシェルで一時的に作業する場合):

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

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

PYTHONHOME=C:\python33_x64

開発環境で必要な場合はPYTHONPATHに他のライブラリパスを追加する必要がありますが、DLLsLibsite-packages適切にセットアップすることが最も重要です。

お役に立てれば。

29
bossi

核となる理由は非常に単純です:Pythonはそのモジュールディレクトリを見つけられないので、もちろんencodingsもロードできません。

埋め込みに関するPythonドキュメント は、「Py_Initialize()は、最良の推測に基づいてモジュール検索パスを計算します」...「特に、_lib/pythonX.Y_という名前のディレクトリを探します」

それでも、モジュールが(ちょうど)libにインストールされている場合-python binary-相対)-上記の推測は間違っています。

DocsはPYTHONHOMEPYTHONPATHが考慮されていると言っていますが、そうではないことがわかりました。実際の存在やコンテンツは完全に無関係でした。

効果があったのは、Py_SetPath()の呼び出しだけでした。 _[path-to]\lib_を引数としてbeforePy_Initialize()

これは、コードに直接アクセスして制御できる埋め込みシナリオのオプションにすぎません。既製のソリューションでは、問題を解決するために特別な手順が必要になる場合があります。

8
Semanino

Mac OSでbrewのpython3をインストールしようとして同じことを実行しました!ここでの問題は、Mac OSでは、homebrewが「本物」をpythonレイヤー全体をあなたが考えるよりも深くすることです。homebrewの出力から考えると、

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

正しいでしょうが、$ PYTHONPATH/python3を呼び出すとすぐにクラッシュし、「エンコードが見つかりません」という中断6が発生します。これは、$ PYTHONHOMEがbin、libなどを含む完全なインストールのように見えますが、Mac OSの「フレームワーク」にある実際のPythonではないためです。これを行う:

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

(必要に応じてバージョン番号を置き換えます)、正常に機能します。

5
user405

私はまったく同じ問題に遭遇しました(同じPythonバージョン、OS、コードなど)。

プログラムの作業ディレクトリにPythonのLib /ディレクトリをコピーするだけです(VCそれは.vcprojがあるディレクトリです)

4
Calvin1602

Python3kから、スタートアップにはエンコーディングモジュールが必要です。これはPYTHONHOME\Libディレクトリにあります。実際、API Py_Initialize()はinitを実行し、エンコーディングモジュールをインポートします。 PYTHONHOME\Libがsys.pathにあることを確認し、エンコーディングモジュールがあることを確認します。

4
tempbottle

python 3.5、anaconda 3、windows 7 32 bit。

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

必要なヘッダーを見つけることができるように初期化する前に、私のパスは「...\Anaconda3 \」になりました。 Py_SetPythonHomeを呼び出す追加の手順が必要でした。さもないと、python import files。

4
aquirdturtle

リリースビルドで何か問題が発生しているようで、適切なコーデックが含まれていないか、システムAPIに使用するコーデックを誤認しています。 _python_d_実行可能ファイルが機能しているため、os.getfsencoding()に対して何が返されますか? (C APIを使用して、Initialize/Finalize呼び出しの間に呼び出します)

3
ncoghlan

私には問題があり、ここで言及したさまざまな解決策をいじっていました。 Visual Studioからプロジェクトを実行していたため、どうやらシステムパスではなく、Visual Studio内の環境パスを設定する必要がありました。

プロジェクトsolution\properties\environmentに単純なPYTHONHOME = PATH\TO\PYTHON\DIRを追加すると、問題は解決しました。

2
user1538653

私は同じ問題を抱えていて、この質問を見つけました。しかし、ここでの回答からは、問題を解決できませんでした。私はcpythonコードのデバッグを開始し、バグが発見されるかもしれないと考えました。そのため、python課題トラッカーで課題を開きました。

私の間違いは、_Py_SetPath_がすべての推論されたパスをクリアすることを理解していなかったことです。したがって、この関数を呼び出すときにすべてのパスを設定する必要があります。

完了のために、以下の会話の最も重要な部分もコピーしました。


元の問題テキスト

Visual Studio 2017とnumpyなどのいくつかのパッケージを使用して、WindowsでCPython 3.7.3のソースを自分でコンパイルしました。 Pythonインタープリターを起動すると、numpyをインポートして使用できます。ただし、C-APIを介して同じスクリプトを実行すると、ModuleNotFoundErrorが返されます。

だから、私が最初にしたことは、numpyが私のsite-packagesディレクトリにあり、実際にnumpy-1.16.2-py3.7-win-AMD64.Eggという名前のフォルダがあるかどうかを確認することでした。 (pythonインタープリターがnumpyを見つけることができるため、意味があります)

次に、C-APIを介してスクリプトを実行したときに作成されたsys.path変数に関する情報を取得しました。

_#### 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
_

Sys.pathの内容を調べると、2つのことがわかりました。

  1. _C:\Work\build\product\python37.Zip_には正しいパス '_C:\Work\build\product\'_があります。 Zipファイルはありませんでした。すべてのファイルとディレクトリが解凍されました。そこで、python37.Zipという名前のアーカイブにファイルを圧縮し、インポートエラーを解決しました。

  2. _C:\Users\rvq\AppData\Roaming\Python\Python37\site-packages_が間違っているのは_C:\Work\build\product\Lib\site-packages_であるはずですが、この間違ったパスがどのように作成されるかわかりません。

次に試したのは、Py_SetPath(L"C:/Work/build/product/Lib/site-packages")を呼び出す前にPy_Initialize()を使用することでした。これは

致命的なPythonエラー 'ファイルシステムエンコーディングをロードできません' ModuleNotFoundError: 'encodings'という名前のモジュールはありません

正確にこれらの2つの呼び出しで最小のc ++プロジェクトを作成し、Cpythonのデバッグを開始しました。

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

Py_Initialize()の呼び出しを次の呼び出しまで追跡しました

_static int
zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)
_

zipimport.cの内部

この関数の上のコメントには、次のことが記載されています。

新しいzipimporterインスタンスを作成します。 'archivepath'は、zipファイルまたはzipファイル内の特定のパスへのパスのようなオブジェクトでなければなりません。たとえば、mydirectoryがアーカイブ内の有効なディレクトリである場合、「/ tmp/myimport.Zip」または「/tmp/myimport.Zip/mydirectory」になります。 「archivepath」が有効なZipアーカイブを指していない場合、「ZipImportError」が発生します。 zipimporterオブジェクトの「archive」属性には、対象となるzipfileの名前が含まれています。

だから、私にとっては、C-APIはPy_SetPathで設定されたパスがzipファイルへのパスであると期待しているようです。これは予想される動作ですか、それともバグですか?それがバグではない場合、ディレクトリも検出できるようにこれを変更する方法はありますか?

PS:Python 3.5.2+を使用しているときにModuleNotFoundErrorが発生しませんでした。これは以前にプロジェクトで使用したバージョンでした。また、環境変数PYTHONHOMEまたはPYTHONPATHを設定したかどうかも確認しましたが、システム上でそれらのいずれかが表示されませんでした。


回答

これはおそらく文書化の失敗であり、他の何よりも多いでしょう。ただし、初期化の再設計の最中であるため、このフィードバックを提供するのが良いタイミングです。

簡単な答えは、通常、標準ライブラリを_Lib/encodings_に置くことで、Pythonが_sys.path_ディレクトリを見つけられることを確認する必要があるということです。 _Py_SetPath_は推測されたすべてのパスをクリアするため、Pythonが見るべきすべての場所を指定する必要があります。 (Pythonが自動的に見える場所のルールは複雑で、プラットフォームによって異なります。これは修正したいものです。)

存在しないパスは問題ありません。これがZipファイルです。 stdlibをZipに入れることを選択できます。デフォルトパスに名前を付けると、自動的に検出されますが、zipのままにしてディレクトリを参照することもできます。

埋め込みに関する詳細な説明は、携帯電話で入力する準備が整っている以上です。うまくいけば、これで十分です。

2
R_Valdez

私にとって、これはPython 64ビット.6.4から.6.5に更新したときに起こりました。 "python.dllを抽出できません。権限があります。"

Pycharmも設定でリロードしましたが、インタープリターのロードに失敗しました。 pythonコマンドを実行すると、管理者モードの有無にかかわらず同じエラーが発生しました。

理由

Pythonのインストールでエラーが発生しましたincludeフォルダーpythonインストールディレクトリC:\ Users\USERNAME\AppData\Local\Programs\Python\Python36がありませんでした

再インストールPythonも問題を解決します(削除およびインストールではありません)

解決

アンインストールPython and Install of Pythonもう一度。

実行中のインストーラーは、インクルードフォルダーを除く同じファイルを抽出するだけだったため

2
Prateek

私の場合、Windowsでは、複数のpythonバージョンがインストールされている場合、PYTHONPATHが1つのバージョンを指していると、他のバージョンは機能しませんでした。 PYTHONPATHを削除すると、すべて正常に動作します

1
AmitE