CURENT / andes

Python toolbox / library for power system transient dynamics simulation with symbolic modeling and numerical analysis 🔥
https://ltb.curent.org
Other
208 stars 108 forks source link

Reloading pycode from a custom `user_pycode_path` fails in Python 3.9 due to missing `importlib.util` import #499

Open willjschmitt opened 7 months ago

willjschmitt commented 7 months ago

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):

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

willjschmitt commented 7 months ago

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

cuihantao commented 7 months ago

Thanks for reporting! Working on it!

cuihantao commented 7 months ago

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