Pip: Hacia PEP 518

Creado en 21 oct. 2017  ·  101Comentarios  ·  Fuente: pypa/pip

Estoy ausente sin permiso este fin de semana, pero según tengo entendido, debe haber una discusión sobre PEP 518 y su implementación en pip.

Abrí este problema porque no pude ubicar dónde estaba ocurriendo la discusión, si es que es así. Además, ¿sería genial tenerlo en un lugar que no sea pypa-dev/distutils-sig?

auto-locked maintenance

Comentario más útil

En general, necesita instalaciones de pip separadas para ejecutarse dentro de un subproceso, debido a los cachés en lugares como pkg_resources (aunque podría estar equivocado allí).

Sin embargo, eso no significa que deba llamar a pip , puede crear una API que serialice datos a través de la CLI y llamar a python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" y leer más datos de la salida estándar. Sería posible convertir la solución recursiva de pips llamando a pips llamando a pips llamando a pips convirtiéndola en una pila usando una API de este tipo (dado que toda recursividad también se puede describir como una pila), esencialmente estaría creando una API privada que se llama como un proceso.

Todavía planeo leer este hilo (¡últimamente tuve un montón de platos girando!), pero una cosa más: realmente no tenemos un calendario de lanzamiento, lo lanzamos cuando esté listo, no en una fecha determinada. A veces tenemos una idea general de cuándo nos gustaría lanzar, pero eso nunca está escrito en piedra.

Todos 101 comentarios

4799 es donde está ocurriendo gran parte del debate. Fue motivado principalmente por:

  1. Entendí que el único bloqueador pendiente para el soporte de PEP 518 era el #4764 (a través de https://github.com/pypa/pip/pull/4144#issuecomment-302711736)
  2. Entonces apareció el #4799, y lo miré para ver si podía entender todo el trabajo en curso que estaba haciendo @xoviat .
  3. En el transcurso de eso, #4647 apareció como un bloqueador de lanzamiento que decía que el soporte de PEP 518 estaba roto.

Mientras investigaba tratando de averiguar qué decía @xoviat en #4799, se hizo evidente que teníamos algunos problemas con la construcción recursiva de entornos de construcción (X necesita Y para construir e Y necesita Z, ...) aunque yo Todavía no tengo claro si se trata de errores de implementación, problemas de diseño más profundos o casos extremos desagradables que podemos posponer sin demasiados problemas.

Personalmente, estoy en el punto en el que estoy fuera de mi alcance. No entiendo la implementación de @xoviat para juzgar si es necesario, o si aún necesitamos fusionar #4764 y arreglar #4647 para estar listo. Tampoco sé lo fácil que será arreglar el #4647 ( @xoviat parece estar diciendo que necesitamos fusionar el #4799 para arreglar el #4647, pero eso trae sus propios problemas).

Se me acabó el tiempo y la energía para continuar con la discusión este fin de semana, así que me retiraré en este punto (al menos por un tiempo). Para mí, el punto clave es que queremos un nivel aceptable de soporte de PEP 518 para el pip 10. Me gustaría que alguien me diera una idea de si estamos cerca de llegar o si estamos a semanas de distancia, para poder puede evitar que la gente se entusiasme con el pip 10 solo para luego decir que no será hasta el año nuevo...

Gracias por un resumen muy útil @pfmoore.

@ncoghlan @dstufft @xoviat ¿Podemos traer la discusión aquí? Hacerlo en un PR cerrado se siente raro para mí. ._.

Cosa segura.

@pradyunsg Sé que no tienes tiempo para esto. Pero ha tenido más éxito que yo en obtener la aprobación de relaciones públicas, así que si lo desea, estaré más que feliz de guiarlo a través de la implementación actual, cómo funciona y los posibles problemas que tiene. Explicaré cómo resolví algunos (pero no todos) de estos problemas y mis ideas para una solución completa (que nuevamente, puedo hacer después de PEP 517 si no se hace). Sinceramente, no me importa quién haga el trabajo, siempre y cuando esté hecho.

En realidad, estás ausente sin permiso, así que déjame escribir un resumen:

pip tiene una jerarquía de objetos, como es común en la mayoría de los proyectos de Python. Todo comienza con el comando, que crea nuevas referencias a objetos, que crean nuevas referencias a objetos inferiores. Es como un árbol.

Definiré el "alcance" de un objeto como una especie de vida. Es la duración que existe un objeto. En este momento, el alcance de PEP 518 en pip es el WheelBuilder . El entorno PEP 518 se configura para bdist_wheel , luego bdist_wheel se ejecuta dentro de ese entorno y luego se derriba el entorno.

Entonces, ¿cuál es el problema con eso? El problema es que el alcance del entorno PEP 518 debe ser igual o mayor que el alcance de todas las llamadas a setup.py . Más específicamente, necesita encapsular un objeto que existe durante la duración de las llamadas setup.py . Ese objeto es Requirement .

La primera decisión obvia que encontrará es: lo que debería tener una referencia a BuildEnvironment , y el Requirement es un buen lugar como cualquier otro. De hecho, es el mejor lugar en mi humilde opinión para poner la referencia porque setup.py se llama si y solo si existe Requirement .

El siguiente problema que puede encontrar es este: ¿cómo instalamos los requisitos BuildEnvironment ? Podríamos desembolsar hasta pip . Y esa es la decisión que tomó el implementador original. Pero hay un problema con eso: pip no tiene forma de saber cuántas llamadas de shell está haciendo porque cada pip podría volver a llamarse a sí mismo. De hecho, un paquete creado con fines malintencionados con dependencias circulares podría bloquear la computadora de alguien si pip generara demasiados procesos.

Otro problema es ¿qué llamada de shell deberíamos hacer? En realidad, es más complicado de lo que podría pensar, porque obtener los parámetros de la línea de comandos es francamente un PITA donde necesita hacer esa llamada. Por lo tanto, es posible que tenga problemas para pasar los parámetros originales que el usuario le pasó al niño. La solución utilizada por el implementador original implicó el uso de finder , pero creo que conoce el problema con eso.

Sacar a un niño de ti mismo sin algún tipo de clase de administrador que pueda matar a los niños cuando el usuario presiona ctrl+C no solo está mal, es malicioso, especialmente cuando no sabes cuántos procesos has generado. Personalmente, no sé si los niños mueren en la implementación actual (esto podría ser FUD), pero si no lo hacen, la implementación actual en mi humilde opinión es incorrecta (aparte de las otras preocupaciones).

Algunas posibles soluciones a ese problema son las siguientes:

  1. Si desea obtener PEP 518, su mejor opción es probablemente algún tipo de archivo de bloqueo que solo permita hasta 10 bloqueos más o menos para asegurarse de que el pip no se multiplique infinitamente. Luego, puede pasar los requisitos exactos al niño junto con los argumentos de la línea de comandos.

  2. Una solución adecuada, que me gustaría implementar después de PEP 517, es tener una clase BuildEnvironmentManager que se inicialice directamente en el comando install . el BuildEnvironmentManager tendría una referencia a todos los objetos allí ( RequirementPreparer , WheelBuilder , etc.), y tendría un único método: get_build_environment(requirement_set) . Luego podría implementar un método en RequirementPreparer que sea algo así como set_build_environment_manager , que luego puede usar para obtener entornos de compilación. El BuildEnvironmentManager podría incluso detectar múltiples usos del mismo entorno (más comúnmente ['setuptools', 'wheel'] ) y proporcionar el mismo entorno si se necesita varias veces para que no necesite crearlo ( muy común inicialmente con proyectos que no tienen pyproject.toml ). Idealmente, también habría algún diseño OOP para tratar de eliminar las referencias circulares (no trivial).

@xoviat Si bien es posible que no cubra el caso de malicia deliberada, ¿tengo razón al pensar que un caché de compilación (que se usó incluso cuando se especificó --no-binary :all: ) con la capacidad de rastrear no solo las compilaciones completadas, sino también en -los de progreso, ¿sería suficiente para garantizar que terminaran los ciclos de dependencia de compilación? Esta sería una variante de su primera sugerencia (un límite entre procesos en la cantidad de invocaciones de pip simultáneas), pero reformulada como:

  1. Solo se permite que un proceso en una máquina construya el mismo paquete al mismo tiempo
  2. Hay un "ID de compilación" de nivel superior que pip pasa a cualquier subconstrucción que genere (por ejemplo, el PID del proceso de nivel superior combinado con el nombre del paquete que se está compilando)
  3. Si la memoria caché de compilación indica que se está compilando algo con un ID de compilación diferente , espere a que finalice esa compilación.
  4. Si la memoria caché de compilación indica que ya se está compilando algo para el mismo ID de compilación, salte con un error que informa la dependencia circular e indica que se requerirá --binary <name> para que la compilación funcione

pip también necesitaría implementar la sugerencia de @pfmoore de eximir setuptools y wheel de la lógica predeterminada de necesitar tanto setuptools como wheel como dependencias de compilación, de lo contrario, la inyección de dependencia de compilación implícita desencadenaría inherentemente la lógica de detección de dependencia circular.

Usar el disco para evitar tener que resolver problemas de diseño de programación orientada a objetos no es una mala idea. Esa es como una opción intermedia entre implementar PEP 518 completamente correctamente y simplemente piratear algo juntos.

También interactuaría muy bien con entornos en contenedores y chroots en general, ya que podríamos usar herramientas de nivel de sistema operativo para mantener diferentes compilaciones de nivel de Python aisladas entre sí, por lo que pip solo necesitaría averiguar cómo asegurar sus propios subprocesos. cooperar entre sí.

@xoviat gracias por el resumen anterior. Como dije, llegué al límite de mi comprensión del código en esta área, y tu explicación me ha ayudado enormemente.

En realidad, no había mirado el código de #4144 antes. Lo acabo de hacer y realmente no quiero que eso sea un envío.

implementando PEP 518 completamente correctamente y simplemente pirateando algo juntos.

Honestamente, creo que todo se reduce a esto. Implementar PEP 518 completa y correctamente es una tarea que retrasaría/podría retrasar pip 10 un poco (justo) si seguimos ese camino.

Creo que un término medio seguro aquí sería requerir que las dependencias de compilación estén disponibles como ruedas. De esa forma, podemos evitar el problema de recurrencia ya que las dependencias de compilación (y todas sus dependencias) no necesitarían compilarse a través de este proceso.

¿Como suena esto?

Está restringida, pero creo que una primera implementación restringida es mejor que una primera implementación en la que puedes dispararte a ti mismo en el pie si no tienes cuidado.

Implementar PEP 518 completa y correctamente es una tarea que retrasaría/podría retrasar pip 10 un poco (justo) si seguimos ese camino.

Gracias por confirmar eso, ese era mi miedo.

Sin embargo, ahora estoy confundido, ya que pensé que al menos el PEP 518 parcial ya estaba en el maestro. Específicamente, según tengo entendido, # 4647 demuestra un error en el soporte de PEP 518 en el maestro, por lo que claramente ya tenemos algo , ya que lo que sea que sea no es correcto ...

Así que tenemos que hacer algo, y parece que las opciones son:

  1. Saquen todo lo que tengamos para apoyar al PEP 518 en este momento.
  2. Ordenar lo que tenemos y enviar apoyo parcial.
  3. Implemente PEP 518 por completo antes de lanzar pip 10.

Como usted dice (3) significa un largo retraso antes del pip 10 y tenemos otras correcciones que realmente me gustaría ver publicadas (las correcciones de Unicode son una de las que regularmente tenemos problemas). Así que no estoy interesado en eso. No mencionó (1), y no estoy seguro de si eso se debe a que pensó que no contábamos con el apoyo de PEP 518 o si asumió que retirarlo no era una opción. Personalmente, no me gusta la idea: es un paso atrás y envía un mensaje bastante negativo sobre el PEP en sí, si es tan difícil de implementar correctamente. Pero creo que deberíamos ser explícitos en rechazarlo.

Su propuesta para (2), que enviemos una versión de PEP 518 que solo admita ruedas como dependencias de compilación (todavía tendríamos que arreglar #4647, ya que la demostración de eso usa una dependencia de compilación que es una rueda) parece razonable , en el sentido de que es práctico para nosotros implementar. Mi principal reserva es que no tengo idea de cuán problemática sería esa restricción para las personas que desean usar PEP 518.

Así que supongo que siento que estamos atascados hagamos lo que hagamos, pero el soporte parcial que cubre solo las ruedas como dependencias de compilación es la mejor opción de un lote malo :-(

Los autores de PEP (en https://github.com/pypa/pip/pull/4799#issuecomment-338331267 y https://github.com/pypa/pip/pull/4799#issuecomment-338332575 en respuesta a mi pregunta en https://github.com/pypa/pip/pull/4799#issuecomment-338325354) fueron bastante claros en cuanto a que la compatibilidad total con PEP requería la creación de dependencias de compilación, por lo que tiene que ser solo un recurso provisional.

Pero no seré yo quien implementará esto, así que estoy feliz de aceptar el juicio de quien lo haga. Una cosa que hice fue crear #4803 y marcarlo como un bloqueador de versiones, como un recordatorio de que debemos documentar cómo nos desviamos de la especificación, si es necesario.

(Y fuera de tema para este problema, pero ¿puedo sugerir que tengamos cuidado de no cometer los mismos errores cuando comencemos a implementar PEP 517? Asegurémonos de comprender todas las implicaciones de implementación antes de profundizar demasiado en la codificación: mi instinto es que PEP 517 va a ser un problema de diseño aún más complejo que PEP 518...)

Estoy más familiarizado con las distribuciones cuando se trata de la perspectiva de "construir todo desde la fuente", y definitivamente separamos el proceso de "arrancar la raíz de compilación" del de las compilaciones de paquetes regulares. El arranque automático completo desde la fuente es difícil , ya que termina teniendo que hacer cosas como arrancar su compilador C.

Entonces, para pip, creo que es razonable decir que las dependencias de compilación siempre se podrán instalar desde archivos de rueda. El refinamiento que puede introducir después de 10.x es tener un caché de compilación que sea distinto del caché de rueda normal, de modo que los usuarios del caché puedan estar seguros de que todas las ruedas que se construyeron en un entorno controlado, en lugar de descargarse de PyPI. u otro servidor de índices.

Personalmente, no me gusta la idea: es un paso atrás y envía un mensaje bastante negativo sobre el PEP en sí, si es tan difícil de implementar correctamente.

No estoy necesariamente de acuerdo con eso. Es difícil de implementar correctamente para pip. Pero pip, como se indica en el PEP, es uno de los únicos extremos frontales que la gente va a usar. Creo que es nuestro trabajo como implementadores de lenguajes, y pip realmente es un lenguaje que la gente usa para empaquetar sus proyectos de python, para simplificar al máximo la creación de un sistema de compilación sin tener que pensar en todos estos problemas difíciles. Para ellos debería funcionar a la perfección porque hemos hecho el trabajo duro.

Creo que un término medio seguro aquí sería requerir que las dependencias de compilación estén disponibles como ruedas.

En realidad, eso es exactamente lo que hace #4799. Si quieres, puedo restaurar esa rama y luego puedes bifurcarla y enviarla como PR.

Sin embargo, dos cosas en el lado de la implementación de las cosas de (2) siguen en pie, como @xoviat había señalado anteriormente:

  1. descubrir cómo crear el subproceso (arguments et al)
    Creo que debería ser factible.

  2. qué versiones de paquetes se instalarán.
    Esto probablemente debería hacerse en el mismo proceso principal, aunque no estoy seguro de cómo sucedería exactamente, dado que el código de resolución actual todavía está entrelazado con el código en pip._internal.operations.prepare . Voy a investigar esto en algún momento de esta semana.

Sin embargo, no estoy seguro de quién tendría tiempo para hacer esto.


envía un mensaje bastante negativo sobre el propio PEP, si es tan difícil de implementar correctamente.

Probablemente no sea difícil de implementar correctamente. Es solo que con la forma en que está el código base de pip hoy, no es trivial implementarlo en pip: hay cosas que suceden en lugares extraños y creo que si eso se limpia, sería bastante trivial.

No mencionó (1), y no estoy seguro de si eso se debe a que pensó que no contábamos con el apoyo de PEP 518 o si asumió que retirarlo no era una opción.

Supuse que echarse atrás no es una opción.

Ahora que lo pienso, ¿qué tan importante es enviar PEP 518 en pip 10? Siento que si se puede aplazar hasta el próximo lanzamiento principal, sería (además de ser la forma más fácil de salir de esta situación) sencillo y ambos 517 + 518 podrían aterrizar en un gran lanzamiento. Esto se siente lo suficientemente limpio como para no ser yo quien diga que este no es el camino a seguir.

@dstufft @xavfernandez pensamientos?


La idea de @ncoghlan de un build-cache me parece una buena idea, aunque no estoy seguro de entender todas sus implicaciones.


Si quieres, puedo restaurar esa rama y luego puedes bifurcarla y enviarla como PR.

Probablemente no tendré tiempo e incluso si lo tuviera, es posible que no esté reutilizando ninguna confirmación existente. Pero restaurar esa rama no puede hacer daño. :)

Mi principal reserva es que no tengo idea de cuán problemática sería esa restricción para las personas que desean usar PEP 518.

Hemos tenido esta discusión exacta excepto que probablemente ni siquiera lo sabías. Esta situación es la situación X. Llamar a egg_info antes de configurar el entorno de compilación es la situación Y (#4799).

Pero no seré yo quien implementará esto, así que estoy feliz de aceptar el juicio de quien lo haga.

¿Supongo que eso significa que #4799 está de vuelta sobre la mesa entonces? ¿Siempre y cuando pase todas las pruebas y haga lo que dice hacer?

Aargh, esas X e Y vuelven a atormentarme de nuevo :wink: Sí, estoy diciendo que no tengo idea de las probabilidades relativas de los 2 casos. Entiendo que está diciendo que los requisitos de construcción que no son ruedas son lo suficientemente raros como para que podamos ignorar ese caso. Así que hubo un voto de "está bien" y uno de "no sé" entre nosotros, básicamente. No estoy tratando de bloquear esta opción, solo digo dónde están los límites de mi intuición, eso es todo.

@xoviat Tengo algunas preguntas. Sería genial si las respondieras antes de hacer un nuevo PR. :)

  • ¿Cómo va a determinar qué paquetes se instalan?
  • ¿Va a restringir a dependencias de compilación solo binarias?

He trabajado con muchos de los proyectos científicos por lo que podría ser que soy parcial. Pero puedo recitar una lista de proyectos con dependencias de construcción de ruedas y realmente no puedo pensar en un proyecto con dependencias de origen. Puede ser que esté equivocado.

@rgommers , ¿estaría de acuerdo con que PEP 518 solo admita las dependencias de compilación disponibles como ruedas si estuviera en el siguiente pip?

¿Cómo va a determinar qué paquetes se instalan?

El subproceso obtiene la lista de requisitos exactamente como se especifica. De esa manera pasa por el resolver.

¿Va a restringir a dependencias de compilación solo binarias?

Sí, de hecho, esa es la razón por la cual la prueba falló. La dependencia de compilación en la prueba no es una rueda.

Ahora que lo pienso, ¿qué tan importante es enviar PEP 518 en pip 10? Siento que si se puede aplazar hasta el próximo lanzamiento principal, sería (además de ser la forma más fácil de salir de esta situación) sencillo y ambos 517 + 518 podrían aterrizar en un gran lanzamiento. Esto se siente lo suficientemente limpio como para no ser yo quien diga que este no es el camino a seguir.

¿Cuál es nuestra opinión sobre si conseguiremos a alguien con tiempo para hacer los PEP 517 y 518 para el pip 11? No soy optimista. Me parece que ambos son grandes porciones de trabajo, y también tenemos el trabajo de resolución en curso. Si bien no estoy a favor de retrasar pip 10 más de lo necesario, me siento igualmente incómodo con dejar que todos nuestros planes de características principales se desvíen mientras lanzamos una serie de lanzamientos esencialmente menores.

Para decirlo de otra manera, decir "vamos por un lanzamiento de pip 10" provocó un resurgimiento de la actividad en el trabajo PEP 518. Si eliminamos eso del pip 10, por mi parte me concentraré en preparar las cosas para el lanzamiento, y sospecho que es probable que PEP 518 pierda impulso nuevamente. ¿Qué es poner las cosas en actividad de nuevo? @xoviat ha estado trabajando en la implementación, pero ha tenido problemas para que el resto de nosotros entendamos los problemas con los que ha estado luchando hasta ahora. No quiero dejarlo trabajando sin comentarios de nuevo.

Lo que podríamos hacer es lanzar un "pip 9.1" con solo las correcciones incrementales que tenemos listas y reservar el número de versión "pip 10" para la implementación de (al menos una de) las 3 funciones importantes que están en trámite. Pero si hacemos eso, me gustaría intentar [1] comprometerme con un lanzamiento de pip 10 en el primer trimestre de 2018. Estaría de acuerdo con eso como enfoque. Pero, ¿alguien tiene una idea de lo que implicaría retirar el apoyo parcial que tenemos actualmente en Master? O al documentar lo que tenemos y cuáles son sus limitaciones (para que la gente no intente usarlo asumiendo que está completo, encuentre errores y plantee problemas a los que tenemos que responder con "esta función aún no está completa, lo siento, pero espere pip 10")? ¿Estamos simplemente intercambiando una gran parte del trabajo por otra diferente?

[1] En la medida en que podamos comprometernos con cualquier cosa con un recurso voluntario extremadamente limitado como todo lo que tenemos disponible.

He trabajado con muchos de los proyectos científicos por lo que podría ser que soy parcial

Gracias, a veces es difícil conocer los antecedentes de las personas. Si está familiarizado con los proyectos científicos, eso alivia mucho mis preocupaciones.

Lo que podríamos hacer es lanzar un "pip 9.1" con solo las correcciones incrementales que tenemos listas y reservar el número de versión "pip 10" para la implementación de (al menos una de) las 3 funciones importantes que están en trámite.

Realmente me gusta esto. +1 a un pip 9.1.0 en lugar de un pip 10.0.0

Me gustaría intentar [1] comprometerme con un lanzamiento de pip 10 en el primer trimestre de 2018. Estaría de acuerdo con eso como enfoque.

Tuve una idea muy interesante: pip cumple 10 años el 12 de octubre de 2018. Esa sería la fecha perfecta para hacer un lanzamiento de pip 10.0.0. Es una línea de tiempo completamente diferente. No digo que debamos retrasar las características de la ballena blanca hasta entonces, pero una parte de mí realmente quiere que este número de versión y la edad coincidan también.

Sospecho que es probable que PEP 518 pierda impulso nuevamente.

Haré lo que pueda para asegurarme de que no lo haga. Esperemos que @xoviat esté dispuesto a hacerlo también. :)

¿Alguien tiene una idea de lo que implicaría retirar el apoyo parcial que tenemos actualmente en Master?

No me importará echarle un vistazo a esto mañana. Dado que @dstufft fue el que se revisó en el n.° 4144, creo que su aporte al respecto sería valioso.

Nota: no me gustaría hacer nada tan drástico como dar marcha atrás sin el acuerdo de @dstufft y @xavfernandez , así que veamos qué tienen que decir también.

@dstufft no tiene suficiente tiempo en el día. También tiene que asegurarse de que el almacén no se caiga.

vamos a ver lo que tienen que decir, también.

Sí, por favor. :)

Desde una perspectiva de UX: contrarrestar de manera integral el ataque de "confianza confiable" es realmente doloroso [1], y encontrará muchas personas que dicen "Compilo todo desde la fuente" en realidad no lo están haciendo, en algún lugar de su proceso allí será un paso inicial en el que confían en un binario proporcionado por otra persona (p. ej., el entorno de tiempo de ejecución y la cadena de herramientas de compilación de su proveedor de sistema operativo), o de una generación anterior de su propia plataforma (p. ej., las raíces de compilación para las nuevas versiones de Fedora y RHEL se basa en versiones anteriores de Fedora y RHEL, no comienzan completamente desde cero). Incluso una distribución de Linux basada en fuente como Gentoo comienza con un instalador para brindarle un entorno de compilación funcional con un kernel de Linux, un compilador de C, controladores de hardware, etc.

Así que creo que es completamente razonable que pip 10 diga que --no-binary :all: solo se aplica a las dependencias de tiempo de ejecución, no a las dependencias de compilación. Si la gente quiere construir explícitamente su raíz de compilación a partir de la fuente, aún pueden; es solo que pip 10 no lo automatizará implícitamente debido a los problemas inherentes de arranque recursivo involucrados en permitir compilaciones de fuente implícitas para sus dependencias de compilación.

Sin embargo, para permitir que las personas indiquen que esperan que el entorno de compilación esté completamente preconfigurado, sería razonable agregar una opción --no-implicit-builddeps separada para que la instalación falle por completo si se necesita un arranque binario implícito como parte de una compilación fuente. . De esa manera, las personas que intentan asegurarse de que todo esté compilado desde el origen (incluidas las dependencias de compilación) pueden hacer el equivalente a:

pip install --no-binary :all: --no-implicit-builddeps -r build-requirements.txt
pip install --no-binary :all: --no-implicit-builddeps -r requirements.txt

Y defina tantos grupos de instalación distintos como sea necesario para llegar a un punto en el que el primero no necesite nada más que CPython y cualquier cadena de herramientas de compilación que no sea de Python preinstaladas.

Un posible complemento futuro para ese concepto sería permitir que las personas digan --buildenv <path> para especificar un entorno de compilación preconfigurado para usar en cualquier compilación de origen requerida, en lugar de realizar cada compilación en un entorno aislado. Sin embargo, no intentaría incluir eso en pip 10; sugeriría limitar 10.x al camino feliz de "se permiten dependencias de compilación binaria" y la opción alternativa de "fallar la compilación si se necesita una dependencia de compilación binaria y aún no está disponible en el intérprete que se está ejecutando actualmente".

[1] https://www.schneier.com/blog/archives/2006/01/countering_trus.html

He pensado en otra opción, que parece razonable y no requeriría demasiada refactorización: esencialmente usar subprocesos múltiples para poner el subproceso principal en espera mientras se configura el entorno de compilación. La idea es algo así: en install.py , tendrías un BuildEnvironmentManager :

class BuildEnvironmentManager(Thread):
    '''Has references to literally everything (cache, resolver, etc.)'''
    def run(self):
        while True:
            requirement_list, future = self.build_environment_queue.get()

            # install the requirements using all of the things
            # that we have

            # then put the build environment in the future
            future.put(BuildEnvironment())

Entonces tendría otro archivo (uso backend.py porque no está lo suficientemente lleno y probablemente podría usar más cosas en él, y está en el extremo inferior del árbol):

class Future(Queue):
    pass

class BuildEnvironmentQueue(object):
    def __init__(self):
        self._queue = Queue()

    def request_build_environment(self, requirement_list):
        f = Future()
        self._queue.put((requirement_list, f))
        return f.get()

    def get():
        return self._queue.get()

Y en operaciones/prepare.py:

# This call will put the thread to sleep until we have a build environment
# with the requirements installed
self.build_environment_queue.request_build_environment(requirement_list)

Esto tiene la ventaja de requerir una refactorización mínima, tener un BuildEnvironmentManager serializado (para que los entornos de compilación se puedan optimizar y saber exactamente qué solicitudes se han realizado en un solo objeto) y mantener todo contenido en un proceso (para que el el peor de los casos es un punto muerto). Por supuesto, sería necesario deshabilitar el registro para los otros subprocesos, pero eso no es un gran problema.

Respondiendo a mi propia pregunta sobre el enfoque basado en queue.Queue: es mejor evitar confiar en concurrent.futures, ya que su uso requeriría la venta de https://pypi.org/project/futures/ en Python 2.7.

Sin conocer bien el código base pip , la idea de consolidar la administración del entorno de compilación en un solo lugar todavía parece una opción atractiva.

concurrent.futures no es necesario para ese enfoque. Future es solo un envoltorio más descriptivo.

La única primitiva requerida es una cola: https://docs.python.org/2/library/queue.html

Supongo que podemos mover estas líneas a BuildEnvironmentManager .

He trabajado con muchos de los proyectos científicos por lo que podría ser que soy parcial. Pero puedo recitar una lista de proyectos con dependencias de construcción de ruedas y realmente no puedo pensar en un proyecto con dependencias de origen. Puede ser que esté equivocado.

Bueno, por un lado, hay todos los sistemas operativos que no son [Windows, macOS, Linux], IIRC esos no están cubiertos por manylinux1 .

@rgommers , ¿estaría de acuerdo con que PEP 518 solo admita las dependencias de compilación disponibles como ruedas si estuviera en el siguiente pip?

No es mi llamada, pero estaría feliz con cualquier paso adelante aquí. El soporte PEP 518 es opcional de todos modos, por lo que solo funciona cuando hay ruedas disponibles (cubre> 90% de los casos, diría yo) en pip 10 sigue siendo una mejora significativa.

Tenga en cuenta que incluso las plataformas que no permiten ruedas en PyPI seguirán teniendo un caché de rueda local, lo que significa que incluso si pip no puede iniciar cosas implícitamente , aún puede imprimirlas y decir "instale estas dependencias de compilación de alguna manera , y entonces esto funcionará".

Pero, ¿alguien tiene una idea de lo que implicaría retirar el apoyo parcial que tenemos actualmente en Master?

Investigué esto; no parece ser demasiado difícil. Estaré feliz de hacer un PR si decidimos ir por este camino.

+1 a un pip 9.1.0 en lugar de un pip 10.0.0

Finalmente tuve tiempo de leer correctamente el hilo distutils-sig y mirar las relaciones públicas y las discusiones relevantes (#4351, #4144, #4799 y muchos otros). Ahora creo que ya que hemos anunciado pip 10; eso es lo que deberíamos hacer, con el soporte parcial de PEP 518 -- no 9.1.0.

este número de versión y edad para coincidir

Gorrón. :(

@ncoghlan Tal vez este comentario pasó desapercibido -- https://github.com/pypa/pip/pull/4799#issuecomment -338416543

En caso de que no fuera así, sería bueno si pudieras explicar por qué no funcionaría porque entiendo ese tipo de configuración y definitivamente estoy abierto a aprender más al respecto. :)

@pradyunsg Creo que en su mayoría funcionaría, ya que es una implementación específica de la idea de caché de compilación. El único aspecto que no cubre es construir bucles de dependencia, ya que le falta una forma de detectar "Me acaban de pedir que construya algo que ya estoy intentando construir".

Tenga en cuenta que pip no necesita resolver mágicamente los bucles de dependencia, solo necesita detectarlos y fallar tan pronto como detecte uno, en lugar de entrar en un bucle infinito.

no cubre es construir bucles de dependencia,

¿Eso no ocurriría con dependencias de compilación solo binarias?

@pradyunsg El comentario vinculado se refería a una forma de permitir compilaciones de origen para dependencias de compilación, lo que significa que las dependencias circulares se convierten en una preocupación potencial. Si requerimos dependencias binarias, entonces pip solo puede confiar en el caché de rueda existente por el momento.

Ah bien. ¡Gracias! :)

Estoy a favor de un pip 10 con una implementación parcial de PEP 518 limitada solo a las dependencias de compilación binaria (o ya disponible en la memoria caché de rueda de pip) si eso es todo lo que logramos incluir.

Todavía no he leído el hilo completo, pero solo quiero señalar que un efecto secundario de limitar las dependencias de compilación binarias será que es ~imposible tener una dependencia de C en sus dependencias de compilación en muchos casos. Sí, tenemos ruedas binarias en Windows, macOS y algunas versiones de Linux, pero no en:

  • Cualquier Linux que no use glibc (Alpine Linux dentro de Docker es uno de los más populares).
  • Cualquier sistema operativo *nix que no sea Linux, como FreeBSD, etc.

Esto significaría que cualquier proyecto basado en CFFI, por ejemplo, no podría usar PEP 518 o sería desinstalable en esas plataformas.

¡Esto podría haber sido mencionado ya! Estaré leyendo este hilo más tarde.

@dstufft Eso es correcto. Pero lo que estamos proponiendo es que usar el caché de pip es una opción. Entonces, solo puede pip wheel o pip install sus dependencias de compilación primero y luego se almacenarán en el caché.

¡Esto podría haber sido mencionado ya!

No. :)

Esto significaría que cualquier proyecto basado en CFFI, por ejemplo, no podría usar PEP 518 o sería desinstalable en esas plataformas.

Por supuesto. :-(

La forma de evitar esto en mi cabeza sería que podríamos hacer que el comportamiento de PEP 518 sea opcional: si hay un archivo pyproject.toml , usamos el entorno de aislamiento + compilación; de lo contrario, recurrimos al comportamiento actual de usar setup.py .

Estaré leyendo este hilo más tarde.

Por favor, hazlo. :)

Tuve exactamente el mismo comentario que Donald; Entiendo que este hilo es que solo binario es temporal porque no hay tiempo para implementarlo para pip 10. ¿Correcto?

Si se propuso como una decisión permanente, entonces -1 por supuesto.

Tuve exactamente el mismo comentario que Donald; Entiendo que este hilo es que solo binario es temporal porque no hay tiempo para implementarlo para pip 10. ¿Correcto?

Eso es correcto. pip debería ser compatible con las dependencias de origen, pero nos falta mano de obra.

La forma de evitar esto en mi cabeza sería que podríamos hacer que el comportamiento de PEP 518 sea opcional: si hay un archivo pyproject.toml, usamos el entorno de aislamiento + compilación; de lo contrario, recurrimos al comportamiento actual de usar setup.py.

Releí este comentario y voy a estar en desacuerdo aquí. El soporte de PEP 518 no debería ser opcional (por razones de implementación relacionadas con PEP 517) en mi humilde opinión, pero los proyectos no deberían volverse desinstalables en estas plataformas.

Más específicamente, el proyecto particular que está instalando no debe determinar si obtiene PEP 518. Eso debe determinarse si sus dependencias de compilación están disponibles como ruedas o en el caché. Además, también podemos hacer que el soporte de PEP 518 sea obligatorio para esas plataformas si enviamos un mensaje como el siguiente:

Error: build dependency X is not in the pip cache. Run "pip install X" before installing Y.

Resumiendo mi propia perspectiva:

  1. Considero que "No hay soporte de compilación implícito para dependencias de compilación" como una limitación temporal en pip 10 para hacer que ciertas clases de problemas (por ejemplo, bucles de dependencia de compilación) sean imposibles de encontrar en la primera iteración lanzada de la función. Las iteraciones futuras del soporte de back-end de compilación conectable pueden permitir compilaciones de origen implícitas para dependencias de compilación, al tiempo que se implementan medidas adecuadas para evitar los nuevos problemas que surgen una vez que lo permite.
  2. Emitir el comando python -m pip wheel X Y Z relevante en un mensaje de error sin ejecutar la compilación implícitamente es una solución adecuada por ahora, ya que garantiza que pip no pueda inadvertidamente fork bombear una máquina.
  3. Las compilaciones aisladas probablemente no deberían ser las predeterminadas todavía, a menos que la rueda específica que se está construyendo tenga un archivo pyproject.toml , o las compilaciones aisladas se soliciten explícitamente desde la línea de comando. Este es un problema de compatibilidad con versiones anteriores, ya que los proyectos existentes esperarán el comportamiento no aislado. Una vez que las compilaciones aisladas han estado disponibles para una versión o dos, y se han resuelto los problemas de uso con ellas, pueden convertirse en las predeterminadas en general (quizás con una opción de línea de comando para especificar un entorno de compilación particular para usar en lugar de generar implícitamente compilaciones aisladas). unos)

@ncoghlan Solo para darle un aviso: sin aislamiento de compilación predeterminado significa que no hay PEP 517 (al menos con mi enfoque) porque solo la versión más nueva de setuptools lo admite (necesitamos instalar una configuración más nueva independientemente de lo que esté en la persona computadora). Prácticamente, creo que eso podría retrasar PEP 517 al menos un año porque aumentará drásticamente la cantidad de esfuerzo requerido para implementarlo (que requiere PEP 517 y código no PEP 517).

Este es un problema de compatibilidad con versiones anteriores, ya que los proyectos existentes esperarán el comportamiento no aislado.

La mayoría de las personas tienen scripts de CI que ejecutan pip install X y luego ejecutan pip install Y . Estos proyectos necesitarían agregar un pypproject.toml . Pero agregar pyproject.toml no es mucho trabajo, y podemos agregar un indicador de línea de comando para deshabilitar el aislamiento de compilación si es necesario.

Al menos deberíamos emitir una advertencia si un proyecto no tiene pyproject.toml en pip 10 (lo que parece que no va a tener soporte PEP 517 de todos modos).

@xoviat "No sería tanto trabajo ajustarlo" no es así como funciona la compatibilidad con versiones anteriores. Si lo fuera, pip ya habría cambiado a --user como el modelo de instalación predeterminado que no es venv :)

En lo que respecta a PEP 517, no puede depender de PEP 517 como editor de paquetes sin agregar un archivo pyproject.toml , por lo que está bien si solo los setup.py no obtienen soporte de PEP 517 por defecto.

¿Estarías bien con escupir una advertencia?

Lo vería como un problema si una compilación que actualmente funciona bien comenzara a emitir una advertencia solo porque pip se actualizó, incluso si ni el proyecto en sí ni ninguna de sus dependencias han cambiado.

PEP 518 y 517 se diseñaron deliberadamente para no causar interrupciones en los proyectos existentes en los que todos los editores involucrados continuaron confiando únicamente en las herramientas de configuración.

Tiene sentido que pip apunte a consolidarse de nuevo en una sola ruta de compilación PEP 518 incluso para proyectos basados ​​en herramientas de configuración, pero el momento para eso es después de que las compilaciones aisladas hayan visto una o dos versiones de uso práctico, no en la primera versión que los soporta en absoluto.

Tuve exactamente el mismo comentario que Donald; Entiendo que este hilo es que solo binario es temporal porque no hay tiempo para implementarlo para pip 10. ¿Correcto?

Sí. Exactamente.


Tiene sentido que pip apunte a consolidar de nuevo a una única ruta de compilación PEP 518, incluso para proyectos basados ​​en herramientas de configuración, pero el momento para eso es después de que las compilaciones aisladas hayan visto una o dos versiones de uso práctico, no en la primera versión que los apoya en todo.

+1

Creo que deberíamos apuntar a eliminar el camino anterior, como 2 lanzamientos principales. Cuando pip aterriza por completo y con soporte PEP 518 adecuado; debemos desaprobar la lógica de compilación anterior y eliminarla de acuerdo con la política de desaprobación estándar.

Estoy de acuerdo con el resumen de Nick y...

porque aumentará dramáticamente la cantidad de esfuerzo requerido para implementarlo

No. No creo que implementar PEP 518 de esta manera tenga obstáculos importantes; Hice un breve comentario sobre https://github.com/pypa/pip/pull/4799#issuecomment -339219397 sobre cómo se podría implementar esto dentro de pip.


Lo que queremos hacer es proporcionar a las personas una transición limpia de lo antiguo a lo nuevo. Por lo tanto, debemos mantener la lógica de instalación actual de pip 9 sin cambios, lo que básicamente admitiría todo lo que hacemos actualmente de la manera exacta en que lo hacemos.

Poner un archivo pyproject.toml en el archivo significaría que el paquete está optando por el estándar más nuevo y está dispuesto a probar el soporte para el nuevo comportamiento, pasando por el entorno de compilación con aislamiento y compilación solo binaria. -dependencias (por ahora).

No. No creo que implementar PEP 518 de esta manera tenga obstáculos importantes;

Discutiendo PEP 517 aquí. Perdón por la confusion.

Tendríamos que ejecutar las pruebas dos veces para verificar ambas rutas de código. Ah, bueno, PEP 517 probablemente sea diferido.

OMI,

  1. Advertencia si un proyecto no tiene pyproject.toml suena como una muy mala idea. Después de todo, el 99% de los proyectos en PyPI actualmente no tienen pyproject.toml , y no podemos enviar spam a los usuarios finales con advertencias sobre las que no pueden hacer nada (aparte de informar el problema a los proyectos). ). ¿Me estoy perdiendo de algo?
  2. No creo que el aislamiento de compilación se haya mencionado en absoluto en PEP 518. Es una característica adicional que pip ha querido incluir desde hace algún tiempo, pero no está vinculada al soporte de PEP 518, excepto por el hecho coincidente de que el mismo PR implementó ambos (AFAIR). Entonces, si el aislamiento de compilación es lo que nos está dando problemas aquí, estoy de acuerdo con tener solo PEP 518 inicialmente y agregar aislamiento como una fase 2. Sin embargo, dejaré esa decisión a las personas que implementan las cosas.

¿Me estoy perdiendo de algo?

No.

Estoy de acuerdo con tener solo PEP 518 inicialmente y agregar aislamiento como fase 2.

Creo que deberíamos hacer PEP 518 y construir el aislamiento juntos, ya que es una buena manera de hacer que la gente cambie a construcciones aisladas.

Si bien ni PEP 518 ni PEP 517 requieren compilaciones aisladas, PEP 517 las recomienda por motivos sólidos: https://www.python.org/dev/peps/pep-0517/#recommendations -for-build-frontends-non-normative

Sin un caché de artefacto binario local, los entornos de compilación aislados no son prácticos, pero una vez que tiene uno de esos (como ahora lo tiene pip ), son mucho más factibles, ya que:

  1. En la mayoría de las instalaciones, ni siquiera necesitará hacer una compilación de fuente en primer lugar
  2. Cuando necesite hacer una compilación de origen, generalmente configurará el entorno de compilación desde el caché

Al mismo tiempo, los entornos de compilación aislados requieren un poco más de trabajo por parte de los editores, ya que significan que los metadatos con errores romperán las propias compilaciones del editor de una manera que les obliga a decir explícitamente "Mis dependencias de compilación no están completamente declaradas" para poder hacer una construcción.

Por lo tanto, tener compilaciones basadas pyproject.toml aisladas desde el principio proporciona un punto de cambio natural, ya que todo el PEP se trata de proporcionar una manera de declarar clara y consistentemente las dependencias de compilación por separado de las dependencias de tiempo de ejecución. Eso significa que las personas que cambian de setup.py presumiblemente lo hacen porque les importa hacer ese tipo de cosas, mientras que las personas que llegan frescas para nuevos proyectos simplemente lo tratarán como otro aro que las herramientas de empaque los obligan a saltar. mediante.

Entonces, solo algunas cosas que quiero confirmar antes de comenzar a escribir el código:

  • El soporte de PEP 517 no es un bloqueador para pip 10
  • PEP 518 en pip 10

    • suscripción a través pyproject.toml

    • solo admite dependencias de compilación solo binarias

    • construcciones aisladas

PEP 517 no puede ser un bloqueador para pip 10 porque aún no está listo y no hay un camino claro a seguir en este punto (hay un camino a seguir pero no está claro).

Tengo un comentario y una pregunta en respuesta al comentario de @xoviat aquí que resume los desafíos de implementación, así como después de leer este hilo rápidamente.

Primero, con respecto al tema de la recursión de cosas que posiblemente exploten, en general, cualquier función recursiva puede "traducirse" a una iterativa. Me pregunto si ese enfoque podría ayudar aquí al proporcionar más control.

En segundo lugar, ¿qué compra desembolsar en lugar de llamar a una función pip desde Python? ¿Hay alguna razón por la que no se pueda crear/refactorizar una función de API interna que haga lo que sea que el desembolso esté tratando de lograr? Eso debería proporcionar más flexibilidad al invocar la llamada (en comparación con los parámetros CLI). Esto también podría proporcionar más control al permitirle administrar más fácilmente el estado del proceso general.

¿Hay alguna razón por la que no se pueda crear/refactorizar una función de API interna que haga lo que sea que el desembolso esté tratando de lograr?

En segundo lugar, ¿qué compra desembolsar en lugar de llamar a una función pip desde Python?

Compra tiempo que actualmente no tenemos. pip ya está atrasado en su calendario de lanzamiento.

Primero, con respecto al tema de la recursión de cosas que posiblemente exploten, en general, cualquier función recursiva puede "traducirse" a una iterativa.

No soy anti recursión. Soy anti proceso-recursión. Creo que está bien si desea usar el 100 % de la CPU (bueno, sería el 20 % en Python), pero en última instancia, el usuario debe poder abrir el administrador de tareas y eliminar el máximo de 15 procesos que hay. Para mí, una situación que podría provocar una explosión del proceso es inaceptable.

Sin embargo, eso no responde a la pregunta de por qué gana tiempo. ¿Qué dificulta la creación de una función de API interna que haga lo mismo?

En cualquier caso, si el desembolso resuelve algún problema en particular, una posibilidad para facilitar este enfoque podría ser exponer temporalmente un comando CLI privado/interno que facilite pasar cualquier información que se necesite (por ejemplo, podría ser incluso un objeto de Python serializado , etc.).

Sin embargo, eso no responde a la pregunta de por qué gana tiempo. ¿Qué dificulta la creación de una función de API interna que haga lo mismo?

Si crees que es fácil, adelante. No lo digo con sarcasmo: por favor, adelante, porque resolverá todos los problemas.

No creo que sea fácil. Estoy haciendo la pregunta para obtener una idea de por qué es difícil. (Supongo que ha pensado en esto porque dijo que ahorraría tiempo).

En general, necesita instalaciones de pip separadas para ejecutarse dentro de un subproceso, debido a los cachés en lugares como pkg_resources (aunque podría estar equivocado allí).

Sin embargo, eso no significa que deba llamar a pip , puede crear una API que serialice datos a través de la CLI y llamar a python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" y leer más datos de la salida estándar. Sería posible convertir la solución recursiva de pips llamando a pips llamando a pips llamando a pips convirtiéndola en una pila usando una API de este tipo (dado que toda recursividad también se puede describir como una pila), esencialmente estaría creando una API privada que se llama como un proceso.

Todavía planeo leer este hilo (¡últimamente tuve un montón de platos girando!), pero una cosa más: realmente no tenemos un calendario de lanzamiento, lo lanzamos cuando esté listo, no en una fecha determinada. A veces tenemos una idea general de cuándo nos gustaría lanzar, pero eso nunca está escrito en piedra.

En última instancia, Python tiene una profundidad de recursión máxima para asegurarse de que las cosas no se salgan de control. Tendríamos que implementar eso si fuéramos con ese enfoque.

Sí, un enfoque basado en la pila hace que sea bastante eficiente ir bastante profundo (mucho más profundo que cualquier cosa que no sea un bucle de dependencia, por ejemplo, podríamos tener algo que dependa literalmente de cada paquete y aún así estar bien), lo principal hacer es detectar bucles.

Una forma bastante ingenua y fácil de hacer la detección de bucles es simplemente poner un límite superior en la cantidad de elementos en la pila y decir que si alcanza este límite, seguramente debe estar en una situación de bucle y error. Las desventajas de eso son, por supuesto, que los bucles no se detectan lo antes posible, y los paquetes con cadenas de dependencia de compilación más profundas que el límite simplemente no funcionan.

En general, la mejor opción (ya que si usa un enfoque basado en la pila puede acceder a toda la pila) es simplemente atravesar la pila y ver si el elemento que estamos intentando instalar ya está en la pila en algún lugar, y si es ruptura y error porque hemos llegado a un bucle (este error podría presentarse al usuario final o podría aparecer en el resolutor eventualmente para probar una versión diferente, aunque eso lo hace mucho más lento).

Y para responder directamente a la pregunta de @cjerdonek : en principio, esto no es difícil, lo que complica las cosas son algunas suposiciones arquitectónicas integradas en la forma en que pip funciona actualmente que ya no son ciertas en un mundo donde cada fuente compila obtiene su propio entorno de compilación aislado, en lugar de ejecutarse directamente en el entorno de instalación.

Eso significa que la forma más fácil de reutilizar la lógica de administración de dependencia existente pip sin tropezar con esas limitaciones arquitectónicas internas y sin arriesgarse a romper el código que funciona actualmente es ejecutar otra instancia de pip en un subproceso. Eso está bien en su mayoría, excepto por la consecuencia de que fallar en detectar y rescatar los bucles de dependencia puede bombardear el sistema que ejecuta la compilación.

Me gusta la idea de @dstufft de convertir a un enfoque iterativo/basado en pilas y desembolsar una función de pip interna usando el patrón python -c "from pip._internals import coolapithing; coolapithing(sys.stdin.read())" . Eso parece más simple basado en la discusión, así como robusto.

Creo que el primer paso hacia esto sería reducir el enfoque recursivo directo a una sola función de Python recursiva con la entrada y salida esperadas (al menos esbozarla), y luego esto podría traducirse/convertirse al enfoque iterativo. Y sí, podría mantener un set de llamadas visitadas para evitar el bucle, lo que parece ser uno de los aspectos más fáciles de resolver.

Investigué / pensé un poco más en convertir el enfoque recursivo en uno iterativo. El trabajo parcial de @xoviat en PEP 518 (PR #4799) me ayudó a encontrar el punto de recurrencia (con el que algunos de ustedes probablemente ya estén familiarizados). Está en su comentario de código:

# TODO: Use single process with recursion handling

donde luego invoca pip install ... .

Mi idea es que parece que esto podría resolverse con una variante de pip install (para las dependencias de compilación) con algo como el siguiente cambio:

  • Si la instalación no requiere subinstalaciones, realice la instalación.
  • De lo contrario, regrese con una lista (posiblemente parcial) de las subinstalaciones que se requieren (por ejemplo, escribiendo la información en un archivo acordado si la escritura en la salida estándar aún no funciona).

De esta manera, el proceso raíz de nivel superior puede generar progresivamente un árbol de dependencias de compilación. Y puede procesar hojas a medida que se encuentran. A medida que se procesan las hojas, los nodos que antes no eran hojas se convertirán en hojas, y así sucesivamente. Con esta implementación, en cualquier momento solo habrá como máximo una instalación de pip en un subproceso.

Una ligera variación de lo que sugerí anteriormente es que la llamada de subproceso / comando pip necesaria puede devolver / emitir una lista de las invocaciones de subinstalación que requeriría una instalación candidata (un pip get-subinstalls o simplemente pip subinstalls mando). La única diferencia con lo que sugerí anteriormente es que este comando se limitaría a informar información. En realidad, no haría la instalación. Entonces, implementarlo podría ser más simple/más fácil de probar.

@cjerdonek No veo ningún problema con esa idea. Pero, en última instancia, alguien necesita implementarlo (¿creo que @pradyunsg iba a trabajar en algo este fin de semana?) y, como siempre, es posible que se descubran más dificultades.

Algo ha ocurrido. Si alguien más quiere recoger esto, no tengo
asuntos. :)

También me gusta la idea de @dstufft .

El domingo, 29 de octubre de 2017, 08:47 xoviat, [email protected] escribió:

@cjerdonek https://github.com/cjerdonek No veo ningún problema con
esa idea. Pero en última instancia, alguien necesita implementarlo (creo que
@pradyunsg https://github.com/pradyunsg iba a trabajar en algo
este fin de semana?) y, como siempre, es posible que se descubran más dificultades.


Estás recibiendo esto porque te mencionaron.

Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-340234567 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/ADH7SYImpWgJGg-DzQRcO_9hHfE6ZxEAks5sw-5RgaJpZM4QBdSg
.

Volviendo a esto, ¿queremos seguir adelante con el enfoque de invocación de stack+internal sugerido por @dstufft?

/ping @ncoghlan @pfmoore @xavfernandez

Sí, por favor. Cualquier cosa para sacar esto adelante.

¿Hay alguien que pueda resumir dónde nos encontramos con PEP 517 y PEP 518 en relación con un lanzamiento de pip 10? Específicamente:

  1. ¿El maestro está actualmente en un estado liberable? Lo último que escuché fue que la compatibilidad con PEP 518 se rompió (hay al menos un problema de bloqueo de versiones abierto relacionado con PEP 518 - #4647).
  2. ¿Es probable que tengamos una implementación de PEP 517 y/o PEP 518 en funcionamiento en un plazo que haga razonable retrasar el pip 10 hasta que estén disponibles?
  3. Suponiendo que arreglamos las cosas en (1), ¿queremos hacer un lanzamiento de pip 10 sin PEP 517/518? Produjimos un correo electrónico de advertencia sobre el lanzamiento, para que la gente sepa que se avecina. Y hay algunas correcciones razonablemente significativas allí (por ejemplo, correcciones de codificación para Windows) que sería bueno publicar.

Mi sensación es que estamos esperando los bloqueadores de lanzamiento, pero no estamos lo suficientemente cerca del soporte de PEP 517/518 para bloquear pip 10 en ellos. Pero no creo que nadie esté trabajando en #4647 excepto como parte de la implementación de PEP 518.

Una opción alternativa sería documentar las limitaciones del soporte PEP 518 actual y degradar el #4647 para que no sea un bloqueador de versiones. No sé lo suficiente sobre los casos de uso para saber si eso es viable.

Acabo de ver esta discusión: disculpas por la implementación inicial a medias que es probable que actúe como una bomba de bifurcación, y gracias a todos los que se tomaron el tiempo para comprenderlo y generar mejores ideas.

FWIW, creo que restringirlo a la instalación de ruedas para los requisitos de construcción sería un compromiso aceptable para la primera versión.

Esto también me recuerda que probablemente debería arreglar las cosas para que el flit no sea un requisito de construcción en sí mismo.

disculpas por la implementación inicial a medias que puede actuar como una bomba de horquilla,

No es necesario disculparse. Como dije, no puedes predecir estos problemas en el primer intento. Incluso sabiendo lo que sabemos ahora, retrasar el PR solo habría pospuesto estas discusiones.

¿El maestro está actualmente en un estado liberable?

IIUC, puede bombardear un sistema a partir de ahora; ¿Es eso correcto? Si es así, creo que no lo es.

¿Es probable que tengamos una implementación de PEP 517 y/o PEP 518 en funcionamiento en un plazo que haga razonable retrasar el pip 10 hasta que estén disponibles?

Creo que la solución fácil (a corto plazo) sería limitarse a las ruedas para las dependencias de compilación. Intentaré intentarlo en algún momento de la próxima semana. Si eso no se materializa, estaré bien si eliminamos el soporte PEP 518 actual del maestro y cortamos un 10.0.0 de eso.

No creo que nadie esté trabajando en #4647 excepto como parte de la implementación de PEP 518.

Creo que te refieres a la implementación completa de PEP 518 con dependencias de compilación de origen permitidas.

Ah, y sobre #4647: la descripción anterior de @xoviat dice que arreglar eso requeriría cambiar/mover el código y la propiedad/visibilidad de los objetos (específicamente BuildEnvironment ), lo cual no es trivial.

Creo que restringirlo a las ruedas debería ser tan simple como cambiar esta línea:

https://github.com/pypa/pip/blob/fc6b2c192088737f81259b6446f627f20ce46443/src/pip/_internal/wheel.py#L696

a:

finder.format_control = FormatControl(set(), set([':all:']))

El segundo campo es un conjunto de paquetes para buscar solo como binarios, con un caso especial para ':all:' para referirse a todos los paquetes.

Si. Pero eso por sí solo no abordaría el #4647. Además, nada de este código va
a través de un resolutor.

El sábado 2 de diciembre de 2017 a las 01:23 Thomas Kluyver [email protected] escribió:

Creo que restringirlo a ruedas debería ser tan simple como cambiar esto
línea:

https://github.com/pypa/pip/blob/fc6b2c192088737f81259b6446f627f20ce46443/src/pip/_internal/wheel.py#L696

a:

buscador.format_control = FormatControl(set(), set([':todos:']))

El segundo campo hay un conjunto de paquetes para encontrar solo como binarios, con
un caso especial para ':todos:' para referirse a todos los paquetes.


Estás recibiendo esto porque te mencionaron.

Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348598368 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/ADH7SUi0QMS3rr5Iba90XWZmFweGmqeBks5s8FlEgaJpZM4QBdSg
.

Correcto, hay un montón de otras cosas mal con él. Pero eso debería evitar el bombardeo de bifurcaciones, que creo que es la preocupación más apremiante.

Si alguien quiere hacerse cargo de mi PR original ("arreglar los problemas de PEP 518"),
no debería ser difícil modificarlo para que el aislamiento de compilación no sea
habilitado sin un pyproject.toml. La razón original por la que no se fusionó
fue que eliminó el soporte para instalar dependencias desde la fuente con
PEP 518. Sin embargo, ahora que la gente comienza a darse cuenta de que PEP 518 puede
no estar en pip 10 en absoluto, pueden estar más dispuestos a aceptar ese PR. I
personalmente no tengo tiempo para defenderlo, pero eso no debería detener a otros
adelante, ya que solo se requerirán unas pocas líneas de cambios
(aparte de fallar la prueba PEP 518).

En realidad, en contra de mi buen juicio, estoy dispuesto a implementar PEP 517 y 518 en breve si los desarrolladores de pip están de acuerdo con mis condiciones:

  1. Las dependencias serán solo de las ruedas inicialmente.
  2. pip tendrá un backend de compilación interno inicialmente, aunque eventualmente se eliminará

No tengo problemas con 1; No tengo preferencia de ninguna manera por 2.

El domingo 3 de diciembre de 2017 a las 02:36, xoviat [email protected] escribió:

En realidad, en contra de mi buen juicio, estoy dispuesto a implementar tanto PEP
517 y 518 en breve si los desarrolladores de pip estarán de acuerdo con mis condiciones:

  1. Las dependencias serán solo de las ruedas inicialmente.
  2. pip tendrá un backend de compilación interno inicialmente, aunque
    eventualmente será eliminado


Estás recibiendo esto porque te mencionaron.

Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348720096 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/ADH7ST6riptZkYMap5Z5SstRf-VmE7eAks5s8bu5gaJpZM4QBdSg
.

FYI, las condiciones no son arbitrarias, pero están ahí para hacer posible la implementación inicial. ¿Está @pfmoore de acuerdo con esto?

No estoy particularmente cómodo con el tono de la oferta "en contra de mi buen juicio... estoy de acuerdo con mis condiciones". No voy a objetar si los otros desarrolladores de pip están felices de aceptar esta oferta, pero personalmente no tengo tiempo en este momento para reiniciar todo el debate sobre los detalles de implementación. Básicamente, me remito a @dstufft y @xavfernandez sobre esto ( @pradyunsg ya ha dado su opinión).

El tono de la oferta es así porque los métodos de implementación se cerraron debido a desacuerdos fundamentales sobre cómo sería una implementación inicial. Prefiero estar de acuerdo con los principios ahora que pasar a otro debate de implementación.

Solo diré que tampoco estoy muy cómodo con el tono, es
simplemente, no tengo el tiempo o la energía para explicar por qué se usó ese tono
etc. La misma razón para la concisa respuesta de mi parte.

Tal vez también valga la pena decir, estoy bien con las dependencias de compilación binaria solo en
la primera implementación, no a más largo plazo. esto no se aplica a
dependencias de tiempo de ejecución (ya que eso también ha surgido de alguna manera en otro
discusión).

El domingo, 3 de diciembre de 2017, 23:37 xoviat, [email protected] escribió:

El tono de la oferta es como es porque los métodos de
implementación se cerraron debido a desacuerdos fundamentales sobre lo que
se vería una implementación inicial. Prefiero estar de acuerdo en el
principios ahora que pasar a otro debate de implementación.


Estás recibiendo esto porque te mencionaron.

Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/pypa/pip/issues/4802#issuecomment-348802032 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/ADH7ScUh-BveonoTxZ5FkkeSynFvoLb8ks5s8uNRgaJpZM4QBdSg
.

Honestamente, probablemente no sea un uso efectivo del tiempo de nadie discutir más el tono de la publicación, ya que no es relevante para incluir estas funciones en el pip 10. Sin embargo, necesito una garantía de que mis condiciones son aceptables para fusionar desde @pfmoore ( quien ha indicado que no puede dar tal seguridad, lo cual es aceptable dado que a nadie se le paga por su tiempo aquí), @dstufft , o @xavfernandez.

Nuevamente, las condiciones no son mi opinión personal, sino que están impulsadas por la implementación. Si relajo estas condiciones, entonces no puedo prometer una implementación, por lo que no tiene sentido dedicar tiempo a preparar un PR, y luego la gente lee la diferencia y pregunta "oh, ¿por qué está esta línea aquí?" y luego "oh, ¿así que esto no se puede fusionar?" porque hubo una falta de comunicación sobre cuál era exactamente el propósito del PR.

De acuerdo con el tono. Mi punto es simplemente que no fusionaré el cambio [1], por lo que mi punto de vista no es realmente tan importante aquí.

[1] Obviamente, lo digo sin haber visto la implementación, así que espero que quede claro que mis razones no tienen que ver con la calidad del código; se trata de no tener tiempo para asegurarme de que entiendo el código lo suficientemente bien como para estar dispuesto a fusionarse, básicamente.

@xoviat ¿Cuáles son sus planes de implementación con respecto al enfoque iterativo versus recursivo que discutimos anteriormente?

Además, para aclarar, ¿está diciendo que primero completará una implementación parcial de PEP 517 y 518 que se puede fusionar, seguida de una implementación completa que se puede fusionar? ¿O está diciendo que solo realizará la implementación parcial, o está diciendo que realizará una implementación completa a través de etapas anteriores que no necesariamente se podrán fusionar? (En parte, estoy tratando de tener una mejor idea de lo que quiere decir con "inicialmente" y "eventualmente" en su comentario ).

La primera condición elimina todo el problema de la recursividad.

Además, para aclarar, ¿está diciendo que primero completará una implementación parcial de PEP 517 y 518 que se puede fusionar, seguida de una implementación completa que se puede fusionar?

Lo que digo es que completaré una implementación parcial que funcionará en el 95 % de los casos de uso; específicamente en el caso donde las dependencias tienen ruedas (muy común ahora) y estás en una plataforma manylinux/windows/OSX (la gran mayoría de los usuarios).

No es una implementación completa. Pero la forma en que obtiene relaciones públicas no fusionables es tratando de hacer el enfoque de "todo o nada" en el que cumple con el estándar o no lo hace.

Tenga en cuenta que una implementación completa requerirá la clasificación de algunos problemas bastante desagradables que necesitarán un PR por separado (ya que tener un PR con más de 100 comentarios generalmente significa que el código no está bien revisado). [1]

[1] https://github.com/btc1/bitcoin/pull/11#issuecomment-313843216

Cerraré este problema ahora: tenemos soporte preliminar para PEP 518 en pip 10 que solo admite ruedas como dependencias de construcción. Abriré un nuevo tema para discutir sobre el soporte completo y otro para el soporte PEP 517 (citando aquí como relevante).

Gracias @ncoghlan @rgommers @cjerdonek por sus ideas y ayuda aquí. Gracias @takluyver por la implementación inicial de PEP 518. Gracias @xoviat (que ahora es @ghost ) por toda la ayuda para implementar estos cambios. Gracias @benoit-pierre por tu ayuda para mejorar el soporte actual.

PD: comentario 100! :tada:

Este hilo se ha bloqueado automáticamente ya que no ha habido ninguna actividad reciente después de que se cerró. Abra un nuevo problema para los errores relacionados.

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