Reloading pycode from a custom `user_pycode_path` fails in Python 3.9 due to missing `importlib.util` import
Describe the bug
It looks like it was a bug that one could import import importlib directly and importlib.util was exported as a part of it directly. In Python 3.10, this behavior was changed, which causes an AttributeError on the second loading of the pycode from a custom user_pycode_path:
Traceback (most recent call last):
File "/home/will/andes_import_lib.py", line 11, in <module>
system = andes.System(options={"pycode_path": os.environ["PYCODE_PATH"]})
File "/home/will/anaconda3/envs/andes-3-10/lib/python3.10/site-packages/andes/system.py", line 212, in __init__
self.undill(autogen_stale=autogen_stale)
File "/home/will/anaconda3/envs/andes-3-10/lib/python3.10/site-packages/andes/system.py", line 1537, in undill
loaded = self._load_calls()
File "/home/will/anaconda3/envs/andes-3-10/lib/python3.10/site-packages/andes/system.py", line 1568, in _load_calls
pycode = import_pycode(user_pycode_path=user_pycode_path)
File "/home/will/anaconda3/envs/andes-3-10/lib/python3.10/site-packages/andes/system.py", line 2229, in import_pycode
pycode = _import_pycode_from(pycode_path)
File "/home/will/anaconda3/envs/andes-3-10/lib/python3.10/site-packages/andes/system.py", line 2249, in _import_pycode_from
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
AttributeError: module 'importlib' has no attribute 'util'
See https://discuss.python.org/t/python3-11-importlib-no-longer-exposes-util/25641/7 for more context
To Reproduce
Steps to reproduce the behavior:
Assuming andes_pycode_path_bug.py:
import logging
import os
import andes
logging.basicConfig(level=logging.DEBUG)
system = andes.System(options={"pycode_path": os.environ["PYCODE_PATH"]})
Then run the following reproduction steps assuming bash:
conda create --name=andes-3-10 python=3.10 andes=1.8.10 --channel=conda-forge --yes
conda activate andes-3-10
export PYCODE_PATH=$(mktemp -d)
# This will successfully generate new pycode in the temp directory.
# Loading a new system again in the same script succeeds, since it caches the `pycode` module,
# which is reloaded from.
python andes_pycode_path_bug.py
# This will fail with the `AttributeError` mentioned above.
python andes_pycode_path_bug.py
Doing the same thing assuming python=3.8 does not fail and successfully loads. It looks like a python patch version in 3.9 is the version that this breaks on, but I did not find the specific patch it broke on.
Expected behavior I'd expect the pycode from the user-specified path to load successfully on all subsequent loads.
Screenshots If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
- OS: Ubuntu 22.04 on WSL2
- ANDES version (please paste the preamble from
andes)
_ _ | Version 1.8.10
/_\ _ _ __| |___ ___ | Python 3.10.13 on Linux, 12/07/2023 03:35:47 PM
/ _ \| ' \/ _` / -_|_-< |
/_/ \_\_||_\__,_\___/__/ | This program comes with ABSOLUTELY NO WARRANTY.
**pip packages (please paste the output from pip list)
Package Version
--------------- ------------
andes 1.8.10
certifi 2023.11.17
chardet 5.2.0
colorama 0.4.6
coloredlogs 15.0.1
contourpy 1.2.0
cycler 0.12.1
dill 0.3.7
et-xmlfile 1.1.0
fonttools 4.46.0
gmpy2 2.1.2
humanfriendly 10.0
kiwisolver 1.4.5
kvxopt 0.0.0
llvmlite 0.41.1
matplotlib 3.8.2
mpmath 1.3.0
multiprocess 0.70.15
munkres 1.1.4
numba 0.58.1
numpy 1.26.2
openpyxl 3.1.2
packaging 23.2
pandas 2.1.3
pathos 0.3.1
Pillow 10.1.0
pip 23.3.1
pox 0.3.3
ppft 1.7.6.7
psutil 5.9.5
pyparsing 3.1.1
python-dateutil 2.8.2
pytz 2023.3.post1
PyYAML 6.0.1
SciPy 1.11.4
setuptools 68.2.2
six 1.16.0
sympy 1.10.1
texttable 1.7.0
tqdm 4.66.1
tzdata 2023.3
unicodedata2 15.1.0
wheel 0.42.0
XlsxWriter 3.1.9
Additional context Add any other context about the problem here.
This should be a pretty easy fix by adding an additional import importlib.util to the top of system.py, which I'll prepare as a PR shortly
Thanks for reporting! Working on it!
This is probably a bug with Python 3.10. I'm using Python 3.11.6, and
>>> import importlib
>>> importlib.util
<module 'importlib.util' (frozen)>
I'm happy to make the change, and in the meantime, you can try Python 3.11