Skip to content

Commit

Permalink
Add support for os.PathLike objects, fixes #72
Browse files Browse the repository at this point in the history
  • Loading branch information
phill-85 authored and sbraz committed Apr 29, 2020
1 parent 684ff08 commit cf2b7df
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
19 changes: 12 additions & 7 deletions pymediainfo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ def __init__(self, xml, encoding_errors="strict"):
for xml_track in xml_dom.iterfind(xpath):
self.tracks.append(Track(xml_track))
@staticmethod
def _parse_filename(filename):
if hasattr(os, "PathLike") and isinstance(filename, os.PathLike):
return os.fspath(filename), False
elif pathlib is not None and isinstance(filename, pathlib.PurePath):
return str(filename), False
else:
url = urlparse.urlparse(filename)
return filename, bool(url.scheme)
@staticmethod
def _get_library(library_file=None):
os_is_nt = os.name in ("nt", "dos", "os2", "ce")
if os_is_nt:
Expand Down Expand Up @@ -271,7 +280,7 @@ def parse(cls, filename, library_file=None, cover_data=False,
* ``"JSON"``
* ``%``-delimited templates (see ``mediainfo --Info-Parameters``)
:type filename: str or pathlib.Path
:type filename: str or pathlib.Path or os.PathLike
:rtype: str if `output` is set.
:rtype: :class:`MediaInfo` otherwise.
:raises FileNotFoundError: if passed a non-existent file
Expand All @@ -295,14 +304,10 @@ def parse(cls, filename, library_file=None, cover_data=False,
"""
lib, handle, lib_version_str, lib_version = cls._get_library(library_file)
if pathlib is not None and isinstance(filename, pathlib.PurePath):
filename = str(filename)
url = False
else:
url = urlparse.urlparse(filename)
filename, is_url = cls._parse_filename(filename)
# Try to open the file (if it's not a URL)
# Doesn't work on Windows because paths are URLs
if not (url and url.scheme):
if not is_url:
# Test whether the file is readable
with open(filename, "rb"):
pass
Expand Down
27 changes: 27 additions & 0 deletions tests/test_pymediainfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,33 @@ def test_parse_non_existent_path_pathlib(self):
path = self.pathlib.Path(data_dir) / "this file does not exist"
self.assertRaises(FileNotFoundError, MediaInfo.parse, path)

class MediaInfoFilenameTypesTest(unittest.TestCase):
def test_parse_filename_str(self):
path = os.path.join(data_dir, "test.txt")
filename, is_url = MediaInfo._parse_filename(path)
# Windows paths are URLs
if not os_is_nt:
self.assertFalse(is_url)
self.assertEqual(filename, path)
def test_parse_filename_pathlib(self):
pathlib = pytest.importorskip("pathlib")
path = pathlib.Path(data_dir, "test.txt")
filename, is_url = MediaInfo._parse_filename(path)
self.assertFalse(is_url)
self.assertEqual(filename, os.path.join(data_dir, "test.txt"))
@pytest.mark.skipif(sys.version_info < (3, 6), reason="os.PathLike requires Python 3.6")
def test_parse_filename_pathlike(self):
class PathLikeObject(os.PathLike):
def __fspath__(self):
return os.path.join(data_dir, "test.txt")
path = PathLikeObject()
filename, is_url = MediaInfo._parse_filename(path)
self.assertFalse(is_url)
self.assertEqual(filename, os.path.join(data_dir, "test.txt"))
def test_parse_filename_url(self):
filename, is_url = MediaInfo._parse_filename("https://localhost")
self.assertTrue(is_url)

class MediaInfoTestParseNonExistentFile(unittest.TestCase):
@pytest.mark.skipif(os_is_nt, reason="Windows paths are URLs")
def test_parse_non_existent_path(self):
Expand Down

0 comments on commit cf2b7df

Please sign in to comment.