distutils : 사용자 정의 매개 변수를 setup.py에 전달하는 방법은 무엇입니까?
명령 줄과 setup.cfg 구성 파일에서 사용자 정의 매개 변수를 distutils의 setup.py 스크립트로 전달하는 방법을 알려주십시오. 내 패키지 특정 매개 변수를 허용하는 setup.py 스크립트를 작성하고 싶습니다. 예를 들면 :
python setup.py install -foo myfoo
고마워,
Mher
Setuptools / Distuils가 끔찍하게 문서화되어 있으므로 이에 대한 답을 찾는 데 문제가있었습니다. 그러나 결국 나는 이 예를 우연히 발견했습니다 . 또한 이 비슷한 질문이 도움이되었습니다. 기본적으로 옵션이있는 사용자 지정 명령은 다음과 같습니다.
from distutils.core import setup, Command
class InstallCommand(Command):
description = "Installs the foo."
user_options = [
('foo=', None, 'Specify the foo to bar.'),
]
def initialize_options(self):
self.foo = None
def finalize_options(self):
assert self.foo in (None, 'myFoo', 'myFoo2'), 'Invalid foo!'
def run(self):
install_all_the_things()
setup(
...,
cmdclass={
'install': InstallCommand,
}
)
여기에 아주 간단한 해결책이 있습니다. 여러분이해야 할 일은 sys.argv
distutils를 호출하기 전에 필터링하고 직접 처리하는 것 setup(..)
입니다. 이 같은:
if "--foo" in sys.argv:
do_foo_stuff()
sys.argv.remove("--foo")
...
setup(..)
의 distutils이 작업을 수행하는 방법에 대한 문서 결국 나는이 하나 건너 온, 끔찍한 : 히치하이커는 포장 안내 , 어떤 용도 sdist
와 user_options
. 나는 찾을 확장의 distutils이 특히 도움이되지 참조.
이것이 distutils를 사용하는 "적절한"방법처럼 보이지만 (적어도 내가 찾을 수있는 유일한 방법은 모호하게 문서화되어 있음). 나는 아무것도 찾을 수 없습니다 --with
와 --without
다른 답변에서 언급 된 스위치.
이 distutils 솔루션의 문제점은 내가 찾고있는 것에 너무 관여한다는 것입니다 (당신에게도 해당 될 수 있습니다). 수십 개의 라인을 추가하고 서브 클래 싱하는 sdist
것은 나에게 잘못되었습니다.
네, 2015 년 그리고 모두에서 명령과 옵션을 추가하기위한 문서 setuptools
와 distutils
여전히 크게 없습니다.
몇 시간이 지나자 install
명령에 사용자 지정 옵션을 추가하기위한 다음 코드를 알아 냈습니다 setup.py
.
from setuptools.command.install import install
class InstallCommand(install):
user_options = install.user_options + [
('custom_option=', None, 'Path to something')
]
def initialize_options(self):
install.initialize_options(self)
self.custom_option = None
def finalize_options(self):
#print('The custom option for install is ', self.custom_option)
install.finalize_options(self)
def run(self):
global my_custom_option
my_custom_option = self.custom_option
install.run(self) # OR: install.do_egg_install(self)
install.run ()이 "기본적으로"호출되었는지 또는 패치되었는지 확인한다는 점을 언급 할 가치가 있습니다.
if not self._called_from_setup(inspect.currentframe()):
orig.install.run(self)
else:
self.do_egg_install()
이 시점에서 다음을 사용하여 명령을 등록합니다 setup
.
setup(
cmdclass={
'install': InstallCommand,
},
:
실제로 맞춤 매개 변수를 스크립트에 전달할 수 없습니다. 그러나 다음과 같은 방법이 가능하며 문제를 해결할 수 있습니다.
- 옵션 기능은를 사용하여 활성화 할 수 있으며
--with-featurename
표준 기능은를 사용하여 비활성화 할 수 있습니다--without-featurename
. [AFAIR는 setuptools가 필요합니다.] - 환경 변수를 사용할 수 있지만이 변수
set
는 Windows에 있어야하며 접두어는 linux / OS X에서 작동합니다 (FOO=bar python setup.py
). cmd_class
새로운 기능을 구현할 수있는 고유 한 es로 distutils를 확장 할 수 있습니다. 또한 체인이 가능하므로이를 사용하여 스크립트의 변수를 변경할 수 있습니다. (python setup.py foo install
)는foo
명령을 실행하기 전에 실행install
합니다.
어떻게 든 도움이되기를 바랍니다. 일반적으로 추가 매개 변수가 정확히 무엇을해야하는지 좀 더 많은 정보를 제공하는 것이 좋습니다. 더 나은 솔루션이있을 수 있습니다.
아마도 당신은 위의 모든 답변을 읽은 후에도 여전히 어려움을 겪고있는 저처럼 노련하지 않은 프로그래머 일 것입니다. 따라서 잠재적으로 도움이 될 수있는 또 다른 예를 찾을 수 있습니다 ( 및 명령 줄 인수 입력에 대한 이전 답변의 주석을 다룰 수 있음 ).
class RunClientCommand(Command):
"""
A command class to runs the client GUI.
"""
description = "runs client gui"
# The format is (long option, short option, description).
user_options = [
('socket=', None, 'The socket of the server to connect (e.g. '127.0.0.1:8000')',
]
def initialize_options(self):
"""
Sets the default value for the server socket.
The method is responsible for setting default values for
all the options that the command supports.
Option dependencies should not be set here.
"""
self.socket = '127.0.0.1:8000'
def finalize_options(self):
"""
Overriding a required abstract method.
The method is responsible for setting and checking the
final values and option dependencies for all the options
just before the method run is executed.
In practice, this is where the values are assigned and verified.
"""
pass
def run(self):
"""
Semantically, runs 'python src/client/view.py SERVER_SOCKET' on the
command line.
"""
print(self.socket)
errno = subprocess.call([sys.executable, 'src/client/view.py ' + self.socket])
if errno != 0:
raise SystemExit("Unable to run client GUI!")
setup(
# Some other omitted details
cmdclass={
'runClient': RunClientCommand,
},
위의 내용은 내가 작성한 일부 코드에서 테스트되었습니다. 이해하기 쉽도록 약간 더 자세한 독 스트링도 포함 시켰습니다.
명령 줄 : python setup.py runClient --socket=127.0.0.1:7777
. print 문을 사용한 빠른 재확인은 실제로 올바른 인수가 run 메소드에 의해 선택되었음을 보여줍니다.
기타 리소스 내가 유용 (발견 더 및 더 예) :
https://seasonofcode.com/posts/how-to-add-custom-build-steps-and-commands-to-setuppy.html
I successfully used a workaround to use a solution similar to totaam's suggestion. I ended up popping my extra arguments from the sys.argv list:
import sys
from distutils.core import setup
foo = 0
if '--foo' in sys.argv:
index = sys.argv.index('--foo')
sys.argv.pop(index) # Removes the '--foo'
foo = sys.argv.pop(index) # Returns the element after the '--foo'
# The foo is now ready to use for the setup
setup(...)
Some extra validation could be added to ensure the inputs are good, but this is how I did it
A quick and easy way similar to that given by totaam would be to use argparse to grab the -foo argument and leave the remaining arguments for the call to distutils.setup(). Using argparse for this would be better than iterating through sys.argv manually imho. For instance, add this at the beginning of your setup.py:
argparser = argparse.ArgumentParser(add_help=False)
argparser.add_argument('--foo', help='required foo argument', required=True)
args, unknown = argparser.parse_known_args()
sys.argv = [sys.argv[0]] + unknown
The add_help=False
argument means that you can still get the regular setup.py help using -h
(provided --foo
is given).
To be fully compatible with both python setup.py install
and pip install .
you need to use environment variables because pip
option --install-option=
is bugged:
- pip
--install-option
leaks across lines - Determine what should be done about --(install|global)-option with Wheels
- pip not naming abi3 wheels correctly
This is a full example not using the --install-option
:
import os
environment_variable_name = 'MY_ENVIRONMENT_VARIABLE'
environment_variable_value = os.environ.get( environment_variable_name, None )
if environment_variable_value is not None:
sys.stderr.write( "Using '%s=%s' environment variable!\n" % (
environment_variable_name, environment_variable_value ) )
setup(
name = 'packagename',
version = '1.0.0',
...
)
Then, you can run it like this on Linux:
MY_ENVIRONMENT_VARIABLE=1 pip install .
MY_ENVIRONMENT_VARIABLE=1 pip install -e .
MY_ENVIRONMENT_VARIABLE=1 python setup.py install
MY_ENVIRONMENT_VARIABLE=1 python setup.py develop
But, if you are on Windows, run it like this:
set "MY_ENVIRONMENT_VARIABLE=1" && pip install .
set "MY_ENVIRONMENT_VARIABLE=1" && pip install -e .
set "MY_ENVIRONMENT_VARIABLE=1" && python setup.py install
set "MY_ENVIRONMENT_VARIABLE=1" && python setup.py develop
References:
'IT Share you' 카테고리의 다른 글
Elixir에서 기능을 나열 할 모듈을 얻을 수있는 방법이 있습니까? (0) | 2020.11.30 |
---|---|
첫 번째 정규식과 일치하는 문자열 반환 (0) | 2020.11.30 |
Azure 저장소 위치에 하위 컨테이너를 만드는 방법 (0) | 2020.11.30 |
Page.User.Identity.IsAuthenticated는 FormsAuthentication.SignOut () 후에도 여전히 true입니다. (0) | 2020.11.30 |
텍스트 파일을 만들고 bash를 사용하여 채우기 (0) | 2020.11.30 |