kislyuk / argcomplete

Python and tab completion, better together.
https://kislyuk.github.io/argcomplete/
Apache License 2.0
1.39k stars 129 forks source link

Output of `argcomplete.warn` does not show #472

Closed hannahbast closed 4 months ago

hannahbast commented 4 months ago

I want to print some debug messages during autocompletion, but nothing ever shows. My latest attempt was to export _ARC_DEBUG=1, rerun eval "$(register-python-argcomplete3 my_script)", and print something using argcomplete.warn(...) (before calling argcomplete.autocomplete(...) of course), but it doesn't show.

When I look at the ouput of register-python-argcomplete3 my_script, I see the following bash function. It redirects stdout and stderr to /dev/null. When I redefine the function manually by removing the 1>/dev/null 2>/dev/null part, I do see my debug messages.

What am I doing wrong?

_python_argcomplete() {
    local IFS=$'\013'
    local SUPPRESS_SPACE=0
    if compopt +o nospace 2> /dev/null; then
        SUPPRESS_SPACE=1
    fi
    COMPREPLY=( $(IFS="$IFS" \
                  COMP_LINE="$COMP_LINE" \
                  COMP_POINT="$COMP_POINT" \
                  COMP_TYPE="$COMP_TYPE" \
                  _ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
                  _ARGCOMPLETE=1 \
                  _ARGCOMPLETE_SUPPRESS_SPACE=$SUPPRESS_SPACE \
                  "$1" 8>&1 9>&2 1>/dev/null 2>/dev/null) )
    if [[ $? != 0 ]]; then
        unset COMPREPLY
    elif [[ $SUPPRESS_SPACE == 1 ]] && [[ "$COMPREPLY" =~ [=/:]$ ]]; then
        compopt -o nospace
    fi
}
kislyuk commented 4 months ago

Hi, thanks for your interest in argcomplete. Are you calling argcomplete.warn() outside the context of a completer callable? It is only supported in completer callables (and only when they are invoked). Can you give a complete example (including the Python portion)?

hannahbast commented 4 months ago

@kislyuk Thanks for the reply! I don't mean anything special. Let's just take the following simple example and let's assume I want to see the value of COMP_LINE when in autocomplete mode for debugging purposes. Let's call the file argcomplete-test.py and do eval "$(register-python-argcomplete3 ./argcomplete-test.py)" and then type ./argcomplete-test.py <TAB>. Is there any sensible way (without meddling with the bash function) to see what the print statement prints outside of a completer callable?

#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK

import argparse
import argcomplete
import os
import sys

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--foo', required=True, help='foo help')
    comp_line = os.getenv('COMP_LINE', '[not in AC mode]')
    print('COMP_LINE: %s' % comp_line, file=sys.stderr)
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    print(args.foo)

if __name__ == '__main__':
    main()
kislyuk commented 4 months ago

No - the muting of print statements is intentional. Programs that depend on argcomplete print a variety of stuff during their startup process that we don't want to be shown when pressing <TAB>.

kislyuk commented 4 months ago

In general, argcomplete.warn() is only supported in completers. This is because argcomplete.warn() is not instrumented to run in the caller scope until argcomplete.autocomplete() is called - and once it's called, it never returns (as described in the docs). The only reason warn() is supported in completers is that they are callbacks - they get called in the course of running autocomplete().

I'm going to close this issue now, since it doesn't seem to be describing a bug. If you feel like there's a bug or missing feature, please feel free to describe the specifics of how it would be implemented while maintaining the existing API/protocol.