Come includere i dati del pacchetto con setuptools / distribut?


135

Quando si utilizzano setuptools / distribut, non riesco a ottenere il file di installazione da estrarre package_data. Tutto quello che ho letto dice che il seguente è il modo corretto di farlo. Qualcuno può avvisare per favore?

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

dove si myapp/data/trova la posizione dei file di dati.


2
Sto riscontrando lo stesso problema ... La specifica manuale ha data_filesrisolto il problema. Ma questo è soggetto a errori e non "mi sento bene" per me. Qualcuno può verificare che sia davvero necessario duplicare la configurazione in entrambi package_datae data_files?
exhuma,

github.com/wimglenn/resources-example Mostra una moderna struttura di progetto setuptools, che può impacchettare correttamente i file di dati in ruote e sdist usando pyproject.toml. Nessun setup.pyfile richiesto.
mercoledì

Risposte:


289

Mi rendo conto che questa è una vecchia domanda, ma per le persone che si fanno strada qui tramite Google: package_dataè una bugia bassa e sporca . Viene utilizzato solo durante la creazione di pacchetti binari ( python setup.py bdist ...) ma non durante la creazione di pacchetti sorgente ( python setup.py sdist ...). Questo è, ovviamente, ridicolo - ci si aspetterebbe che la costruzione di una distribuzione di origine comporterebbe una raccolta di file che potrebbero essere inviati a qualcun altro per costruire la distribuzione binaria.

In ogni caso, l'utilizzo MANIFEST.infunzionerà sia per le distribuzioni binarie che per quelle di origine.


97
Ho studiato questo problema nell'ultima ora e ho provato molti approcci. Come dici tu, package_datafunziona per bdiste non sdist. Tuttavia , MANIFEST.infunziona per sdist, ma non per bdist! Pertanto, il meglio che ho potuto inventare è quello di includere entrambi package_datae MANIFEST.inal fine di soddisfare entrambi bdiste sdist.
Wesley Baugh,

7
Ne ho trovato un altro per supportare @WesleyBaugh. In stackoverflow.com/a/2969087/261718 , Usa MANIFEST.inper i file che non installerai, come la documentazione, e package_dataper i file che usi che non sono codice Python (come un'immagine o un modello).
Drake Guan,

12
Sto usando sdist e ho dovuto includere entrambi MANIFEST.in e package_data . Sembra che MANIFEST.incontrolli ciò che è incluso nella distribuzione e package_data controlla ciò che successivamente viene copiato nella directory site_packages durante l'installazione. In modo confuso, i percorsi in MANIFEST.insono relativi alla posizione di setup.py ed package_dataè relativo ai singoli pacchetti (ad es. Moduli) root.
Edward Newell,

9
"Modificato nella versione 2.7: Tutti i file che corrispondono a package_data verranno aggiunti al file MANIFEST se non viene fornito alcun modello. Vedere Specifica dei file da distribuire." da distutils . Quindi, vedrai il comportamento dei file package_dataautomaticamente inclusi in ZIP solo se non disponi di un file MANIFEST.in esistente e solo se usi 2.7+.
Giovanni il

29
Seriamente, sento che questo biglietto è una sessione di terapia di gruppo per persone che usano gli strumenti di installazione e scoprono che posto orribile si sono trovati nella vita.
Matt Joyce,

32

Ho appena avuto questo stesso problema. La soluzione era semplicemente quella di rimuoverla include_package_data=True.

Dopo aver letto qui , mi sono reso conto che include_package_datamira a includere i file dal controllo della versione , anziché limitarsi a "includere i dati del pacchetto", come suggerisce il nome. Dai documenti:

I file di dati [di include_package_data] devono essere sotto controllo CVS o Subversion

...

Se si desidera un controllo più preciso su quali file sono inclusi (ad esempio, se si hanno file di documentazione nelle directory dei pacchetti e si desidera escluderli dall'installazione), è possibile utilizzare anche la package_dataparola chiave.

L'eliminazione di tale argomento lo ha risolto, il che è per coincidenza il motivo per cui ha funzionato anche quando sei passato a distutils, dal momento che non accetta tale argomento.


2
La mia esperienza è diversa, ho avuto lo stesso problema senza includere la include_package_data=Truevoce. L'unica soluzione per me è aggiungere una voce in Manifest come suggerito sopra. Ti dispiace che stavo usando setuptools, forse la tua versione funziona con 'distribut'?
TimStaley,

4
Il motivo reale per cui la rimozione del include_package_dataproblema risolto è ulteriormente nel testo originale - Se si utilizza l' include_package_dataargomento specifico di setuptools, i file specificati da package_datanon verranno automaticamente aggiunti al manifest a meno che non siano elencati nel MANIFEST.infile.
Piotr Dobrogost,

Qual è il caso d'uso di aver package_dataimpostato un elenco non vuoto e specificare include_package_data=False? E perché dovresti specificare i file due volte dentro MANIFEST.ine package_data?
Herbert,

21

Seguire la raccomandazione di @Joe di rimuovere la include_package_data=Truelinea ha funzionato anche per me.

Per elaborare un po 'di più, non ho alcun MANIFEST.in file. Uso Git e non CVS.

Il repository prende questo tipo di forma:

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

Corro python setup.py sdistper un distributore di origine (non ho provato binario).

E quando sono all'interno di un nuovo ambiente virtuale, ho un myproject-4.19.tar.gzfile e lo uso

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

E oltre a tutto ciò che viene installato nel mio ambiente virtuale site-packages, questi file di dati speciali vengono installati su /opt/local/myproject/datae /opt/local/myproject/etc.


16

include_package_data=True ha funzionato per me.

Se usi git, ricordati di includerlo setuptools-gitin install_requires. Molto meno noioso di avere un Manifestpercorso incluso o incluso package_data(nel mio caso è un'app django con tutti i tipi di statica)

(incollato il commento che ho fatto, come ha detto k3-rnc , in realtà è utile così com'è)


7

Aggiornamento : questa risposta è vecchia e le informazioni non sono più valide. Tutte le configurazioni setup.py devono essere utilizzate import setuptools. Ho aggiunto una risposta più completa su https://stackoverflow.com/a/49501350/64313


Ho risolto questo passaggio passando a distutils. Sembra che la distribuzione sia obsoleta e / o danneggiata.

from distutils.core import setup

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

2
distribuire non è deprecato, sta sostituendo distutils. Non so perché avessi il problema, ma non è questo il motivo.
AGF

1
Questa è stata la risposta che ho ricevuto dall'IRC, quindi a chi credo? Se hai un esempio funzionante con Distribuisci, apprezzerei allora.
cmcginty,

6
chiarimento: distribuire è destinato a sostituire gli strumenti di installazione, entrambi sono costruiti sulla cima di distutils. distutils stesso verrà infine sostituito da un nuovo pacchetto, chiamato "distutils2" in python2 e "packaging" in python3
Kevin Horn,

1
Il passaggio a distutils ha risolto il mio problema in cui include_package_data=Truenon veniva onorato. Quindi, con quell'impostazione è necessario solo MANIFEST.in - non è necessario duplicare l'elenco dei file package_datanell'impostazione.
Daniel Sokolowski,

4

Domanda antica e tuttavia ... la gestione dei pacchetti di Python lascia davvero molto a desiderare. Quindi ho avuto il caso d'uso di installare pip usando localmente in una directory specificata e sono rimasto sorpreso che entrambi i percorsi package_data e data_files non abbiano funzionato. Non ero entusiasta di aggiungere ancora un altro file al repository, quindi ho finito per sfruttare l'opzione data_files e l'opzione setup.py --install-data; qualcosa come questo

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


3

Ho avuto lo stesso problema per un paio di giorni, ma anche questo thread non è stato in grado di aiutarmi perché tutto era confuso. Quindi ho fatto le mie ricerche e ho trovato la seguente soluzione:

Fondamentalmente in questo caso, dovresti fare:

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

L'intero altro stackoverflow risponde qui


Ho provato questo, ma ancora niente viene copiato.
Gerrit,

3

Basta rimuovere la linea:

include_package_data=True,

dal tuo script di installazione, e funzionerà bene. (Testato proprio ora con gli ultimi setuptools.)


È pazzo ma funziona sia con sdistche bdist_wheel, hai controllato perché?
Szabolcs,

1
Posso davvero confermare che sdistignora package_dataquando è impostato.
Sander Steffann,

A questo punto sono passati mesi, ma mi sembra di ricordare di aver cercato nel codice, di essermi perso due volte, di aver preso un pettine ESTREMAMENTE fine nella documentazione e di ottenere soddisfazione. Apparentemente vari script di esempio contengono questo flag e non causano fine al mal di testa.
Ian

1

Uso di setup.cfg (setuptools ≥ 30.3.0)

A partire da setuptools 30.3.0 (rilasciato il 08-12-2016), è possibile mantenere setup.pydimensioni molto ridotte e spostare la configurazione in un setup.cfgfile. Con questo approccio, è possibile inserire i dati del pacchetto in una [options.package_data]sezione:

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

In questo caso, setup.pypuoi essere breve quanto:

from setuptools import setup
setup()

Per ulteriori informazioni, vedere la configurazione di setup utilizzando i file setup.cfg .

Si parla di deprecaresetup.cfg a favore di pyproject.tomlquanto proposto nel PEP 518 , ma questo è ancora provvisorio a partire dal 2020-02-21.


Questa risposta trascura di menzionare il file MANIFEST, quindi penso che in realtà non funzionerà con gli sdist. Solo con ruote. Dovresti menzionarlo.
mercoledì

@wim Non ho abbastanza comprensione di MANIFEST, sdist e ruote per rispondere. Questo ha funzionato per me usando pip install.
Gerrit,

Questo perché pip install, per una versione abbastanza moderna di pip, prima costruirà una ruota e poi la installerà. Ancora per molti utenti questo approccio non riuscirà silenziosamente a includere i dati del pacchetto. Vedi la risposta accettata e i commenti sotto di essa per i dettagli al riguardo. L'uso di a setup.cfgè in realtà solo un modo diverso di scrivere ciò che l'OP stava già facendo nella setup.pydomanda (passando l' package_dataargomento della parola chiave nella chiamata a setup), quindi non penso che ciò sia particolarmente utile come risposta a questa domanda . Non affronta affatto il problema di fondo.
mercoledì
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.