7

我正在P使用 setuptools 和 pkg_resources 开发一个包,该包在安装后需要下载一些二进制文件并将它们放在专用目录 ( P/bin/) 中。

我正在尝试使用pkg_ressources.resource_filename获取绝对目录路径。(为了使用 virtualenv)

在使用 安装期间python setup.py install,pkg_ressources.resource_filename 不会返回类似 的路径/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是一个临时文件,例如/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 http://stackoverflow.com/a/18159969

    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
    },
)

安装过程中是否有标准的方式获取安装目录,跨平台兼容python 2和3?如果没有,我该怎么办?

4

2 回答 2

2

一种解决方法是使用该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 不兼容,因为关于模块的已知错误site。(参见相关的 SO

于 2016-03-24T16:25:11.270 回答
0

最简单的解决方案是遵循此答案的第一个片段。

本质上,您只需将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

于 2021-11-30T18:30:16.480 回答