2626import _imp
2727import _io
2828import sys
29+ import time
2930import _warnings
3031import marshal
3132
@@ -725,8 +726,8 @@ def _classify_pyc(data, name, exc_details):
725726 return flags
726727
727728
728- def _validate_timestamp_pyc (data , source_mtime , source_size , name ,
729- exc_details ):
729+ def _validate_timestamp_pyc (self , data , source_mtime , source_size , name ,
730+ bytecode_path , exc_details ):
730731 """Validate a pyc against the source last-modified time.
731732
732733 *data* is the contents of the pyc file. (Only the first 16 bytes are
@@ -738,19 +739,32 @@ def _validate_timestamp_pyc(data, source_mtime, source_size, name,
738739
739740 *name* is the name of the module being imported. It is used for logging.
740741
742+ *bytecode_path* is the path of the pyc file.
743+
741744 *exc_details* is a dictionary passed to ImportError if it raised for
742745 improved debugging.
743746
744747 An ImportError is raised if the bytecode is stale.
745748
746749 """
747- if _unpack_uint32 (data [8 :12 ]) != (source_mtime & 0xFFFFFFFF ):
750+ timestamp = _unpack_uint32 (data [8 :12 ])
751+ if timestamp != (int (source_mtime ) & 0xFFFFFFFF ):
748752 message = f'bytecode is stale for { name !r} '
749753 _bootstrap ._verbose_message ('{}' , message )
750754 raise ImportError (message , ** exc_details )
751755 if (source_size is not None and
752756 _unpack_uint32 (data [12 :16 ]) != (source_size & 0xFFFFFFFF )):
753757 raise ImportError (f'bytecode is stale for { name !r} ' , ** exc_details )
758+ if time .time () - source_mtime < 2 :
759+ try :
760+ bytecode_mtime = self .path_mtime (bytecode_path )
761+ except OSError :
762+ pass
763+ else :
764+ if bytecode_mtime < source_mtime :
765+ message = f'bytecode may be stale for { name !r} '
766+ _bootstrap ._verbose_message ('{}' , message )
767+ raise ImportError (message , ** exc_details )
754768
755769
756770def _validate_hash_pyc (data , source_hash , name , exc_details ):
@@ -794,7 +808,7 @@ def _code_to_timestamp_pyc(code, mtime=0, source_size=0):
794808 "Produce the data for a timestamp-based pyc."
795809 data = bytearray (MAGIC_NUMBER )
796810 data .extend (_pack_uint32 (0 ))
797- data .extend (_pack_uint32 (mtime ))
811+ data .extend (_pack_uint32 (int ( mtime ) ))
798812 data .extend (_pack_uint32 (source_size ))
799813 data .extend (marshal .dumps (code ))
800814 return data
@@ -1111,7 +1125,7 @@ def get_code(self, fullname):
11111125 except OSError :
11121126 pass
11131127 else :
1114- source_mtime = int ( st ['mtime' ])
1128+ source_mtime = st ['mtime' ]
11151129 try :
11161130 data = self .get_data (bytecode_path )
11171131 except OSError :
@@ -1139,10 +1153,12 @@ def get_code(self, fullname):
11391153 exc_details )
11401154 else :
11411155 _validate_timestamp_pyc (
1156+ self ,
11421157 data ,
11431158 source_mtime ,
11441159 st ['size' ],
11451160 fullname ,
1161+ bytecode_path ,
11461162 exc_details ,
11471163 )
11481164 except (ImportError , EOFError ):
0 commit comments