Caching quirk with ternary operator, delta_generator

This code runs with no errors:

import streamlit as st
from streamlit import session_state as state


@st.cache
def my_function(condition):
    if condition:
        progress = state.progress
    for i in range(5):
        if condition:
            progress.progress((i+1)/5)


state.progress = st.empty()
my_function(True)

This represents a function that does a lot of work. Because it does a lot of work, I want to be able to update a progress bar inside of it, and also use @st.cache on it. However, I can’t pass the progress bar as a parameter because Streamlit delta generators can’t be cached. So instead, I pass it in the state. Additionally, sometimes I might want to use the function for its logical usage, without displaying a progress bar (e.g. if i want to import it into a python script that uses no Streamlit), so I have the condition as a parameter.
Everything is fine for now because the code runs, although it is a bit janky. However, there is a Pycharm linting warning, because progress might be undefined in its eyes:
image

So, I add one line to my_function():

import streamlit as st
from streamlit import session_state as state

@st.cache
def my_function(condition):
    progress = None # <<<<<<<<<
    if condition:
        progress = state.progress
    for i in range(5):
        if condition:
            progress.progress((i+1)/5)

state.progress = st.empty()
my_function(True)

Everything still works.

But as soon as I switch to a ternary operator to save some space, I get an error:

import streamlit as st
from streamlit import session_state as state


@st.cache
def my_function(condition):
    progress = state.progress if condition else None
    for i in range(5):
        if condition:
            progress.progress((i+1)/5)


state.progress = st.empty()
my_function(True)

I find this behavior really weird because the logic hasn’t really changed, so I’m wondering what’s happening.

Your second version doesn’t work for me.

Don’t branch on a condition which is always True, that’s only going to confuse readers of your code, including code analysis tools and yourself.

Not an answer to your question: If you switch to @st.experimental_memo, your code with the ternary operator works without issues:

import streamlit as st
from streamlit import session_state as state

@st.experimental_memo
def my_function():
    condition = True
    progress = state.progress if condition else 0
    for i in range(5):
        if condition:
            progress.progress((i + 1) / 5)

state.progress = st.empty()
my_function()

Forgot to change the last two to use parameters, my bad.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.