update
This commit is contained in:
25
.CondaPkg/env/Lib/logging/__init__.py
vendored
25
.CondaPkg/env/Lib/logging/__init__.py
vendored
@@ -1521,7 +1521,7 @@ class Logger(Filterer):
|
||||
To pass exception information, use the keyword argument exc_info with
|
||||
a true value, e.g.
|
||||
|
||||
logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
|
||||
logger.debug("Houston, we have a %s", "thorny problem", exc_info=True)
|
||||
"""
|
||||
if self.isEnabledFor(DEBUG):
|
||||
self._log(DEBUG, msg, args, **kwargs)
|
||||
@@ -1533,7 +1533,7 @@ class Logger(Filterer):
|
||||
To pass exception information, use the keyword argument exc_info with
|
||||
a true value, e.g.
|
||||
|
||||
logger.info("Houston, we have a %s", "notable problem", exc_info=1)
|
||||
logger.info("Houston, we have a %s", "notable problem", exc_info=True)
|
||||
"""
|
||||
if self.isEnabledFor(INFO):
|
||||
self._log(INFO, msg, args, **kwargs)
|
||||
@@ -1545,7 +1545,7 @@ class Logger(Filterer):
|
||||
To pass exception information, use the keyword argument exc_info with
|
||||
a true value, e.g.
|
||||
|
||||
logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
|
||||
logger.warning("Houston, we have a %s", "bit of a problem", exc_info=True)
|
||||
"""
|
||||
if self.isEnabledFor(WARNING):
|
||||
self._log(WARNING, msg, args, **kwargs)
|
||||
@@ -1562,7 +1562,7 @@ class Logger(Filterer):
|
||||
To pass exception information, use the keyword argument exc_info with
|
||||
a true value, e.g.
|
||||
|
||||
logger.error("Houston, we have a %s", "major problem", exc_info=1)
|
||||
logger.error("Houston, we have a %s", "major problem", exc_info=True)
|
||||
"""
|
||||
if self.isEnabledFor(ERROR):
|
||||
self._log(ERROR, msg, args, **kwargs)
|
||||
@@ -1580,7 +1580,7 @@ class Logger(Filterer):
|
||||
To pass exception information, use the keyword argument exc_info with
|
||||
a true value, e.g.
|
||||
|
||||
logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
|
||||
logger.critical("Houston, we have a %s", "major disaster", exc_info=True)
|
||||
"""
|
||||
if self.isEnabledFor(CRITICAL):
|
||||
self._log(CRITICAL, msg, args, **kwargs)
|
||||
@@ -1598,7 +1598,7 @@ class Logger(Filterer):
|
||||
To pass exception information, use the keyword argument exc_info with
|
||||
a true value, e.g.
|
||||
|
||||
logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
|
||||
logger.log(level, "We have a %s", "mysterious problem", exc_info=True)
|
||||
"""
|
||||
if not isinstance(level, int):
|
||||
if raiseExceptions:
|
||||
@@ -1985,18 +1985,11 @@ class LoggerAdapter(object):
|
||||
"""
|
||||
return self.logger.hasHandlers()
|
||||
|
||||
def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
|
||||
def _log(self, level, msg, args, **kwargs):
|
||||
"""
|
||||
Low-level log implementation, proxied to allow nested logger adapters.
|
||||
"""
|
||||
return self.logger._log(
|
||||
level,
|
||||
msg,
|
||||
args,
|
||||
exc_info=exc_info,
|
||||
extra=extra,
|
||||
stack_info=stack_info,
|
||||
)
|
||||
return self.logger._log(level, msg, args, **kwargs)
|
||||
|
||||
@property
|
||||
def manager(self):
|
||||
@@ -2056,7 +2049,7 @@ def basicConfig(**kwargs):
|
||||
that this argument is incompatible with 'filename' - if both
|
||||
are present, 'stream' is ignored.
|
||||
handlers If specified, this should be an iterable of already created
|
||||
handlers, which will be added to the root handler. Any handler
|
||||
handlers, which will be added to the root logger. Any handler
|
||||
in the list which does not have a formatter assigned will be
|
||||
assigned the formatter created in this function.
|
||||
force If this keyword is specified as true, any existing handlers
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
132
.CondaPkg/env/Lib/logging/config.py
vendored
132
.CondaPkg/env/Lib/logging/config.py
vendored
@@ -1,4 +1,4 @@
|
||||
# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved.
|
||||
# Copyright 2001-2023 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
@@ -485,10 +485,10 @@ class BaseConfigurator(object):
|
||||
c = config.pop('()')
|
||||
if not callable(c):
|
||||
c = self.resolve(c)
|
||||
props = config.pop('.', None)
|
||||
# Check for valid identifiers
|
||||
kwargs = {k: config[k] for k in config if valid_ident(k)}
|
||||
kwargs = {k: config[k] for k in config if (k != '.' and valid_ident(k))}
|
||||
result = c(**kwargs)
|
||||
props = config.pop('.', None)
|
||||
if props:
|
||||
for name, value in props.items():
|
||||
setattr(result, name, value)
|
||||
@@ -500,6 +500,33 @@ class BaseConfigurator(object):
|
||||
value = tuple(value)
|
||||
return value
|
||||
|
||||
def _is_queue_like_object(obj):
|
||||
"""Check that *obj* implements the Queue API."""
|
||||
if isinstance(obj, queue.Queue):
|
||||
return True
|
||||
# defer importing multiprocessing as much as possible
|
||||
from multiprocessing.queues import Queue as MPQueue
|
||||
if isinstance(obj, MPQueue):
|
||||
return True
|
||||
# Depending on the multiprocessing start context, we cannot create
|
||||
# a multiprocessing.managers.BaseManager instance 'mm' to get the
|
||||
# runtime type of mm.Queue() or mm.JoinableQueue() (see gh-119819).
|
||||
#
|
||||
# Since we only need an object implementing the Queue API, we only
|
||||
# do a protocol check, but we do not use typing.runtime_checkable()
|
||||
# and typing.Protocol to reduce import time (see gh-121723).
|
||||
#
|
||||
# Ideally, we would have wanted to simply use strict type checking
|
||||
# instead of a protocol-based type checking since the latter does
|
||||
# not check the method signatures.
|
||||
queue_interface = [
|
||||
'empty', 'full', 'get', 'get_nowait',
|
||||
'put', 'put_nowait', 'join', 'qsize',
|
||||
'task_done',
|
||||
]
|
||||
return all(callable(getattr(obj, method, None))
|
||||
for method in queue_interface)
|
||||
|
||||
class DictConfigurator(BaseConfigurator):
|
||||
"""
|
||||
Configure logging using a dictionary-like object to describe the
|
||||
@@ -732,16 +759,16 @@ class DictConfigurator(BaseConfigurator):
|
||||
|
||||
def _configure_queue_handler(self, klass, **kwargs):
|
||||
if 'queue' in kwargs:
|
||||
q = kwargs['queue']
|
||||
q = kwargs.pop('queue')
|
||||
else:
|
||||
q = queue.Queue() # unbounded
|
||||
rhl = kwargs.get('respect_handler_level', False)
|
||||
if 'listener' in kwargs:
|
||||
lklass = kwargs['listener']
|
||||
else:
|
||||
lklass = logging.handlers.QueueListener
|
||||
listener = lklass(q, *kwargs['handlers'], respect_handler_level=rhl)
|
||||
handler = klass(q)
|
||||
|
||||
rhl = kwargs.pop('respect_handler_level', False)
|
||||
lklass = kwargs.pop('listener', logging.handlers.QueueListener)
|
||||
handlers = kwargs.pop('handlers', [])
|
||||
|
||||
listener = lklass(q, *handlers, respect_handler_level=rhl)
|
||||
handler = klass(q, **kwargs)
|
||||
handler.listener = listener
|
||||
return handler
|
||||
|
||||
@@ -768,37 +795,39 @@ class DictConfigurator(BaseConfigurator):
|
||||
klass = cname
|
||||
else:
|
||||
klass = self.resolve(cname)
|
||||
if issubclass(klass, logging.handlers.MemoryHandler) and\
|
||||
'target' in config:
|
||||
# Special case for handler which refers to another handler
|
||||
try:
|
||||
tn = config['target']
|
||||
th = self.config['handlers'][tn]
|
||||
if not isinstance(th, logging.Handler):
|
||||
config.update(config_copy) # restore for deferred cfg
|
||||
raise TypeError('target not configured yet')
|
||||
config['target'] = th
|
||||
except Exception as e:
|
||||
raise ValueError('Unable to set target handler %r' % tn) from e
|
||||
if issubclass(klass, logging.handlers.MemoryHandler):
|
||||
if 'flushLevel' in config:
|
||||
config['flushLevel'] = logging._checkLevel(config['flushLevel'])
|
||||
if 'target' in config:
|
||||
# Special case for handler which refers to another handler
|
||||
try:
|
||||
tn = config['target']
|
||||
th = self.config['handlers'][tn]
|
||||
if not isinstance(th, logging.Handler):
|
||||
config.update(config_copy) # restore for deferred cfg
|
||||
raise TypeError('target not configured yet')
|
||||
config['target'] = th
|
||||
except Exception as e:
|
||||
raise ValueError('Unable to set target handler %r' % tn) from e
|
||||
elif issubclass(klass, logging.handlers.QueueHandler):
|
||||
# Another special case for handler which refers to other handlers
|
||||
if 'handlers' not in config:
|
||||
raise ValueError('No handlers specified for a QueueHandler')
|
||||
# if 'handlers' not in config:
|
||||
# raise ValueError('No handlers specified for a QueueHandler')
|
||||
if 'queue' in config:
|
||||
qspec = config['queue']
|
||||
if not isinstance(qspec, queue.Queue):
|
||||
if isinstance(qspec, str):
|
||||
q = self.resolve(qspec)
|
||||
if not callable(q):
|
||||
raise TypeError('Invalid queue specifier %r' % qspec)
|
||||
q = q()
|
||||
elif isinstance(qspec, dict):
|
||||
if '()' not in qspec:
|
||||
raise TypeError('Invalid queue specifier %r' % qspec)
|
||||
q = self.configure_custom(dict(qspec))
|
||||
else:
|
||||
|
||||
if isinstance(qspec, str):
|
||||
q = self.resolve(qspec)
|
||||
if not callable(q):
|
||||
raise TypeError('Invalid queue specifier %r' % qspec)
|
||||
config['queue'] = q
|
||||
config['queue'] = q()
|
||||
elif isinstance(qspec, dict):
|
||||
if '()' not in qspec:
|
||||
raise TypeError('Invalid queue specifier %r' % qspec)
|
||||
config['queue'] = self.configure_custom(dict(qspec))
|
||||
elif not _is_queue_like_object(qspec):
|
||||
raise TypeError('Invalid queue specifier %r' % qspec)
|
||||
|
||||
if 'listener' in config:
|
||||
lspec = config['listener']
|
||||
if isinstance(lspec, type):
|
||||
@@ -819,18 +848,19 @@ class DictConfigurator(BaseConfigurator):
|
||||
if not callable(listener):
|
||||
raise TypeError('Invalid listener specifier %r' % lspec)
|
||||
config['listener'] = listener
|
||||
hlist = []
|
||||
try:
|
||||
for hn in config['handlers']:
|
||||
h = self.config['handlers'][hn]
|
||||
if not isinstance(h, logging.Handler):
|
||||
config.update(config_copy) # restore for deferred cfg
|
||||
raise TypeError('Required handler %r '
|
||||
'is not configured yet' % hn)
|
||||
hlist.append(h)
|
||||
except Exception as e:
|
||||
raise ValueError('Unable to set required handler %r' % hn) from e
|
||||
config['handlers'] = hlist
|
||||
if 'handlers' in config:
|
||||
hlist = []
|
||||
try:
|
||||
for hn in config['handlers']:
|
||||
h = self.config['handlers'][hn]
|
||||
if not isinstance(h, logging.Handler):
|
||||
config.update(config_copy) # restore for deferred cfg
|
||||
raise TypeError('Required handler %r '
|
||||
'is not configured yet' % hn)
|
||||
hlist.append(h)
|
||||
except Exception as e:
|
||||
raise ValueError('Unable to set required handler %r' % hn) from e
|
||||
config['handlers'] = hlist
|
||||
elif issubclass(klass, logging.handlers.SMTPHandler) and\
|
||||
'mailhost' in config:
|
||||
config['mailhost'] = self.as_tuple(config['mailhost'])
|
||||
@@ -841,8 +871,7 @@ class DictConfigurator(BaseConfigurator):
|
||||
factory = functools.partial(self._configure_queue_handler, klass)
|
||||
else:
|
||||
factory = klass
|
||||
props = config.pop('.', None)
|
||||
kwargs = {k: config[k] for k in config if valid_ident(k)}
|
||||
kwargs = {k: config[k] for k in config if (k != '.' and valid_ident(k))}
|
||||
try:
|
||||
result = factory(**kwargs)
|
||||
except TypeError as te:
|
||||
@@ -860,6 +889,7 @@ class DictConfigurator(BaseConfigurator):
|
||||
result.setLevel(logging._checkLevel(level))
|
||||
if filters:
|
||||
self.add_filters(result, filters)
|
||||
props = config.pop('.', None)
|
||||
if props:
|
||||
for name, value in props.items():
|
||||
setattr(result, name, value)
|
||||
|
||||
135
.CondaPkg/env/Lib/logging/handlers.py
vendored
135
.CondaPkg/env/Lib/logging/handlers.py
vendored
@@ -187,15 +187,18 @@ class RotatingFileHandler(BaseRotatingHandler):
|
||||
Basically, see if the supplied record would cause the file to exceed
|
||||
the size limit we have.
|
||||
"""
|
||||
# See bpo-45401: Never rollover anything other than regular files
|
||||
if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
|
||||
return False
|
||||
if self.stream is None: # delay was set...
|
||||
self.stream = self._open()
|
||||
if self.maxBytes > 0: # are we rolling over?
|
||||
pos = self.stream.tell()
|
||||
if not pos:
|
||||
# gh-116263: Never rollover an empty file
|
||||
return False
|
||||
msg = "%s\n" % self.format(record)
|
||||
self.stream.seek(0, 2) #due to non-posix-compliant Windows feature
|
||||
if self.stream.tell() + len(msg) >= self.maxBytes:
|
||||
if pos + len(msg) >= self.maxBytes:
|
||||
# See bpo-45401: Never rollover anything other than regular files
|
||||
if os.path.exists(self.baseFilename) and not os.path.isfile(self.baseFilename):
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -232,19 +235,19 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||
if self.when == 'S':
|
||||
self.interval = 1 # one second
|
||||
self.suffix = "%Y-%m-%d_%H-%M-%S"
|
||||
self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(\.\w+)?$"
|
||||
extMatch = r"(?<!\d)\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(?!\d)"
|
||||
elif self.when == 'M':
|
||||
self.interval = 60 # one minute
|
||||
self.suffix = "%Y-%m-%d_%H-%M"
|
||||
self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}(\.\w+)?$"
|
||||
extMatch = r"(?<!\d)\d{4}-\d{2}-\d{2}_\d{2}-\d{2}(?!\d)"
|
||||
elif self.when == 'H':
|
||||
self.interval = 60 * 60 # one hour
|
||||
self.suffix = "%Y-%m-%d_%H"
|
||||
self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}(\.\w+)?$"
|
||||
extMatch = r"(?<!\d)\d{4}-\d{2}-\d{2}_\d{2}(?!\d)"
|
||||
elif self.when == 'D' or self.when == 'MIDNIGHT':
|
||||
self.interval = 60 * 60 * 24 # one day
|
||||
self.suffix = "%Y-%m-%d"
|
||||
self.extMatch = r"^\d{4}-\d{2}-\d{2}(\.\w+)?$"
|
||||
extMatch = r"(?<!\d)\d{4}-\d{2}-\d{2}(?!\d)"
|
||||
elif self.when.startswith('W'):
|
||||
self.interval = 60 * 60 * 24 * 7 # one week
|
||||
if len(self.when) != 2:
|
||||
@@ -253,11 +256,17 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||
raise ValueError("Invalid day specified for weekly rollover: %s" % self.when)
|
||||
self.dayOfWeek = int(self.when[1])
|
||||
self.suffix = "%Y-%m-%d"
|
||||
self.extMatch = r"^\d{4}-\d{2}-\d{2}(\.\w+)?$"
|
||||
extMatch = r"(?<!\d)\d{4}-\d{2}-\d{2}(?!\d)"
|
||||
else:
|
||||
raise ValueError("Invalid rollover interval specified: %s" % self.when)
|
||||
|
||||
self.extMatch = re.compile(self.extMatch, re.ASCII)
|
||||
# extMatch is a pattern for matching a datetime suffix in a file name.
|
||||
# After custom naming, it is no longer guaranteed to be separated by
|
||||
# periods from other parts of the filename. The lookup statements
|
||||
# (?<!\d) and (?!\d) ensure that the datetime suffix (which itself
|
||||
# starts and ends with digits) is not preceded or followed by digits.
|
||||
# This reduces the number of false matches and improves performance.
|
||||
self.extMatch = re.compile(extMatch, re.ASCII)
|
||||
self.interval = self.interval * interval # multiply by units requested
|
||||
# The following line added because the filename passed in could be a
|
||||
# path object (see Issue #27493), but self.baseFilename will be a string
|
||||
@@ -299,7 +308,7 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||
|
||||
r = rotate_ts - ((currentHour * 60 + currentMinute) * 60 +
|
||||
currentSecond)
|
||||
if r < 0:
|
||||
if r <= 0:
|
||||
# Rotate time is before the current time (for example when
|
||||
# self.rotateAt is 13:45 and it now 14:15), rotation is
|
||||
# tomorrow.
|
||||
@@ -328,17 +337,21 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||
daysToWait = self.dayOfWeek - day
|
||||
else:
|
||||
daysToWait = 6 - day + self.dayOfWeek + 1
|
||||
newRolloverAt = result + (daysToWait * (60 * 60 * 24))
|
||||
if not self.utc:
|
||||
dstNow = t[-1]
|
||||
dstAtRollover = time.localtime(newRolloverAt)[-1]
|
||||
if dstNow != dstAtRollover:
|
||||
if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
|
||||
addend = -3600
|
||||
else: # DST bows out before next rollover, so we need to add an hour
|
||||
addend = 3600
|
||||
newRolloverAt += addend
|
||||
result = newRolloverAt
|
||||
result += daysToWait * _MIDNIGHT
|
||||
result += self.interval - _MIDNIGHT * 7
|
||||
else:
|
||||
result += self.interval - _MIDNIGHT
|
||||
if not self.utc:
|
||||
dstNow = t[-1]
|
||||
dstAtRollover = time.localtime(result)[-1]
|
||||
if dstNow != dstAtRollover:
|
||||
if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
|
||||
addend = -3600
|
||||
if not time.localtime(result-3600)[-1]:
|
||||
addend = 0
|
||||
else: # DST bows out before next rollover, so we need to add an hour
|
||||
addend = 3600
|
||||
result += addend
|
||||
return result
|
||||
|
||||
def shouldRollover(self, record):
|
||||
@@ -369,32 +382,28 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||
dirName, baseName = os.path.split(self.baseFilename)
|
||||
fileNames = os.listdir(dirName)
|
||||
result = []
|
||||
# See bpo-44753: Don't use the extension when computing the prefix.
|
||||
n, e = os.path.splitext(baseName)
|
||||
prefix = n + '.'
|
||||
plen = len(prefix)
|
||||
for fileName in fileNames:
|
||||
if self.namer is None:
|
||||
# Our files will always start with baseName
|
||||
if not fileName.startswith(baseName):
|
||||
continue
|
||||
else:
|
||||
# Our files could be just about anything after custom naming, but
|
||||
# likely candidates are of the form
|
||||
# foo.log.DATETIME_SUFFIX or foo.DATETIME_SUFFIX.log
|
||||
if (not fileName.startswith(baseName) and fileName.endswith(e) and
|
||||
len(fileName) > (plen + 1) and not fileName[plen+1].isdigit()):
|
||||
continue
|
||||
|
||||
if fileName[:plen] == prefix:
|
||||
suffix = fileName[plen:]
|
||||
# See bpo-45628: The date/time suffix could be anywhere in the
|
||||
# filename
|
||||
parts = suffix.split('.')
|
||||
for part in parts:
|
||||
if self.extMatch.match(part):
|
||||
if self.namer is None:
|
||||
prefix = baseName + '.'
|
||||
plen = len(prefix)
|
||||
for fileName in fileNames:
|
||||
if fileName[:plen] == prefix:
|
||||
suffix = fileName[plen:]
|
||||
if self.extMatch.fullmatch(suffix):
|
||||
result.append(os.path.join(dirName, fileName))
|
||||
else:
|
||||
for fileName in fileNames:
|
||||
# Our files could be just about anything after custom naming,
|
||||
# but they should contain the datetime suffix.
|
||||
# Try to find the datetime suffix in the file name and verify
|
||||
# that the file name can be generated by this handler.
|
||||
m = self.extMatch.search(fileName)
|
||||
while m:
|
||||
dfn = self.namer(self.baseFilename + "." + m[0])
|
||||
if os.path.basename(dfn) == fileName:
|
||||
result.append(os.path.join(dirName, fileName))
|
||||
break
|
||||
m = self.extMatch.search(fileName, m.start() + 1)
|
||||
|
||||
if len(result) < self.backupCount:
|
||||
result = []
|
||||
else:
|
||||
@@ -410,17 +419,14 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||
then we have to get a list of matching filenames, sort them and remove
|
||||
the one with the oldest suffix.
|
||||
"""
|
||||
if self.stream:
|
||||
self.stream.close()
|
||||
self.stream = None
|
||||
# get the time that this sequence started at and make it a TimeTuple
|
||||
currentTime = int(time.time())
|
||||
dstNow = time.localtime(currentTime)[-1]
|
||||
t = self.rolloverAt - self.interval
|
||||
if self.utc:
|
||||
timeTuple = time.gmtime(t)
|
||||
else:
|
||||
timeTuple = time.localtime(t)
|
||||
dstNow = time.localtime(currentTime)[-1]
|
||||
dstThen = timeTuple[-1]
|
||||
if dstNow != dstThen:
|
||||
if dstNow:
|
||||
@@ -431,26 +437,19 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||
dfn = self.rotation_filename(self.baseFilename + "." +
|
||||
time.strftime(self.suffix, timeTuple))
|
||||
if os.path.exists(dfn):
|
||||
os.remove(dfn)
|
||||
# Already rolled over.
|
||||
return
|
||||
|
||||
if self.stream:
|
||||
self.stream.close()
|
||||
self.stream = None
|
||||
self.rotate(self.baseFilename, dfn)
|
||||
if self.backupCount > 0:
|
||||
for s in self.getFilesToDelete():
|
||||
os.remove(s)
|
||||
if not self.delay:
|
||||
self.stream = self._open()
|
||||
newRolloverAt = self.computeRollover(currentTime)
|
||||
while newRolloverAt <= currentTime:
|
||||
newRolloverAt = newRolloverAt + self.interval
|
||||
#If DST changes and midnight or weekly rollover, adjust for this.
|
||||
if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
|
||||
dstAtRollover = time.localtime(newRolloverAt)[-1]
|
||||
if dstNow != dstAtRollover:
|
||||
if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
|
||||
addend = -3600
|
||||
else: # DST bows out before next rollover, so we need to add an hour
|
||||
addend = 3600
|
||||
newRolloverAt += addend
|
||||
self.rolloverAt = newRolloverAt
|
||||
self.rolloverAt = self.computeRollover(currentTime)
|
||||
|
||||
class WatchedFileHandler(logging.FileHandler):
|
||||
"""
|
||||
@@ -833,10 +832,8 @@ class SysLogHandler(logging.Handler):
|
||||
"local7": LOG_LOCAL7,
|
||||
}
|
||||
|
||||
#The map below appears to be trivially lowercasing the key. However,
|
||||
#there's more to it than meets the eye - in some locales, lowercasing
|
||||
#gives unexpected results. See SF #1524081: in the Turkish locale,
|
||||
#"INFO".lower() != "info"
|
||||
# Originally added to work around GH-43683. Unnecessary since GH-50043 but kept
|
||||
# for backwards compatibility.
|
||||
priority_map = {
|
||||
"DEBUG" : "debug",
|
||||
"INFO" : "info",
|
||||
|
||||
Reference in New Issue
Block a user