From 7e18deef652a9d413d5dbd19d61073ba7eb5460e Mon Sep 17 00:00:00 2001 From: Mayank Asthana Date: Wed, 10 Oct 2018 20:16:44 +0530 Subject: [PATCH] bpo-34926: Make mimetypes.guess_type accept os.PathLike objects (GH-9777) :meth:`mimetypes.MimeTypes.guess_type` now accepts :term:`path-like object` in addition to url strings. --- Doc/library/mimetypes.rst | 9 +++++-- Lib/mimetypes.py | 3 ++- Lib/test/test_mimetypes.py | 24 +++++++++++++++++++ .../2018-10-10-00-22-57.bpo-34926.CA0rqd.rst | 2 ++ 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-10-10-00-22-57.bpo-34926.CA0rqd.rst diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 67b7a717853..973014abba5 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -30,8 +30,10 @@ the information :func:`init` sets up. .. index:: pair: MIME; headers - Guess the type of a file based on its filename or URL, given by *url*. The - return value is a tuple ``(type, encoding)`` where *type* is ``None`` if the + Guess the type of a file based on its filename, path or URL, given by *url*. + URL can be a string or a :term:`path-like object`. + + The return value is a tuple ``(type, encoding)`` where *type* is ``None`` if the type can't be guessed (missing or unknown suffix) or a string of the form ``'type/subtype'``, usable for a MIME :mailheader:`content-type` header. @@ -49,6 +51,9 @@ the information :func:`init` sets up. *strict* is ``False``, some additional non-standard but commonly used MIME types are also recognized. + .. versionchanged:: 3.8 + Added support for url being a :term:`path-like object`. + .. function:: guess_all_extensions(type, strict=True) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index bc647115b18..8861b75362d 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -95,7 +95,7 @@ class MimeTypes: exts.append(ext) def guess_type(self, url, strict=True): - """Guess the type of a file based on its URL. + """Guess the type of a file which is either a URL or a path-like object. Return value is a tuple (type, encoding) where type is None if the type can't be guessed (no or unknown suffix) or a string @@ -113,6 +113,7 @@ class MimeTypes: Optional `strict' argument when False adds a bunch of commonly found, but non-standard types. """ + url = os.fspath(url) scheme, url = urllib.parse._splittype(url) if scheme == 'data': # syntax of data URLs: diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 4e2c9089b57..554d3d5cead 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -1,6 +1,7 @@ import io import locale import mimetypes +import pathlib import sys import unittest @@ -77,6 +78,29 @@ class MimeTypesTestCase(unittest.TestCase): strict=True) self.assertEqual(exts, ['.g3', '.g\xb3']) + def test_path_like_ob(self): + filename = "LICENSE.txt" + filepath = pathlib.Path(filename) + filepath_with_abs_dir = pathlib.Path('/dir/'+filename) + filepath_relative = pathlib.Path('../dir/'+filename) + path_dir = pathlib.Path('./') + + expected = self.db.guess_type(filename) + + self.assertEqual(self.db.guess_type(filepath), expected) + self.assertEqual(self.db.guess_type( + filepath_with_abs_dir), expected) + self.assertEqual(self.db.guess_type(filepath_relative), expected) + self.assertEqual(self.db.guess_type(path_dir), (None, None)) + + def test_keywords_args_api(self): + self.assertEqual(self.db.guess_type( + url="foo.html", strict=True), ("text/html", None)) + self.assertEqual(self.db.guess_all_extensions( + type='image/jpg', strict=True), []) + self.assertEqual(self.db.guess_extension( + type='image/jpg', strict=False), '.jpg') + @unittest.skipUnless(sys.platform.startswith("win"), "Windows only") class Win32MimeTypesTestCase(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2018-10-10-00-22-57.bpo-34926.CA0rqd.rst b/Misc/NEWS.d/next/Library/2018-10-10-00-22-57.bpo-34926.CA0rqd.rst new file mode 100644 index 00000000000..5b009cb8774 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-10-10-00-22-57.bpo-34926.CA0rqd.rst @@ -0,0 +1,2 @@ +:meth:`mimetypes.MimeTypes.guess_type` now accepts :term:`path-like object` in addition to url strings. +Patch by Mayank Asthana.