Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Lib/logging/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,11 @@ def shouldRollover(self, record):
if self.stream is None: # delay was set...
self.stream = self._open()
if self.maxBytes > 0: # are we rolling over?
pos = self.stream.tell()
try:
pos = self.stream.tell()
except io.UnsupportedOperation:
# gh-143237: Never rollover a named pipe.
return False
if not pos:
# gh-116263: Never rollover an empty file
return False
Expand Down
23 changes: 23 additions & 0 deletions Lib/test/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -6369,6 +6369,29 @@ def test_should_not_rollover_non_file(self):
self.assertFalse(rh.shouldRollover(self.next_rec()))
rh.close()

@unittest.skipUnless(hasattr(os, "mkfifo"), 'requires os.mkfifo()')
def test_should_not_rollover_named_pipe(self):
# gh-143237 - test with non-seekable special file (named pipe)
filename = os_helper.TESTFN
self.addCleanup(os_helper.unlink, filename)
try:
os.mkfifo(filename)
except PermissionError as e:
self.skipTest('os.mkfifo(): %s' % e)

def other_side():
with open(filename, 'rb') as f:
f.read(1)

thread = threading.Thread(target=other_side)
with threading_helper.start_threads([thread]):
rh = logging.handlers.RotatingFileHandler(
filename, encoding="utf-8", maxBytes=1)
try:
self.assertFalse(rh.shouldRollover(self.next_rec()))
finally:
rh.close()
Comment on lines +6390 to +6393
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi, can we use self.addCleanup(rh.close) or

with contextlib.closing(rh):
    self.assertFalse(rh.shouldRollover(self.next_rec()))

to simplify this test code?

Copy link
Member Author

Choose a reason for hiding this comment

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

self.addCleanup(rh.close) will not work -- it should be closed before exiting the with block, otherwise the thread will hang.

I did not use contextlib.closing() only because contextlib is not yet imported. The difference is not so large. Maybe I'll do this at the end.


def test_should_rollover(self):
with open(self.fn, 'wb') as f:
f.write(b'\n')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix support of named pipes in the rotating :mod:`logging` handlers.
Loading