Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to clear specific cache for class instance function #8638

Open
3 of 4 tasks
yanivkrol opened this issue May 9, 2024 · 6 comments
Open
3 of 4 tasks

Unable to clear specific cache for class instance function #8638

yanivkrol opened this issue May 9, 2024 · 6 comments
Labels
area:backend feature:cache Related to st.cache_data and st.cache_resource priority:P3 status:confirmed Bug has been confirmed by the Streamlit team type:bug Something isn't working

Comments

@yanivkrol
Copy link

Checklist

  • I have searched the existing issues for similar issues.
  • I added a very descriptive title to this issue.
  • I have provided sufficient information below to help reproduce this issue.

Summary

With the new feature of specific cache clear in 1.34, I'm unable to clear specific cache for class instance function (self).
The "self" argument is named "_self" so it won't be calculated for hash

Reproducible Code Example

import random
import streamlit as st

class Test:
    @st.cache_data
    def print_random(_self, var):
        st.text(random.randint(0, 10000))

test = Test()
st.title('Hello World')
if st.button('Print Random Number'):
    test.print_random(1)
if st.button('Clear cache'):
    test.print_random.clear(1)

Steps To Reproduce

  1. click on 'Print Random Number'
  2. click on 'Clear cache'
  3. click on 'Print Random Number'

Expected Behavior

Different number printed

Current Behavior

Same number printed, i.e. the function is not executed, i.e. the cache is not cleared

Is this a regression?

  • Yes, this used to work in a previous version.

Debug info

  • Streamlit version: 1.34.0
  • Python version: 3.10
  • Operating System: macOS
  • Browser: chrome

Additional Information

This works perfectly without arguments, clearing the entire cache for the function

@yanivkrol yanivkrol added status:needs-triage Has not been triaged by the Streamlit team type:bug Something isn't working labels May 9, 2024
Copy link

github-actions bot commented May 9, 2024

If this issue affects you, please react with a 👍 (thumbs up emoji) to the initial post.

Your feedback helps us prioritize which bugs to investigate and address first.

Visits

@raethlein
Copy link
Collaborator

raethlein commented May 10, 2024

@yanivkrol Thanks for opening the issue! I got it to clear the cache when you pass the instance to the clear function like this: test.print_random.clear(test, 1)

Full example
import random
import streamlit as st

class Test:
    @st.cache_data
    def print_random(_self, var):
        st.text(random.randint(0, 10000))

test = Test()
st.title('Hello World')
if st.button('Print Random Number'):
    test.print_random(1)
if st.button('Clear cache'):
    test.print_random.clear(test, 1)

This should be sufficient as a workaround! I guess it should be possible for our clear function to detect that it is an instance method and account for self automatically

@raethlein raethlein added status:confirmed Bug has been confirmed by the Streamlit team feature:cache Related to st.cache_data and st.cache_resource area:backend type:bug Something isn't working and removed status:needs-triage Has not been triaged by the Streamlit team type:bug Something isn't working labels May 10, 2024
Copy link

If this issue affects you, please react with a 👍 (thumbs up emoji) to the initial post.

Your feedback helps us prioritize which bugs to investigate and address first.

Visits

@yanivkrol
Copy link
Author

yanivkrol commented May 11, 2024

@yanivkrol Thanks for opening the issue! I got it to clear the cache when you pass the instance to the clear function like this: test.print_random.clear(test, 1)

Full example
This should be sufficient as a workaround! I guess it should be possible for our clear function to detect that it is an instance method and account for self automatically

@raethlein Cool thanks, haven't thought of that.
Though it makes more sense to reference the function statically Test.print_random.clear(test, 1)

@MICHAjkhoihgbvbkjvbvfjhcdjcxxhgc

I want to help me bor

@Asaurus1
Copy link
Contributor

Asaurus1 commented May 17, 2024

CachedFunc.clear doesn't appear to implement a descriptor-protocol. So

class Test:

    @st.cache_data
    def print_random(self, val):
        ...

Test.print_random
# This is a closure wrapper(*args, **kwargs) which wraps a call to a CachedFunc object cached_func
# e.g. cached_func(*args, **kwargs)

test = Test()
test.print_random  
# This is a bound-method of the closure wrapper(*args, **kwargs) which injects 'test' as the first argument "self"
# e.g. it calls cached_func(self, *args, **kwargs)

Test.print_random.clear
# This is a reference to the .clear() function of the underlying CachedFunc object that's in the "wrapper" closure. 
# It does not get "self" automatically passed to it.

test.print_random.clear
# bound methods "pass-through" attribute lookup to the un-bound method they reference, 
# (you, in fact, cannot set test.print_random.clear to a value in python3.11). 
# This means test.print_random.clear IS Test.print_random.clear.

To get around this, I believe wrapper.clear needs to be implemented as a non-data descriptor (with a __get__ method), such that when you call test.print_random.clear, it recognizes print_random as a bound-method and calls the underlying cached_func.clear() method with test.print_random.__self__ as the first argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:backend feature:cache Related to st.cache_data and st.cache_resource priority:P3 status:confirmed Bug has been confirmed by the Streamlit team type:bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants