Setuptools / dağıtımı ile paket verileri nasıl dahil edilir?


137

Setuptools / dağıtımı kullanırken, yükleyicinin herhangi bir package_datadosyayı almasını sağlayamıyorum . Okuduğum her şey aşağıdakilerin doğru şekilde yapıldığını söylüyor. Birisi lütfen tavsiye edebilir mi?

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

nerede myapp/data/veri dosyalarının konumudur.


2
Aynı sorunu yaşıyorum ... El ile belirleme data_filessorunu çözdü. Ancak bu hataya açıktır ve bana "doğru hissettirmez". Birisi gerçekten olduğunu doğrulayabilir gerekli hem de yapılandırmayı çoğaltmak package_datave data_files?
exhuma

github.com/wimglenn/resources-example Veri dosyalarını kullanarak tekerleklere ve sdistlere doğru şekilde paketleyebilen modern bir kurulum araçları proje yapısı gösterir pyproject.toml. Hiçbir setup.pydosyası gereklidir.
wim

Yanıtlar:


289

Bunun eski bir soru olduğunu anlıyorum, ancak Google üzerinden yollarını bulan insanlar için: package_dataalçak, kirli bir yalan . Oluştururken sadece kullanılır ikili paketleri ( python setup.py bdist ...) ama değil kaynak paketlerini oluştururken ( python setup.py sdist ...). Tabii ki bu çok saçma - bir kaynak dağıtımı oluşturmanın ikili dağıtımı oluşturmak için başka birine gönderilebilecek bir dosya koleksiyonuyla sonuçlanmasını bekleyebiliriz.

Her durumda, kullanarak MANIFEST.inçalışacak hem ikili ve kaynak dağılımları için.


97
Bu konuyu son bir saattir araştırıyorum ve birçok yaklaşımı deniyorum. Dediğiniz gibi, değil package_dataiçin çalışır . Ancak , çalışır , ama değil için ! Bu nedenle, ile gelip mümkün olmuştur iyi hem dahil etmektir ve her iki karşılamak için ve . bdistsdistMANIFEST.insdistbdistpackage_dataMANIFEST.inbdistsdist
Wesley Baugh

7
@WesleyBaugh'ı desteklemek için başka bir tane buldum. In stackoverflow.com/a/2969087/261718 , Kullanım MANIFEST.indosyaları için size belgeler gibi yüklenmez ve package_datadosyalar için (bir resim veya bir şablon gibi) o değil Python kodu kullanabilirsiniz.
Drake Guan

12
Ben Sdist kullanarak ve her iki dahil etmek zorunda am MANIFEST.in ve package_data . Görünüşe göre MANIFEST.indağıtımda nelerin dahil edildiğini ve package_data, kurulum sırasında daha sonra site_packages dizinine nelerin kopyalanacağını kontrol eder. Kafa karıştırıcı bir şekilde, yollar MANIFEST.insetup.py'nin yerine göredir ve package_datatek tek paketler (örn. Modüller) köküne göredir.
Edward Newell

9
"Sürüm 2.7'de değiştirildi: Herhangi bir şablon sağlanmamışsa package_data ile eşleşen tüm dosyalar MANIFEST dosyasına eklenecektir. Dağıtılacak dosyaları belirtme konusuna bakın." bölgeleri . Bu nedenle, dosyaların davranışını yalnızca mevcut MANIFEST.in dosyanız yoksa ve yalnızca 2.7+ kullanıyorsanız ZIP'e package_dataotomatik olarak dahil edildiğini görürsünüz.
Johnus

29
Cidden, bu biletin, kurulum araçlarını kullanan ve hayatta kendilerini ne kadar korkunç bir yer bulduklarını keşfeden insanlar için bir grup terapisi seansı gibi hissediyorum.
Matt Joyce

32

Aynı sorunu yaşadım. Çözüm, basitçe kaldırmaktı include_package_data=True.

Burada okuduktan sonra , adından da anlaşılacağı gibi, yalnızca "paket verilerini dahil et" yerine sürüm kontrolündeninclude_package_data dosyaları dahil etmeyi amaçladığını fark ettim . Dokümanlardan:

[İnclude_package_data] veri dosyaları CVS veya Subversion kontrolü altında olmalıdır

...

Hangi dosyaların dahil edileceği üzerinde daha ayrıntılı bir kontrol istiyorsanız (örneğin, paket dizinlerinizde dokümantasyon dosyalarınız varsa ve bunları kurulumdan hariç tutmak istiyorsanız), aynı zamanda package_dataanahtar kelimeyi de kullanabilirsiniz .

Bu argümanı çıkarmak sorunu çözdü, bu yüzden de bu argümanı almadığı için distutils'e geçtiğinizde de işe yaradı.


2
Deneyimlerim farklı, include_package_data=Truegiriş dahil olmadan aynı sorun vardı . Benim için tek çözüm yukarıda belirtildiği gibi Manifest'e bir giriş eklemektir. Kurulum araçlarını kullandığımı mı düşünüyorsunuz, belki sürümünüz 'dağıtma' ile çalışıyor?
TimStaley

4
include_package_dataÇözme sorununun kaldırılmasının asıl nedeni orijinal metinde daha fazla - Setuptools'a özgü include_package_databağımsız değişken kullanılıyorsa, dosyada package_datalistelenmedikçe, belirtilen dosyalar otomatik olarak manifest'e eklenmeyecektir MANIFEST.in.
Piotr Dobrogost

Sahip kullanım durumu nedir package_databoş olmayan bir listeye seti ve belirtme include_package_data=False? Ve neden iki kez MANIFEST.inve içinde dosya belirtmeniz gerekiyor package_data?
Herbert

21

@Joe'nin include_package_data=Trueçizgiyi kaldırma tavsiyesinden sonra benim için de çalıştı.

Biraz daha detaylandırmak için dosyam yok MANIFEST.in . CVS yerine Git kullanıyorum.

Depo bu tür bir şekil alır:

/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 sdistBir kaynak dağıtımı için çalıştırıyorum (ikili denemedim).

Yepyeni bir sanal ortamın içindeyken, bir dosyam var myproject-4.19.tar.gzve

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

Ve sanal ortamlarıma yüklenen her şey dışında site-packages, bu özel veri dosyaları /opt/local/myproject/datave /opt/local/myproject/etc.


16

include_package_data=True benim için çalıştı.

Eğer git kullanırsanız, eklemeyi unutmayın setuptools-gitiçinde install_requires. ManifestTüm yolu içeren veya dahil olandan çok daha az sıkıcı package_data(benim durumumda her türlü statüye sahip bir django uygulaması)

(yaptığım yorumu yapıştırdım, k3-rnc'nin bahsettiği gibi aslında olduğu gibi yararlı)


7

Güncelleme : Bu cevap eski ve bilgiler artık geçerli değil. Tüm setup.py yapılandırmaları kullanmalıdır import setuptools. Https://stackoverflow.com/a/49501350/64313 adresine daha eksiksiz bir yanıt ekledim


Bunu distutiller'e geçerek çözdüm. Dağıtımın kullanımdan kaldırıldığı ve / veya bozuk olduğu anlaşılıyor.

from distutils.core import setup

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

2
dağıtma onaylanmamıştır, dağıtımcıların yerini almaktadır. Sorunu neden yaşadığını bilmiyorum, ama nedeni bu değil.
agf

1
IRC'den aldığım yanıt buydu, o zaman kime inanıyorum? Eğer dağıtımı kullanarak çalışan bir örnek varsa o zaman takdir ediyorum.
cmcginty

6
açıklama: dağıtmak kurulum araçlarının yerini almak içindir, her ikisi de distutils üzerine inşa edilmiştir. distutils'in kendisi sonunda python2'de "distutils2" ve python3'te "ambalaj" olarak adlandırılan yeni bir paket ile değiştirilecek
Kevin Horn

1
Distutils'e geçmek, onurlandırılmadığım sorunumu çözdü include_package_data=True. Bu ayar ile sadece MANIFEST.in dosyasına ihtiyacınız vardır - package_dataayarda dosya listenizi kopyalamanıza gerek yoktur .
Daniel Sokolowski

4

Eski soru ve henüz ... python paket yönetimi gerçekten arzulanan bir çok şey bırakıyor. Bu yüzden pip kullanarak belirtilen bir dizine yerel olarak yükleme kullanım durumu vardı ve hem package_data hem de data_files yolları işe yaramadı şaşırdı. Ben repo başka bir dosya eklemek için istekli değildi, bu yüzden data_files ve setup.py seçeneği --install-veri kaldırarak sona erdi; böyle bir şey

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


3

Birkaç gün boyunca aynı sorunu vardı ama her şey kafa karıştırıcı olduğu gibi bu iş parçacığı bile bana yardımcı olamadı. Bu yüzden araştırmamı yaptım ve aşağıdaki çözümü buldum:

Temel olarak bu durumda şunları yapmalısınız:

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'],
   },
)

Diğer yığın yığını akışı cevabı burada


Bunu denedim, ama yine de hiçbir şey kopyalanmıyor.
gerrit

3

Sadece hattı kaldırın:

include_package_data=True,

kurulum komut dosyasından, ve iyi çalışır. (En son kurulum araçlarıyla şimdi test edildi.)


Çılgınca ama ikisinde de çalışıyor sdistve bdist_wheelnedenini kontrol ettin mi?
Szabolcs

1
Gerçekten bu ayarlandığında sdistyok sayar teyit edebilirim package_data.
Sander Steffann

Bu noktada aylar oldu, ancak kodda kazmayı, iki kez kaybolmayı, belgelere ÇOK ince dişli bir tarak almayı ve memnuniyet kazanmayı hatırlıyorum. Görünüşe göre çeşitli örnek betikler bu bayrağı içerir ve baş ağrısının sona ermesine neden olmaz.
Ian

1

Setup.cfg kullanma (setuptools ≥ 30.3.0)

Setuptools 30.3.0 (2016-12-08'de yayınlandı) ile başlayarak, setup.pyçok küçük tutabilir ve yapılandırmayı bir setup.cfgdosyaya taşıyabilirsiniz . Bu yaklaşımla paket verilerinizi bir [options.package_data]bölüme koyabilirsiniz :

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

Bu durumda, setup.pyaşağıdakiler kadar kısa olabilir:

from setuptools import setup
setup()

Daha fazla bilgi için bkz . Setup.cfg dosyalarını kullanarak kurulumu yapılandırma .

Orada küçümseyen bazı konuşmasetup.cfg lehine pyproject.tomlönerildiği gibi PEP 518 , ancak bu hala 2020-02-21 tarihinden itibaren geçicidir.


Bu cevap MANIFEST dosyasından bahsetmeyi ihmal eder, bu yüzden sdistlerle çalışmadığını düşünüyorum. Sadece tekerlekli. Bundan bahsetmelisin.
wim

@wim Buna cevap vermek için MANIFEST, sdist ve tekerlekleri yeterince anlayamadım. Bu benim için çalıştı pip install.
gerrit

Çünkü pip install, yeterince modern bir pip versiyonu için, önce bir tekerlek inşa edecek ve daha sonra bunu kuracaktır. Yine de birçok kullanıcı için bu yaklaşım sessizce paket verilerini içeremez. Bununla ilgili ayrıntılar için kabul edilen cevaba ve altındaki yorumlara bakın. A kullanmak setup.cfggerçekten OP'nin setup.pysoruda ne yaptığını yazmanın farklı bir yoludur ( package_dataçağrıda anahtar kelime argümanını ileterek setup), bu yüzden bu sorunun bu soruya cevap olarak özellikle yararlı olduğunu düşünmüyorum . Altta yatan sorunu hiç ele almıyor.
wim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.