Skip to content

Commit b2405a5

Browse files
committed
when rotating log files with no namer specified, match whole extension (pythonGH-93205)
1 parent 08e4e88 commit b2405a5

File tree

2 files changed

+61
-19
lines changed

2 files changed

+61
-19
lines changed

Lib/logging/handlers.py

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -365,32 +365,37 @@ def getFilesToDelete(self):
365365
dirName, baseName = os.path.split(self.baseFilename)
366366
fileNames = os.listdir(dirName)
367367
result = []
368-
# See bpo-44753: Don't use the extension when computing the prefix.
369-
n, e = os.path.splitext(baseName)
370-
prefix = n + '.'
371-
plen = len(prefix)
372-
for fileName in fileNames:
373-
if self.namer is None:
374-
# Our files will always start with baseName
375-
if not fileName.startswith(baseName):
376-
continue
377-
else:
368+
if self.namer is None:
369+
prefix = baseName + '.'
370+
plen = len(prefix)
371+
for fileName in fileNames:
372+
if fileName[:plen] == prefix:
373+
suffix = fileName[plen:]
374+
if self.extMatch.match(suffix):
375+
result.append(os.path.join(dirName, fileName))
376+
else:
377+
# See bpo-44753: Don't use the extension when computing the prefix.
378+
n, e = os.path.splitext(baseName)
379+
prefix = n + '.'
380+
plen = len(prefix)
381+
for fileName in fileNames:
378382
# Our files could be just about anything after custom naming, but
379383
# likely candidates are of the form
380384
# foo.log.DATETIME_SUFFIX or foo.DATETIME_SUFFIX.log
381385
if (not fileName.startswith(baseName) and fileName.endswith(e) and
382386
len(fileName) > (plen + 1) and not fileName[plen+1].isdigit()):
383387
continue
384388

385-
if fileName[:plen] == prefix:
386-
suffix = fileName[plen:]
387-
# See bpo-45628: The date/time suffix could be anywhere in the
388-
# filename
389-
parts = suffix.split('.')
390-
for part in parts:
391-
if self.extMatch.match(part):
392-
result.append(os.path.join(dirName, fileName))
393-
break
389+
if fileName[:plen] == prefix:
390+
suffix = fileName[plen:]
391+
# See bpo-45628: The date/time suffix could be anywhere in the
392+
# filename
393+
394+
parts = suffix.split('.')
395+
for part in parts:
396+
if self.extMatch.match(part):
397+
result.append(os.path.join(dirName, fileName))
398+
break
394399
if len(result) < self.backupCount:
395400
result = []
396401
else:

Lib/test/test_logging.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5554,6 +5554,43 @@ def test_compute_files_to_delete(self):
55545554
self.assertTrue(fn.startswith(prefix + '.') and
55555555
fn[len(prefix) + 2].isdigit())
55565556

5557+
def test_compute_files_to_delete_same_filename_different_extensions(self):
5558+
# See GH-93205 for background
5559+
wd = pathlib.Path(tempfile.mkdtemp(prefix='test_logging_'))
5560+
self.addCleanup(shutil.rmtree, wd)
5561+
times = []
5562+
dt = datetime.datetime.now()
5563+
n_files = 10
5564+
for _ in range(n_files):
5565+
times.append(dt.strftime('%Y-%m-%d_%H-%M-%S'))
5566+
dt += datetime.timedelta(seconds=5)
5567+
prefixes = ('a.log', 'a.log.b')
5568+
files = []
5569+
rotators = []
5570+
for i, prefix in enumerate(prefixes):
5571+
backupCount = i+1
5572+
rotator = logging.handlers.TimedRotatingFileHandler(wd / prefix, when='s',
5573+
interval=5,
5574+
backupCount=backupCount,
5575+
delay=True)
5576+
rotators.append(rotator)
5577+
for t in times:
5578+
files.append('%s.%s' % (prefix, t))
5579+
# Create empty files
5580+
for f in files:
5581+
(wd / f).touch()
5582+
# Now the checks that only the correct files are offered up for deletion
5583+
for i, prefix in enumerate(prefixes):
5584+
backupCount = i+1
5585+
rotator = rotators[i]
5586+
candidates = rotator.getFilesToDelete()
5587+
self.assertEqual(len(candidates), n_files - backupCount)
5588+
matcher = re.compile(r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(\.\w+)?$")
5589+
for c in candidates:
5590+
d, fn = os.path.split(c)
5591+
self.assertTrue(fn.startswith(prefix))
5592+
suffix = fn[(len(prefix)+1):]
5593+
self.assertRegexpMatches(suffix, matcher)
55575594

55585595
def secs(**kw):
55595596
return datetime.timedelta(**kw) // datetime.timedelta(seconds=1)

0 commit comments

Comments
 (0)