zsh completion requires pressing tab twice

❯ black --<TAB>
# Nothing will happen
❯ black --<TAB>
unsorted
--code                        Format the code passed in as a string.
...
# work after second time

Expected:

❯ black --<TAB>
unsorted
--code                        Format the code passed in as a string.
...
# work after first time
Original investigation
❯ _BLACK_COMPLETE=zsh_source black
#compdef black

_black_completion() {
    local -a completions
    local -a completions_with_descriptions
    local -a response
    (( ! $+commands[black] )) && return 1

    response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _BLACK_COMPLETE=zsh_complete black)}")

    for type key descr in ${response}; do
        if [[ "$type" == "plain" ]]; then
            if [[ "$descr" == "_" ]]; then
                completions+=("$key")
            else
                completions_with_descriptions+=("$key":"$descr")
            fi
        elif [[ "$type" == "dir" ]]; then
            _path_files -/
        elif [[ "$type" == "file" ]]; then
            _path_files -f
        fi
    done

    if [ -n "$completions_with_descriptions" ]; then
        _describe -V unsorted completions_with_descriptions -U
    fi

    if [ -n "$completions" ]; then
        compadd -U -V unsorted -a completions
    fi
}

compdef _black_completion black;

that is equivalent to

_black() {
  _black_completion() {
      local -a completions
      local -a completions_with_descriptions
      local -a response
      (( ! $+commands[black] )) && return 1

      response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _BLACK_COMPLETE=zsh_complete black)}")

      for type key descr in ${response}; do
          if [[ "$type" == "plain" ]]; then
              if [[ "$descr" == "_" ]]; then
                  completions+=("$key")
              else
                  completions_with_descriptions+=("$key":"$descr")
              fi
          elif [[ "$type" == "dir" ]]; then
              _path_files -/
          elif [[ "$type" == "file" ]]; then
              _path_files -f
          fi
      done

      if [ -n "$completions_with_descriptions" ]; then
          _describe -V unsorted completions_with_descriptions -U
      fi

      if [ -n "$completions" ]; then
          compadd -U -V unsorted -a completions
      fi
  }

  compdef _black_completion black;
}
compdef _black black  # because first line comment

So, in the first time, compdef _black black tell zsh the completion function is _black(), but _black() not return any completion items, only define a new function named _black_completion and compdef _black_completion black. So when the second time, it work.

The fix method is remove the nested function definition:

❯ _BLACK_COMPLETE=zsh_source black
#compdef black

local -a completions
local -a completions_with_descriptions
local -a response
(( ! $+commands[black] )) && return 1

response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _BLACK_COMPLETE=zsh_complete black)}")

for type key descr in ${response}; do
    if [[ "$type" == "plain" ]]; then
        if [[ "$descr" == "_" ]]; then
            completions+=("$key")
        else
            completions_with_descriptions+=("$key":"$descr")
        fi
    elif [[ "$type" == "dir" ]]; then
        _path_files -/
    elif [[ "$type" == "file" ]]; then
        _path_files -f
    fi
done

if [ -n "$completions_with_descriptions" ]; then
    _describe -V unsorted completions_with_descriptions -U
fi

if [ -n "$completions" ]; then
    compadd -U -V unsorted -a completions
fi