On master, clean conda install, with a pip -e install . to get the development version, if I add:
from matplotlib import rcParams to the top of colors.py, I get an error
Traceback (most recent call last):
File "testImport.py", line 1, in <module>
import matplotlib.pyplot as plt
File "/Users/jklymak/matplotlib/lib/matplotlib/__init__.py", line 106, in <module>
from . import cbook, rcsetup
File "/Users/jklymak/matplotlib/lib/matplotlib/rcsetup.py", line 31, in <module>
from matplotlib.colors import is_color_like
File "/Users/jklymak/matplotlib/lib/matplotlib/colors.py", line 68, in <module>
from matplotlib import rcParams
ImportError: cannot import name 'rcParams' from 'matplotlib' (/Users/jklymak/matplotlib/lib/matplotlib/__init__.py)
(FWIW, I don't want to do this, I really want to do import matplotlib.scale as mscale but it throws the same error inside scale.py, so the is the simplest reproducible error).
The other cases where folks have seen this (#1280, #12983, #13407, #15353) have seemed to be cases where there was a name clash. Bit this is a pretty clean install, so I don't think thats the issue.
we import matplotlib and start executing __init__.py. This immediately stuffs the module object into sys.module, but it is empty
do a bunch of lines, up to L106
we start to executed colors.py
in colors.py we import matplotlib (which works because we have a module object for it)
we then try to access rcParams which fails because it has not been put into the module object yet (because it among other things needs the code farther down the rcsetup.py file to be defined).
Probably the simplest fix is to move the colors import into the function where it is used (to defer it until after import time), but I am not ever sure that will work as we need that function to define rcParams to begin with.
Where do you want to import scale that it is causing a circular import?
I was trying to fix SymLogNorm by reusing scale.SymmetricLogTransform, so I was trying to import into colors.py.
I feel you have explained the circular imports to me before, thanks for doing so again. But it seems somewhat broken that we can't import any modules that use rcParams. My 10 minutes online indicates that instead of from matplotlib import rcParams we did import matplotlib and then accessed matplotlib.rcParams we would avoid problems like this.
I think that might work, but would depend on exactly how and where we use it in the imported modules. You can't use rcParams as part of building its self ;)
One thing that may help is that we should never do (from within the codebase) from matplotlib import rcParams and always import matplotlib as mpl; ... <later> mpl.rcParams. This would help a lot with first-import import order problems. I've been slowly swapping these as part of other PRs but we could just do a mass search/replace across the library and document that.
I'll close this as there are a number of PRs that changed importing rcParams directly to getting it from matplotlib.rcParams (there are still some files that does this though). The fundamental problem with cyclic imports is harder to do something about.
Activity
tacaswell commented on Feb 2, 2020
That is because rcparams imports colors.
What is happening is that:
Probably the simplest fix is to move the colors import into the function where it is used (to defer it until after import time), but I am not ever sure that will work as we need that function to define rcParams to begin with.
Where do you want to import scale that it is causing a circular import?
jklymak commented on Feb 2, 2020
I was trying to fix SymLogNorm by reusing scale.SymmetricLogTransform, so I was trying to import into colors.py.
I feel you have explained the circular imports to me before, thanks for doing so again. But it seems somewhat broken that we can't import any modules that use rcParams. My 10 minutes online indicates that instead of from matplotlib import rcParams we did import matplotlib and then accessed matplotlib.rcParams we would avoid problems like this.
tacaswell commented on Feb 2, 2020
I think that might work, but would depend on exactly how and where we use it in the imported modules. You can't use rcParams as part of building its self ;)
anntzer commented on Feb 3, 2020
One thing that may help is that we should never do (from within the codebase) from matplotlib import rcParams and always import matplotlib as mpl; ... <later> mpl.rcParams. This would help a lot with first-import import order problems. I've been slowly swapping these as part of other PRs but we could just do a mass search/replace across the library and document that.
oscargus commented on Jun 4, 2022
I'll close this as there are a number of PRs that changed importing rcParams directly to getting it from matplotlib.rcParams (there are still some files that does this though). The fundamental problem with cyclic imports is harder to do something about.