I have subtle import issue that creates variables with references to objects different to what I expect, and it all depends on whether the module I’m writing is imported “as is” or as part of a package.
Let’s say I have a simple module that defines a Config
class and a function to set it up:
class Config:
def __init__(self, **kwargs):
if kwargs.get("print_keys", None):
self.print_keys = kwargs.pop("print_keys")
else:
self.print_keys = ["centre", "shortName"]
rcParams = Config()
def set_config(config=None):
global rcParams
print("Before change:", id(rcParams))
if config is None:
config = Config()
rcParams = config
print("After change:", id(rcParams))
If I save this in a module named simple.py
, then I can successfully test it with this module:
# import gribtool as gt # note this line is uncommented later
import simple as gt # note this line is commented later
def test_set_config():
config = gt.Config(print_keys=["centre"])
print("Initial rcParams id:", id(gt.rcParams))
gt.set_config(config=config)
print("Updated rcParams id:", id(gt.rcParams))
assert gt.rcParams.print_keys == ["centre"]
test_set_config()
The output is:
Initial rcParams id: 128205347716160
Before change: 128205347716160
After change: 128205347716832
Updated rcParams id: 128205347716832
So far so good. Now, the problem is that I want this to be part of a package. I move this module to a package (a directory) named gribtool
, and then I create the __init__.py
file with the expected content:
from .simple import *
Then, I uncomment the line with import gribtool as gt
in the test module above, and then it fails with this output:
Initial rcParams id: 134251413862864
Before change: 134251413862864
After change: 134251413864064
Updated rcParams id: 134251413862864
Traceback (most recent call last):
File "/home/navarro/AEMET/GRIB_TOOL/test_config.py", line 13, in <module>
test_set_config()
File "/home/navarro/AEMET/GRIB_TOOL/test_config.py", line 10, in test_set_config
assert gt.rcParams.print_keys == ["centre"]
AssertionError
As you can see, the problem is that the rcParams
that is being modified within the set_config
function is different from the one in the simple
module despite the global
instruction.
How can I make sure I’m referring to the right objects?