Estoy tratando de modificar pip, para que después de cada instalación o desinstalación, mi requirements.txt se actualice.

Para hacerlo, he modificado el archivo pip en el bin/ de mi entorno virtual.

pip:

#!/Users/username/ProjectEnv/bin/python3

# -*- coding: utf-8 -*-
import re
import sys

from pip import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    status = main()
    if status == 0 or status is None:
        sys.argv = ['pip', 'freeze', '>', '../Project/requirements.txt']
        sys.exit(main())

Esto no funcionó. Intenté imprimir los argumentos de la línea de comando y poner un punto de interrupción, pero no funcionaron tan bien.

pip:

#!/Users/username/ProjectEnv/bin/python3

# -*- coding: utf-8 -*-
import re
import sys
import pdb
pdb.set_trace()

from pip import main

if __name__ == '__main__':
    for arg in sys.argv:
        print(arg)
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    status = main()
    if status == 0 or status is None:
        sys.argv = ['pip', 'freeze', '>', '../Project/requirements.txt']
        sys.exit(main())

¿Qué estoy haciendo mal aquí?

1
Utku 14 ene. 2017 a las 14:35

3 respuestas

La mejor respuesta

Puede llamar al método freeze usted mismo en la biblioteca de pip. Devolverá un generador que le proporciona la salida línea por línea de lo que se imprime en la pantalla en pip --freeze.

from pip.operations import freeze

packages = freeze.freeze()
with open('../Project/requirements.txt', 'w') as f:
    for x in packages:
        f.write(x)
        f.write('\n')
1
2ps 14 ene. 2017 a las 13:25

El problema era que estaba modificando el archivo incorrecto. Modifiqué el pip en ProjectEnv/bin/, pero ese no era el archivo que se estaba ejecutando cuando escribí, digamos, pip install some_module.

Tomó un tiempo descubrir esto porque which pip también generó /Users/username/ProjectEnv/bin/pip.

type pip ha demostrado la verdad. Produjo: pip is aliased to 'pip3'.

Entonces, este es un buen ejemplo de por qué deberíamos alias which a type. O, por qué deberíamos dejar de usar which y usar siempre type.

0
Utku 14 ene. 2017 a las 13:49

Creo que sería mejor con un script bash como pip_with_autofreeze.sh :

#!/usr/bin/env sh
pip $@ && pip freeze > requirements.txt

Ejecútelo con ./pip_with_autofreeze.sh install flask, por ejemplo.

Coloque el script en una ubicación adecuada de su $PATH como ~/bin, y puede llamarlo desde cualquier virtualenv que cree en el futuro. Pip se referirá a lo que sea que virtualenv le indique.

0
Harald Nordgren 20 ene. 2017 a las 03:03