Aquí está mi script setup.py simplificado con cosas que no son de código eliminadas:
#!/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'],
)
MANIFIESTO en:
include *.txt
include whyteboard-help/*.*
recursive-include locale *.mo
recursive-include images *.png
Cuando ejecuto "python setup.py install sdist" obtengo un bonito .tar.gz con una carpeta raíz "whyteboard-0.41", con mis carpetas locale / images / y whyteboard-help / dentro. Esto también tiene mi script whyteboard.py que inicia mi programa desde dentro del paquete fuente de whyteboard.
Entonces:
whyteboard/
├── locale/
├── images
├── whyteboard-help/
├── whyteboard/
│ ├── __init__.py
│ └── other packages etc
├── whyteboard.py
├── README
├── setup.py
└── CHANGELOG
Esto refleja la fuente de mi programa, así es como debería ser todo y es correcto.
Sin embargo, cuando ejecuto "python setup.py install", ninguno de mis archivos de datos está escrito, solo el paquete fuente "whyteboard" y el whyteboard.py se coloca en /usr/local/lib/python2.6/dist-packages/ .
Idealmente, me gustaría que se creara la misma estructura de directorios que la que se generó en el archivo .tar.gz en dist-packages, ya que así es como mi programa espera buscar sus recursos.
¿Cómo puedo "instalar" para crear esta estructura de directorio? Parece estar ignorando mi archivo de manifiesto, por lo que puedo decir.
fuente
Respuestas:
Algunas notas además de la respuesta de Ned (que aborda el problema central):
Distutils no instala paquetes y módulos de Python dentro de un subdirectorio por proyecto dentro
site-packages
(odist-packages
en Debian / Ubuntu): se instalan directamente ensite-packages
, como ha visto. Por lo tanto, elwhyteboard-xx
directorio que lo contiene en su sdist no existirá en el formulario final instalado.Una implicación de esto es que debe tener cuidado de nombrar su
data_files
de una manera que aclare a qué proyecto pertenecen, porque esos archivos / directorios se instalan directamente en elsite-packages
directorio global , no dentro de ningúnwhyteboard
directorio que los contenga .O, en su lugar, podría crear sus datos
package_data
delwhyteboard
paquete (lo que significa que debe vivir dentro de ese paquete, es decir, al lado__init__.py
), y entonces esto no es un problema.Por último, no tiene mucho sentido tener tanto un
whyteboard.py
módulopy_modules
como unwhyteboard/__init__.py
paquetepackages
. Los dos son mutuamente excluyentes, y si tiene ambos, elwhyteboard.py
módulo será ignorado por las importaciones a favor del paquete del mismo nombre.Si
whyteboard.py
es solo un script y no está destinado a ser importado, entonces debería usar la opción de scripts y eliminarlopy_modules
.fuente
MANIFEST.in
le dice a Distutils qué archivos incluir en la distribución de origen, pero no afecta directamente qué archivos están instalados. Para eso, debe incluir los archivos apropiados en elsetup.py
archivo, generalmente como datos de paquete o como archivos adicionales .fuente
No pude averiguar por qué
MANIFEST.in
se ignoraba mi archivo cuando lo ejecutépython setup.py install
; resulta queinclude_package_data=True
resuelve el problema. Lapackage_data
opción no es realmente necesaria.fuente
include_package_data=True
no es el valor predeterminado?Deberías usar herramientas de configuración:
#!/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'], )
En realidad, esto no usa el archivo MANIFEST para hacer el trabajo, pero incluye todos los archivos necesarios.
fuente
package_data
diccionario aparecen en el lugar correcto solo después de que los agreguéinclude_package_data=Tru
.Ejecución de Python 2.6.1 en Mac OS X, no tenía absolutamente ninguna suerte, excepto mediante el uso de las data_files parámetro en setup.py. Todo con MANIFEST.in simplemente resultó en archivos incluidos en el paquete dist, pero nunca instalados. Revisé algunos otros paquetes y de hecho estaban usando data_files para especificar archivos adicionales.
Creé una función corta para ayudar a enumerar todos los archivos de un árbol de directorios en el
(target_dir, [lista de archivos]) formato que espera data_files:
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
Ahora puedo llamar a esto dentro de mi llamada de configuración:
setup(... data_files = gen_data_files("docs", "lib") ...
Y todo en esos árboles se instala.
fuente
Ejemplo ejecutable mínimo publicado
Conclusión clave: solo
MANIFEST.in
funcionó para mí,package_data
no lo hizo.Probado en Ubuntu 19.10, Python 3.7.5, wheel == 0.32.3, setuptools == 41.1.0, twine == 3.1.1.
Cómo los usuarios finales usan el paquete de https://pypi.org/project/python-sample-package-with-data/ :
python3 -m pip install --user python-sample-package-with-data python-sample-package-with-data
Rendimiento esperado:
Cómo lo publican los mantenedores:
# 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
Los archivos reales:
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-muestra-paquete-con-datos
#!/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
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='[email protected]', packages=find_packages(), include_package_data=True, scripts=['python-sample-package-with-data'], )
Bibliografía:
fuente