Skip to content

Conversation

@serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Jul 11, 2024

@serhiy-storchaka
Copy link
Member Author

serhiy-storchaka commented Jul 11, 2024

  • TODO: new tests and a NEWS entry.

@ZeroIntensity
Copy link
Member

The reproducer from #120932 could be turned into a test:

import importlib
from pathlib import Path

MODULE_NAME = "tmod"
MODULE_PATH = Path(MODULE_NAME + ".py")


with open(MODULE_PATH, "w") as f:
    f.write("a = 1")

mod = importlib.import_module(MODULE_NAME)
old = mod.a

with open(MODULE_PATH, "w") as f:
    f.write("a = 2")

mod = importlib.reload(mod)
new = mod.a

assert old != new  # failed, 1 != 1

Copy link
Member Author

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, the test fails with about 10% probability.

It seems that overwriting a file not always updates its mtime. I do not know what to do with this.

except OSError:
pass
else:
if bytecode_mtime < source_mtime:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is still possible to get a stale bytecode if write the new source very quickly after creating the pyc file. Using <= instead of < here would be more reliable, but this breaks several existing tests which create bad pyc files very quickly after creating py files.

Using nanosecond precision may make all this more reliable without breaking existing tests, but this will require changing the public interface -- adding the mtime_ns key in path_stats().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using nanoseconds precision does not help.

@serhiy-storchaka
Copy link
Member Author

I fixed unstable tests. @brettcannon, what are your thoughts about this? This is not a panacea, you still can import a stale pyc file if rewrite the source file very quickly after creating the pyc file. But this significantly reduces the chance of this. And I tried to minimize the cost. Is it worth to do this?

@brettcannon
Copy link
Member

I think the idea is fine if the performance hit is minimal (it's time.time() period and an extra stat call if the time difference is minimal enough).

@brettcannon
Copy link
Member

Let me think about it and I will get back to you this month (probably at the core dev sprints).

@brettcannon brettcannon self-assigned this Sep 5, 2025
@brettcannon
Copy link
Member

If pyperformance doesn't show a perf hit then I'm fine with this change. We can always revert it later if it turns out to be problematic.

@@ -0,0 +1,2 @@
Import checks now also the modification time of the ``.pyc`` file for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Import checks now also the modification time of the ``.pyc`` file for
Import now also checks the modification time of the ``.pyc`` file for

bytecode_mtime = 0
delay = 1e-3
for j in range(10):
time.sleep(delay)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to set the mtime programmatically or mocking out the appropriate code to avoid the sleep call?

@brettcannon
Copy link
Member

I'm fine with the change if pyperformance doesn't show any perf hit. We can always revert if it turns out to be an issue.

@brettcannon brettcannon removed their assignment Sep 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants