File tree Expand file tree Collapse file tree 2 files changed +38
-3
lines changed
Expand file tree Collapse file tree 2 files changed +38
-3
lines changed Original file line number Diff line number Diff line change 99
1010import os
1111import errno
12+ import stat
1213import sys
1314import time
1415import traceback
@@ -138,11 +139,29 @@ class FileHandler(Handler):
138139 """File handler which supports reopening of logs.
139140 """
140141
141- def __init__ (self , filename , mode = "a" ):
142+ def __init__ (self , filename , mode = None ):
142143 Handler .__init__ (self )
143- self .stream = open (filename , mode )
144+ open_mode = mode or 'a'
145+
146+ try :
147+ self .stream = open (filename , open_mode )
148+ except OSError as e :
149+ retried = False
150+ if not mode :
151+ if e .errno == errno .ESPIPE :
152+ st_mode = os .stat (filename ).st_mode
153+ if stat .S_ISCHR (st_mode ) or stat .S_ISFIFO (st_mode ):
154+ # Python 3 can't open special files like
155+ # /dev/stdout in 'a' mode due to an implicit seek call
156+ # that fails with ESPIPE. Retry in 'w' mode.
157+ self .stream = open (filename , 'w' )
158+ open_mode = 'w'
159+ retried = True
160+ if not retried :
161+ raise
162+
144163 self .baseFilename = filename
145- self .mode = mode
164+ self .mode = open_mode
146165
147166 def reopen (self ):
148167 self .close ()
Original file line number Diff line number Diff line change @@ -220,6 +220,22 @@ def test_emit_error(self):
220220 self .assertTrue (dummy_stderr .written .endswith ('OSError\n ' ),
221221 dummy_stderr .written )
222222
223+ if os .path .exists ('/dev/stdout' ):
224+ StdoutTestsBase = FileHandlerTests
225+ else :
226+ # Skip the stdout tests on platforms that don't have /dev/stdout.
227+ StdoutTestsBase = object
228+
229+ class StdoutTests (StdoutTestsBase ):
230+ def test_ctor_with_dev_stdout (self ):
231+ handler = self ._makeOne ('/dev/stdout' )
232+ # Modes 'w' and 'a' have the same semantics when applied to
233+ # character device files and fifos.
234+ self .assertIn (handler .mode , ['w' , 'a' ])
235+ self .assertEqual (handler .baseFilename , '/dev/stdout' )
236+ self .assertEqual (handler .stream .name , '/dev/stdout' )
237+ handler .close ()
238+
223239class RotatingFileHandlerTests (FileHandlerTests ):
224240
225241 def _getTargetClass (self ):
You can’t perform that action at this time.
0 commit comments