복붙노트

[PYTHON] cmdclass를 재정의 할 때 python setuptools install_requires가 무시됩니다.

PYTHON

cmdclass를 재정의 할 때 python setuptools install_requires가 무시됩니다.

다음과 같은 setup.py 있습니다 :

from setuptools import setup
from subprocess import call
from setuptools.command.install import install

class MyInstall(install):
    def run(self):
        call(["pip install -r requirements.txt --no-clean"], shell=True)
        install.run(self)

setup(
    author='Attila Zseder',
    version='0.1',
    name='entity_extractor',
    packages=['...'],
    install_requires=['DAWG', 'mrjob', 'cchardet'],
    package_dir={'': 'modules'},
    scripts=['...'],
    cmdclass={'install': MyInstall},
)

github에서 라이브러리를 몇 개 설치하고 dependencies_links 옵션을 사용하고 싶지 않기 때문에 MyInstall이 필요합니다. 예를 들어 여기서는 권장하지 않기 때문에 requirements.txt로 할 수 있습니다.

이 패키지를 pip와 함께 설치하면 모든 것이 잘 작동하지만 몇 가지 이유 때문에 순수 python setup.py install과 함께 작동하는 방식으로이 문제를 해결해야합니다. 그리고 그렇지 않습니다.

setup ()에서 cmdclass를 내 자신의 클래스로 재정의하면 install_requires가 무시되는 것 같습니다. 해당 줄을 주석 처리하는 즉시 해당 패키지가 설치됩니다.

나는 install_requires가 distutils (예를 들어 잘 기억한다면)에서 지원되지 않지만 setuptools에 있다는 것을 안다. 그리고 cmdclass는 install_requires에 아무런 영향을 미치지 않습니다.

나는이 문제를 몇 시간 동안 봤는데, stackoverflow에 대한 많은 종류의 관련 답변을 발견했지만,이 특별한 문제는 발견하지 못했습니다.

필요한 모든 패키지를 requirements.txt에 넣으면 모든 것이 잘 작동하지만 왜 이런 일이 일어나는지 이해하고 싶습니다. 감사!

해결법

  1. ==============================

    1.같은 문제가 방금 나에게 일어났습니다. 어떤 식 으로든 무언가가 설치 도구를 설치해 distutils로 'old-style install'을하도록 유도합니다. 실제로는 install_requires를 지원하지 않습니다.

    같은 문제가 방금 나에게 일어났습니다. 어떤 식 으로든 무언가가 설치 도구를 설치해 distutils로 'old-style install'을하도록 유도합니다. 실제로는 install_requires를 지원하지 않습니다.

    setuptools / setuptools / command / install.py 줄 51-74에서 run (self)을 호출하는 install.run (self)을 호출합니다.

    https://bitbucket.org/pypa/setuptools/src/8e8c50925f18eafb7e66fe020aa91a85b9a4b122/setuptools/command/install.py?at=default

    def run(self):
        # Explicit request for old-style install?  Just do it
        if self.old_and_unmanageable or self.single_version_externally_managed:
            return _install.run(self)
    
        # Attempt to detect whether we were called from setup() or by another
        # command.  If we were called by setup(), our caller will be the
        # 'run_command' method in 'distutils.dist', and *its* caller will be
        # the 'run_commands' method.  If we were called any other way, our
        # immediate caller *might* be 'run_command', but it won't have been
        # called by 'run_commands'.  This is slightly kludgy, but seems to
        # work.
        #
        caller = sys._getframe(2)
        caller_module = caller.f_globals.get('__name__','')
        caller_name = caller.f_code.co_name
    
        if caller_module != 'distutils.dist' or caller_name!='run_commands':
            # We weren't called from the command line or setup(), so we
            # should run in backward-compatibility mode to support bdist_*
            # commands.
            _install.run(self)
        else:
            self.do_egg_install()
    

    이 동작이 의도 된 것인지 확실하지 않지만

    install.run(self)
    

    install.do_egg_install()
    

    당신의 문제를 해결해야합니다. 적어도 그것은 나를 위해 작동하지만, 나는 또한 더 자세한 대답을 주셔서 감사하겠습니다. 감사!

  2. ==============================

    2.https://stackoverflow.com/a/20196065에 따르면 더 정확한 방법은 bdist_egg 명령을 무시하는 것입니다.

    https://stackoverflow.com/a/20196065에 따르면 더 정확한 방법은 bdist_egg 명령을 무시하는 것입니다.

    너는 시도 할 수 있었다 :

    from setuptools.command.bdist_egg import bdist_egg as _bdist_egg
    
    class bdist_egg(_bdist_egg):
        def run(self):
            call(["pip install -r requirements.txt --no-clean"], shell=True)
            _bdist_egg.run(self)
    
    ...
    
    setup(...
        cmdclass={'bdist_egg': bdist_egg},  # override bdist_egg
    )
    

    그것은 나를 위해 일하고 install_requireis 더 이상 무시. 그럼에도 불구하고 나는 대부분의 사람들이 cmdclass install을 오버라이드 (override)하는 것처럼 보이고 무시되는 install_require에 대해 불평하지 않는 이유를 아직도 이해하지 못한다.

  3. ==============================

    3.나는 이것이 오래된 질문이라는 것을 알고 있지만 비슷한 문제에 부딪쳤다. 내가 찾은 해결책은 나를 위해이 문제를 해결했다. cmd_class에서 설정하는 설치 클래스는 물리적으로 install이라는 이름이어야한다. 관련 문제에 대한 답변을 참조하십시오.

    나는 이것이 오래된 질문이라는 것을 알고 있지만 비슷한 문제에 부딪쳤다. 내가 찾은 해결책은 나를 위해이 문제를 해결했다. cmd_class에서 설정하는 설치 클래스는 물리적으로 install이라는 이름이어야한다. 관련 문제에 대한 답변을 참조하십시오.

    함수를 직접 호출하는 대신 post_install에서 self.execute (_func_name, (), msg = "msg")를 사용해야합니다

    이와 같이 구현하면 KEgg가 구현 한 do_egg_install 해결 방법을 피할 수 있습니다.

    from setuptools.command.install import install as _install
    ...
    def _post_install():
        #code here
    class install(_install):
        def run(self):
            _install.run(self)
            self.execute(_post_install, (), msg="message here")
    
  4. from https://stackoverflow.com/questions/21915469/python-setuptools-install-requires-is-ignored-when-overriding-cmdclass by cc-by-sa and MIT license