사용자가 명령을 실행할 수 있도록 설치 후 Python 스크립트 파일을 setuptools setup.py 파일의 일부로 지정할 수 있습니까?
python setup.py install
로컬 프로젝트 파일 아카이브 또는
pip install <name>
PyPI 프로젝트의 경우 표준 setuptools 설치가 완료되면 스크립트가 실행됩니까? 단일 Python 스크립트 파일로 코딩 할 수있는 설치 후 작업을 수행하려고합니다 (예 : 사용자에게 사용자 지정 설치 후 메시지 전달, 다른 원격 소스 저장소에서 추가 데이터 파일 가져 오기).
나는 몇 년 전에 주제를 다루는 이 SO 답변을 보았고 당시의 합의는 install 하위 명령을 만들어야한다는 것입니다. 이 경우에도 사용자가 스크립트를 실행하기 위해 두 번째 명령을 입력 할 필요가 없도록 누군가가이를 수행하는 방법에 대한 예제를 제공 할 수 있습니까?
답변
참고 : 아래 솔루션은 소스 배포 zip 또는 tarball을 설치하거나 소스 트리에서 편집 가능한 모드로 설치할 때만 작동합니다. 그것은 것입니다 하지 바이너리 휠에서 설치할 때 (작동 .whl
)
이 솔루션은 더 투명합니다.
에 몇 가지를 추가 setup.py
하고 추가 파일이 필요하지 않습니다.
또한 두 가지 다른 설치 후 작업을 고려해야합니다. 하나는 개발 / 편집 가능 모드 용이고 다른 하나는 설치 모드 용입니다.
설치 후 스크립트를 포함하는 다음 두 클래스를 다음에 추가하십시오 setup.py
.
from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install
class PostDevelopCommand(develop):
"""Post-installation for development mode."""
def run(self):
develop.run(self)
# PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION
class PostInstallCommand(install):
"""Post-installation for installation mode."""
def run(self):
install.run(self)
# PUT YOUR POST-INSTALL SCRIPT HERE or CALL A FUNCTION
함수에 cmdclass
인수를 삽입하십시오 .setup()
setup.py
setup(
...
cmdclass={
'develop': PostDevelopCommand,
'install': PostInstallCommand,
},
...
)
설치 전 준비를 수행하는 다음 예제와 같이 설치 중에 쉘 명령을 호출 할 수도 있습니다.
from setuptools import setup
from setuptools.command.develop import develop
from setuptools.command.install import install
from subprocess import check_call
class PreDevelopCommand(develop):
"""Pre-installation for development mode."""
def run(self):
check_call("apt-get install this-package".split())
develop.run(self)
class PreInstallCommand(install):
"""Pre-installation for installation mode."""
def run(self):
check_call("apt-get install this-package".split())
install.run(self)
setup(
...
추신 : setuptools에 사용할 수있는 사전 설치 진입 점이 없습니다. 왜 없는지 궁금하다면 이 토론을 읽으십시오 .
답변
참고 : 아래 솔루션은 소스 배포 zip 또는 tarball을 설치하거나 소스 트리에서 편집 가능한 모드로 설치할 때만 작동합니다. 그것은 것입니다 하지 바이너리 휠에서 설치할 때 (작동 .whl
)
이것은 설치 후 스크립트에서 패키지 종속성이 이미 설치되어 있어야 할 때 저에게 효과가 있었던 유일한 전략입니다.
import atexit
from setuptools.command.install import install
def _post_install():
print('POST INSTALL')
class new_install(install):
def __init__(self, *args, **kwargs):
super(new_install, self).__init__(*args, **kwargs)
atexit.register(_post_install)
setuptools.setup(
cmdclass={'install': new_install},
답변
참고 : 아래 솔루션은 소스 배포 zip 또는 tarball을 설치하거나 소스 트리에서 편집 가능한 모드로 설치할 때만 작동합니다. 그것은 것입니다 하지 바이너리 휠에서 설치할 때 (작동 .whl
)
해결책은 post_setup.py
in setup.py
의 디렉토리 를 포함하는 것 입니다 . post_setup.py
사후 설치를 수행하는 기능이 포함 setup.py
되며 적절한 시간에만 가져 와서 실행합니다.
에서 setup.py
:
from distutils.core import setup
from distutils.command.install_data import install_data
try:
from post_setup import main as post_install
except ImportError:
post_install = lambda: None
class my_install(install_data):
def run(self):
install_data.run(self)
post_install()
if __name__ == '__main__':
setup(
...
cmdclass={'install_data': my_install},
...
)
에서 post_setup.py
:
def main():
"""Do here your post-install"""
pass
if __name__ == '__main__':
main()
setup.py
디렉토리에서 시작하는 일반적인 아이디어를 사용하면 가져올 수 있습니다. post_setup.py
그렇지 않으면 빈 함수가 시작됩니다.
에서 post_setup.py
1, if __name__ == '__main__':
문 당신이 발사 수동으로 할 수 있습니다 명령 줄에서 설치 후.
답변
@Apalala, @Zulu 및 @mertyildiran의 답변 결합; 이것은 Python 3.5 환경에서 저에게 효과적이었습니다.
import atexit
import os
import sys
from setuptools import setup
from setuptools.command.install import install
class CustomInstall(install):
def run(self):
def _post_install():
def find_module_path():
for p in sys.path:
if os.path.isdir(p) and my_name in os.listdir(p):
return os.path.join(p, my_name)
install_path = find_module_path()
# Add your post install code here
atexit.register(_post_install)
install.run(self)
setup(
cmdclass={'install': CustomInstall},
...
또한 install_path
셸 작업을 수행하기 위해 에서 패키지의 설치 경로에 액세스 할 수 있습니다 .
답변
설치 후 수행하고 요구 사항을 유지하는 가장 쉬운 방법은 다음과 같은 호출을 장식하는 것입니다 setup(...)
.
from setup tools import setup
def _post_install(setup):
def _post_actions():
do_things()
_post_actions()
return setup
setup = _post_install(
setup(
name='NAME',
install_requires=['...
)
)
setup()
선언 할 때 실행 됩니다 setup
. 요구 사항 설치가 완료되면 _post_install()
내부 기능을 실행하는 기능이 실행됩니다 _post_actions()
.
답변
atexit을 사용하는 경우 새 cmdclass를 만들 필요가 없습니다. setup () 호출 직전에 atexit 레지스터를 간단히 만들 수 있습니다. 같은 일을합니다.
또한 종속성을 먼저 설치해야하는 경우 pip가 패키지를 제자리로 이동하기 전에 atexit 핸들러가 호출되므로 pip 설치와 함께 작동 하지 않습니다 .
답변
제시된 권장 사항으로 문제를 해결할 수 없었으므로 여기에 도움이되었습니다.
setup()
에서 설치 직후 실행하려는 함수를 다음과 같이 호출 할 수 있습니다 setup.py
.
from setuptools import setup
def _post_install():
<your code>
setup(...)
_post_install()