mirror of https://github.com/python/cpython.git
Closes #27493: accepted Path objects in file handlers for logging.
This commit is contained in:
parent
d3afb62b8f
commit
638e622055
|
@ -84,6 +84,9 @@ sends logging output to a disk file. It inherits the output functionality from
|
||||||
with that encoding. If *delay* is true, then file opening is deferred until the
|
with that encoding. If *delay* is true, then file opening is deferred until the
|
||||||
first call to :meth:`emit`. By default, the file grows indefinitely.
|
first call to :meth:`emit`. By default, the file grows indefinitely.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
As well as string values, :class:`~pathlib.Path` objects are also accepted
|
||||||
|
for the *filename* argument.
|
||||||
|
|
||||||
.. method:: close()
|
.. method:: close()
|
||||||
|
|
||||||
|
@ -160,6 +163,9 @@ for this value.
|
||||||
with that encoding. If *delay* is true, then file opening is deferred until the
|
with that encoding. If *delay* is true, then file opening is deferred until the
|
||||||
first call to :meth:`emit`. By default, the file grows indefinitely.
|
first call to :meth:`emit`. By default, the file grows indefinitely.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
As well as string values, :class:`~pathlib.Path` objects are also accepted
|
||||||
|
for the *filename* argument.
|
||||||
|
|
||||||
.. method:: reopenIfNeeded()
|
.. method:: reopenIfNeeded()
|
||||||
|
|
||||||
|
@ -287,6 +293,9 @@ module, supports rotation of disk log files.
|
||||||
:file:`app.log.2`, etc. exist, then they are renamed to :file:`app.log.2`,
|
:file:`app.log.2`, etc. exist, then they are renamed to :file:`app.log.2`,
|
||||||
:file:`app.log.3` etc. respectively.
|
:file:`app.log.3` etc. respectively.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
As well as string values, :class:`~pathlib.Path` objects are also accepted
|
||||||
|
for the *filename* argument.
|
||||||
|
|
||||||
.. method:: doRollover()
|
.. method:: doRollover()
|
||||||
|
|
||||||
|
@ -365,6 +374,10 @@ timed intervals.
|
||||||
.. versionchanged:: 3.4
|
.. versionchanged:: 3.4
|
||||||
*atTime* parameter was added.
|
*atTime* parameter was added.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
As well as string values, :class:`~pathlib.Path` objects are also accepted
|
||||||
|
for the *filename* argument.
|
||||||
|
|
||||||
.. method:: doRollover()
|
.. method:: doRollover()
|
||||||
|
|
||||||
Does a rollover, as described above.
|
Does a rollover, as described above.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright 2001-2015 by Vinay Sajip. All Rights Reserved.
|
# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Permission to use, copy, modify, and distribute this software and its
|
# Permission to use, copy, modify, and distribute this software and its
|
||||||
# documentation for any purpose and without fee is hereby granted,
|
# documentation for any purpose and without fee is hereby granted,
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
Logging package for Python. Based on PEP 282 and comments thereto in
|
Logging package for Python. Based on PEP 282 and comments thereto in
|
||||||
comp.lang.python.
|
comp.lang.python.
|
||||||
|
|
||||||
Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved.
|
Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
|
||||||
|
|
||||||
To use, simply 'import logging' and log away!
|
To use, simply 'import logging' and log away!
|
||||||
"""
|
"""
|
||||||
|
@ -994,6 +994,8 @@ def __init__(self, filename, mode='a', encoding=None, delay=False):
|
||||||
"""
|
"""
|
||||||
Open the specified file and use it as the stream for logging.
|
Open the specified file and use it as the stream for logging.
|
||||||
"""
|
"""
|
||||||
|
# Issue #27493: add support for Path objects to be passed in
|
||||||
|
filename = os.fspath(filename)
|
||||||
#keep the absolute path, otherwise derived classes which use this
|
#keep the absolute path, otherwise derived classes which use this
|
||||||
#may come a cropper when the current directory changes
|
#may come a cropper when the current directory changes
|
||||||
self.baseFilename = os.path.abspath(filename)
|
self.baseFilename = os.path.abspath(filename)
|
||||||
|
|
|
@ -246,6 +246,9 @@ def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None,
|
||||||
|
|
||||||
self.extMatch = re.compile(self.extMatch, re.ASCII)
|
self.extMatch = re.compile(self.extMatch, re.ASCII)
|
||||||
self.interval = self.interval * interval # multiply by units requested
|
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
|
||||||
|
filename = self.baseFilename
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
t = os.stat(filename)[ST_MTIME]
|
t = os.stat(filename)[ST_MTIME]
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
import codecs
|
import codecs
|
||||||
import configparser
|
import configparser
|
||||||
import datetime
|
import datetime
|
||||||
|
import pathlib
|
||||||
import pickle
|
import pickle
|
||||||
import io
|
import io
|
||||||
import gc
|
import gc
|
||||||
|
@ -575,6 +576,29 @@ def test_builtin_handlers(self):
|
||||||
self.assertFalse(h.shouldFlush(r))
|
self.assertFalse(h.shouldFlush(r))
|
||||||
h.close()
|
h.close()
|
||||||
|
|
||||||
|
def test_path_objects(self):
|
||||||
|
"""
|
||||||
|
Test that Path objects are accepted as filename arguments to handlers.
|
||||||
|
|
||||||
|
See Issue #27493.
|
||||||
|
"""
|
||||||
|
fd, fn = tempfile.mkstemp()
|
||||||
|
os.close(fd)
|
||||||
|
os.unlink(fn)
|
||||||
|
pfn = pathlib.Path(fn)
|
||||||
|
cases = (
|
||||||
|
(logging.FileHandler, (pfn, 'w')),
|
||||||
|
(logging.handlers.RotatingFileHandler, (pfn, 'a')),
|
||||||
|
(logging.handlers.TimedRotatingFileHandler, (pfn, 'h')),
|
||||||
|
)
|
||||||
|
if sys.platform in ('linux', 'darwin'):
|
||||||
|
cases += ((logging.handlers.WatchedFileHandler, (pfn, 'w')),)
|
||||||
|
for cls, args in cases:
|
||||||
|
h = cls(*args)
|
||||||
|
self.assertTrue(os.path.exists(fn))
|
||||||
|
os.unlink(fn)
|
||||||
|
h.close()
|
||||||
|
|
||||||
@unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.')
|
@unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.')
|
||||||
@unittest.skipUnless(threading, 'Threading required for this test.')
|
@unittest.skipUnless(threading, 'Threading required for this test.')
|
||||||
def test_race(self):
|
def test_race(self):
|
||||||
|
|
Loading…
Reference in New Issue