classification
Title: importlib and math.pi interact strangely
Type: Stage: resolved
Components: Extension Modules Versions: Python 3.11, Python 3.10
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: jack__d, prescod2
Priority: normal Keywords:

Created on 2021-06-10 22:45 by prescod2, last changed 2021-06-13 21:00 by ned.deily. This issue is now closed.

Files
File name Uploaded Description Edit
foo.py prescod2, 2021-06-10 22:45
Messages (2)
msg395583 - (view) Author: Paul Prescod (prescod2) Date: 2021-06-10 22:45
from importlib import util

mathmodule = util.find_spec("math")
math1 = util.module_from_spec(mathmodule)
print(math1.pi)

=====

$ python3.8 /tmp/foo.py 
3.141592653589793

$ python3.9 /tmp/foo.py 
Traceback (most recent call last):
  File "/tmp/foo.py", line 5, in <module>
    print(math1.pi)
AttributeError: module 'math' has no attribute 'pi'
msg395594 - (view) Author: Jack DeVries (jack__d) * Date: 2021-06-11 00:59
That is because pi, along with other constants in the math module are defined during module execution, not module creation:

https://github.com/python/cpython/blob/62f1d2b3d7dda99598d053e10b785c463fdcf591/Modules/cmathmodule.c#L1257-L1262

Taking the example right here (https://docs.python.org/3/library/importlib.html#checking-if-a-module-can-be-imported) from the docs, you can see how they call exec_module() after module_from_spec.

If you change your code to do that as well, you will find that pi is now defined:

========

from importlib import util

mathmodule = util.find_spec("math")
math1 = util.module_from_spec(mathmodule)
mathmodule.loader.exec_module(math1)
print(math1.pi)

========
History
Date User Action Args
2021-06-13 21:00:20ned.deilysetstatus: open -> closed
resolution: not a bug
stage: resolved
2021-06-11 00:59:07jack__dsetnosy: + jack__d
messages: + msg395594
2021-06-10 22:45:59prescod2create