「pythonsetup.pyinstall」でMANIFEST.inが無視されます-データファイルがインストールされていませんか?


89

これは、コード以外のものが削除された、削除されたsetup.pyスクリプトです。

#!/usr/bin/env python

from distutils.core import setup
from whyteboard.misc import meta


setup(
    name = 'Whyteboard',
    version = meta.version,

    packages = ['whyteboard', 'whyteboard.gui', 'whyteboard.lib', 'whyteboard.lib.pubsub',
                'whyteboard.lib.pubsub.core', 'whyteboard.lib.pubsub.utils', 'whyteboard.misc'],

    py_modules = ['whyteboard'],
    scripts = ['whyteboard.py'],
)

MANIFEST.in:

include *.txt
include whyteboard-help/*.*
recursive-include locale *.mo
recursive-include images *.png

「pythonsetup.pyinstall sdist」を実行すると、「whyteboard-0.41」ルートフォルダーと、locale / images /フォルダーとwhyteboard-help /フォルダーが含まれる素敵な.tar.gzが得られます。これには、whyteboardソースパッケージ内からプログラムを起動するwhyteboard.pyスクリプトも含まれています。

そう:

whyteboard/
 ├── locale/
 ├── images
 ├── whyteboard-help/
 ├── whyteboard/
 │  ├── __init__.py
 │  └── other packages etc
 ├── whyteboard.py
 ├── README
 ├── setup.py
 └── CHANGELOG

これは私のプログラムのソースを反映しており、すべてがどうあるべきかであり、正しいものです。

ただし、「python setup.py install」を実行すると、データファイルは書き込まれません。「whyteboard」ソースパッケージのみが書き込まれ、whyteboard.pyは/usr/local/lib/python2.6/dist-packages/に配置されます。 。

理想的には、.tar.gzファイルで生成されたものと同じディレクトリ構造をdist-packagesで作成する必要があります。これは、私のプログラムがそのリソースを探す方法であるためです。

このディレクトリ構造を作成するために「インストール」を取得するにはどうすればよいですか?私の知る限り、マニフェストファイルを無視しているようです。


回答:


30

ネッドの答え(コアの問題に当てはまる)に加えて、いくつかの注意事項:

Distutilsは、Pythonパッケージとモジュールをプロジェクトごとのサブディレクトリ内site-packages(またはdist-packagesDebian / Ubuntu上)にインストールsite-packagesしません。これまで見てきたように、これらはに直接インストールされます。したがって、whyteboard-xxsdistに含まれているディレクトリは、最終的にインストールされた形式では存在しません。

これが意味することの1つは、data_filesそれらのファイル/ディレクトリはsite-packages、含まれているwhyteboardディレクトリ内ではなく、グローバルディレクトリに直接インストールされるため、それらが属するプロジェクトを明確にする方法で名前を付けるように注意する必要があるということです。

または、代わりにパッケージのデータpackage_dataを作成することもできwhyteboardます(つまり、パッケージ内、つまり隣に存在する必要があります__init__.py)。そうすれば、これは問題になりません。

最後に、whyteboard.pyモジュールpy_moduleswhyteboard/__init__.pyパッケージの両方をに入れることはあまり意味がありませんpackages。この2つは相互に排他的であり、両方がある場合、whyteboard.pyモジュールはインポートによって無視され、同じ名前のパッケージが優先されます。

whyteboard.pyが単なるスクリプトであり、インポートを目的としていない場合は、スクリプトオプションを使用して、から削除する必要がありpy_modulesます。


1
それは残念です。私はパッケージデータを持つという考えが好きではありません-私にとって、それらのリソースがソースディレクトリの外にある方が理にかなっています。また、プログラム名の前にディレクトリ名を付ける必要もありません(ヘルプファイルに対してはすでにそうしていますが)。うーん...
スティーブン・スプロート

67

MANIFEST.inソースディストリビューションに含めるファイルをDistutilsに指示しますが、インストールされるファイルには直接影響しません。そのためにはsetup.py、通常、パッケージデータまたは追加ファイルとして適切なファイルをファイルに含める必要があります


パッケージデータのリストを追加しようとしましたが、指定したファイルが使用されませんでした。パッケージの全体的なインストールに対して、ファイルの場所がインストールされているかどうかはわかりませんでした。とにかく、それでも私が期待した正しいディレクトリ構造にファイルを書き込んでいませんでした。
スティーブンスプロート2010

この回答にリンクされているドキュメントには、data_filesとpackage_dataがインストールされている場所について必要なすべての情報が記載されています。これらのオプションが機能しない場合は、試した正確な構文、結果、および期待した内容で質問を更新してください。
カールマイヤー

4
これは私にとってはうまくいきます:setup.pyのdata_packages内のMANIFEST.inエントリを複製すると、すべてが機能します。ありがとうネッド-私はこの点を何年も理解できていません。うまくいけば、私のdistutils / setuptools / distributeエクスペリエンスがより理にかなっているでしょう。
Jonathan Hartley

7
インストールされないファイルをパッケージに含めることができるというこの設計は意味がありますか?いつ使用されますか?
ロジャーダール

27

私なぜ私は把握できなかったMANIFEST.in私が実行したときに、ファイルは無視されていたpython setup.py install-が判明include_package_data=True解き問題。このpackage_dataオプションは実際には必要ありません。


良いキャッチ、なぜinclude_package_data=Trueデフォルト値ではないのですか?

8

MacOSXでpython2.6.1を実行していると、setup.pyのdata_filesパラメーターを使用する以外はまったく運がありませんでした。MANIFEST.inを使用すると、ファイルがdistパッケージに含まれるようになりますが、インストールされることはありません。他のいくつかのパッケージを確認しましたが、実際にはdata_filesを使用して追加のファイルを指定していました。

のディレクトリツリーからすべてのファイルを列挙するのに役立つ短い関数を作成しました

(target_dir、[ファイルリスト]) data_filesが期待する形式:

def gen_data_files(*dirs):
    results = []

    for src_dir in dirs:
        for root,dirs,files in os.walk(src_dir):
            results.append((root, map(lambda f:root + "/" + f, files)))
    return results

これで、セットアップ呼び出し内でこれを呼び出すことができます。

setup(... data_files = gen_data_files("docs", "lib") ...

そして、それらの木のすべてがインストールされます。


11
これは素晴らしいですが、どこにインストールされますか?私の場合、「pip install」を使用すると、data_filesはvirtualenvのルート(つまり、すべてのvirtualenvのパッケージで共有される単一のディレクトリ)に移動します。「setup.pyinstall」を使用する場合、data_filesは「site-」に移動します。 packages / <mypackage> .egg / "。ファイルが実行時に必要なデータである場合、どちらの場合も、コードがこれらのファイルを見つけるのは簡単ではありません。もちろん、実行時に両方のディレクトリを検索する必要があります。ファイルが私のLICENSEファイルである場合、どちらの場合も、ユーザーが私のソースからLICENSEにアクセスするのは簡単ではありません。困惑。
Jonathan Hartley

8

setuptoolsを使用する必要があります。

#!/usr/bin/env python

from setuptools import setup, find_packages
from whyteboard.misc import meta


setup(
  name = 'Whyteboard',
  version = meta.version,

  packages = find_packages(),
  include_package_data=True,

  py_modules = ['whyteboard'],
  scripts = ['whyteboard.py'],
)

これは実際にはマニフェストファイルを使用してジョブを実行しているわけではありませんが、必要なすべてのファイルが含まれています。


これはsetuptoolsでうまくいきました。Debianパッケージをビルドすると、package_data辞書にリストされている空き地ファイルが、を追加しinclude_package_data=Truた後にのみ正しい場所に表示されます。
mlt 2013

3

最小限の公開された実行可能な例

重要なポイント:MANIFEST.in私のためだけに機能し、機能package_dataしませんでした。

Ubuntu 19.10、Python 3.7.5、wheel == 0.32.3、setuptools == 41.1.0、twine == 3.1.1でテスト済み。

エンドユーザーがhttps://pypi.org/project/python-sample-package-with-data/のパッケージを使用する方法:

python3 -m pip install --user python-sample-package-with-data
python-sample-package-with-data

期待される出力:

hello data

メンテナがそれを公開する方法:

# One time setup.
python3 -m pip install --user setuptools wheel twine

# Every time you want to publish.
python setup.py sdist bdist_wheel
twine upload dist/*
rm -rf build dist *.egg-info

実際のファイル:

MANIFEST.in

# Or else pip install cannot find README.md on the setup.py under certain conditions.
include README.md

# This actually adds the data file.
include python_sample_package_with_data/mydata.txt

python-sample-package-with-data

#!/usr/bin/env python3

import python_sample_package_with_data

print(python_sample_package_with_data.get_data(), end='')

python_sample_package_with_data / __init__。py

try:
    import importlib.resources as importlib_resources
except ImportError:
    # In PY<3.7 fall-back to backported `importlib_resources`.
    import importlib_resources

def get_data():
    return importlib_resources.read_text(__name__, 'mydata.txt')

python_sample_package_with_data / mydata.txt

hello data

setup.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from setuptools import setup, find_packages

from os import path
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md')) as f:
    long_description = f.read()

setup(
    name='python-sample-package-with-data',
    version='0.0.3',
    description='My short description',
    long_description=long_description,
    long_description_content_type='text/markdown',
    url='https://github.com/cirosantilli/python-sample-package-with-data',
    author='Ciro Santilli',
    author_email='ciro.santilli.contact@gmail.com',
    packages=find_packages(),
    include_package_data=True,
    scripts=['python-sample-package-with-data'],
)

参考文献:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.