MANIFEST.in "python setup.py install" üzerinde yok sayıldı - hiçbir veri dosyası yüklenmedi mi?


91

İşte benim soyulmuş setup.py betiğim ve kod dışı öğeler kaldırılmış:

#!/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

"Python setup.py install sdist" i çalıştırdığımda, içinde yerel / images / ve whyteboard-help / klasörlerimle birlikte "whyteboard-0.41" kök klasörüne sahip güzel bir .tar.gz alıyorum. Burada ayrıca, programımı whyteboard kaynak paketinin içinden başlatan whyteboard.py betiğim var.

Yani:

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

Bu, programımın kaynağını yansıtıyor, her şeyin nasıl olması gerektiğidir ve doğrudur.

Ancak "python setup.py install" komutunu çalıştırdığımda veri dosyalarımdan hiçbiri yazılmıyor - yalnızca "whyteboard" kaynak paketi ve whyteboard.py /usr/local/lib/python2.6/dist-packages/ içine yerleştiriliyor .

İdeal olarak, .tar.gz dosyasında oluşturulanla aynı dizin yapısının dağıtım paketlerinde oluşturulmasını istiyorum, çünkü programımın kaynaklarını bu şekilde aramasını bekliyor.

Bu dizin yapısını oluşturmak için nasıl "kur" alabilirim? Anladığım kadarıyla, bildirim dosyamı görmezden geliyor gibi görünüyor.


Yanıtlar:


30

Ned'in cevabına ek olarak (temel soruna hitap eden) bazı notlar:

Distutils Python paketlerini ve modüllerini proje başına bir alt dizinin içine site-packages(veya dist-packagesDebian / Ubuntu'ya) kurmaz: Gördüğünüz gibi bunlar doğrudan içine yüklenir site-packages. Bu nedenle, whyteboard-xxsdist'inizdeki içeren dizin, son kurulan formda bulunmayacaktır.

Bunun çıkarımlarından biri, data_fileshangi projeye ait olduklarını açıklığa kavuşturacak şekilde kendi isminize dikkat etmeniz gerektiğidir , çünkü bu dosyalar / dizinler doğrudan global site-packagesdizine kurulur , herhangi birwhyteboard dizinin .

Veya bunun yerine paketle ilgili verilerinizi package_dataoluşturabilirsiniz whyteboard(bu , paketin içinde, yani yanında yaşaması gerektiği anlamına gelir __init__.py) ve o zaman bu bir sorun olmaz.

Son olarak, hem bir whyteboard.pymodülün hem de py_modulesbir whyteboard/__init__.pypaketin olması pek mantıklı değil packages. İkisi birbirini dışlar ve her ikisine de sahipseniz whyteboard.pymodül, aynı isimdeki paket lehine ithalatlar tarafından yok sayılacaktır.

Eğer whyteboard.pysadece bir senaryo olduğunu ve ithal edilecek tasarlanmamıştır, o zaman kullanması gereken komut bunun için bir seçenek ve çıkarın py_modules.


1
Bu talihsizlik. Paket verisine sahip olma fikrinden hoşlanmıyorum - bana göre, bu kaynakların kaynak dizinin dışında yaşaması daha mantıklı. Ayrıca, program adının önüne dizin adlarının eklenmesini de sevmiyorum (bunu yardım dosyaları için zaten yapmış olsam da). Hmm ..
Steven Sproat

68

MANIFEST.inDistutils'e kaynak dağıtımına hangi dosyaların dahil edileceğini söyler, ancak hangi dosyaların yüklendiğini doğrudan etkilemez. Bunun için setup.py, genellikle paket verileri veya ek dosyalar olarak uygun dosyaları dosyaya eklemeniz gerekir .


Paket verisi listesi eklemeyi denedim, ancak belirttiğim dosyaların hiçbiri kullanılmadı. Paketin genel kurulumuna göre dosyaların konumlarının yüklenip yüklenmediğinden emin değildim. Her neyse, yine de dosyalarımı beklediğim doğru dizin yapısında yazmıyordu.
Steven Sproat

Bu cevapta bağlantısı verilen dokümantasyon size data_files ve package_data'nın nerede kurulduğu hakkında ihtiyacınız olan tüm bilgileri verir. Bu seçenekler işinize yaramıyorsa, lütfen sorunuzu tam olarak denediğiniz sözdizimi, sonuçlar ve beklediğinizle güncelleyin.
Carl Meyer

4
Bu benim için çalışıyor: MANIFEST.in'deki girdilerimi setup.py'nin data_packages içinde çoğaltmak her şeyin çalışmasını sağlar. Teşekkürler Ned - Yıllardır bu noktayı anlayamadım. Umarım şimdi dağıtımlarım / kurulum araçlarım / dağıtım deneyimlerim daha mantıklı olacaktır.
Jonathan Hartley

7
Pakete yüklenmeyecek dosyaları dahil edebilme tasarımı mantıklı mı? Ne zaman kullanılacak?
Roger Dahl

29

Dosyamın neden MANIFEST.inkoştuğumda göz ardı edildiğini anlayamadım python setup.py install- ortaya çıktı include_package_data=True, sorunu çözdü. package_dataSeçeneğinin gerçekten gerekli değildir.


iyi yakalamak, neden include_package_data=Truevarsayılan değer değil?
liang

9

Kurulum araçlarını kullanmalısınız:

#!/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'],
)

Bu aslında işi yapmak için MANIFEST dosyasını kullanmaz, ancak gerekli tüm dosyaları içerir.


Bu benim için kurulum araçlarıyla çalıştı . Debian paketi oluşturuyorum ve package_datasözlükte listelenen glade dosyalarımın ancak ekledikten sonra doğru yerde göründüğünü görüyorum include_package_data=Tru.
mlt

8

Python 2.6.1'i Mac OSX'te çalıştırırken, setup.py'deki data_files parametresini kullanmak dışında kesinlikle hiç şansım olmadı . MANIFEST.in ile yapılan her şey, dosyaların dist paketine dahil edilmesiyle sonuçlandı, ancak hiçbir zaman yüklenmedi. Diğer bazı paketleri kontrol ettim ve gerçekten de ek dosyaları belirtmek için data_files kullanıyorlardı.

Bir dizin ağacındaki tüm dosyaları numaralandırmaya yardımcı olmak için kısa bir işlev oluşturdum.

(target_dir, [dosya listesi]) data_files'ın beklediği format:

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

Şimdi bunu kurulum çağrımın içinde arayabilirim:

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

Ve bu ağaçlardaki her şey kurulur.


11
Bu harika, ama nereye kurulur? Benim için, "pip install" kullanırken, data_files'ım virtualenv'imin köküne gider (yani, tüm virtualenv paketleri tarafından paylaşılan tek bir dizin) "setup.py install" kullanılıyorsa, data_files'ım "site- paketler / <mypackage> .egg / ". Dosyalar çalışma zamanında gerekli verilerse, kodumun bu dosyaları bulması her iki durumda da önemsiz değildir ve tabii ki çalışma zamanında her iki dizini de aramam gerekir. Dosyalar benim LİSANS dosyamsa, kullanıcılarımın kaynağımdan LİSANS'a ulaşması hiçbir durumda önemsiz değildir. Şaşkın.
Jonathan Hartley

4

Minimum yayınlanmış çalıştırılabilir örnek

Anahtar paket servisi olan restoran: sadece MANIFEST.inbenim için çalıştı, işe package_datayaramadı.

Ubuntu 19.10, Python 3.7.5, wheel == 0.32.3, setuptools == 41.1.0, twine == 3.1.1 üzerinde test edilmiştir.

Son kullanıcılar https://pypi.org/project/python-sample-package-with-data/ adresindeki paketi nasıl kullanır :

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

Beklenen çıktı:

hello data

Bakımcılar bunu nasıl yayınlar:

# 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

Asıl dosyalar:

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

Kaynakça:

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.