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

@st.cache_data cannot handle UUID objects (but @st.cache can) #6440

Closed
3 of 5 tasks
timothygebhard opened this issue Apr 6, 2023 · 0 comments · Fixed by #6459
Closed
3 of 5 tasks

@st.cache_data cannot handle UUID objects (but @st.cache can) #6440

timothygebhard opened this issue Apr 6, 2023 · 0 comments · Fixed by #6459
Labels
priority:P2 status:confirmed Bug has been confirmed by the Streamlit team type:bug Something isn't working

Comments

@timothygebhard
Copy link

timothygebhard commented Apr 6, 2023

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

It looks like the "new" @st.cache_data decorator chokes on uuid.UUID objects, while the deprecated @st.cache seems to handle them just fine; see minimal example.

Reproducible Code Example

import streamlit as st
import uuid


@st.cache
def works(some_id: uuid.UUID) -> None:
    print("Works")


@st.cache_data
def doesnt_work(some_id: uuid.UUID) -> None:
    print("Nope")


some_id = uuid.uuid4()

works(some_id)
doesnt_work(some_id)

Steps To Reproduce

No response

Expected Behavior

No response

Current Behavior

The minimal example above produces the following output:

2023-04-06 10:46:30.563 WARNING streamlit.runtime.caching.cache_data_api: No runtime found, using MemoryCacheStorageManager
2023-04-06 10:46:30.678 
  Warning: to view this Streamlit app on a browser, run it with the following
  command:

    streamlit run /Users/timothy/Library/Application Support/JetBrains/PyCharmCE2023.1/scratches/scratch_7.py [ARGUMENTS]
2023-04-06 10:46:30.680 `st.cache` is deprecated. Please use one of Streamlit's new caching commands,
`st.cache_data` or `st.cache_resource`.

More information [in our docs](https://docs.streamlit.io/library/advanced-features/caching).
2023-04-06 10:46:30.681 No runtime found, using MemoryCacheStorageManager
Traceback (most recent call last):
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 383, in _to_bytes
    reduce_data = obj.__reduce__()
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/copyreg.py", line 76, in _reduce_ex
    raise TypeError(f"cannot pickle {cls.__name__!r} object")
TypeError: cannot pickle 'function' object

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/cache_utils.py", line 375, in _make_value_key
    update_hash(
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 56, in update_hash
    ch.update(hasher, val)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 209, in update
    b = self.to_bytes(obj)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 191, in to_bytes
    b = b"%s:%s" % (tname, self._to_bytes(obj))
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 239, in _to_bytes
    self.update(h, item)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 209, in update
    b = self.to_bytes(obj)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 191, in to_bytes
    b = b"%s:%s" % (tname, self._to_bytes(obj))
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 388, in _to_bytes
    self.update(h, item)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 209, in update
    b = self.to_bytes(obj)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 191, in to_bytes
    b = b"%s:%s" % (tname, self._to_bytes(obj))
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 385, in _to_bytes
    raise UnhashableTypeError() from ex
streamlit.runtime.caching.cache_errors.UnhashableTypeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/timothy/Library/Application Support/JetBrains/PyCharmCE2023.1/scratches/scratch_7.py", line 20, in <module>
    doesnt_work(some_id)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/cache_utils.py", line 194, in wrapper
    return cached_func(*args, **kwargs)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/cache_utils.py", line 223, in __call__
    return self._get_or_create_cached_value(args, kwargs)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/cache_utils.py", line 237, in _get_or_create_cached_value
    value_key = _make_value_key(
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/cache_utils.py", line 381, in _make_value_key
    raise UnhashableParamError(cache_type, func, arg_name, arg_value, exc)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/cache_utils.py", line 375, in _make_value_key
    update_hash(
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 56, in update_hash
    ch.update(hasher, val)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 209, in update
    b = self.to_bytes(obj)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 191, in to_bytes
    b = b"%s:%s" % (tname, self._to_bytes(obj))
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 239, in _to_bytes
    self.update(h, item)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 209, in update
    b = self.to_bytes(obj)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 191, in to_bytes
    b = b"%s:%s" % (tname, self._to_bytes(obj))
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 388, in _to_bytes
    self.update(h, item)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 209, in update
    b = self.to_bytes(obj)
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 191, in to_bytes
    b = b"%s:%s" % (tname, self._to_bytes(obj))
  File "/usr/local/anaconda3/envs/demo-project/lib/python3.10/site-packages/streamlit/runtime/caching/hashing.py", line 385, in _to_bytes
    raise UnhashableTypeError() from ex
streamlit.runtime.caching.cache_errors.UnhashableParamError: Cannot hash argument 'some_id' (of type `uuid.UUID`) in 'doesnt_work'.

To address this, you can tell Streamlit not to hash this argument by adding a
leading underscore to the argument's name in the function signature:

\```
@st.cache_data
def doesnt_work(_some_id, ...):
    ...
\```
            
Works

Is this a regression?

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

Debug info

  • Streamlit version: 1.20.0
  • Python version: 3.10.10
  • Operating System: macOS 13.2.1 (22D68)
  • Browser: —
  • Virtual environment: conda

Additional Information

The root of the problems seems to be this:

Cannot hash argument 'some_id' (of type `uuid.UUID`) in 'doesnt_work'.

Which is a little strange because pickling and hashing UUID objects does not seem to be a problem in general:

>>> import pickle
>>> import uuid
>>> pickle.dumps(uuid.uuid4())
b'\x80\x04\x950\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c\x04UUID\x94\x93\x94)\x81\x94}\x94\x8c\x03int\x94\x8a\x10\xa8\x0eL\x84\x14\xd9\xcf\x8d\xae@M\x9e\x11\xb0\x9cvsb.'
>>> hash(uuid.uuid4())
1532964488252874118

A simple workaround for now is to cast UUID objects to strings (which are cacheable also with @st.cache_data), but of course it would be nicer if that were not necessary :)

Are you willing to submit a PR?

  • Yes, I am willing to submit a PR!
@timothygebhard timothygebhard added status:needs-triage Has not been triaged by the Streamlit team type:bug Something isn't working labels Apr 6, 2023
@vdonato vdonato added status:confirmed Bug has been confirmed by the Streamlit team priority:P2 and removed status:needs-triage Has not been triaged by the Streamlit team labels Apr 11, 2023
kajarenc added a commit that referenced this issue Apr 11, 2023
* Fix #6440 Add uuid to types we natively hash

UUID is a built-in Python type (lives in the standard library). This PR adds support for uuid hashing, so it would be possible to use uuid objects as parameters for functions decorated with @st.cache_data
eric-skydio pushed a commit to eric-skydio/streamlit that referenced this issue Dec 20, 2023
* Fix streamlit#6440 Add uuid to types we natively hash

UUID is a built-in Python type (lives in the standard library). This PR adds support for uuid hashing, so it would be possible to use uuid objects as parameters for functions decorated with @st.cache_data
zyxue pushed a commit to zyxue/streamlit that referenced this issue Mar 22, 2024
* Fix streamlit#6440 Add uuid to types we natively hash

UUID is a built-in Python type (lives in the standard library). This PR adds support for uuid hashing, so it would be possible to use uuid objects as parameters for functions decorated with @st.cache_data
zyxue pushed a commit to zyxue/streamlit that referenced this issue Apr 16, 2024
* Fix streamlit#6440 Add uuid to types we natively hash

UUID is a built-in Python type (lives in the standard library). This PR adds support for uuid hashing, so it would be possible to use uuid objects as parameters for functions decorated with @st.cache_data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority:P2 status:confirmed Bug has been confirmed by the Streamlit team type:bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants