¿Cómo agregar datos de paquetes de forma recursiva en Python setup.py?
distutils (4)
- Utilice Setuptools lugar de distutils.
- Utilice archivos de datos en lugar de datos de paquetes. Estos no requieren
__init__.py
. Genere las listas de archivos y directorios utilizando el código estándar de Python, en lugar de escribirlo literalmente:
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()
Tengo una nueva biblioteca que tiene que incluir muchas subcarpetas de archivos de datos pequeños, y estoy tratando de agregarlos como datos de paquetes. Imagina que tengo mi biblioteca como tal:
library
- foo.py
- bar.py
data
subfolderA
subfolderA1
subfolderA2
subfolderB
subfolderB1
...
Quiero agregar todos los datos en todas las subcarpetas a través de setup.py, pero parece que tengo que ir manualmente a cada subcarpeta (hay alrededor de 100) y agregar un archivo .py de inicio . Además, setup.py encontrará estos archivos de forma recursiva, o debo agregar manualmente todos estos en setup.py como:
package_data={
''mypackage.data.folderA'': [''*''],
''mypackage.data.folderA.subfolderA1'': [''*''],
''mypackage.data.folderA.subfolderA2'': [''*'']
},
Puedo hacer esto con un guión, pero parece un dolor súper. ¿Cómo puedo lograr esto en setup.py?
PD: la jerarquía de estas carpetas es importante porque se trata de una base de datos de archivos de material y queremos que se conserve el árbol de archivos cuando los presentemos en una GUI para el usuario, por lo que sería ventajoso mantener esta estructura de archivos intacta. .
El problema con la respuesta glob
es que solo hace mucho. Es decir, no es totalmente recursivo. El problema con la respuesta copy_tree
es que los archivos que se copian se quedarán en una desinstalación.
La solución adecuada es una recursiva que le permitirá establecer el parámetro package_data
en la llamada de configuración.
He escrito este pequeño método para hacer esto:
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},
....
)
Notará que cuando haga una pip uninstall package_name
paquete pip uninstall package_name
, verá que se enumeran sus archivos adicionales (como se rastrea con el paquete).
Puedo sugerir un pequeño código para agregar archivos de datos en la configuración ():
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,
)
Si no tiene ningún problema para ensuciar su código setup.py, use distutils.dir_util.copy_tree
.
Todo el problema es cómo excluir archivos de él.
Heres algunos el código:
import os.path
from distutils import dir_util
from distutils import sysconfig
from distutils.core import setup
__packagename__ = ''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)
Algunas notas :
setup(...)
pero use copy_tree()
para extender el directorio que desea a la ruta de instalación.