Issue #28225: bz2 module now supports pathlib

Initial patch by Ethan Furman.
diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst
index 6c49d9f..d5f6225 100644
--- a/Doc/library/bz2.rst
+++ b/Doc/library/bz2.rst
@@ -61,6 +61,9 @@
    .. versionchanged:: 3.4
       The ``'x'`` (exclusive creation) mode was added.
 
+   .. versionchanged:: 3.6
+      Accepts a :term:`path-like object`.
+
 
 .. class:: BZ2File(filename, mode='r', buffering=None, compresslevel=9)
 
@@ -128,6 +131,9 @@
       The :meth:`~io.BufferedIOBase.read` method now accepts an argument of
       ``None``.
 
+   .. versionchanged:: 3.6
+      Accepts a :term:`path-like object`.
+
 
 Incremental (de)compression
 ---------------------------
diff --git a/Lib/bz2.py b/Lib/bz2.py
index bc78c54..6f56328 100644
--- a/Lib/bz2.py
+++ b/Lib/bz2.py
@@ -11,6 +11,7 @@
 
 from builtins import open as _builtin_open
 import io
+import os
 import warnings
 import _compression
 
@@ -42,9 +43,9 @@
     def __init__(self, filename, mode="r", buffering=None, compresslevel=9):
         """Open a bzip2-compressed file.
 
-        If filename is a str or bytes object, it gives the name
-        of the file to be opened. Otherwise, it should be a file object,
-        which will be used to read or write the compressed data.
+        If filename is a str, bytes, or PathLike object, it gives the
+        name of the file to be opened. Otherwise, it should be a file
+        object, which will be used to read or write the compressed data.
 
         mode can be 'r' for reading (default), 'w' for (over)writing,
         'x' for creating exclusively, or 'a' for appending. These can
@@ -91,7 +92,7 @@
         else:
             raise ValueError("Invalid mode: %r" % (mode,))
 
-        if isinstance(filename, (str, bytes)):
+        if isinstance(filename, (str, bytes, os.PathLike)):
             self._fp = _builtin_open(filename, mode)
             self._closefp = True
             self._mode = mode_code
@@ -99,7 +100,7 @@
             self._fp = filename
             self._mode = mode_code
         else:
-            raise TypeError("filename must be a str or bytes object, or a file")
+            raise TypeError("filename must be a str, bytes, file or PathLike object")
 
         if self._mode == _MODE_READ:
             raw = _compression.DecompressReader(self._fp,
@@ -289,8 +290,9 @@
          encoding=None, errors=None, newline=None):
     """Open a bzip2-compressed file in binary or text mode.
 
-    The filename argument can be an actual filename (a str or bytes
-    object), or an existing file object to read from or write to.
+    The filename argument can be an actual filename (a str, bytes, or
+    PathLike object), or an existing file object to read from or write
+    to.
 
     The mode argument can be "r", "rb", "w", "wb", "x", "xb", "a" or
     "ab" for binary mode, or "rt", "wt", "xt" or "at" for text mode.
diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py
index 46ad2c4..482242c 100644
--- a/Lib/test/test_bz2.py
+++ b/Lib/test/test_bz2.py
@@ -6,6 +6,7 @@
 import os
 import pickle
 import glob
+import pathlib
 import random
 import subprocess
 import sys
@@ -560,6 +561,13 @@
         with BZ2File(str_filename, "rb") as f:
             self.assertEqual(f.read(), self.DATA)
 
+    def testOpenPathLikeFilename(self):
+        filename = pathlib.Path(self.filename)
+        with BZ2File(filename, "wb") as f:
+            f.write(self.DATA)
+        with BZ2File(filename, "rb") as f:
+            self.assertEqual(f.read(), self.DATA)
+
     def testDecompressLimited(self):
         """Decompressed data buffering should be limited"""
         bomb = bz2.compress(b'\0' * int(2e6), compresslevel=9)
diff --git a/Misc/NEWS b/Misc/NEWS
index abf9c93..bc4aa8c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -46,6 +46,8 @@
 Library
 -------
 
+- Issue #28225: bz2 module now supports pathlib.  Initial patch by Ethan Furman.
+
 - Issue #28227: gzip now supports pathlib.  Patch by Ethan Furman.
 
 - Issue #27358: Optimized merging var-keyword arguments and improved error