Skip to content

Commit 638e622

Browse files
committed
Closes python#27493: accepted Path objects in file handlers for logging.
1 parent d3afb62 commit 638e622

4 files changed

Lines changed: 44 additions & 2 deletions

File tree

Doc/library/logging.handlers.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ sends logging output to a disk file. It inherits the output functionality from
8484
with that encoding. If *delay* is true, then file opening is deferred until the
8585
first call to :meth:`emit`. By default, the file grows indefinitely.
8686

87+
.. versionchanged:: 3.6
88+
As well as string values, :class:`~pathlib.Path` objects are also accepted
89+
for the *filename* argument.
8790

8891
.. method:: close()
8992

@@ -160,6 +163,9 @@ for this value.
160163
with that encoding. If *delay* is true, then file opening is deferred until the
161164
first call to :meth:`emit`. By default, the file grows indefinitely.
162165

166+
.. versionchanged:: 3.6
167+
As well as string values, :class:`~pathlib.Path` objects are also accepted
168+
for the *filename* argument.
163169

164170
.. method:: reopenIfNeeded()
165171

@@ -287,6 +293,9 @@ module, supports rotation of disk log files.
287293
:file:`app.log.2`, etc. exist, then they are renamed to :file:`app.log.2`,
288294
:file:`app.log.3` etc. respectively.
289295

296+
.. versionchanged:: 3.6
297+
As well as string values, :class:`~pathlib.Path` objects are also accepted
298+
for the *filename* argument.
290299

291300
.. method:: doRollover()
292301

@@ -365,6 +374,10 @@ timed intervals.
365374
.. versionchanged:: 3.4
366375
*atTime* parameter was added.
367376

377+
.. versionchanged:: 3.6
378+
As well as string values, :class:`~pathlib.Path` objects are also accepted
379+
for the *filename* argument.
380+
368381
.. method:: doRollover()
369382

370383
Does a rollover, as described above.

Lib/logging/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2001-2015 by Vinay Sajip. All Rights Reserved.
1+
# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
22
#
33
# Permission to use, copy, modify, and distribute this software and its
44
# documentation for any purpose and without fee is hereby granted,
@@ -18,7 +18,7 @@
1818
Logging package for Python. Based on PEP 282 and comments thereto in
1919
comp.lang.python.
2020
21-
Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved.
21+
Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
2222
2323
To use, simply 'import logging' and log away!
2424
"""
@@ -994,6 +994,8 @@ def __init__(self, filename, mode='a', encoding=None, delay=False):
994994
"""
995995
Open the specified file and use it as the stream for logging.
996996
"""
997+
# Issue #27493: add support for Path objects to be passed in
998+
filename = os.fspath(filename)
997999
#keep the absolute path, otherwise derived classes which use this
9981000
#may come a cropper when the current directory changes
9991001
self.baseFilename = os.path.abspath(filename)

Lib/logging/handlers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None,
246246

247247
self.extMatch = re.compile(self.extMatch, re.ASCII)
248248
self.interval = self.interval * interval # multiply by units requested
249+
# The following line added because the filename passed in could be a
250+
# path object (see Issue #27493), but self.baseFilename will be a string
251+
filename = self.baseFilename
249252
if os.path.exists(filename):
250253
t = os.stat(filename)[ST_MTIME]
251254
else:

Lib/test/test_logging.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import codecs
2727
import configparser
2828
import datetime
29+
import pathlib
2930
import pickle
3031
import io
3132
import gc
@@ -575,6 +576,29 @@ def test_builtin_handlers(self):
575576
self.assertFalse(h.shouldFlush(r))
576577
h.close()
577578

579+
def test_path_objects(self):
580+
"""
581+
Test that Path objects are accepted as filename arguments to handlers.
582+
583+
See Issue #27493.
584+
"""
585+
fd, fn = tempfile.mkstemp()
586+
os.close(fd)
587+
os.unlink(fn)
588+
pfn = pathlib.Path(fn)
589+
cases = (
590+
(logging.FileHandler, (pfn, 'w')),
591+
(logging.handlers.RotatingFileHandler, (pfn, 'a')),
592+
(logging.handlers.TimedRotatingFileHandler, (pfn, 'h')),
593+
)
594+
if sys.platform in ('linux', 'darwin'):
595+
cases += ((logging.handlers.WatchedFileHandler, (pfn, 'w')),)
596+
for cls, args in cases:
597+
h = cls(*args)
598+
self.assertTrue(os.path.exists(fn))
599+
os.unlink(fn)
600+
h.close()
601+
578602
@unittest.skipIf(os.name == 'nt', 'WatchedFileHandler not appropriate for Windows.')
579603
@unittest.skipUnless(threading, 'Threading required for this test.')
580604
def test_race(self):

0 commit comments

Comments
 (0)