Я упаковал некоторый код python с setuptools
. Код использует файл данных, но после установки пакета с помощью pip
код не может найти файл данных. Что я делаю неправильно?
Ниже представлена структура файла и содержимое файла. Файлы можно найти здесь. Код python setup.py
пытается использовать файл данных mesa/a.txt
. Код работает нормально, если я не упакую и не пишу его.
|
|- tm/
| |- __init__.py
| |- test2.py
|- mesa/
| |- __init__.py
| |- a.txt
|- MANIFEST.in
|- setup.py
MANIFEST.in
:
include mesa/a.txt
setup.py
:
from setuptools import setup
setup(name='bobab',
version='0.1',
py_modules=['tm.test2'],
author_email='[email protected]',
package_data = {
'tm': ['mesa/a.txt']
},
)
'mesa/a.txt
:
hello world!
tm/test2.py
:
import os
def main():
print 'hi'
print open(os.path.join('..', 'mesa', 'a.txt'), 'r').read() # print file content
if __name__ == "__main__":
main()
Я использую команду python setup.py sdist
для создания пакета. Для установки пакета я использую следующую команду:
unzip bobab-0.1.zip
cd bobab-0.1
python setup.py install
Пакет не видит файл данных mesa/a.txt
, как показано в сообщении об ошибке ниже:
Python 2.7.12 (default, Dec 4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
>>> import tm.test2
>>> tm.test2.main()
hi
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "tm/test2.py", line 5, in main
print open(os.path.join('..', 'mesa', 'a.txt'), 'r').read()
IOError: [Errno 2] No such file or directory: '../mesa/a.txt'
Я использую Python 2.7.
Ниже приведены журналы для упаковки и установки. Интересно, что в журнале упаковки упоминается, что файл данных mesa/a.txt
был добавлен в пакет, но в журнале установки не упоминается его наличие.
Журнал упаковки:
C:\Users\Franck\Documents\GitHub\misc\src\test>python setu
p.py sdist
running sdist
running egg_info
creating bobab.egg-info
writing bobab.egg-info\PKG-INFO
writing top-level names to bobab.egg-info\top_level.txt
writing dependency_links to bobab.egg-info\dependency_links.txt
writing pbr to bobab.egg-info\pbr.json
writing manifest file 'bobab.egg-info\SOURCES.txt'
reading manifest file 'bobab.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'bobab.egg-info\SOURCES.txt'
warning: sdist: standard file not found: should have one of README, README.rst,
README.txt
running check
warning: check: missing required meta-data: url
warning: check: missing meta-data: either (author and author_email) or (maintain
er and maintainer_email) must be supplied
creating bobab-0.1
creating bobab-0.1\bobab.egg-info
creating bobab-0.1\mesa
creating bobab-0.1\tm
copying files to bobab-0.1...
copying MANIFEST.in -> bobab-0.1
copying setup.py -> bobab-0.1
copying bobab.egg-info\PKG-INFO -> bobab-0.1\bobab.egg-info
copying bobab.egg-info\SOURCES.txt -> bobab-0.1\bobab.egg-info
copying bobab.egg-info\dependency_links.txt -> bobab-0.1\bobab.egg-info
copying bobab.egg-info\pbr.json -> bobab-0.1\bobab.egg-info
copying bobab.egg-info\top_level.txt -> bobab-0.1\bobab.egg-info
copying mesa\a.txt -> bobab-0.1\mesa
copying tm\__init__.py -> bobab-0.1\tm
copying tm\test2.py -> bobab-0.1\tm
Writing bobab-0.1\setup.cfg
creating 'dist\bobab-0.1.zip' and adding 'bobab-0.1' to it
adding 'bobab-0.1\MANIFEST.in'
adding 'bobab-0.1\PKG-INFO'
adding 'bobab-0.1\setup.cfg'
adding 'bobab-0.1\setup.py'
adding 'bobab-0.1\bobab.egg-info\dependency_links.txt'
adding 'bobab-0.1\bobab.egg-info\pbr.json'
adding 'bobab-0.1\bobab.egg-info\PKG-INFO'
adding 'bobab-0.1\bobab.egg-info\SOURCES.txt'
adding 'bobab-0.1\bobab.egg-info\top_level.txt'
adding 'bobab-0.1\mesa\a.txt'
adding 'bobab-0.1\tm\test2.py'
adding 'bobab-0.1\tm\__init__.py'
removing 'bobab-0.1' (and everything under it)
Журнал установки:
(sedona) dernonco@ilcompn0:/mnt/ilcompn0d1/user/dernonco/temp/bobab-0.1$ python setup.py install
running install
running bdist_egg
running egg_info
writing bobab.egg-info/PKG-INFO
writing top-level names to bobab.egg-info/top_level.txt
writing dependency_links to bobab.egg-info/dependency_links.txt
reading manifest file 'bobab.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'bobab.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/tm
copying tm/__init__.py -> build/lib.linux-x86_64-2.7/tm
copying tm/test2.py -> build/lib.linux-x86_64-2.7/tm
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/tm
copying build/lib.linux-x86_64-2.7/tm/__init__.py -> build/bdist.linux-x86_64/egg/tm
copying build/lib.linux-x86_64-2.7/tm/test2.py -> build/bdist.linux-x86_64/egg/tm
byte-compiling build/bdist.linux-x86_64/egg/tm/__init__.py to __init__.pyc
byte-compiling build/bdist.linux-x86_64/egg/tm/test2.py to test2.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying bobab.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying bobab.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying bobab.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying bobab.egg-info/pbr.json -> build/bdist.linux-x86_64/egg/EGG-INFO
copying bobab.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/bobab-0.1-py2.7.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing bobab-0.1-py2.7.egg
Copying bobab-0.1-py2.7.egg to /mnt/ilcompn0d1/user/dernonco/pyenv/sedona/lib/python2.7/site-packages
Adding bobab 0.1 to easy-install.pth file
Installed /mnt/ilcompn0d1/user/dernonco/pyenv/sedona/lib/python2.7/site-packages/bobab-0.1-py2.7.egg
Processing dependencies for bobab==0.1
Finished processing dependencies for bobab==0.1
Необходимо адаптировать несколько вещей:
MANIFEST.in
будет использоваться только тогда, когда вы упаковываете исходные диски, поэтому python setup.py sdist
будет включать mesa/a.txt
даже с вашей текущей настройкой. Это не относится к бинарным дистрибутивам, ни bdist_egg
ни bdist_wheel
не читают MANIFEST.in
. package_data
обычно используется для файлов, отличных от python, размещенных внутри пакета, но mesa
не помещается внутри tm
dir, поэтому относительный путь неверен. Вы можете обойти это, установив пунктирный путь:
package_data={'tm': ['../mesa/a.txt']}
Однако, если mesa
является частью пакета tm
, имеет смысл поставить его там, где он принадлежит.
os.path.join('..', 'mesa', 'a.txt')
разрешает путь относительно текущего каталога, поэтому эта строка может найти файл только в том случае, если вы находитесь в каталоге tm
- после установки пакет, вряд ли это произойдет. Вам необходимо правильно разрешить путь, например, против атрибута __file__
:
os.path.join(os.path.dirname(__file__), '..', 'mesa', 'a.txt')
Дополнительные примечания:
py_modules=['tm.test2']
packages=['tm']
и не нужно заботиться об обновлении py_modules
при добавлении дополнительных модулей в пакет tm
. setuptools
предлагает модуль с именем pkg_resources
который предлагает полезные функции управления для файлов, отличных от python, установленных через package_data
. Например,
open(os.path.join('..', 'mesa', 'a.txt'), 'r').read()
можно заменить на
pkg_resources.resource_string('tm', '../mesa/a.txt')
Обратитесь к разделу API ResourceManager в документации setuptools
если вы хотите узнать больше.
когда я работаю с файлами, вызывающими другие файлы в разных папках, я использую этот код в верхней части файла.
from os.path import dirname, join, abspath
sys.path.insert(0, abspath(join(dirname(__file__), '..')))
а потом
from file_name import value
setuptools
.