Pipenv: [pregunta] ¿Cómo integrar con setup.py?

Creado en 7 feb. 2017  ·  38Comentarios  ·  Fuente: pypa/pipenv

Usando requirements.txt puedo hacerlo:

from pip.req import parse_requirements
requirements = [str(r.req) for r in
                parse_requirements('requirements.txt', session=False)]
test_requirements = [str(r.req) for r in
                     parse_requirements('requirements-test.txt', session=False)]

¿Cómo puedo hacer lo mismo usando Pipfile?

Comentario más útil

Primero, descargo de responsabilidad: Mi experiencia es principalmente con paquetes lib. Podría perder algunos puntos. ¡Tengo el derecho de equivocarme y estoy listo para usarlo!
Además, esto me hizo rascarme la cabeza un par de veces. Realmente me gustaría alguna revisión sobre esto.

Ahora, vamos a llegar a esto.

Comenzaré con esta declaración @elgertam :

[...] mi uso de Pipfile me lleva a pensar que install_requires realmente es casi idéntico a lo que pasa en Pipfile. Si necesito numpy, pipenv instalo numpy y se ingresa una nueva entrada en el grupo [paquetes] de mi Pipfile [...]

Agregó numpy a su entorno, no agregó numpy a las dependencias de su aplicación.
Esas son dos cosas diferentes. Sigue leyendo, verás lo que quiero decir.

En otras palabras, mi uso es totalmente diferente de los requisitos.txt, que solía generar antes de comprometerme usando pip freeze> requisitos.txt.

Sorprendentemente, su uso no es tan diferente si lo piensa:

  • Su flujo de trabajo anterior: pip install stuff -> pip freeze > requirements.txt -> alimentar install_requires de requirements.txt
  • Su nuevo (intento) flujo de trabajo: pipenv install stuff -> Pipfile actualizado automáticamente -> tratando de alimentar install_requires con Pipfile .
  • ¿Cuál es la idea prevista? Agregar cosas a install_requires -> pipenv install -> Entorno y Pipfile.lock actualizados.

Y para esa forma de trabajo prevista, desea un Pipfile que indique que desea instalar su aplicación.
Algo así como el requests Pipfile vinculado por @isobit.

O, un ejemplo:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]
pytest = ">=2.8.0"
tox = "*"

[packages]
"-e ." = "*"

Su Pipfile es para describir su entorno, no las dependencias de un paquete. Como puede ver, el Pipfile anterior define lo que quiero instalar, que es el paquete local en modo editable.

Esto puede parecer un poco "inútil", ya que en este momento todo está controlado por un solo paquete, pero digamos que desea instalar su aplicación, pero con requests[security] , pero no es una dependencia estricta de su aplicación, usted hacer pipenv install requests[security] , y luego:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]
pytest = ">=2.8.0"
tox = "*"

[packages]
"-e ." = "*"
requests = { extras = ['security'] }

Y voilà, aquí hay un ejemplo de la diferencia entre sus requisitos abstractos y sus requisitos concretos. Lo mismo ocurre si desea instalar gunicorn o cualquier otra cosa necesaria en el entorno, pero eso no es parte de la aplicación en sí.

¿Qué me estoy perdiendo aquí, @vphilippon? ¿Por qué los [paquetes] de Pipfile están demasiado restringidos para usar en install_requires o tests_require?

Si he explicado esto lo suficientemente bien, puedes ver que se supone que es al revés.
Pones tus dependencias en install_requires , pones tu paquete en Pipfile , y luego obtienes un entorno, con un Pipfile.lock para la reproducibilidad (ya que resolverá y respetará tu dependencias del paquete).

Por test_require , admito que no estoy seguro de que encaje en todo esto. IIRC, es una característica específica setuptools . Podríamos argumentar que es un conjunto de dependencias abstractas para probar, y esperar que pipenv resuelva e instale las que luego hacen pipenv install --dev , para todos los paquetes, pero tengo la sensación de que no es del todo correcto. No tengo una idea u opinión clara sobre esto y la razón de ser, lo siento.

Espero que todo esto tenga sentido de alguna manera.

Todos 38 comentarios

Debería poder lograr esto con el siguiente código. Esto cargará el Pipfile de su proyecto actual y devolverá las dependencias en una lista compatible con pip.

from pipenv.project import Project
from pipenv.utils import convert_deps_to_pip

pfile = Project(chdir=False).parsed_pipfile
requirements = convert_deps_to_pip(pfile['packages'], r=False)
test_requirements = convert_deps_to_pip(pfile['dev-packages'], r=False)

Háganos saber si tiene más preguntas :)

Lo anterior es muy útil. Me he encontrado con problemas con setup.py dependiendo de que Pipenv esté instalado en un virtualenv antes de que se pueda ejecutar setup.py install (o cualquier otra cosa). Las únicas soluciones a este problema que se me ocurren son vender Pipenv en un proyecto, lo que parece menos que ideal, o incluso piratear de alguna manera el archivo setup.py para instalar Pipenv antes de intentar ejecutar las importaciones from pipenv... , lo que parece incorrecto. ¿Alguien tiene alguna idea o solución mejor que esta?

¿Deberíamos ~acosar~ sugerir a otros en la comunidad de Python (PyPA, etc.) que simplemente bendigan a Pipenv como una herramienta incluida oficialmente en futuras versiones de Python? 😄

¿Ayudaría agregar pipenv a setup_requires ? Parece que también podría ser necesario agregarlo a install_requires lo que parece desafortunado.

No hagas esto.

@kennethreitz , ¿qué quieres decir con "esto"? ¿Te refieres a la integración con setup.py, la solución @nateprewitt o las dos últimas sugerencias?

Entonces, ¿cómo deben saber los usuarios que necesitan instalar pipenv?

Dado que pipenv es una herramienta que se usa para instalar cosas, no al revés, no hay razón para requerirlo en su setup.py. Lo que advierte Kenneth es importar pipenv en setup.py, ya que es una aplicación cli y puede causar problemas.

El 17 de octubre de 2017, a las 9:37 a. m., Iddan Ahahronson [email protected] escribió:

Entonces, ¿cómo deben saber los usuarios que necesitan instalar pipenv?


Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub o silencie el hilo.

Entonces, ¿cómo puedo usar el código de @nateprewitt - en setup.py?

@iddan : he intentado resolver el problema de arranque de Pipenv simplemente comercializando una versión de Pipenv en el esqueleto de mi proyecto (https://github.com/elgertam/cookiecutter-pypackage/blob/master/%7B%7Bcookiecutter.project_slug%7D %7D/setup.py). Hasta ahora no he tenido ningún problema, aunque no puedo decir que haya tenido muchas oportunidades de probarlo en una situación en la que instalé un paquete usando setup.py .

Puedo entender por qué nos preocuparía no ejecutar una CLI al cargar setup.py, pero por lo que puedo decir, el código que estoy usando (copiado y pegado de la publicación de @nateprewitt aquí) es bastante seguro.

Me imagino que este truco ya no será necesario cuando pip tenga suficientes componentes internos para comprender el formato Pipfile.

@iddan , para ser claros, ese código es únicamente para convertir las dependencias de Pipfiles en un formato de estilo requirements.txt que leerá pip. Parece que Kenneth redactó algo de la publicación original, pero no estoy seguro de qué.

Pipenv está diseñado como una herramienta de implementación y administración del entorno, no para distribución como setup.py. Recomendamos encarecidamente documentar que está utilizando un Pipfile y posiblemente vincular a pipenv.org para obtener instrucciones de instalación. Trate esto de la misma manera que trata a pip, no se espera que un usuario instale pip cada vez que instala un nuevo paquete de Python.

Lo entiendo perfectamente. Lo que no entiendo es qué espera que suceda cuando un usuario descarga un paquete usando este script y no tiene instalado pipenv

@nateprewitt , si queremos distribuir un paquete entonces (a través de los medios habituales, usando pip ), deberíamos mantener una copia de la lista de dependencias en setup.py o requirements.txt ? Tenía la esperanza de usar mi Pipfile como una única fuente de verdad.

Para aclarar, asumo que el código en la primera respuesta está destinado a ejecutarse como parte de una compilación, en lugar de usarse en un setup.py .

A menos que esté muy equivocado, el código en https://github.com/kennethreitz/pipenv/issues/209#issuecomment -278185133 es seguro para usar si está construyendo una rueda (=dist binario), pero no si estás construyendo sdist (= fuente dist).

Para las ruedas, setup.py no se incluye en el paquete (sino que se evalúa en tiempo de compilación y los archivos de metadatos se construyen en función de la información que recopila). Con ruedas, nunca se ejecuta setup.py en la máquina donde se está instalando el paquete, solo donde se construyó.

Con sdist, setup.py en realidad se ejecuta en la máquina de instalación y, por lo tanto pipenv debe estar disponible allí.

Oh si. @tuukkamustonen , mi caso de uso particular es un sdist. Dado que no quiero requerir que el usuario del paquete instale pipenv antes de hacer un pip install , asumo que estoy obligado a derivar mi install_requires fuera de setup.py (es decir, manualmente o como parte de una compilación)?

Si estoy leyendo correctamente, creo que Kenneth y los demás mantenedores no quieren que tratemos Pipenv como una dependencia del proyecto como lo haríamos con pytest , o incluso una dependencia normal del paquete. Idealmente, parece que deberíamos instalar y actualizar Pipenv de la misma manera que pip , es decir, pip se instala cuando se instala Python o cuando se instala virtualenv Se crea

Dicho esto, @isobit se hizo eco de mis pensamientos de que Pipfile debería ser la única fuente de verdad. Puedo ver dos casos de uso convincentes para favorecer a Pipfile (y hay otros): primero, una canalización de CI/CD que depende de Pipfile para configurar el entorno de compilación es mucho más sólida que una que depende de los requisitos.txt; y segundo, un colaborador puede intentar instalar un proyecto basado en Pipfile a ciegas y puede frustrarse si python setup.py install no funciona de la manera que espera. Teniendo en cuenta que ni Pipenv ni Pipfile-aware pip son herramientas estándar de Python todavía, y Pipenv es de hecho la implementación de referencia para Pipfile, tenemos pocas opciones para resolver el problema:

1) Especifique en la documentación de su proyecto que su proyecto depende de Pipenv . Todavía puede depender de Pipenv en su setup.py , y esto fallará si Pipenv no está instalado en su entorno de Python. Concretamente, un colaborador de su código tendría que instalar manualmente Pipenv en su virtualenv para poder instalar el proyecto con setup.py .
2) Todavía tiene setup.py dependiendo de requirements.txt , que genera periódicamente en función de su Pipfile . Esto sigue siendo totalmente compatible con pip y setuptools , pero requiere que cualquier mantenedor genere requirements.txt cada vez que se construye e implementa el proyecto. Una posible variación de esto sería que una canalización de CI/CD actualice requirements.txt en el momento de la compilación.
3) Vendorice una versión de Pipenv en un proyecto y llámelo usando from _vendor.pipenv.project import Project... dentro setup.py . Una variación de esto podría ser importar solo desde la versión comercializada cuando falla la importación global.
4) Alguna otra opción que no se presenta aquí y que no soy lo suficientemente inteligente como para pensar.

Personalmente estoy usando (3) (consulte https://github.com/kennethreitz/pipenv/issues/209#issuecomment-300550425) hasta que Pipfile se convierta en un estándar más común, momento en el cual no tendré ninguno de mis proyectos. dependen directamente del código de Pipenv, ya que Pipenv parece claramente destinado a ser una herramienta para administrar un entorno virtual basado en un Pipfile, y no necesariamente una biblioteca de Pipfile en sí.

Espero que esto aclare el problema según lo que he leído aquí, pero si me equivoqué o dije algo atroz, házmelo saber @nateprewitt.

Tengo la sensación de que el problema aquí surge de un mal uso original (OMI) de requirements.txt para empezar. Eso es aparte del uso de pipenv .

Voy a señalar este maravilloso artículo de Donald Stufft, setup.py vs. requirements.txt:
https://caremad.io/posts/2013/07/setup-vs-requirement/

TL; DR (pero realmente debería leer): El setup.py 's install_requires está destinado a detallar los requisitos (dependencias) de un paquete. El requirements.txt (que sería reemplazado por el combo Pipfile / Pipfile.lock aquí) debe usarse para enumerar qué paquetes exactos se usarán para satisfacer lo que se requiere, según el metadatos de setup.py , para crear un entorno reproducible.
Rellenar el install_requires desde el requirements.txt es como retroceder.

setup.py es install_requires =/= requirements.txt (o Pipfile / Pipfile.lock ).
Pipfile (o más bien Pipfile.lock ) debe ser la única fuente de verdad de los paquetes para instalar en el entorno de la aplicación.
setup.py 's install_requires proporciona metadatos utilizados para generar un Pipfile.lock válido.

Creo que de ahí viene la fricción. Espero que tenga sentido.

Me gusta mucho esa respuesta, Vincent, y estoy totalmente de acuerdo en que Pipfile.lock es un reemplazo completo (y mejor) de requirements.txt .

Sin embargo, después de haber usado Pipenv durante algunos meses, mi uso de Pipfile me lleva a pensar que install_requires realmente es casi idéntico a lo que se incluye en Pipfile . Si necesito numpy , pipenv install numpy y una nueva entrada entra en el grupo [packages] de mi Pipfile: numpy = "*" . En otras palabras, mi uso es totalmente diferente de requirements.txt , que solía generar antes de comprometerme usando pip freeze > requirements.txt .

Tal vez esta es solo una forma peculiar en la que estoy usando Pipenv, y voy contra la corriente (también instalo mi virtualenv en .venv/ dentro del directorio del proyecto, así que soy un Pythonista deshonesto), en el cual caso, puedo cumplir fácilmente con la convención de la comunidad Python de tener un muro de separación entre setup.py y Pipfile | Pipfile.lock | requirements.txt .

¿Qué me estoy perdiendo aquí, @vphilippon?

Gracias por la información, @vphilippon. Tal vez estamos haciendo esto al revés, parece que lo que realmente queremos es lo contrario: una forma de usar deps abstractos de install_requires en nuestro Pipfile, como menciona Donald con respecto a -e . en el requirements.txt . Parece que ya había un problema al respecto (# 339), pero no parecía ir a ninguna parte.

¿Esto ya está cubierto por la sintaxis de Pipfile? Acabo de notar que la biblioteca de solicitudes Pipfile usa "e1839a8" = {path = ".", editable = true, extras=["socks"]} en su sección de paquetes. Algo similar es evidente en los ejemplos de Pipfile , pero no veo ninguna otra documentación.

Primero, descargo de responsabilidad: Mi experiencia es principalmente con paquetes lib. Podría perder algunos puntos. ¡Tengo el derecho de equivocarme y estoy listo para usarlo!
Además, esto me hizo rascarme la cabeza un par de veces. Realmente me gustaría alguna revisión sobre esto.

Ahora, vamos a llegar a esto.

Comenzaré con esta declaración @elgertam :

[...] mi uso de Pipfile me lleva a pensar que install_requires realmente es casi idéntico a lo que pasa en Pipfile. Si necesito numpy, pipenv instalo numpy y se ingresa una nueva entrada en el grupo [paquetes] de mi Pipfile [...]

Agregó numpy a su entorno, no agregó numpy a las dependencias de su aplicación.
Esas son dos cosas diferentes. Sigue leyendo, verás lo que quiero decir.

En otras palabras, mi uso es totalmente diferente de los requisitos.txt, que solía generar antes de comprometerme usando pip freeze> requisitos.txt.

Sorprendentemente, su uso no es tan diferente si lo piensa:

  • Su flujo de trabajo anterior: pip install stuff -> pip freeze > requirements.txt -> alimentar install_requires de requirements.txt
  • Su nuevo (intento) flujo de trabajo: pipenv install stuff -> Pipfile actualizado automáticamente -> tratando de alimentar install_requires con Pipfile .
  • ¿Cuál es la idea prevista? Agregar cosas a install_requires -> pipenv install -> Entorno y Pipfile.lock actualizados.

Y para esa forma de trabajo prevista, desea un Pipfile que indique que desea instalar su aplicación.
Algo así como el requests Pipfile vinculado por @isobit.

O, un ejemplo:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]
pytest = ">=2.8.0"
tox = "*"

[packages]
"-e ." = "*"

Su Pipfile es para describir su entorno, no las dependencias de un paquete. Como puede ver, el Pipfile anterior define lo que quiero instalar, que es el paquete local en modo editable.

Esto puede parecer un poco "inútil", ya que en este momento todo está controlado por un solo paquete, pero digamos que desea instalar su aplicación, pero con requests[security] , pero no es una dependencia estricta de su aplicación, usted hacer pipenv install requests[security] , y luego:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]
pytest = ">=2.8.0"
tox = "*"

[packages]
"-e ." = "*"
requests = { extras = ['security'] }

Y voilà, aquí hay un ejemplo de la diferencia entre sus requisitos abstractos y sus requisitos concretos. Lo mismo ocurre si desea instalar gunicorn o cualquier otra cosa necesaria en el entorno, pero eso no es parte de la aplicación en sí.

¿Qué me estoy perdiendo aquí, @vphilippon? ¿Por qué los [paquetes] de Pipfile están demasiado restringidos para usar en install_requires o tests_require?

Si he explicado esto lo suficientemente bien, puedes ver que se supone que es al revés.
Pones tus dependencias en install_requires , pones tu paquete en Pipfile , y luego obtienes un entorno, con un Pipfile.lock para la reproducibilidad (ya que resolverá y respetará tu dependencias del paquete).

Por test_require , admito que no estoy seguro de que encaje en todo esto. IIRC, es una característica específica setuptools . Podríamos argumentar que es un conjunto de dependencias abstractas para probar, y esperar que pipenv resuelva e instale las que luego hacen pipenv install --dev , para todos los paquetes, pero tengo la sensación de que no es del todo correcto. No tengo una idea u opinión clara sobre esto y la razón de ser, lo siento.

Espero que todo esto tenga sentido de alguna manera.

@vphilippon Lo explicaste bastante bien, y creo que me has convencido.

TL; DR: Especifique las dependencias abstractas y absolutamente necesarias en setup.py , luego agregue contexto (y por lo tanto concreción) en Pipfile y Pipfile.lock , incluido el fantástico "-e ." = "*" entrada.

Un problema con https://github.com/kennethreitz/pipenv/issues/209#issuecomment -337409290 es que cuando queremos implementar nuestra aplicación en un servidor, no obtenemos un entorno reproducible.

Me refiero a que normalmente, al desarrollar una _biblioteca_ que se usará en otros proyectos, queremos que nuestro install_requires sea bastante flexible (= sin vinculación a versiones exactas). Si. Pero cuando creamos una aplicación web (o cualquier aplicación) y la implementamos en un servidor remoto o en un contenedor docker, probablemente queramos dependencias fijas. Incluso si especificamos versiones exactas en install_requires , las dependencias transitivas no están bloqueadas y la instalación puede descargar una versión diferente (más nueva) de una dependencia transitiva y eso puede interrumpir su implementación.

(Declarar manualmente versiones exactas de dependencias transitivas no es una opción, es demasiado engorroso).

En este caso de uso, deberíamos depender de un archivo de bloqueo de estilo requirements.txt (que especifica versiones exactas incluso para dependencias transitivas). Sin embargo, no parece que pipenv permita excluir los requisitos de desarrollo en pipenv lock -r (por ejemplo pipenv lock --no-dev -r ), de modo que podamos crear tales requirements.txt (que luego pueden ser leer en install_requires )?

Citaré el artículo de Donald Stufft:

Por lo general, una aplicación tiene un conjunto de dependencias, a menudo incluso un conjunto muy complejo de dependencias, con las que se ha probado. Al ser una instancia específica que se ha implementado, normalmente no tiene un nombre ni ninguno de los otros metadatos relacionados con el empaquetado. Esto se refleja en las capacidades de un archivo de requisitos de pip.

En otras palabras: la aplicación no es el paquete. La aplicación es el entorno, con un conjunto de dependencias concretas instaladas. Las dependencias de una aplicación deben estar representadas por requirements.txt (o Pipfile / Pipfile.lock ), no por un solo paquete install_requires .

Personalmente, iría tan lejos como para decir que el conjunto completo de dependencias ancladas (incluida la transitiva) debe estar en un requirements.txt para la aplicación, no en el setup.py del paquete. Esto describe la idea de que la implementación de una aplicación no se realiza con pip install myapp==1.0.0 , sino con pip install -r requirements.txt (o pipenv install con Pipfile.lock ), donde requirements.txt incluye myapp==1.0.0 , así como todas las demás dependencias y dependencias transitivas fijadas.
Puede parecer que estoy yendo un poco lejos, pero he trabajado en un contexto donde la "aplicación" implementada está impulsada por un conjunto de paquetes. No hay un solo paquete que represente a la aplicación en sí, por lo que esta noción de que "el paquete no es la aplicación" se me planteó muy pronto 😄.

Tengo la fuerte sensación de que Pipenv/Pipfile/Pipfile.lock sigue esta idea.
Esa sería la razón por la que parece haber una brecha para pasar de Pipfile.lock a setup.py 's install_requires : en cualquier caso, realmente no está destinado a hacerse de esa manera.

@maintainers Me gustaría su opinión aquí para saber si realmente es así como ve todo esto. He estado predicando una visión de cómo deberíamos tratar las dependencias, pero tampoco quiero hablar en su lugar.

@vphilippon Creo que hay diferentes puntos de vista y terminología. Pero, en última instancia, queremos una lista de dependencias ancladas para instalar. Entonces, un requirements.txt con versiones ancladas (o un paquete con tales dependencias declaradas, realmente no importa). La pregunta es, ¿cómo crear realmente un archivo de este tipo?

Con pip-compile (de pip-tools ), puedo compilar tales requirements.txt desde requirements.in y contendrá solo las dependencias que no son de desarrollo que necesita mi aplicación. No estoy seguro si estoy interpretando su respuesta correctamente. ¿Realmente quiere decir que debemos mantener dependencias ancladas requirements.txt a mano (también duplicando ligeramente lo que ya está en setup.py ), también para dependencias transitivas? Esa no puede ser la solución...

Si hubiera pipenv lock --no-dev -r , creo que eso resolvería este problema.

@tuukkamustonen Perdón por la confusión, en realidad solo estaba abordando la idea de install_requires vs requirements.txt / Pipfile / Pipfile.lock .

Entonces, un requirements.txt con versiones ancladas (o un paquete con tales dependencias declaradas, realmente no importa).

Creo que la distinción es realmente importante, pero como dijiste, aquí hay diferentes puntos de vista. Acordemos estar en desacuerdo por ahora. Como nota al margen, sería bueno tener un lugar para continuar con el tema sin agregar ruido a un problema específico. Ese es el tipo de cosas que necesitan más discusión y compartir en la comunidad, en mi opinión.

Sin embargo, no parece que pipenv permita excluir los requisitos de desarrollo en pipenv lock -r

Pero, en última instancia, queremos una lista de dependencias ancladas para instalar. [...] La pregunta es, ¿cómo crear realmente un archivo de este tipo? [...] Con pip-compile (de pip-tools), puedo compilar tales requisitos.txt desde requisitos.in y contendrá solo las dependencias que no son de desarrollo que necesita mi aplicación.

Ah, me salté esa parte al principio, lo siento. Y parece que tienes razón: no puedo encontrar una manera de decir pipenv install --not-dev-stuff (aunque estaba bastante seguro de que había uno, raro) y generar un entorno que no sea de desarrollo. ¿Cuál es el punto de tener 2 secciones separadas entonces? Es posible que ahora me esté perdiendo algo, y eso no está relacionado con el uso con setup.py . Tal vez valga la pena discutirlo en un nuevo número.

EDITAR:
Cometí un error aquí. De hecho, no encontré una manera de generar Pipfile.lock sin paquetes de desarrollo, pero , en un nuevo entorno, con Pipfile / Pipfile.lock existentes, haciendo pipenv install no instala los paquetes de desarrollo. Esto no resuelve el punto de @tuukkamustonen , pero me equivoqué al afirmar que no había forma de instalar un "entorno de producción", mi error.

Uf, eso fue mucho para ponerse al día.

A menos que me equivoque gravemente, es seguro usar el código en el n.° 209 (comentario) si está construyendo una rueda (=dist binario), pero no si está construyendo sdist (=dist fuente).

@tuukkamustonen, esto solo está diseñado para usarse en un script independiente para implementaciones, no lo incluya en su setup.py. Esta es una solución semi-hacky de antes de que tuviéramos pipenv lock -r , hace muchos meses. Sin embargo, este enfoque funcionará para su caso de uso de dividir packages y dev-packages .

Personalmente estoy usando (3) (ver #209 (comentario)) hasta que Pipfile se convierta en un estándar más común, momento en el cual ninguno de mis proyectos dependerá directamente del código Pipenv, ya que Pipenv parece claramente destinado a ser un herramienta para administrar un virtualenv basado en un Pipfile, y no necesariamente una biblioteca de Pipfile en sí.

@elgertam parece que sus opiniones pueden haber cambiado desde este comentario, pero quisiera señalar que probablemente no sea una buena idea agrupar pipenv con su proyecto. No hay nada que lo prohíba explícitamente, pero hacemos muchos parches de rutas que tienden a causar problemas cuando se usan de esta manera. Supongo que simplemente envolveré esto con una advertencia de "úselo bajo su propio riesgo".

mantenedores Me gustaría su opinión aquí para saber si realmente es así como ven todo esto. He estado predicando una visión de cómo deberíamos tratar las dependencias, pero tampoco quiero hablar en su lugar.

Creo que estás bastante en línea con nuestra visión durante la duración del proyecto. ¡Gracias por compilar todo esto y articularlo tan bien @vphilippon!

Parece que las otras partes relevantes de esta discusión se han movido al #942, así que creo que estamos bien aquí. Por favor, hágame un ping si no abordé nada.

Seguí con una propuesta concreta en https://github.com/pypa/pipfile/issues/98 que creo que nos brinda algo práctico y pragmático que podría mejorar DX para mantener las bibliotecas de Python.

¿Pensamientos?

import json, jmespath

install_requires = []
with open('Pipfile.lock') as f:
    context = json.loads(f.read())
    install_requires.extend(map(
        lambda n, v : n + v,
        jmespath.search('default | keys(@)', context),
        jmespath.search('default.*.version', context),
    ))

setup(
    name='foobar',
    packages=find_packages(),
    setup_requires=['jmespath'],
    install_requires=install_requires,
)

@cornfeedhobo tengo entendido que setup_requires no funciona bien con pip. ¿Podría elaborar un poco sobre cómo sugeriría usar esta muestra?

La muestra no funcionará a menos que instale jmespath primero porque setup.py se evalúa como código Python normal. El argumento setup_requires en realidad no logra nada: si el programa llega tan lejos, se garantiza la instalación de jmespath.

Mencioné esto en otro problema, pero no puedo ubicarlo en el cajero automático (hay tantas discusiones duplicadas en todo el rastreador de problemas que ya es imposible encontrar nada), así que lo diré nuevamente: Por favor, no ponga nada que no esté construido. en el interior de setup.py a menos que proporcione un respaldo adecuado o tenga una razón perfecta. Un paquete que contenga el setup.py anterior ni siquiera funcionará con Pipenv con jmespath instalado en virtualenv; Pipenv invoca setup.py egg_info en un entorno limpio y no podrá ejecutar la importación jmespath. Esta es una mala práctica. Por favor, evítelo.

@epot no estaba al tanto de eso

@uranusjr Gracias por la respuesta bien pensada con detalles. Solo estoy explorando todo este tema, por lo que podría regresar por más vergüenza. También estoy rastreando pypa/pipfile#98

¿Qué sucede si no requerimos jmespath ?

import json


install_requires = []
tests_require = []

with open('Pipfile.lock') as fd:
    lock_data = json.load(fd)
    install_requires = [
        package_name + package_data['version']
        for package_name, package_data in lock_data['default'].items()
    ]
    tests_require = [
        package_name + package_data['version']
        for package_name, package_data in lock_data['develop'].items()
    ]

@mschwager No desea anclar la versión, o los usuarios tendrán dificultades. #1921 es un ejemplo de una biblioteca que usa == termina rompiendo la compilación de un usuario.

Mis disculpas, pero ¿cuál es la diferencia entre usar setup.py para usarlo como un paquete o requirements.txt / Pipfile para administrar las dependencias de dicho paquete? Las bibliotecas requeridas TIENEN que ser idénticas entre setup.py y requirements.txt / Pipfile , ¿verdad? Por lo tanto, no hay motivo para no integrar Pipfile . setup.py ya analiza requirements.txt . ¿Por qué no debería poder analizar Pipfile ?

Sería genial deshacerse de requirements.txt y solo usar Pipfile

No, no hay razón para que sean idénticos. Esa es una suposición bastante radical, y muchos en la comunidad suplicarían la diferencia.

De hecho, sin embargo, hay razones por las que _pueden_ ser idénticos. Pipenv no excluye eso. Simplemente está fuera del alcance y no es compatible con este proyecto. Puede crear una biblioteca totalmente compatible con eso y aprovechar PEP 518 , que está implementado en pip 10.0, para brindar soporte en el momento de la compilación.

Como dijiste, no hay razón para no permitir que setup.py analice Pipfile. Espero que lo hagas realidad :)

¿Entiendes que a algunas personas les gustan las bibliotecas abstractas de setup.py pero que no son imprescindibles? Quiero decir que golang solo tiene requisitos concretos pero aún puede sustituir una biblioteca requerida con su propia bifurcación solo porque coincide con el nombre. Es comprensible que la interacción setup.py simplemente no esté dentro del alcance.

Sin embargo, sería interesante ver cuál es la hoja de ruta a largo plazo de pipenv. Sería genial ver que se convierta en la herramienta de referencia en python. por ejemplo, de alguna manera reemplaza setup.py o genera un setup.py apropiado para el usuario, de cualquier manera, pipenv es un administrador de paquetes de facto es increíble. Solo me preguntaba si existe la posibilidad de ampliar el alcance para incluir setup.py.

Si pipenv es como npm, etc., entonces su paquete.json permite la instalación remota, no hay razón para que pipenv no pueda interactuar o reemplazar setup.py, por lo que está dentro del alcance. ¿Estoy teniendo sentido o suena como si estuviera tomando pastillas locas?

Gracias por pensar que es imprescindible. Teniendo en cuenta que es tan crucial, creo que podremos ejecutar un sistema de compilación basado en Pipfile en muy poco tiempo.

¿Fue útil esta página
0 / 5 - 0 calificaciones