web-dev-qa-db-fra.com

Y compris les fichiers non-Python avec setup.py

Comment je fais setup.py inclure un fichier qui ne fait pas partie du code? (Plus précisément, c'est un fichier de licence, mais cela pourrait être autre chose.)

Je veux pouvoir contrôler l'emplacement du fichier. Dans le dossier source d'origine, le fichier se trouve à la racine du package. (c’est-à-dire au même niveau que le __init__.py.) Je veux qu'il reste exactement là lorsque le paquet est installé, quel que soit le système d'exploitation. Comment je fais ça?

167
Ram Rachum

La meilleure façon de faire est probablement d’utiliser la directive setuptoolspackage_data. Cela signifie que vous devez utiliser setuptools (ou distribute ) au lieu de distutils, mais cette mise à niveau est très transparente " ".

Voici un exemple complet (mais non testé):

from setuptools import setup, find_packages

setup(
    name='your_project_name',
    version='0.1',
    description='A description.',
    packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']),
    package_data={'': ['license.txt']},
    include_package_data=True,
    install_requires=[],
)

Notez les lignes spécifiques qui sont critiques ici:

package_data={'': ['license.txt']},
include_package_data=True,

package_data Est un dict de noms de paquets (vide = tous les paquets) dans une liste de modèles (peut inclure des globs). Par exemple, si vous souhaitez uniquement spécifier des fichiers dans votre package, vous pouvez également le faire:

package_data={'yourpackage': ['*.txt', 'path/to/resources/*.txt']}

La solution ici est certainement pas de renommer vos fichiers non -py avec une extension .py.

Voir présentation de Ian Bicking pour plus d'informations.

MISE À JOUR: Une autre [meilleure] approche

Une autre approche qui fonctionne bien si vous souhaitez simplement contrôler le contenu de la distribution source (sdist) et disposer de fichiers en dehors du paquet (par exemple, le répertoire de niveau supérieur) consiste à ajouter un fichier MANIFEST.in. . Voir the Python pour le format de ce fichier.

Depuis l’écriture de cette réponse, j’ai constaté que l’utilisation de MANIFEST.in Est généralement une approche moins frustrante pour simplement s’assurer que votre distribution source (tar.gz) Contient les fichiers dont vous avez besoin.

Par exemple, si vous souhaitez inclure le requirements.txt À partir du niveau supérieur, incluez de manière récursive le répertoire "data" au niveau supérieur:

include requirements.txt
recursive-include data *

Néanmoins, pour que ces fichiers puissent être copiés au moment de l’installation dans le dossier du paquet à l’intérieur de paquet-site, vous devrez fournir include_package_data=True À la fonction setup(). Voir Ajout de fichiers non codés pour plus d'informations.

179
Hans L

Pour accomplir ce que vous décrivez, vous devez suivre deux étapes ...

  • Le fichier doit être ajouté à l'archive source
  • setup.py doit être modifié pour installer le fichier de données sur le chemin source

Étape 1: pour ajouter le fichier à l'archive source, incluez-le dans le MANIFEST .

Créez un modèle MANIFESTE dans le dossier qui contient setup.py

MANIFEST est fondamentalement un fichier texte avec une liste de tous les fichiers qui seront inclus dans l'archive source.

Voici à quoi ressemble le MANIFEST de mon projet:

  • CHANGELOG.txt
  • INSTALL.txt
  • LICENSE.txt
  • pypreprocessor.py
  • README.txt
  • setup.py
  • test.py
  • TODO.txt

Remarque: Bien que sdist ajoute des fichiers automatiquement , je préfère les spécifier explicitement pour en être sûr au lieu de prédire ce qu'il fait et ce qu'il ne 't.

Étape 2: pour installer le fichier de données dans le dossier source, modifiez setup.py .

Puisque vous souhaitez ajouter un fichier de données (LICENSE.txt) au dossier d'installation source, vous devez modifier le chemin d'installation des données afin qu'il corresponde au chemin d'installation source. Cela est nécessaire car, par défaut, les fichiers de données sont installés dans un emplacement différent de celui des fichiers source.

Pour modifier le répertoire d'installation des données afin qu'il corresponde au répertoire d'installation source ...

Tirez les informations de répertoire d'installation de distutils avec:

from distutils.command.install import INSTALL_SCHEMES

Modifiez le répertoire d'installation des données afin qu'il corresponde au répertoire d'installation source:

for scheme in INSTALL_SCHEMES.values():
    scheme['data'] = scheme['purelib']

Et ajoutez le fichier de données et l'emplacement à setup ():

data_files=[('', ['LICENSE.txt'])]

Remarque: Les étapes ci-dessus doivent permettre de réaliser exactement ce que vous avez décrit de manière standard sans nécessiter de bibliothèques d'extension.

43
Evan Plaice

créer MANIFEST.in dans la racine du projet avec recursive-include dans le répertoire requis ou include avec le nom du fichier.

include LICENSE
include README.rst
recursive-include package/static *
recursive-include package/templates *

la documentation peut être trouvée ici

12
All Іѕ Vаиітy

Dans setup.py sous setup (:

setup(
   name = 'foo library'
   ...
  package_data={
   'foolibrary.folderA': ['*'],     # All files from folder A
   'foolibrary.folderB': ['*.txt']  #All text files from folder B
   },
5
Dashing Adam Hughes

Étape 1: créez un fichier MANIFEST.in Dans le même dossier que setup.py

Étape 2: incluez le chemin relatif vers les fichiers que vous voulez ajouter dans MANIFEST.in

include README.rst
include docs/*.txt
include funniest/data.json

Étape 3: définissez include_package_data=True Dans la fonction setup() pour copier ces fichiers dans le package de site

la référence est ici

4
debuglife

Voici une réponse plus simple qui a fonctionné pour moi.

Tout d'abord, pour a Python Dev ci-dessus, setuptools n'est pas requis:

package_data is also available to pure distutils setup scripts 
since 2.3. – Éric Araujo

C’est formidable, car le fait de mettre une exigence setuptools sur votre paquet signifie que vous devrez l’installer également. En bref:

from distutils.core import setup

setup(
    # ...snip...
    packages          = ['pkgname'],
    package_data      = {'pkgname': ['license.txt']},
)
3
Gringo Suave

Je voulais simplement faire un suivi sur quelque chose que j'ai trouvé avec Python 2.7 sur Centos 6. Ajouter les fichiers package_data ou data_files mentionnés ci-dessus n'a pas fonctionné. J'ai ajouté MANIFEST.IN aux fichiers. Je voulais savoir qui mettait les fichiers non-python dans l'archive, mais je ne les ai pas installés sur la machine cible via RPM.

En fin de compte, j'ai pu récupérer les fichiers dans ma solution en utilisant les "options" de setup/setuptools. Les fichiers d’option vous permettent de modifier différentes sections du fichier de spécifications à partir de setup.py. Comme suit.

from setuptools import setup


setup(
    name='theProjectName',
    version='1',
    packages=['thePackage'],
    url='',
    license='',
    author='me',
    author_email='[email protected]',
    description='',
    options={'bdist_rpm': {'install_script': 'filewithinstallcommands'}},
)

fichier - MANIFEST.in:

include license.txt

fichier - fichier avec les commandes d'installation:

mkdir -p $RPM_BUILD_ROOT/pathtoinstall/
#this line installs your python files
python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
#install license.txt into /pathtoinstall folder
install -m 700 license.txt $RPM_BUILD_ROOT/pathtoinstall/
echo /pathtoinstall/license.txt >> INSTALLED_FILES
1
Scott Bowers

Je voulais poster un commentaire sur l'une des questions mais je n'ai pas assez de réputation pour le faire>.>

Voici ce qui a fonctionné pour moi (c'est ce que j'ai fait après avoir référé à la documentation):

package_data={
    'mypkg': ['../*.txt']
},

include_package_data: False

Curieusement, la dernière ligne était également cruciale pour moi (vous pouvez également omettre cet argument de mot clé - cela fonctionne de la même manière).

Cela permet de copier tous les fichiers texte de votre répertoire principal ou racine (un niveau supérieur du paquet mypkg que vous souhaitez distribuer).

J'espère que cela t'aides!

1
rv.kvetch