J'ai une nouvelle bibliothèque qui doit inclure beaucoup de sous-dossiers de petits fichiers de données, et j'essaie de les ajouter en tant que données de package. Imaginez que j'ai ma bibliothèque comme ça:
library
- foo.py
- bar.py
data
subfolderA
subfolderA1
subfolderA2
subfolderB
subfolderB1
...
Je veux ajouter toutes les données dans tous les sous-dossiers via setup.py, mais il semble que je dois manuellement aller dans chaque sous-dossier (il y en a environ 100) et ajouter un init. fichier py. De plus, setup.py trouvera-t-il ces fichiers de manière récursive, ou dois-je les ajouter manuellement dans setup.py comme:
package_data={
'mypackage.data.folderA': ['*'],
'mypackage.data.folderA.subfolderA1': ['*'],
'mypackage.data.folderA.subfolderA2': ['*']
},
Je peux le faire avec un script, mais cela semble être une super douleur. Comment puis-je y parvenir dans setup.py?
PS, la hiérarchie de ces dossiers est importante car il s'agit d'une base de données de fichiers de matériaux et nous voulons que l'arborescence de fichiers soit préservée lorsque nous les présentons dans une interface graphique à l'utilisateur, il serait donc à notre avantage de garder cette structure de fichiers intacte .
__init__.py
.Générez les listes de fichiers et de répertoires en utilisant le code standard Python, au lieu de l'écrire littéralement:
data_files = []
directories = glob.glob('data/subfolder?/subfolder??/')
for directory in directories:
files = glob.glob(directory+'*')
data_files.append((directory, files))
# then pass data_files to setup()
Le problème avec la réponse glob
est qu'elle ne fait pas grand chose. C'est à dire. ce n'est pas entièrement récursif. Le problème avec le copy_tree
la réponse est que les fichiers copiés seront laissés pour compte lors d'une désinstallation.
La bonne solution est une solution récursive qui vous permettra de définir le package_data
paramètre dans l'appel de configuration.
J'ai écrit cette petite méthode pour ce faire:
import os
def package_files(directory):
paths = []
for (path, directories, filenames) in os.walk(directory):
for filename in filenames:
paths.append(os.path.join('..', path, filename))
return paths
extra_files = package_files('path_to/extra_files_dir')
setup(
...
packages = ['package_name'],
package_data={'': extra_files},
....
)
Vous remarquerez que lorsque vous effectuez une pip uninstall package_name
, que vous verrez vos fichiers supplémentaires répertoriés (comme suivis avec le package).
Si vous n'avez aucun problème à obtenir votre code setup.py sale, utilisez distutils.dir_util.copy_tree
.
Tout le problème est de savoir comment en exclure des fichiers.
Voici le code:
import os.path
from distutils import dir_util
from distutils import sysconfig
from distutils.core import setup
__package= 'x'
setup(
name = __packagename__,
packages = [__packagename__],
)
destination_path = sysconfig.get_python_lib()
package_path = os.path.join(destination_path, __packagename__)
dir_util.copy_tree(__packagename__, package_path, update=1, preserve_mode=0)
Quelques notes :
setup(...)
mais utilisez copy_tree()
pour étendre le répertoire souhaité dans le chemin d'installation.Utilisez glob pour sélectionner tous les sous-dossiers de votre setup.py
...
packages=['your_package'],
package_data={'your_package': ['data/**/*']},
...
Je peux suggérer un petit code pour ajouter des fichiers de données dans setup ():
data_files = []
start_point = os.path.join(__pkgname__, 'static')
for root, dirs, files in os.walk(start_point):
root_files = [os.path.join(root, i) for i in files]
data_files.append((root, root_files))
start_point = os.path.join(__pkgname__, 'templates')
for root, dirs, files in os.walk(start_point):
root_files = [os.path.join(root, i) for i in files]
data_files.append((root, root_files))
setup(
name = __pkgname__,
description = __description__,
version = __version__,
long_description = README,
...
data_files = data_files,
)