Oto mój uproszczony skrypt setup.py z usuniętymi elementami niekodowymi:
#!/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'],
)
MANIFEST w:
include *.txt
include whyteboard-help/*.*
recursive-include locale *.mo
recursive-include images *.png
Kiedy uruchamiam „python setup.py install sdist”, otrzymuję ładny plik .tar.gz z folderem głównym „whyteboard-0.41”, w którym znajdują się moje lokalizacje / images / i whyteboard-help / foldery. Zawiera również mój skrypt whyteboard.py, który uruchamia mój program z pakietu źródłowego whyteboard.
Więc:
whyteboard/
├── locale/
├── images
├── whyteboard-help/
├── whyteboard/
│ ├── __init__.py
│ └── other packages etc
├── whyteboard.py
├── README
├── setup.py
└── CHANGELOG
To odzwierciedla źródło mojego programu, jest takie, jak powinno być i jest poprawne.
Jednak kiedy uruchamiam "python setup.py install", żaden z moich plików danych nie jest zapisywany - tylko pakiet źródłowy "whyteboard", a whyteboard.py jest umieszczany w /usr/local/lib/python2.6/dist-packages/ .
Idealnie, chciałbym mieć taką samą strukturę katalogów jak ta, która została wygenerowana w pliku .tar.gz, aby została utworzona w pakietach dist, ponieważ w ten sposób mój program oczekuje, że będzie szukał swoich zasobów.
Jak mogę „zainstalować”, aby utworzyć taką strukturę katalogów? O ile wiem, wydaje mi się, że ignoruje mój plik manifestu.
źródło
Odpowiedzi:
Kilka uwag oprócz odpowiedzi Neda (które dotyczą podstawowego problemu):
Distutils nie instaluje pakietów i modułów Pythona w podkatalogu na projekt w
site-packages
(lubdist-packages
w Debianie / Ubuntu): są one instalowane bezpośredniosite-packages
, jak widzieliście. Więcwhyteboard-xx
katalog zawierający w twoim sdist nie będzie istniał w ostatecznej zainstalowanej formie.Jedną z konsekwencji tego jest to, że powinieneś uważać na nazwanie swojego
data_files
w sposób, który wyjaśnia, do jakiego projektu należą, ponieważ te pliki / katalogi są instalowane bezpośrednio wsite-packages
katalogu globalnym , a nie w żadnym zawierającymwhyteboard
katalog.Czy można zamiast wprowadzać dane
package_data
zwhyteboard
pakietu (co oznacza, że musi żyją wewnątrz tego pakietu, czyli do następnego__init__.py
), a to nie jest problem.Wreszcie, nie ma większego sensu posiadanie zarówno
whyteboard.py
modułu, jakpy_modules
iwhyteboard/__init__.py
pakietupackages
. Oba wykluczają się wzajemnie, a jeśli masz oba,whyteboard.py
moduł zostanie zignorowany podczas importu na rzecz pakietu o tej samej nazwie.Jeśli
whyteboard.py
jest to tylko skrypt i nie jest przeznaczony do zaimportowania, należy użyć do tego opcji skryptów i usunąć go zpy_modules
.źródło
MANIFEST.in
informuje Distutils, jakie pliki należy dołączyć do dystrybucji źródłowej, ale nie wpływa bezpośrednio na to, które pliki są instalowane. W tym celu należy dołączyć odpowiednie pliki dosetup.py
pliku, zazwyczaj jako dane pakietu lub jako pliki dodatkowe .źródło
Nie mogłem dowiedzieć się, dlaczego mój
MANIFEST.in
plik jest ignorowany, kiedy uruchomiłempython setup.py install
- okazuje się, żeinclude_package_data=True
rozwiązuje problem. Tapackage_data
opcja nie jest w rzeczywistości wymagana.źródło
include_package_data=True
nie ma wartości domyślnej?Powinieneś użyć setuptools:
#!/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'], )
W rzeczywistości nie jest to użycie pliku MANIFESTU do wykonania zadania, ale zawiera wszystkie potrzebne pliki.
źródło
package_data
słowniku pojawiają się we właściwym miejscu dopiero po dodaniuinclude_package_data=Tru
.Uruchamiając Pythona 2.6.1 w systemie Mac OSX, nie miałem absolutnie żadnego szczęścia, z wyjątkiem użycia parametru data_files w setup.py. Wszystko z MANIFEST.in po prostu skutkowało dołączeniem plików do pakietu dist, ale nigdy ich nie instalował. Sprawdziłem kilka innych pakietów i rzeczywiście używali one data_files do określenia dodatkowych plików.
Stworzyłem krótką funkcję, która pomaga wyliczyć wszystkie pliki z drzewa katalogów w
(katalog_docelowy, [lista plików]) format oczekiwany przez 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
Teraz mogę po prostu zadzwonić do tego w mojej rozmowie konfiguracyjnej:
setup(... data_files = gen_data_files("docs", "lib") ...
I wszystko w tych drzewach zostanie zainstalowane.
źródło
Minimalny opublikowany przykład do uruchomienia
Kluczowy
MANIFEST.in
wniosek : działał tylko dla mnie,package_data
nie.Testowano na Ubuntu 19.10, Python 3.7.5, wheel == 0.32.3, setuptools == 41.1.0, twine == 3.1.1.
Jak użytkownicy końcowi korzystają z pakietu z https://pypi.org/project/python-sample-package-with-data/ :
python3 -m pip install --user python-sample-package-with-data python-sample-package-with-data
Oczekiwany wynik:
Jak opiekunowie to publikują:
# 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
Rzeczywiste pliki:
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-sample-package-with-data
#!/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'], )
Bibliografia:
źródło