如何使用 setuptools 和 pkg_ressources 获取安装目录
How to get installation directory using setuptools and pkg_ressources
我正在使用 setuptools 和 pkg_resources 开发一个包 P
,
软件包在安装后需要下载一些二进制文件并将它们放在专用目录中 (P/bin/
)。
我正在尝试使用 pkg_ressources.resource_filename
获取绝对目录路径。 (为了与 virtualenv 一起工作)
在使用 python setup.py install
安装期间,pkg_ressources.resource_filename 不会 return
像 /home/user/tests/venv/lib/python3.4/site-package/P/bin/
这样的路径,但是实际模块的路径,像 /home/user/projects/P/P/bin/
.
这是个问题,因为我需要安装目录(在 virtualenv 中),而不是我的个人项目目录(我开发模块的地方)。
如果我尝试通过 pypi,使用 pip install module
,由 pkg_ressources.resource_filename
编辑的目录 return 是一个类似 /tmp/pip-build-xxxxxxx/P/bin/
的临时文件,这又不是应该放置二进制文件的地方。
这是我的 setup.py:
from setuptools import setup
import os
from setuptools.command.install import install as _install
from pkg_resources import resource_filename
def post_install():
"""Get the binaries online, and give them the execution permission"""
package_dir_bin = resource_filename('P', 'bin') # should be /home/user/tests/venv/lib/python3.4/site-package/P/bin/
# package_dir_bin = resource_filename(Requirement.parse('P'), 'bin') # leads to same results
put_binaries_in(package_dir_bin)
os.system('chmod +x ' + package_dir_bin + '*')
class install(_install):
# see
def run(self):
"""Call superclass run method, then downloads the binaries"""
_install.run(self)
self.execute(post_install, args=[], msg=post_install.__doc__)
setup(
cmdclass={'install': install},
name = 'P',
# many metadata
package_dir = { 'P' : 'P'},
package_data = {
'P' : ['bin/*.txt'] # there is an empty txt file in bin directory
},
)
安装时有没有标准的获取安装目录的方法,跨平台兼容python2、3?
如果没有,我该怎么办?
解决方法是使用 site
包而不是 pkg_resources
,后者似乎不是为在安装期间访问资源而设计的。
安装时检测安装目录的功能如下:
import os, sys, site
def binaries_directory():
"""Return the installation directory, or None"""
if '--user' in sys.argv:
paths = (site.getusersitepackages(),)
else:
py_version = '%s.%s' % (sys.version_info[0], sys.version_info[1])
paths = (s % (py_version) for s in (
sys.prefix + '/lib/python%s/dist-packages/',
sys.prefix + '/lib/python%s/site-packages/',
sys.prefix + '/local/lib/python%s/dist-packages/',
sys.prefix + '/local/lib/python%s/site-packages/',
'/Library/Python/%s/site-packages/',
))
for path in paths:
if os.path.exists(path):
return path
print('no installation path found', file=sys.stderr)
return None
如果使用 virtualenv 安装,此解决方案不 Python 2.7 兼容,因为 known bug about the module site
. (see related )
最简单的解决方案是遵循 this answer 的第一个片段。
基本上,您只需将 setup
调用保存在一个变量中,然后查看其属性。有几个方便的
from setuptools import setup
s = setup(
# ...
)
print(s.command_obj['install'].__dir__())
# [..., 'install_base', 'install_lib', 'install_script', ...]
我展示的分别是/usr
、/usr/lib/pythonX.Y/site-packages
和/usr/bin
的等价物。但还有其他可能有用的属性。这些都是绝对路径。
我正在使用 setuptools 和 pkg_resources 开发一个包 P
,
软件包在安装后需要下载一些二进制文件并将它们放在专用目录中 (P/bin/
)。
我正在尝试使用 pkg_ressources.resource_filename
获取绝对目录路径。 (为了与 virtualenv 一起工作)
在使用 python setup.py install
安装期间,pkg_ressources.resource_filename 不会 return
像 /home/user/tests/venv/lib/python3.4/site-package/P/bin/
这样的路径,但是实际模块的路径,像 /home/user/projects/P/P/bin/
.
这是个问题,因为我需要安装目录(在 virtualenv 中),而不是我的个人项目目录(我开发模块的地方)。
如果我尝试通过 pypi,使用 pip install module
,由 pkg_ressources.resource_filename
编辑的目录 return 是一个类似 /tmp/pip-build-xxxxxxx/P/bin/
的临时文件,这又不是应该放置二进制文件的地方。
这是我的 setup.py:
from setuptools import setup
import os
from setuptools.command.install import install as _install
from pkg_resources import resource_filename
def post_install():
"""Get the binaries online, and give them the execution permission"""
package_dir_bin = resource_filename('P', 'bin') # should be /home/user/tests/venv/lib/python3.4/site-package/P/bin/
# package_dir_bin = resource_filename(Requirement.parse('P'), 'bin') # leads to same results
put_binaries_in(package_dir_bin)
os.system('chmod +x ' + package_dir_bin + '*')
class install(_install):
# see
def run(self):
"""Call superclass run method, then downloads the binaries"""
_install.run(self)
self.execute(post_install, args=[], msg=post_install.__doc__)
setup(
cmdclass={'install': install},
name = 'P',
# many metadata
package_dir = { 'P' : 'P'},
package_data = {
'P' : ['bin/*.txt'] # there is an empty txt file in bin directory
},
)
安装时有没有标准的获取安装目录的方法,跨平台兼容python2、3? 如果没有,我该怎么办?
解决方法是使用 site
包而不是 pkg_resources
,后者似乎不是为在安装期间访问资源而设计的。
安装时检测安装目录的功能如下:
import os, sys, site
def binaries_directory():
"""Return the installation directory, or None"""
if '--user' in sys.argv:
paths = (site.getusersitepackages(),)
else:
py_version = '%s.%s' % (sys.version_info[0], sys.version_info[1])
paths = (s % (py_version) for s in (
sys.prefix + '/lib/python%s/dist-packages/',
sys.prefix + '/lib/python%s/site-packages/',
sys.prefix + '/local/lib/python%s/dist-packages/',
sys.prefix + '/local/lib/python%s/site-packages/',
'/Library/Python/%s/site-packages/',
))
for path in paths:
if os.path.exists(path):
return path
print('no installation path found', file=sys.stderr)
return None
如果使用 virtualenv 安装,此解决方案不 Python 2.7 兼容,因为 known bug about the module site
. (see related
最简单的解决方案是遵循 this answer 的第一个片段。
基本上,您只需将 setup
调用保存在一个变量中,然后查看其属性。有几个方便的
from setuptools import setup
s = setup(
# ...
)
print(s.command_obj['install'].__dir__())
# [..., 'install_base', 'install_lib', 'install_script', ...]
我展示的分别是/usr
、/usr/lib/pythonX.Y/site-packages
和/usr/bin
的等价物。但还有其他可能有用的属性。这些都是绝对路径。