romkatv / powerlevel10k

A Zsh theme

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Python prompt not showing on terminal

hodeinavarro opened this issue · comments

Issue
Prompt defaulting to virtual environment directory name instead of the correct prompt.

Description
I believe all the information is documented in this issue: astral-sh/uv#2668. I originally thought this was a problem with the packager, since I've always used venv and recently switched.

I've been searching around for similar issues and read through the configuration powerlevel10k provides, but it's completely possible I missed something, sorry if so.

I'm not sure if this issue solves the problem though.

I've tried changing POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV to true as the user does, and setting POWERLEVEL9K_VIRTUALENV_GENERIC_NAMES to () as you suggested, both at the same time and also independently, and the outcome is still the same.

That said, you can configure powerlevel10k to display the less meaningful "venv" ~ source

I don't want to display neither more or less meaningful information, I feel like the information is not being displayed at all and a fallback is being considered.

Using Pythons venv module shows the correct information, without changing any parameters on ~/.p10k.zsh, but using virtualenv or uv, powerlevel10k does not show the prompt due to how is being configured, as mentioned in the issue linked above.

it seems that the main difference is how uv sets the VIRTUAL_ENV_PROMPT variable. It appears to be important that the text inside of this is inside parentheses.

uv / virtualenv

if [ "xPrompt with uv" != x ] ; then
    VIRTUAL_ENV_PROMPT="Prompt with uv"
else
    VIRTUAL_ENV_PROMPT=$(basename "$VIRTUAL_ENV")
fi
export VIRTUAL_ENV_PROMPT

ven

if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
    _OLD_VIRTUAL_PS1="${PS1:-}"
    PS1="(Prompt with venv) ${PS1:-}"
    export PS1
    VIRTUAL_ENV_PROMPT="(Prompt with venv) "
    export VIRTUAL_ENV_PROMPT
fi

Oh, I see.

venv stores the value of --prompt in $VIRTUAL_ENV/pyvenv.cfg. This is also where powerlevel10k reads it from. I suppose uv doesn't do that. Perhaps it should, if it wants to be compatible with venv? I don't know anything about Python, so my question/suggestion may be nonsensical.

Well, uv is being mentioned around because I initially run into this issue when changing my package manager, but this is happening both in uv and virtualenv.

I suppose uv doesn't do that.

It certainly does. I believe uv uses either the same or similar scripts/activators as virtualenv , since they initially requested me to test the issue reproduction on virtualenv.

Another friendly user and me tested some configs with uv and virtualenv managers, and both pure zsh and oh-my-zsh show correctly the --prompt, regardless the "configuration" (if VIRTUAL_ENV_PROMPT involves parentheses or not).

The issue arises only for powerlevel10k.
See: astral-sh/uv#2668 (comment)
See: astral-sh/uv#2668 (comment)

Yes, I've already read that issue. What do you think about my comment?

Yes, I've already read that issue. What do you think about my comment?

All venv, uv and virtualenv set the --prompt in $VIRTUAL_ENV/pyvenv.cfg as you mention.
The only difference is that prompt from uv/venv is unquoted, but this doesn't solve the issue, just tested.

Perhaps it should, if it wants to be compatible with venv?

It shouldn't be a goal. Without the theme plugin, both zsh and oh-my-zsh show correctly the prompt set in $VIRTUAL_ENV/pyvenv.cfg.

Surely I know a lot less about bash/zsh than you know about Python, but with all due respect, I think the bug is how powerlevel10k parses the PS1 / VIRTUAL_ENV_PROMPT, since both groups (1. venv and 2. uv and virtualenv) set all the configuration items required.

Now, as to why it's important the difference between with / without parentheses for powerlevel10k I cannot answer that.

I might take a look when I get free time but cannot promise. If you send a clean PR, I'll merge it.

It also feels weird to me arising this issue.

I don't see uv / virtualenv adjusting their scripts just because venv uses parentheses, duh.

Should powerlevel10k take into account which package manager a user uses? All of them? Doesn't sit right to me either.

Maybe your knowledge around the mentioned environment variables provide some light into the issue, but I feel like I'm nitpicking here.

I might take a look when I get free time but cannot promise. If you send a clean PR, I'll merge it.

If I have some free time I'll try to learn how zsh/omz/powerlevel10k works and try to provide some help, sure. I cannot promise anything either because I have no idea of it 🤣

Thank you for your time!

This is where the file is parsed:

function _p9k_parse_virtualenv_cfg() {
typeset -ga reply=(0)
[[ -f $1 && -r $1 ]] || return
local cfg
cfg=$(<$1) || return
local -a match mbegin mend
[[ $'\n'$cfg$'\n' == (#b)*$'\n'prompt[$' \t']#=[$' \t']#([^$' \t']#)[$' \t']#$'\n'* ]] || return
local res=$match[1]
if [[ $res == (\"*\"|\'*\') ]]; then
# The string is quoted in python style, which isn't the same as quoting in zsh.
# For example, the literal 'foo"\'bar' denotes foo"'bar in python but in zsh
# it is malformed.
#
# We cheat a bit and impelement not exactly correct unquoting. It may produce
# different visual results but won't perform unintended expansions or bleed out
# any escape sequences.
#
# Note that venv performs unusual and obviously unintended expansions on the
# value of `prompt`: single-word expansions are performed twice by `activate`,
# and then again on every prompt if `prompt_subst` is in effect. While in general
# I am OK with being bug-compatible with other software, the bugs in venv are a
# bit too extreme for my comfort. I am going to disable all expansions and
# display the configured prompt literally.
res=${(Vg:e:)${res[2,-2]}}
fi
reply=(1 "$res")
}

If the data we are after is in that file, only this function needs to be changed.

The problem was indeed how the information was parsed, but not on the environment variables.

The line

[[ $'\n'$cfg$'\n' == (#b)*$'\n'prompt[$' \t']#=[$' \t']#([^$' \t']#)[$' \t']#$'\n'* ]] || return

was returning, so the reply was (0).

I've implemented a PR with a fix. I don't have the knowledge for very advanced patterns, so I've recurred to reading the file line by line and apply an easy regex.

Thanks for pointing me to the right file :)