Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

importlib.reload does not reload programmatically generated file

The second assertion fails, indicating that importlib.reload silently failed to reload the modified module, can anyone explain why?

import os
import sys
import tempfile
import importlib


# Create some module and import it
dir = tempfile.TemporaryDirectory()
os.mkdir(os.path.join(dir.name, 'test_package'))
with open(os.path.join(dir.name, '__init__.py'), "w") as f:
    f.write("\n")
with open(os.path.join(dir.name, 'test_package', 'some_module.py'), "w") as f:
    f.write("def a():\n    print(\"old\")\n    return 0\n")
sys.path.insert(0, dir.name)

from test_package import some_module

# Check that imported code works as expected
assert some_module.a() == 0

# Alter module and reload
with open(os.path.join(dir.name, 'test_package', 'some_module.py'), "w") as f:
    f.write("def a():\n    print(\"new\")\n    return 1\n")

importlib.reload(some_module)

# Check wether modifications have been reloaded
assert some_module.a() == 1

sys.path.pop(0)

demo: https://ideone.com/wtaENF

EDIT: - python 3.6.1 - archlinux (linux 4.10.13)

like image 563
pixelou Avatar asked Sep 03 '25 13:09

pixelou


1 Answers

The following code, extended with time.sleep(10) doesn't throw the assertion error (the safe threshold appear to be one second). This provides the explanation why the reload didn't work as expected. So the answer to the question why the assertion error is raised is

importlib.reload() uses file timestamp to decide about re-compiling the cached file.

If the code update/change happens very fast, the cached and the script file are considered to be the same version and there is no re-compiling of the cached files from which modules are re-loaded.

import os
import sys
import tempfile
import importlib
import time

# Create some module and import it
dir = tempfile.TemporaryDirectory()
os.mkdir(os.path.join(dir.name, 'test_package'))
with open(os.path.join(dir.name, '__init__.py'), "w") as f:
    f.write("\n")
with open(os.path.join(dir.name, 'test_package', 'some_module.py'), "w") as f:
    f.write("def a():\n    print(\"old\")\n    return 0\n")
sys.path.insert(0, dir.name)

from test_package import some_module

# Check that imported code works as expected
assert some_module.a() == 0
time.sleep(10)
# Alter module and reload
with open(os.path.join(dir.name, 'test_package', 'some_module.py'), "w") as f:
    f.write("def a():\n    print(\"new\")\n    return 1\n")

importlib.reload(some_module)

# Check wether modifications have been reloaded
assert some_module.a() == 1

sys.path.pop(0)