@@ -798,8 +798,112 @@ def test_destinsrc_false_positive(self):
798798 shutil .rmtree (TESTFN , ignore_errors = True )
799799
800800
801+ class TestCopyFile (unittest .TestCase ):
802+
803+ _delete = False
804+
805+ class Faux (object ):
806+ _entered = False
807+ _exited_with = None
808+ _raised = False
809+ def __init__ (self , raise_in_exit = False , suppress_at_exit = True ):
810+ self ._raise_in_exit = raise_in_exit
811+ self ._suppress_at_exit = suppress_at_exit
812+ def read (self , * args ):
813+ return ''
814+ def __enter__ (self ):
815+ self ._entered = True
816+ def __exit__ (self , exc_type , exc_val , exc_tb ):
817+ self ._exited_with = exc_type , exc_val , exc_tb
818+ if self ._raise_in_exit :
819+ self ._raised = True
820+ raise IOError ("Cannot close" )
821+ return self ._suppress_at_exit
822+
823+ def tearDown (self ):
824+ if self ._delete :
825+ del shutil .open
826+
827+ def _set_shutil_open (self , func ):
828+ shutil .open = func
829+ self ._delete = True
830+
831+ def test_w_source_open_fails (self ):
832+ def _open (filename , mode = 'r' ):
833+ if filename == 'srcfile' :
834+ raise IOError ('Cannot open "srcfile"' )
835+ assert 0 # shouldn't reach here.
836+
837+ self ._set_shutil_open (_open )
838+
839+ self .assertRaises (IOError , shutil .copyfile , 'srcfile' , 'destfile' )
840+
841+ def test_w_dest_open_fails (self ):
842+
843+ srcfile = self .Faux ()
844+
845+ def _open (filename , mode = 'r' ):
846+ if filename == 'srcfile' :
847+ return srcfile
848+ if filename == 'destfile' :
849+ raise IOError ('Cannot open "destfile"' )
850+ assert 0 # shouldn't reach here.
851+
852+ self ._set_shutil_open (_open )
853+
854+ shutil .copyfile ('srcfile' , 'destfile' )
855+ self .assertTrue (srcfile ._entered )
856+ self .assertTrue (srcfile ._exited_with [0 ] is IOError )
857+ self .assertEqual (srcfile ._exited_with [1 ].args ,
858+ ('Cannot open "destfile"' ,))
859+
860+ def test_w_dest_close_fails (self ):
861+
862+ srcfile = self .Faux ()
863+ destfile = self .Faux (True )
864+
865+ def _open (filename , mode = 'r' ):
866+ if filename == 'srcfile' :
867+ return srcfile
868+ if filename == 'destfile' :
869+ return destfile
870+ assert 0 # shouldn't reach here.
871+
872+ self ._set_shutil_open (_open )
873+
874+ shutil .copyfile ('srcfile' , 'destfile' )
875+ self .assertTrue (srcfile ._entered )
876+ self .assertTrue (destfile ._entered )
877+ self .assertTrue (destfile ._raised )
878+ self .assertTrue (srcfile ._exited_with [0 ] is IOError )
879+ self .assertEqual (srcfile ._exited_with [1 ].args ,
880+ ('Cannot close' ,))
881+
882+ def test_w_source_close_fails (self ):
883+
884+ srcfile = self .Faux (True )
885+ destfile = self .Faux ()
886+
887+ def _open (filename , mode = 'r' ):
888+ if filename == 'srcfile' :
889+ return srcfile
890+ if filename == 'destfile' :
891+ return destfile
892+ assert 0 # shouldn't reach here.
893+
894+ self ._set_shutil_open (_open )
895+
896+ self .assertRaises (IOError ,
897+ shutil .copyfile , 'srcfile' , 'destfile' )
898+ self .assertTrue (srcfile ._entered )
899+ self .assertTrue (destfile ._entered )
900+ self .assertFalse (destfile ._raised )
901+ self .assertTrue (srcfile ._exited_with [0 ] is None )
902+ self .assertTrue (srcfile ._raised )
903+
904+
801905def test_main ():
802- support .run_unittest (TestShutil , TestMove )
906+ support .run_unittest (TestShutil , TestMove , TestCopyFile )
803907
804908if __name__ == '__main__' :
805909 test_main ()
0 commit comments