Как получить каталог установки с помощью setuptools и pkg_ressources

Я работаю над пакетом 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? Если нет, то что мне делать?


person aluriak    schedule 23.03.2016    source источник


Ответы (1)


Обходной путь — использовать пакет 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

Это решение не совместимо с Python 2.7 в случае установки с использованием virtualenv из-за известной ошибки о модуле site. (см. соответствующий SO)

person aluriak    schedule 24.03.2016
comment
Я, кажется, получаю ложные срабатывания с этим. Я не знаю, почему они оба существуют, но у меня, кажется, есть как '/usr/lib/python%s/dist-packages/', так и /usr/local/lib/python%s/dist-packages/'. Я хочу автоматически найти последний, однако ваш скрипт сначала находит первый, поэтому я получаю неправильный путь. Нет ли надежного способа найти путь, который на самом деле будет использоваться самим Python? Эта функция как бы просто гадает и надеется на лучшее. - person Ben Farmer; 20.11.2018
comment
Существует много определений обходного решения, одно из них может быть тем, которое вы предлагаете: просто гадайте и надейтесь на лучшее. В вашем случае вы можете изменить порядок во внутреннем списке путей, который, очевидно, зависит от целевой ОС. - person aluriak; 21.11.2018
comment
Да, это, к сожалению, слишком хитроумно для моих нужд. Я прибегну к решению, в котором эти вещи находятся во время выполнения. Довольно странно, что эту информацию нельзя найти стандартным способом... - person Ben Farmer; 21.11.2018