@@ -434,6 +434,14 @@ def _classify_pyc(data, name, exc_details):
434
434
"""Perform basic validity checking of a pyc header and return the flags field,
435
435
which determines how the pyc should be further validated against the source.
436
436
437
+ *data* is the contents of the pyc file. (Only the first 16 bytes are
438
+ required, though.)
439
+
440
+ *name* is the name of the module being imported. It is used for logging.
441
+
442
+ *exc_details* is a dictionary passed to ImportError if it raised for
443
+ improved debugging.
444
+
437
445
ImportError is raised when the magic number is incorrect or when the flags
438
446
field is invalid. EOFError is raised when the data is found to be truncated.
439
447
@@ -455,35 +463,51 @@ def _classify_pyc(data, name, exc_details):
455
463
return flags
456
464
457
465
458
- def _validate_timestamp_pyc (data , source_stats , name , exc_details ):
459
- """Validate a pyc against the source mtime and size.
466
+ def _validate_timestamp_pyc (data , source_mtime , source_size , name ,
467
+ exc_details ):
468
+ """Validate a pyc against the source last-modified time.
469
+
470
+ *data* is the contents of the pyc file. (Only the first 16 bytes are
471
+ required.)
472
+
473
+ *source_mtime* is the last modified timestamp of the source file.
474
+
475
+ *source_size* is None or the size of the source file in bytes.
476
+
477
+ *name* is the name of the module being imported. It is used for logging.
478
+
479
+ *exc_details* is a dictionary passed to ImportError if it raised for
480
+ improved debugging.
460
481
461
482
An ImportError is raised if the bytecode is stale.
462
483
463
484
"""
464
- try :
465
- source_mtime = int (source_stats ['mtime' ])
466
- except KeyError :
467
- pass
468
- else :
469
- if _r_long (data [8 :12 ]) != source_mtime :
470
- message = 'bytecode is stale for {!r}' .format (name )
471
- _bootstrap ._verbose_message ('{}' , message )
472
- raise ImportError (message , ** exc_details )
473
- try :
474
- source_size = source_stats ['size' ] & 0xFFFFFFFF
475
- except KeyError :
476
- pass
477
- else :
478
- if _r_long (data [12 :16 ]) != source_size :
479
- raise ImportError ('bytecode is stale for {!r}' .format (name ),
480
- ** exc_details )
485
+ if _r_long (data [8 :12 ]) != (source_mtime & 0xFFFFFFFF ):
486
+ message = 'bytecode is stale for {!r}' .format (name )
487
+ _bootstrap ._verbose_message ('{}' , message )
488
+ raise ImportError (message , ** exc_details )
489
+ if (source_size is not None and
490
+ _r_long (data [12 :16 ]) != (source_size & 0xFFFFFFFF )):
491
+ raise ImportError ('bytecode is stale for {!r}' .format (name ),
492
+ ** exc_details )
481
493
482
494
483
495
def _validate_hash_pyc (data , source_hash , name , exc_details ):
484
496
"""Validate a hash-based pyc by checking the real source hash against the one in
485
497
the pyc header.
486
498
499
+ *data* is the contents of the pyc file. (Only the first 16 bytes are
500
+ required.)
501
+
502
+ *source_hash* is the importlib.util.source_hash() of the source file.
503
+
504
+ *name* is the name of the module being imported. It is used for logging.
505
+
506
+ *exc_details* is a dictionary passed to ImportError if it raised for
507
+ improved debugging.
508
+
509
+ An ImportError is raised if the bytecode is stale.
510
+
487
511
"""
488
512
if data [8 :16 ] != source_hash :
489
513
raise ImportError (
@@ -812,8 +836,13 @@ def get_code(self, fullname):
812
836
_validate_hash_pyc (data , source_hash , fullname ,
813
837
exc_details )
814
838
else :
815
- _validate_timestamp_pyc (data , st , fullname ,
816
- exc_details )
839
+ _validate_timestamp_pyc (
840
+ data ,
841
+ source_mtime ,
842
+ st ['size' ],
843
+ fullname ,
844
+ exc_details ,
845
+ )
817
846
except (ImportError , EOFError ):
818
847
pass
819
848
else :
0 commit comments