From 7f099457b5119f2686ad504354f7087bb467eae9 Mon Sep 17 00:00:00 2001
From: Tim Lehr <timlehr@users.noreply.github.com>
Date: Thu, 29 Feb 2024 09:24:54 -0800
Subject: [PATCH] added support for pathlib.Path filepath arguments for adapter
 IO functions (#1704)

Signed-off-by: Tim Lehr <tim.lehr@disneyanimation.com>
Signed-off-by: Eric Reinecke <reinecke.eric@gmail.com>
---
 .../opentimelineio/adapters/__init__.py         | 17 ++++++++++++++---
 tests/test_builtin_adapters.py                  |  9 +++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/py-opentimelineio/opentimelineio/adapters/__init__.py b/src/py-opentimelineio/opentimelineio/adapters/__init__.py
index 6ed93684d6..7ee6557742 100644
--- a/src/py-opentimelineio/opentimelineio/adapters/__init__.py
+++ b/src/py-opentimelineio/opentimelineio/adapters/__init__.py
@@ -15,6 +15,7 @@
 
 import os
 import itertools
+import pathlib
 
 from .. import (
     exceptions,
@@ -132,10 +133,15 @@ def read_from_file(
         timeline = read_from_file("file_with_no_extension", "cmx_3600")
     """
 
-    adapter = _from_filepath_or_name(filepath, adapter_name)
+    # convert pathlib Path objects to simple string
+    string_filepath = filepath
+    if isinstance(string_filepath, pathlib.PurePath):
+        string_filepath = os.fspath(filepath)
+
+    adapter = _from_filepath_or_name(string_filepath, adapter_name)
 
     return adapter.read_from_file(
-        filepath=filepath,
+        filepath=string_filepath,
         media_linker_name=media_linker_name,
         media_linker_argument_map=media_linker_argument_map,
         **adapter_argument_map
@@ -189,9 +195,14 @@ def write_to_file(
 
     adapter = _from_filepath_or_name(filepath, adapter_name)
 
+    # convert pathlib Path objects to simple string
+    string_filepath = filepath
+    if isinstance(string_filepath, pathlib.PurePath):
+        string_filepath = os.fspath(filepath)
+
     return adapter.write_to_file(
         input_otio=input_otio,
-        filepath=filepath,
+        filepath=string_filepath,
         **adapter_argument_map
     )
 
diff --git a/tests/test_builtin_adapters.py b/tests/test_builtin_adapters.py
index 633cd9ff1d..faf9f46eda 100755
--- a/tests/test_builtin_adapters.py
+++ b/tests/test_builtin_adapters.py
@@ -13,6 +13,7 @@
     otio_json,
 )
 
+import pathlib
 import tempfile
 
 
@@ -90,6 +91,14 @@ def test_otio_json_default(self):
         test_str = otio.adapters.write_to_string(tl)
         self.assertJsonEqual(tl, otio.adapters.read_from_string(test_str))
 
+    def test_otio_pathlib_filepath(self):
+        """Tests reading / writing with a filepath that's a Path object."""
+        tl = otio.adapters.read_from_file(pathlib.Path(SCREENING_EXAMPLE_PATH))
+        with tempfile.TemporaryDirectory() as temp_dir:
+            tmp_path = pathlib.Path(temp_dir) / "tmp_pathlib.otio"
+            otio.adapters.write_to_file(input_otio=tl, filepath=tmp_path)
+            self.assertJsonEqual(tl, otio.adapters.read_from_file(filepath=tmp_path))
+
 
 if __name__ == '__main__':
     unittest.main()