venv/pyproject.toml: argcomplete aufnehmen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
RonaldG
User
Beiträge: 6
Registriert: Freitag 22. Dezember 2023, 13:09

Ich habe eine venv eingerichtet und ein pyproject.toml erstellt.

Code: Alles auswählen

pip install -e .
erstellt ein lauffähiges Programm

Code: Alles auswählen

~/.venvs/cunim/bin> cat cunim 
#!/home/rgg/.venvs/cunim/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from cunim.__main__ import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())
was noch fehlt:
In der Zeile 2 muss noch eine Kommentarzeile eingefügt werden damit die TAB-Completion funktioniert:

Code: Alles auswählen

# PYTHON_ARGCOMPLETE_OK
Weder im PEP 517 noch bei den Beschreibung von setuptools noch im [tools]-Block habe ich etwas brauchbares gefunden.

Hat jemand einen Tipp wie man das machen könnte?
(außer dass man das in die README.md aufnimmt :( )
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Vielleicht geht irgendwas mit einem setuptools plugin?
RonaldG
User
Beiträge: 6
Registriert: Freitag 22. Dezember 2023, 13:09

@Sirius3: Über das Modul "setuptools" bin ich auch gestolpert, habe aber nichts brauchbares gefunden.
Hast du mir ein Beispiel was man damit machen kann?
RonaldG
User
Beiträge: 6
Registriert: Freitag 22. Dezember 2023, 13:09

Hab keine Lösung gefunden.
Work-around: ich schreibe ins README.md, dass man diese Zeile manuell aufnehmen soll.
Schade, denn für mich ist die TAB-Completion ein sehr wichtiges Feature in der bash.

Noch in paar Infos:
  • ~/.venvs/cunim/lib/python3.10/site-packages/pip/_vendor/distlib/scripts.py enthält im SCRIPT_TEMPLATE den Quellcode (mit Platzhaltern)
  • im ScriptMaker._make_script() wird das Programm erstellt (und nach /home/xxx/.venvs/xxx/bin/xxx geschrieben).
  • In der make()-Methode sollte ein _copy_script() aufgerufen werden, aber das habe ich nicht geschafft. Ich habe im pyproject.toml ein bisschen rumgespielt (mit -, _, $, /, ...), aber das weist der TOML-Parser schon zurück :).
  • Eine bash_completion-funktion erstellen war keine Option, denn die müsste ich ja auch irgendwie installieren und später dann auch aktivieren (das ist ja noch komplizierter).
Wie gesagt: schade.
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Ich hab’s nur überflogen, aber dieses Issue scheint genau das Problem zu sein. Hier steht, dass das eigentlich™ funktionieren sollte, weil `argcomplete` von `pip` erstellte Startscripts speziell unterstützt. In dem Issue wird angenommen, dass es nicht funktioniert, weil das Programm irgendwie falsch installiert ist. Vielleicht kannst du das ja mal bei dir nachvollziehen; und wenn es ein anderes Problem ist, ein neues Issue aufmachen? Weil das ja eigentlich™ funktionieren sollte.
RonaldG
User
Beiträge: 6
Registriert: Freitag 22. Dezember 2023, 13:09

Ich habe mich füreeinen schmutzigen/pragmatischen Workaround entschieden :( :
Der Eintry-Point heißt nicht mehr "main", sondern "main_PYTHON_ARGCOMPLETE_OK".

Code: Alles auswählen

cunim = "cunim.__main__:main_PYTHON_ARGCOMPLETE_OK"
Jetzt findet die bash-function von kislyuk (https://github.com/kislyuk/argcomplete) den String und die bash_completion funktioniert.

Code: Alles auswählen

__python_argcomplete_scan_head () 
{ 
    local file="$1";
    local target="$2";
    if [[ -n "${ZSH_VERSION-}" ]]; then
        read -r -k 1024 -u 0 < "$file";
    else
        read -r -N 1024 < "$file";
    fi;
    if [[ "$target" = "interpreter" ]]; then
        read -r <<< "$REPLY";
    fi;
    local regex;
    case "$target" in 
        magic_string)
            regex='PYTHON_ARGCOMPLETE_OK'
        ;;
        easy_install)
            regex="(PBR Generated)|(EASY-INSTALL-(SCRIPT|ENTRY-SCRIPT|DEV-SCRIPT))"
        ;;
        asdf)
            regex="asdf exec "
        ;;
        interpreter)
            regex='^#!(.*)$'
        ;;
    esac;
    local ret="";
    if [[ "$REPLY" =~ $regex ]]; then
        ret=1;
    fi;
    __python_argcomplete_upshift_bash_rematch;
    [[ -n $ret ]]
}

Antworten