@@ -232,19 +232,19 @@ def __init__(self, filename, when='h', interval=1, backupCount=0,
232
232
if self .when == 'S' :
233
233
self .interval = 1 # one second
234
234
self .suffix = "%Y-%m-%d_%H-%M-%S"
235
- self . extMatch = r"^\d {4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(\.\w+)?$ "
235
+ extMatch = r"(?<!\d)\d {4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(?!\d) "
236
236
elif self .when == 'M' :
237
237
self .interval = 60 # one minute
238
238
self .suffix = "%Y-%m-%d_%H-%M"
239
- self . extMatch = r"^\d {4}-\d{2}-\d{2}_\d{2}-\d{2}(\.\w+)?$ "
239
+ extMatch = r"(?<!\d)\d {4}-\d{2}-\d{2}_\d{2}-\d{2}(?!\d) "
240
240
elif self .when == 'H' :
241
241
self .interval = 60 * 60 # one hour
242
242
self .suffix = "%Y-%m-%d_%H"
243
- self . extMatch = r"^\d {4}-\d{2}-\d{2}_\d{2}(\.\w+)?$ "
243
+ extMatch = r"(?<!\d)\d {4}-\d{2}-\d{2}_\d{2}(?!\d) "
244
244
elif self .when == 'D' or self .when == 'MIDNIGHT' :
245
245
self .interval = 60 * 60 * 24 # one day
246
246
self .suffix = "%Y-%m-%d"
247
- self . extMatch = r"^\d {4}-\d{2}-\d{2}(\.\w+)?$ "
247
+ extMatch = r"(?<!\d)\d {4}-\d{2}-\d{2}(?!\d) "
248
248
elif self .when .startswith ('W' ):
249
249
self .interval = 60 * 60 * 24 * 7 # one week
250
250
if len (self .when ) != 2 :
@@ -253,11 +253,17 @@ def __init__(self, filename, when='h', interval=1, backupCount=0,
253
253
raise ValueError ("Invalid day specified for weekly rollover: %s" % self .when )
254
254
self .dayOfWeek = int (self .when [1 ])
255
255
self .suffix = "%Y-%m-%d"
256
- self . extMatch = r"^\d {4}-\d{2}-\d{2}(\.\w+)?$ "
256
+ extMatch = r"(?<!\d)\d {4}-\d{2}-\d{2}(?!\d) "
257
257
else :
258
258
raise ValueError ("Invalid rollover interval specified: %s" % self .when )
259
259
260
- self .extMatch = re .compile (self .extMatch , re .ASCII )
260
+ # extMatch is a pattern for matching a datetime suffix in a file name.
261
+ # After custom naming, it is no longer guaranteed to be separated by
262
+ # periods from other parts of the filename. The lookup statements
263
+ # (?<!\d) and (?!\d) ensure that the datetime suffix (which itself
264
+ # starts and ends with digits) is not preceded or followed by digits.
265
+ # This reduces the number of false matches and improves performance.
266
+ self .extMatch = re .compile (extMatch , re .ASCII )
261
267
self .interval = self .interval * interval # multiply by units requested
262
268
# The following line added because the filename passed in could be a
263
269
# path object (see Issue #27493), but self.baseFilename will be a string
@@ -376,31 +382,22 @@ def getFilesToDelete(self):
376
382
for fileName in fileNames :
377
383
if fileName [:plen ] == prefix :
378
384
suffix = fileName [plen :]
379
- if self .extMatch .match (suffix ):
385
+ if self .extMatch .fullmatch (suffix ):
380
386
result .append (os .path .join (dirName , fileName ))
381
387
else :
382
- # See bpo-44753: Don't use the extension when computing the prefix.
383
- n , e = os .path .splitext (baseName )
384
- prefix = n + '.'
385
- plen = len (prefix )
386
388
for fileName in fileNames :
387
- # Our files could be just about anything after custom naming, but
388
- # likely candidates are of the form
389
- # foo.log.DATETIME_SUFFIX or foo.DATETIME_SUFFIX.log
390
- if (not fileName .startswith (baseName ) and fileName .endswith (e ) and
391
- len (fileName ) > (plen + 1 ) and not fileName [plen + 1 ].isdigit ()):
392
- continue
389
+ # Our files could be just about anything after custom naming,
390
+ # but they should contain the datetime suffix.
391
+ # Try to find the datetime suffix in the file name and verify
392
+ # that the file name can be generated by this handler.
393
+ m = self .extMatch .search (fileName )
394
+ while m :
395
+ dfn = self .namer (self .baseFilename + "." + m [0 ])
396
+ if os .path .basename (dfn ) == fileName :
397
+ result .append (os .path .join (dirName , fileName ))
398
+ break
399
+ m = self .extMatch .search (fileName , m .start () + 1 )
393
400
394
- if fileName [:plen ] == prefix :
395
- suffix = fileName [plen :]
396
- # See bpo-45628: The date/time suffix could be anywhere in the
397
- # filename
398
-
399
- parts = suffix .split ('.' )
400
- for part in parts :
401
- if self .extMatch .match (part ):
402
- result .append (os .path .join (dirName , fileName ))
403
- break
404
401
if len (result ) < self .backupCount :
405
402
result = []
406
403
else :
0 commit comments