setuptools / distributeにパッケージデータを含める方法は?


135

setuptools / distributeを使用すると、インストーラーがpackage_dataファイルをプルできません。私が読んだすべては、以下がそれを行う正しい方法であると言います。誰かがアドバイスしてくれませんか?

setup(
   name='myapp',
   packages=find_packages(),
   package_data={
      'myapp': ['data/*.txt'],
   },
   include_package_data=True,
   zip_safe=False,
   install_requires=['distribute'],
)

どこmyapp/data/のデータファイルの場所があります。


2
同じ問題が発生しています...手動で指定すると問題がdata_files解決しました。しかし、これはエラーが発生しやすく、私には「正しく感じられません」。との両方で設定を複製する必要があることを誰かが確認できますか?package_datadata_files
exhuma

github.com/wimglenn/resources-exampleは 、を使用してデータファイルをWheelsとsdistsに正しくパッケージ化できる最新のsetuptoolsプロジェクト構造を示していpyproject.tomlます。setup.pyファイルは必要ありません。
WIM

回答:


289

これは古い質問であることは承知していますpackage_dataが、Google経由でここに行く道を見つける人々にとって は、卑劣な嘘です。バイナリパッケージを構築する場合にのみ使用され(python setup.py bdist ...)、ソースパッケージを構築する場合には使用されませんpython setup.py sdist ...)。もちろん、これはとんでもないことです。ソース配布を構築すると、ファイルのコレクションが他の誰かに送信されてバイナリ配布を構築できると予想されます。

いずれの場合でも、使用MANIFEST.inはバイナリとソース配布の両方で機能します。


97
私はこの問題をこの1時間調査し、多くのアプローチを試みてきました。あなたが言うように、ではなくのpackage_dataために働きます。しかし、のために働くが、ないために!そこで、私が思い付くことができた最高のは、両方含ませることであるとの両方に対応するためにとを。bdistsdistMANIFEST.insdistbdistpackage_dataMANIFEST.inbdistsdist
ウェズリーバウ

7
@WesleyBaughをサポートする別の人を見つけました。でstackoverflow.com/a/2969087/261718、使用MANIFEST.inファイルのためには、あなたは、ドキュメントのような、そして、インストールされませんpackage_data(画像やテンプレートなど)Pythonコードではありませんあなたが使用するファイルのために。
Drake Guan、2013年

12
私はsdistを使用しており、およびの両方を含める必要がMANIFEST.in ありました package_dataMANIFEST.inディストリビューションに何が含まれるかを制御しているようで、package_dataは、インストール中にsite_packages dirにその後何がコピーされるかを制御しています。紛らわしいことに、パスMANIFEST.inはsetup.pyの場所にpackage_data相対的であり、個々のパッケージ(モジュールなど)のルートに相対的です。
エドワードニューウェル

9
「バージョン2.7で変更:テンプレートが提供されていない場合、package_dataに一致するすべてのファイルがMANIFESTファイルに追加されます。配布するファイルの指定を参照してください。」distutilsから。そのため、既存のMANIFEST.inファイルがなく、2.7以降を使用している場合にのみ、ファイルの動作package_dataが自動的にZIPに含まれるようになります。
Johnus、

29
真剣に、このチケットは、セットアップツールを使用して、人生で自分が見つけた恐ろしい場所を発見する人々のためのグループセラピーセッションのように感じます。
Matt Joyce

32

私はこれと同じ問題を抱えていました。解決策は、単に削除することinclude_package_data=Trueでした。

ここを読んだ後、名前が示すように単に「パッケージデータを含める」のではなく、バージョン管理include_package_dataからファイルを含めることを目的としていることに気付きました。ドキュメントから:

[include_package_dataの]データファイルはCVSまたはSubversionの制御下にある必要があります

...

含めるファイルをより詳細に制御する場合(たとえば、パッケージディレクトリにドキュメントファイルがあり、それらをインストールから除外する場合)、package_dataキーワードを使用することもできます。

その議論を取り除いてそれを修正しました、それは偶然に、その議論を取りませんので、distutilsに切り替えたときにも機能した理由です。


2
私の経験は異なりますが、include_package_data=Trueエントリを含めずに同じ問題が発生しました。私のための唯一の解決策は、上記のようにマニフェストにエントリを追加することです。私がsetuptoolsを使用していたことに気を付けてください、あなたのバージョンは 'distribute'で動作しますか?
TimStaley 2013

4
削除include_package_dataすると問題が解決する実際の理由は、元のテキストにありますsetuptools固有のinclude_package_data引数を使用する場合、で指定package_dataされたMANIFEST.inファイルは、ファイルにリストされていない限り、マニフェストに自動的に追加されません。
Piotr Dobrogost 16

package_data空でないリストに設定して指定した使用例は何include_package_data=Falseですか?そして、なぜあなたは二度のファイルを指定する必要がありますMANIFEST.inpackage_data
ハーバート

21

include_package_data=True行を削除する@Joeの推奨に従うことも私にとってうまくいきました。

もう少し詳しく説明すると、ファイルがありません MANIFEST.in。CVSではなくGitを使用しています。

リポジトリはこのような形をとります:

/myrepo
    - .git/
    - setup.py
    - myproject
        - __init__.py
        - some_mod
            - __init__.py
            - animals.py
            - rocks.py
        - config
            - __init__.py
            - settings.py
            - other_settings.special
            - cool.huh
            - other_settings.xml
        - words
            - __init__.py
            word_set.txt

setup.py

from setuptools import setup, find_packages
import os.path

setup (
    name='myproject',
    version = "4.19",
    packages = find_packages(),  
    # package_dir={'mypkg': 'src/mypkg'},  # didnt use this.
    package_data = {
        # If any package contains *.txt or *.rst files, include them:
        '': ['*.txt', '*.xml', '*.special', '*.huh'],
    },

#
    # Oddly enough, include_package_data=True prevented package_data from working.
    # include_package_data=True, # Commented out.
    data_files=[
#               ('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
        ('/opt/local/myproject/etc', ['myproject/config/settings.py', 'myproject/config/other_settings.special']),
        ('/opt/local/myproject/etc', [os.path.join('myproject/config', 'cool.huh')]),
#
        ('/opt/local/myproject/etc', [os.path.join('myproject/config', 'other_settings.xml')]),
        ('/opt/local/myproject/data', [os.path.join('myproject/words', 'word_set.txt')]),
    ],

    install_requires=[ 'jsonschema',
        'logging', ],

     entry_points = {
        'console_scripts': [
            # Blah...
        ], },
)

python setup.py sdistソースディストリビューション(バイナリを試していません)を実行します。

そして、真新しい仮想環境の中に、私はmyproject-4.19.tar.gz、ファイルを持っていて、

(venv) pip install ~/myproject-4.19.tar.gz
...

そして、私の仮想環境のインストールになっすべて以外のsite-packages、これらの特別なデータファイルがにインストールされます/opt/local/myproject/data/opt/local/myproject/etc


16

include_package_data=True 私のために働いた。

gitを使用する場合は、必ずに含めsetuptools-gitてくださいinstall_requiresManifestすべてのパスを含めるか、含めることよりもはるかに退屈ではありませんpackage_data(私の場合は、あらゆる種類の静的な機能を備えたdjangoアプリです)

k3-rncが実際に役立つので、k3-rncが言ったように、私のコメントを貼り付けました)


7

更新:この回答は古く、情報は無効になっています。すべてのsetup.py構成でを使用する必要がありますimport setuptoolshttps://stackoverflow.com/a/49501350/64313でより完全な回答を追加しました


distutilsに切り替えることでこれを解決しました。配布が非推奨または壊れているようです。

from distutils.core import setup

setup(
   name='myapp',
   packages=['myapp'],
   package_data={
      'myapp': ['data/*.txt'],
   },
)

2
配布は非推奨ではありません。distutilsに置き換わるものです。なぜ問題があったのかはわかりませんが、それは理由ではありません。
AGF

1
それは私がIRCから受け取った応答だったので、誰を信じますか?あなたが配布を使用する実用的な例を持っているなら、私はそれから感謝します。
cmcginty 2011

6
明確化:配布はsetuptoolsを置き換えることを意味し、どちらもdistutilsの上に構築されています。distutils自体は、最終的にはpython2で「distutils2」、python3で「パッケージング」と呼ばれる新しいパッケージに置き換えられます
Kevin Horn

1
distutilsに切り替えると、問題が解決さinclude_package_data=Trueれませんでした。したがって、その設定ではMANIFEST.inのみが必要package_dataです。設定でファイルリストを複製する必要はありません。
Daniel Sokolowski

4

古代の質問ですが、Pythonのパッケージ管理には、まだ多くのことが望まれています。そのため、指定したディレクトリにローカルでpipを使用してインストールするユースケースがあり、package_dataパスとdata_filesパスの両方が機能しないことに驚いていました。リポジトリにさらに別のファイルを追加することに熱心ではなかったので、data_filesとsetup.pyオプション--install-dataを利用することになりました。このようなもの

pip install . --install-option="--install-data=$PWD/package" -t package  


3

私は数日間同じ問題を抱えていましたが、すべてが混乱していたので、このスレッドでさえ私を助けることができませんでした。だから私は私の研究をして、次の解決策を見つけました:

この場合、基本的には次のようにする必要があります。

from setuptools import setup

setup(
   name='myapp',
   packages=['myapp'],
   package_dir={'myapp':'myapp'}, # the one line where all the magic happens
   package_data={
      'myapp': ['data/*.txt'],
   },
)

他の完全なスタックオーバーフローの答えはこちら


これを試しましたが、何もコピーされません。
ジェリット

3

行を削除するだけです:

include_package_data=True,

あなたのセットアップスクリプトから、それはうまくいきます。(現在、最新のsetuptoolsでテストされています。)


それはクレイジーだが、それはとの両方で動作しますsdistbdist_wheel、あなたはなぜチェックしましたか?
Szabolcs

1
これが設定されてsdistいるpackage_data場合、が無視することを確認できます。
サンダーステファン

この時点で数か月になりますが、コードを掘り下げて2度迷子になり、非常に細かい櫛を使ってドキュメントを作成し、満足感を得たことを思い出します。明らかに、さまざまなサンプルスクリプトにこのフラグが含まれており、頭痛の種がなくなることはありません。
イアン

1

setup.cfgの使用(setuptools≥30.3.0)

setuptools 30.3.0(2016年12月8日リリース)以降では、setup.pyサイズを非常に小さく保ち、構成をsetup.cfgファイルに移動できます。このアプローチでは、パッケージデータを[options.package_data]セクションに配置できます。

[options.package_data]
* = *.txt, *.rst
hello = *.msg

この場合、次のsetup.pyように短くすることができます。

from setuptools import setup
setup()

詳細については、setup.cfgファイルを使用したセットアップの構成を参照してください。

PEP 518で提案setup.cfgれているように非推奨するという話いくつかありますが、これは2020-02-21の時点ではまだ暫定的です。pyproject.toml


この回答ではMANIFESTファイルについての言及を無視しているため、実際にはsdistsでは機能しないと思います。ホイールのみ。あなたはそれについて言及すべきです。
WIM

@wimマニフェスト、sdist、ホイールについて十分に理解していないため、それに答えることはできません。これはを使用して私に働きましたpip install
ジェリット

それはpip install、pipの最新バージョンでは、最初にホイールを作成してからインストールするためです。それでも多くのユーザーにとって、このアプローチはパッケージデータを暗黙的に含めることに失敗します。詳細については、承認された回答とその下のコメントを参照してください。aを使用することsetup.cfgは、OPがsetup.py質問ですでに実行していることを記述するための別の方法です(package_dataへの呼び出しでキーワード引数を渡すことによりsetup)。このため、これはこの質問の回答として特に役立つとは思いません。それは根本的な問題にまったく対処していません。
WIM
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.