cannot cache functions which embed a relative import
See original GitHub issueSummary
Caching does not appear to work on functions which, at call time, perform a relative import.
Steps to reproduce
This is a minimal reproducible which gives the same error message I see in my code.
First, set up the troublesome code in a new Python module called “spam” with a submodule “spam.eggs”:
% mkdir spam
then create spam/__init__.py and spam/eggs.py with the following content
% cat spam/__init__.py
def load():
from . import eggs
% cat spam/eggs.py
# nothing
Second, create the following streamlit program - note that load() returns None!
import streamlit as st
import spam
@st.cache
def load():
return spam.load()
Expected behavior:
I expected to load() to a cached value of None.
Actual behavior:
streamlit fails at the cache step with the following:
ValueError: Empty module name
Streamlit encountered an error while caching the body of load(). This is likely due to a bug in /Users/dalke/cvses/chemfp_demo/spam/__init__.py near line 2:
from . import eggs
Please modify the code above to address this.
If you think this is actually a Streamlit bug, you may file a bug report here.
Traceback:
File "/Users/dalke/demo/show_problem.py", line 5, in <module>
def load():
File "/Users/dalke/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1027, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _sanity_check
Is this a regression?
This is the first day I’ve used streamlit. I have no experience to know this.
Debug info
- Streamlit version: Streamlit, version 0.76.0
- Python version: Python 3.9.1
- Using Conda? PipEnv? PyEnv? Pex? No. Straight pip.
- OS version: macOS 10.14.6
- Browser version: Firefox 84.0.2
Additional information
None.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
Top Results From Across the Web
Relative imports in Python 3 - Stack Overflow
The simplest fix for this case, assuming the name mymodule is globally unique, would be to avoid using relative imports, and just use....
Read more >5. The import system — Python 3.11.1 documentation
The import statement is the most common way of invoking the import machinery, ... If the named module cannot be found, a ModuleNotFoundError...
Read more >Traps for the Unwary in Python's Import System
(Note that if the project exclusively uses explicit relative imports for ... since 3.2, you can't just add c or o to get...
Read more >The Definitive Guide to Python import Statements | Chris Yeh
an implicit relative import is written as if the current directory is part of sys.path . Implicit relative imports are only supported in...
Read more >Absolute and Relative Imports in Python - GeeksforGeeks
When a module is imported the interpreter first searches it in sys.modules, which is the cache of all modules which have been previously ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
For those with the same issue, I was able to work around it with:
Not a problem.
Turns out I couldn’t use cache anyway - my underlying system uses a mmap’ed file, which can’t be pickled. The mmap was designed for a fast startup, which should be a natural fit to streamlit. However, it looks like Firefox is taking up most of the memory on my laptop, so when streamlit restarts, the mapped pages are flushed, and I’m limited by how long it takes my laptop to re-read 2GB from mass storage. Which means that cache wouldn’t help as the pickle overhead is higher than mmap read.
In case it helps with the user story, the underlying “load” command in my system has its own gzip reader which is faster than Python’s built-in gzip library. This usually isn’t needed, so rather than import it eagerly when the top-level package is imported, it’s imported only when the input filename ends with “.gz”.