create - python setuptools install_requires se ignora al reemplazar cmdclass
python install setup py (3)
Tengo un setup.py
que se parece a esto:
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},
)
Necesito MyInstall
porque quiero instalar algunas bibliotecas desde github y no quise usar dependency_links
opción dependency_links
, porque está desalentada (por ejemplo here ), así que puedo hacer esto con Requirements.txt.
Cuando instalo este paquete con pip
, todo funciona bien, pero por alguna razón tengo que resolverlo de una manera que también funciona con python setup.py install
. Y no lo hace.
Al reemplazar cmdclass
en setup()
con mi propia clase, parece que se ignora install_requires
. Tan pronto como comente esa línea, esos paquetes se están instalando.
Sé que install_requires no se admite, por ejemplo, en distutils (si recuerdo bien), pero está en setuptools. Y entonces, cmdclass
no tendría ningún efecto en las necesidades de instalación.
Busqué en Google este problema durante horas, encontré muchos tipos de respuestas relacionadas en stackoverflow, pero no para este problema en particular.
Al poner todos los paquetes necesarios a Requirements.txt, todo funciona bien, pero me gustaría entender por qué sucede esto. ¡Gracias!
El mismo problema me acaba de pasar. De alguna manera, parece que algo desencadena herramientas de configuración para hacer una ''instalación de estilo antiguo'' con distutils
, que de hecho no es compatible con install_requires
.
Llama a install.run (self) que llama a run (self) en setuptools / setuptools / command / install.py, línea 51-74
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()
No estoy seguro de si este comportamiento es intencional, pero reemplazando
install.run(self)
con
install.do_egg_install()
debe resolver su problema Al menos me funciona, pero también agradecería una respuesta más detallada. ¡Gracias!
Sé que esta es una vieja pregunta, pero me encontré con un problema similar. La solución que he encontrado soluciona este problema para mí es muy sutil: la clase de install
que está configurando en cmd_class
debe denominarse físicamente install
. Ver esta respuesta en un tema relacionado.
Tenga en cuenta que utilizo la instalación de nombre de clase para mi clase derivada porque eso es lo que python setup.py --help-command usará.
También debe usar self.execute(_func_name, (), msg="msg")
en su post_install en lugar de llamar directamente a la función
Entonces, implementar algo como esto debería hacer que evites la solución de do_egg_install
implementada anteriormente por KEgg.
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")
Según https://.com/a/20196065 una forma más correcta de hacerlo puede ser anular el comando bdist_egg
.
Tu podrías intentar:
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
)
Funcionó para mí y install_require
ya no se ignora. Sin embargo, todavía no entiendo por qué la mayoría de la gente parece anular la cmdclass install
y no se quejan de que ignore la cmdclass install
.