question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

cannot cache functions which embed a relative import

See original GitHub issue

Summary

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:open
  • Created 3 years ago
  • Reactions:1
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
adalkecommented, Feb 15, 2021

For those with the same issue, I was able to work around it with:

def load():
    spam = eval("import spam")
    return spam.load()
1reaction
adalkecommented, Feb 16, 2021

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”.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found