Независимая от ОС установка скриптов с помощью setuptools

#python #python-3.x #linux #windows #setuptools

#python #python-3.x #linux #Windows #setuptools

Вопрос:

В настоящее время я пытаюсь решить проблему, связанную с установкой скриптов в проекте python setuptools , распространяемом с. Один из сценариев

 #! /usr/bin/env python3
"""Terminal querying utility."""

from homeinfotools.query.main import main


if __name__ == '__main__':
    main()
  

находится по адресу <projectdir>/scripts/sysquery .
Сценарий установки находится по адресу <projectdir>/setup.py и содержит следующее:

 #! /usr/bin/env python3
"""Installation script."""

from pathlib import Path
from setuptools import setup


setup(
    name='homeinfotools',
    version_format='{tag}',
    author='HOMEINFO - Digitale Informationssysteme GmbH',
    author_email='REDACTED',
    maintainer='Richard Neumann',
    maintainer_email='REDACTED',
    python_requires='>=3.8',
    install_requires=['setuptools-git-version', 'requests'],
    packages=[
        'homeinfotools',
        'homeinfotools.query',
        'homeinfotools.rpc',
        'homeinfotools.vpn'
    ],
    scripts=[str(path) for path in Path('scripts').iterdir()],
    license='GPLv3',
    description='HOMEINFO Digital Signage Linux configurator.'
)
  

Теперь я столкнулся с проблемой, что установка через

 python setup.py install --optimize=1
  

имеет различное поведение в системах Windows и Linux.
Скрипты устанавливаются как в Windows, так и в Linux по правильным путям.

  • Windows: <pythondir>Scriptssysquery
  • Linux: <prefix>/bin/sysquery

К сожалению, я не могу вызывать скрипты под Windows таким образом. Выдает ошибку «Команда не найдена» (немецкие языки):

 C:UsersHOMEINFO GmbH>sysquery
Der Befehl "sysquery" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

C:UsersHOMEINFO GmbH>
  

Содержимое скрипта после установки в Windows:

 #!"C:Program FilesPython39python.exe"
# EASY-INSTALL-SCRIPT: 'homeinfotools==0.0.0','sysquery'
__requires__ = 'homeinfotools==0.0.0'
__import__('pkg_resources').run_script('homeinfotools==0.0.0', 'sysquery')
  

Это PATH не проблема, поскольку я могу запускать другие скрипты в том же каталоге.
Я свел ошибку к тому факту, что Windows, по-видимому, нуждается в .py суффиксе для скриптов, чтобы вызывать их.
Если я соответствующим образом изменю имена скриптов, я получу два скрипта в Scripts каталоге:

sysqery

 #!"C:Program FilesPython39python.exe"
# EASY-INSTALL-SCRIPT: 'homeinfotools==0.0.0','sysquery'
__requires__ = 'homeinfotools==0.0.0'
__import__('pkg_resources').run_script('homeinfotools==0.0.0', 'sysquery')
  

sysquery.py

 #!"C:Program FilesPython39python.exe"
# EASY-INSTALL-SCRIPT: 'homeinfotools==1.0.5','sysquery.py'
__requires__ = 'homeinfotools==1.0.5'
__import__('pkg_resources').run_script('homeinfotools==1.0.5', 'sysquery.py')
  

В этом случае я могу запустить команду sysquery из командной строки просто отлично.

Однако это оставляет проблему в том, что в системах Linux скрипты также будут установлены с .py суффиксом, что нежелательно.

Итак, я придумал решение для конкретной ОС setup.py , которое работает, но уродливо:

 #! /usr/bin/env python3
"""Installation script."""

from os import name
from pathlib import Path
from setuptools import setup


SCRIPTS = Path('scripts').iterdir()

if name == 'nt':
    SCRIPTS = [path.rename(f'{path}.py') for path in SCRIPTS]


setup(
    name='homeinfotools',
    version_format='{tag}',
    author='HOMEINFO - Digitale Informationssysteme GmbH',
    author_email='REDACTED',
    maintainer='Richard Neumann',
    maintainer_email='REDACTED',
    python_requires='>=3.8',
    install_requires=['setuptools-git-version', 'requests'],
    packages=[
        'homeinfotools',
        'homeinfotools.query',
        'homeinfotools.rpc',
        'homeinfotools.vpn'
    ],
    scripts=[str(path) for path in SCRIPTS],
    license='GPLv3',
    description='HOMEINFO Digital Signage Linux configurator.'
)
  

Краткие сведения

Возможно ли установить скрипты, не зависящие от ОС, без суффиксов и без необходимости переименовывать их в контексте ОС?

Комментарии:

1. «.PY» можно добавить в переменную среды «PATHEXT» в Windows, чтобы позволить оболочкам работать sysquery без расширения. Но прямой запуск скрипта .py ненадежен. Это зависит от действия по умолчанию (обычно «открытого»), связанного с файлами .py. В идеале, сценарии .py всегда должны быть связаны с py.exe лаунчер, который выполняет скрипт в соответствии со своей строкой shebang, если таковая имеется, либо с установленной версией PY_PYTHON , либо с самой высокой установленной версией. На практике пользователи часто устанавливают действие по умолчанию для скриптов .py, чтобы открывать их в редакторе или IDE.

2. Другая проблема заключается в том, что открытие файлов на основе зарегистрированных ассоциаций файлов зависит от их выполнения через WinAPI ShellExecuteExW . WinAPI CreateProcessW может выполнять только двоичные файлы PE или пакетные скрипты .BAT и .CMD через ComSpec оболочку. Оболочки командной строки, такие как CMD, сначала попытаются CreateProcessW и вернутся ShellExecuteExW . Но во многих контекстах (например, в Python subprocess.Popen ) выполняется только CreateProcessW попытка, и в этом случае скрипт .py не может быть выполнен напрямую (т. Е. Открыт с зарегистрированным действием по умолчанию).

3. setuptools решает эти проблемы в Windows, устанавливая скрипты точки входа в качестве исполняемых файлов запуска (например, «sysquery.exe «), которые включают полный путь к python [w].exe и встроенный небольшой скрипт, который вызывает функцию entrypoint . Например, pip команда в Windows представляет собой «pip.exe «сценарий точки входа. Итак, ваш лучший вариант — преобразовать ваши скрипты для использования точек входа setuptools вместо устаревших скриптов.