@@ -232,19 +232,19 @@ def __init__(self, filename, when='h', interval=1, backupCount=0,
232232 if self .when == 'S' :
233233 self .interval = 1 # one second
234234 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) "
236236 elif self .when == 'M' :
237237 self .interval = 60 # one minute
238238 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) "
240240 elif self .when == 'H' :
241241 self .interval = 60 * 60 # one hour
242242 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) "
244244 elif self .when == 'D' or self .when == 'MIDNIGHT' :
245245 self .interval = 60 * 60 * 24 # one day
246246 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) "
248248 elif self .when .startswith ('W' ):
249249 self .interval = 60 * 60 * 24 * 7 # one week
250250 if len (self .when ) != 2 :
@@ -253,11 +253,17 @@ def __init__(self, filename, when='h', interval=1, backupCount=0,
253253 raise ValueError ("Invalid day specified for weekly rollover: %s" % self .when )
254254 self .dayOfWeek = int (self .when [1 ])
255255 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) "
257257 else :
258258 raise ValueError ("Invalid rollover interval specified: %s" % self .when )
259259
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 )
261267 self .interval = self .interval * interval # multiply by units requested
262268 # The following line added because the filename passed in could be a
263269 # path object (see Issue #27493), but self.baseFilename will be a string
@@ -376,31 +382,22 @@ def getFilesToDelete(self):
376382 for fileName in fileNames :
377383 if fileName [:plen ] == prefix :
378384 suffix = fileName [plen :]
379- if self .extMatch .match (suffix ):
385+ if self .extMatch .fullmatch (suffix ):
380386 result .append (os .path .join (dirName , fileName ))
381387 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 )
386388 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 )
393400
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
404401 if len (result ) < self .backupCount :
405402 result = []
406403 else :
0 commit comments