From e551029497bd7b1ff8580c7e0cfa0a839f73a3fe Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 21 Jan 2021 15:21:08 -0800 Subject: [PATCH 01/23] add windows and mac builds to ci --- .github/workflows/python-package.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 2ecbd48ac..66ad6cbfc 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -12,9 +12,10 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: matrix: + os: [ubuntu-latest, windows-latest, macos-11.0] python-version: [2.7, 3.7, 3.8] env: From 29686e3bccef0352adbdb5ea1dbdc7ad8bd977bd Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 21 Jan 2021 15:22:58 -0800 Subject: [PATCH 02/23] fall back to mac 10.15 --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 66ad6cbfc..cd353af1c 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -15,7 +15,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-11.0] + os: [ubuntu-latest, windows-latest, macos-latest] python-version: [2.7, 3.7, 3.8] env: From 1a839eab0cd87f8d5406f43a9b447415b8b8090e Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 11 Feb 2021 22:10:27 -0800 Subject: [PATCH 03/23] split lcov target out from the ci-postbuild target --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 93fe964e1..3c4bddcf1 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ test-contrib: python-version # CI ################################### ci-prebuild: manifest lint -ci-postbuild: coverage lcov +ci-postbuild: coverage ################################### python-version: From b0e560d7dd570b7651693edf38556eb2cfaba079 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 11 Feb 2021 22:10:45 -0800 Subject: [PATCH 04/23] Specify which build does C++ coverage w/ lcov --- .github/workflows/python-package.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index cd353af1c..b99dfaa6b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -11,7 +11,6 @@ on: jobs: build: - runs-on: ${{ matrix.os }} strategy: matrix: @@ -21,6 +20,11 @@ jobs: env: OTIO_CXX_COVERAGE_BUILD: ON OTIO_CXX_BUILD_TMP_DIR: ${{ github.workspace }}/build + + # for configuring which build will be a C++ coverage build / coverage + # report + GH_COV_PY: 3.7 + GH_COV_OS: ubuntu steps: - uses: actions/checkout@v2 @@ -30,9 +34,12 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Install build dependencies + - name: Install coverage dependency + if: contains(matrix.python-version, env.GH_COV_PY) && contains(matrix.os, env.GH_CO_OS) run: | sudo apt-get install lcov + - name: Install python build dependencies + run: | python -m pip install --upgrade pip setuptools wheel flake8>=3.5 check-manifest - name: Run check-manifest and lint check run: make ci-prebuild @@ -42,7 +49,12 @@ jobs: pip install .[dev] -v - name: Run tests and generate coverage report run: make ci-postbuild + # (only on ubuntu/pyhton3.7) + - name: Run tests and generate coverage report + if: contains(matrix.python-version, env.GH_COVERAGE_PYTHON) && contains(matrix.os, env.GH_COVERAGE_OS) + run: make lcov - name: Upload coverage to Codecov + if: contains(matrix.python-version, env.GH_COVERAGE_PYTHON) && contains(matrix.os, env.GH_COVERAGE_OS) uses: codecov/codecov-action@v1 with: flags: unittests From b36754fa387e435281633c95da7a0f46715d823b Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 11 Feb 2021 22:17:39 -0800 Subject: [PATCH 05/23] use == syntax instead of contains - seemed like contains didn't do what I expected, but I suspect the environment variable wasn't being read --- .github/workflows/python-package.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index b99dfaa6b..e8a83636a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -24,7 +24,7 @@ jobs: # for configuring which build will be a C++ coverage build / coverage # report GH_COV_PY: 3.7 - GH_COV_OS: ubuntu + GH_COV_OS: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -35,7 +35,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install coverage dependency - if: contains(matrix.python-version, env.GH_COV_PY) && contains(matrix.os, env.GH_CO_OS) + if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_CO_OS run: | sudo apt-get install lcov - name: Install python build dependencies @@ -47,14 +47,14 @@ jobs: run: | # compile and install into virtualenv/virtual machine (verbosely) pip install .[dev] -v - - name: Run tests and generate coverage report + - name: Run tests w/ python coverage run: make ci-postbuild # (only on ubuntu/pyhton3.7) - - name: Run tests and generate coverage report - if: contains(matrix.python-version, env.GH_COVERAGE_PYTHON) && contains(matrix.os, env.GH_COVERAGE_OS) + - name: Generate C++ coverage report + if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_CO_OS run: make lcov - name: Upload coverage to Codecov - if: contains(matrix.python-version, env.GH_COVERAGE_PYTHON) && contains(matrix.os, env.GH_COVERAGE_OS) + if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_CO_OS uses: codecov/codecov-action@v1 with: flags: unittests From dd749418b2c3e236fed41204208b6c5c303b2397 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Fri, 12 Feb 2021 08:57:43 -0800 Subject: [PATCH 06/23] move the env config out to the top level --- .github/workflows/python-package.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index e8a83636a..039cc9b89 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -3,6 +3,11 @@ name: OpenTimelineIO +# for configuring which build will be a C++ coverage build / coverage report +env: + GH_COV_PY: 3.7 + GH_COV_OS: ubuntu-latest + on: push: branches: [ master ] @@ -21,11 +26,6 @@ jobs: OTIO_CXX_COVERAGE_BUILD: ON OTIO_CXX_BUILD_TMP_DIR: ${{ github.workspace }}/build - # for configuring which build will be a C++ coverage build / coverage - # report - GH_COV_PY: 3.7 - GH_COV_OS: ubuntu-latest - steps: - uses: actions/checkout@v2 with: @@ -35,7 +35,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install coverage dependency - if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_CO_OS + if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_COV_OS run: | sudo apt-get install lcov - name: Install python build dependencies @@ -51,10 +51,10 @@ jobs: run: make ci-postbuild # (only on ubuntu/pyhton3.7) - name: Generate C++ coverage report - if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_CO_OS + if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_COV_OS run: make lcov - name: Upload coverage to Codecov - if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_CO_OS + if: matrix.python-version == env.GH_COV_PY && matrix.os == env.GH_COV_OS uses: codecov/codecov-action@v1 with: flags: unittests From 046829127a21612e51248290a7f5f5fc6fd1e9c2 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Fri, 12 Feb 2021 15:07:13 -0800 Subject: [PATCH 07/23] Skip autogen tests on windows (slashes) --- tests/test_serialized_schema.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_serialized_schema.py b/tests/test_serialized_schema.py index 1c2d4bbb9..bdaaa85a1 100644 --- a/tests/test_serialized_schema.py +++ b/tests/test_serialized_schema.py @@ -24,13 +24,17 @@ import unittest import os +import platform from opentimelineio.console import ( autogen_serialized_datamodel as asd, autogen_plugin_documentation as apd, ) +RUNNING_ON_WINDOWS = platform.system() == "Windows" + +@unittest.skipIf(RUNNING_ON_WINDOWS) class SerializedSchemaTester(unittest.TestCase): def test_serialized_schema(self): """Test if the schema has changed since last time the serialized schema @@ -54,6 +58,7 @@ def test_serialized_schema(self): ) +@unittest.skipIf(RUNNING_ON_WINDOWS) class PluginDocumentationTester(unittest.TestCase): def test_plugin_documentation(self): """Verify that the plugin manifest matches what is checked into the From df626f8227af4965b9bd8c93a25b923f7e36ab7c Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Fri, 12 Feb 2021 18:36:26 -0800 Subject: [PATCH 08/23] sanitize paths when writing autogen docs --- .../opentimelineio/console/autogen_plugin_documentation.py | 7 ++++++- tests/test_serialized_schema.py | 5 ----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py index dad7b9a6e..c9402dac1 100644 --- a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py +++ b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py @@ -213,9 +213,14 @@ def _parsed_args(): def _format_plugin(plugin_map, extra_stuff, sanitized_paths): + # XXX: always force unix path separator so that the output is consistent + # between every platform. + PATH_SEP = "/" + path = plugin_map['path'] + path = path.replace(os.path.sep, PATH_SEP) if sanitized_paths: - path = os.path.sep.join(path.split(os.path.sep)[-3:]) + path = PATH_SEP.join(path.split(PATH_SEP)[-3:]) return PLUGIN_TEMPLATE.format( name=plugin_map['name'], doc=plugin_map['doc'], diff --git a/tests/test_serialized_schema.py b/tests/test_serialized_schema.py index bdaaa85a1..1c2d4bbb9 100644 --- a/tests/test_serialized_schema.py +++ b/tests/test_serialized_schema.py @@ -24,17 +24,13 @@ import unittest import os -import platform from opentimelineio.console import ( autogen_serialized_datamodel as asd, autogen_plugin_documentation as apd, ) -RUNNING_ON_WINDOWS = platform.system() == "Windows" - -@unittest.skipIf(RUNNING_ON_WINDOWS) class SerializedSchemaTester(unittest.TestCase): def test_serialized_schema(self): """Test if the schema has changed since last time the serialized schema @@ -58,7 +54,6 @@ def test_serialized_schema(self): ) -@unittest.skipIf(RUNNING_ON_WINDOWS) class PluginDocumentationTester(unittest.TestCase): def test_plugin_documentation(self): """Verify that the plugin manifest matches what is checked into the From 7247c1e1d2d0b5fbc582e0d121f861ecadefe88d Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Fri, 12 Feb 2021 18:45:56 -0800 Subject: [PATCH 09/23] try escaping the slash in the replacement --- .../opentimelineio/console/autogen_plugin_documentation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py index c9402dac1..321202c45 100644 --- a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py +++ b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py @@ -218,7 +218,10 @@ def _format_plugin(plugin_map, extra_stuff, sanitized_paths): PATH_SEP = "/" path = plugin_map['path'] - path = path.replace(os.path.sep, PATH_SEP) + + # force using PATH_SEP in place of os.path.sep + path = path.replace("\\", PATH_SEP) + if sanitized_paths: path = PATH_SEP.join(path.split(PATH_SEP)[-3:]) return PLUGIN_TEMPLATE.format( From e91e65ec3da5867b9487afbb280cf0c2e62843c2 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Fri, 12 Feb 2021 18:58:52 -0800 Subject: [PATCH 10/23] manifest paths need same treatment --- .../console/autogen_plugin_documentation.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py index 321202c45..ff06d460a 100644 --- a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py +++ b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py @@ -339,13 +339,22 @@ def _manifest_formatted( ) -def generate_and_write_documentation_plugins(public_only=False, sanitized_paths=False): +def generate_and_write_documentation_plugins( + public_only=False, + sanitized_paths=False +): plugin_info_map = otio.plugins.plugin_info_map() + # force using the same path separator regardless of what the OS says + # this ensures same behavior on windows and linux + PATH_SEP = "/" + # start with the manifest list md_out = io.StringIO() - manifest_path_list = plugin_info_map['manifests'] + manifest_path_list = [ + p.replace(os.path.sep, "/") for p in plugin_info_map['manifests'] + ] if public_only: manifest_path_list = manifest_path_list[:2] @@ -353,7 +362,7 @@ def generate_and_write_documentation_plugins(public_only=False, sanitized_paths= sanitized_paths = manifest_path_list[:] if sanitized_paths: sanitized_paths = [ - os.path.sep.join(p.split(os.path.sep)[-3:]) + PATH_SEP.join(p.split(PATH_SEP)[-3:]) for p in manifest_path_list ] From 8cd70016d30bdf64ce037015be64090de1dbb266 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Wed, 17 Feb 2021 14:45:00 -0800 Subject: [PATCH 11/23] switch to tempfile.TemporaryDirectory - windows is stricter about using file handles that are already open, so switching to a pattern where TemporaryDirectory is used to create things should be safer. Its also cleaner than the mkdtemp/try/except pattern that had been used in the tests before. --- setup.py | 16 +++++++++----- tests/test_adapter_plugin.py | 40 +++++++++++++++++++++------------- tests/test_builtin_adapters.py | 35 ++++++++++++++--------------- tests/test_hooks_plugins.py | 31 ++++++++++++++++---------- 4 files changed, 71 insertions(+), 51 deletions(-) diff --git a/setup.py b/setup.py index 539b6f6a4..776fd7af4 100755 --- a/setup.py +++ b/setup.py @@ -44,6 +44,16 @@ class _Ctx(object): _ctx.debug = False +INSTALL_REQUIRES = [ + 'pyaaf2==1.4.0', +] +# python2 dependencies +if sys.version_info[0] < 3: + INSTALL_REQUIRES.append( + "backports.tempfile", + ) + + def cmake_version_check(): if platform.system() == "Windows": required_minimum_version = '3.17.0' @@ -389,11 +399,7 @@ def test_otio(): 'opentimelineview': 'src/opentimelineview', }, - install_requires=( - [ - 'pyaaf2==1.4.0', - ] - ), + install_requires=INSTALL_REQUIRES, entry_points={ 'console_scripts': [ 'otioview = opentimelineview.console:main', diff --git a/tests/test_adapter_plugin.py b/tests/test_adapter_plugin.py index 928994f07..2ccf2affb 100755 --- a/tests/test_adapter_plugin.py +++ b/tests/test_adapter_plugin.py @@ -23,12 +23,20 @@ # import unittest import os -import shutil -import tempfile import opentimelineio as otio from tests import baseline_reader, utils + +# handle python2 vs python3 difference +try: + from tempfile import TemporaryDirectory # noqa: F401 + import tempfile +except ImportError: + # XXX: python2.7 only + from backports import tempfile + + """Unit tests for the adapter plugin system.""" @@ -192,7 +200,7 @@ def test_find_adapter_by_name(self): ) def test_find_manifest_by_environment_variable(self): - suffix = ".plugin_manifest.json" + basename = "unittest.plugin_manifest.json" # back up existing manifest bak = otio.plugins.manifest._MANIFEST @@ -200,9 +208,10 @@ def test_find_manifest_by_environment_variable(self): # Generate a fake manifest in a temp file, and point at it with # the environment variable - temp_dir = tempfile.mkdtemp(prefix='test_find_manifest_by_environment_variable') - try: - temp_file = os.path.join(temp_dir, 'bar' + suffix) + with tempfile.TemporaryDirectory( + prefix='test_find_manifest_by_environment_variable' + ) as temp_dir: + temp_file = os.path.join(temp_dir, basename) otio.adapters.write_to_file(self.man, temp_file, 'otio_json') # clear out existing manifest @@ -224,11 +233,8 @@ def test_find_manifest_by_environment_variable(self): else: del os.environ['OTIO_PLUGIN_MANIFEST_PATH'] - finally: - shutil.rmtree(temp_dir) - def test_plugin_manifest_order(self): - suffix = ".plugin_manifest.json" + basename = "test.plugin_manifest.json" # back up existing manifest bak = otio.plugins.manifest._MANIFEST @@ -247,8 +253,10 @@ def test_plugin_manifest_order(self): ], } - with tempfile.NamedTemporaryFile(suffix=suffix) as otio_path: - otio.adapters.write_to_file(local_manifest, otio_path.name, 'otio_json') + with tempfile.TemporaryDirectory() as temp_dir: + filename = os.path.join(temp_dir, basename) + + otio.adapters.write_to_file(local_manifest, filename, 'otio_json') result = otio.plugins.manifest.load_manifest() self.assertTrue(len(result.adapters) > 0) @@ -256,7 +264,7 @@ def test_plugin_manifest_order(self): self.assertNotIn("local_otio", (ml.name for ml in result.adapters)) # set where to find the new manifest - os.environ['OTIO_PLUGIN_MANIFEST_PATH'] = otio_path.name + os.environ['OTIO_PLUGIN_MANIFEST_PATH'] = filename result = otio.plugins.manifest.load_manifest() # Rather than try and remove any other setuptools based plugins @@ -265,8 +273,10 @@ def test_plugin_manifest_order(self): self.assertTrue(len(result.adapters) > 0) self.assertIn("otio_json", (ml.name for ml in result.adapters)) self.assertIn("local_json", (ml.name for ml in result.adapters)) - self.assertLess([ml.name for ml in result.adapters].index("local_json"), - [ml.name for ml in result.adapters].index("otio_json")) + self.assertLess( + [ml.name for ml in result.adapters].index("local_json"), + [ml.name for ml in result.adapters].index("otio_json") + ) otio.plugins.manifest._MANIFEST = bak if bak_env: diff --git a/tests/test_builtin_adapters.py b/tests/test_builtin_adapters.py index 5023f10ad..c02ebd9f5 100755 --- a/tests/test_builtin_adapters.py +++ b/tests/test_builtin_adapters.py @@ -26,7 +26,6 @@ import os import shutil -import tempfile import unittest import opentimelineio as otio @@ -36,6 +35,15 @@ otio_json, ) +# handle python2 vs python3 difference +try: + from tempfile import TemporaryDirectory # noqa: F401 + import tempfile +except ImportError: + # XXX: python2.7 only + from backports import tempfile + + SAMPLE_DATA_DIR = os.path.join(os.path.dirname(__file__), "sample_data") SCREENING_EXAMPLE_PATH = os.path.join(SAMPLE_DATA_DIR, "screening_example.edl") @@ -45,16 +53,13 @@ class BuiltInAdapterTest(unittest.TestCase, otio_test_utils.OTIOAssertions): def test_disk_io(self): edl_path = SCREENING_EXAMPLE_PATH timeline = otio.adapters.read_from_file(edl_path) - temp_dir = tempfile.mkdtemp(prefix='test_disk_io') - try: - temp_file = os.path.join(temp_dir, "foo.otio") + + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, "test_disk_io.otio") otio.adapters.write_to_file(timeline, temp_file) decoded = otio.adapters.read_from_file(temp_file) self.assertJsonEqual(timeline, decoded) - finally: - shutil.rmtree(temp_dir) - def test_otio_round_trip(self): tl = otio.adapters.read_from_file(SCREENING_EXAMPLE_PATH) @@ -62,9 +67,8 @@ def test_otio_round_trip(self): self.assertEqual(tl.name, "Example_Screening.01") - temp_dir = tempfile.mkdtemp(prefix='test_otio_round_trip') - try: - temp_file = os.path.join(temp_dir, 'test.otio') + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, 'test_otio_round_trip.otio') otio.adapters.otio_json.write_to_file(tl, temp_file) new = otio.adapters.otio_json.read_from_file(temp_file) @@ -73,18 +77,14 @@ def test_otio_round_trip(self): self.assertMultiLineEqual(baseline_json, new_json) self.assertIsOTIOEquivalentTo(tl, new) - finally: - shutil.rmtree(temp_dir) - def test_disk_vs_string(self): """ Writing to disk and writing to a string should produce the same result """ timeline = otio.adapters.read_from_file(SCREENING_EXAMPLE_PATH) - temp_dir = tempfile.mkdtemp(prefix='test_disk_vs_string') - try: - temp_file = os.path.join(temp_dir, "foo.otio") + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, "test_disk_vs_string.otio") otio.adapters.write_to_file(timeline, temp_file) in_memory = otio.adapters.write_to_string(timeline, 'otio_json') with open(temp_file, 'r') as f: @@ -92,9 +92,6 @@ def test_disk_vs_string(self): self.assertEqual(in_memory, on_disk) - finally: - shutil.rmtree(temp_dir) - def test_adapters_fetch(self): """ Test the dynamic string based adapter fetching """ self.assertEqual( diff --git a/tests/test_hooks_plugins.py b/tests/test_hooks_plugins.py index 2aaffb770..c14ac0151 100644 --- a/tests/test_hooks_plugins.py +++ b/tests/test_hooks_plugins.py @@ -23,10 +23,7 @@ # import unittest import os -import tempfile from copy import deepcopy -# import pkg_resources -# import sys import opentimelineio as otio @@ -37,6 +34,15 @@ utils, ) +# handle python2 vs python3 difference +try: + from tempfile import TemporaryDirectory # noqa: F401 + import tempfile +except ImportError: + # XXX: python2.7 only + from backports import tempfile + + HOOKSCRIPT_PATH = "hookscript_example" POST_WRITE_HOOKSCRIPT_PATH = "post_write_hookscript_example" @@ -124,10 +130,11 @@ def test_run_hook_function(self): self.assertEqual(result.metadata.get("extra_data"), True) def test_run_hook_through_adapters(self): - result = otio.adapters.read_from_string('foo', adapter_name='example', - media_linker_name='example', - hook_function_argument_map=TEST_METADATA - ) + result = otio.adapters.read_from_string( + 'foo', adapter_name='example', + media_linker_name='example', + hook_function_argument_map=TEST_METADATA + ) self.assertEqual(result.name, POST_RUN_NAME) self.assertEqual(result.metadata.get("extra_data"), True) @@ -138,19 +145,19 @@ def test_post_write_hook(self): tl = otio.schema.Timeline() tl_copy = deepcopy(tl) - with tempfile.NamedTemporaryFile( - 'wb', prefix='post_hook_', suffix='.otio') as f: + with tempfile.TemporaryDirectory() as temp_dir: + filename = os.path.join(temp_dir, "post_hook_unittest.otio") arg_map = dict() otio.adapters.write_to_file( tl, - f.name, + filename, adapter_name='otio_json', hook_function_argument_map=arg_map ) - self.assertTrue(os.path.exists(f.name)) + self.assertTrue(os.path.exists(filename)) self.assertEqual( - os.path.getsize(f.name), + os.path.getsize(filename), tl.metadata.get('filesize') ) From 644ec3e5eef30a521a889f9d9cc7872bd42d3206 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Wed, 17 Feb 2021 14:48:50 -0800 Subject: [PATCH 12/23] another conversion to TemporaryDirectory --- tests/test_console.py | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/tests/test_console.py b/tests/test_console.py index a3750d7c4..e38bafa0b 100755 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -27,7 +27,6 @@ import unittest import sys import os -import shutil import tempfile import subprocess @@ -174,9 +173,8 @@ class OTIOConvertTests(ConsoleTester, unittest.TestCase): test_module = otio_console.otioconvert def test_basic(self): - temp_dir = tempfile.mkdtemp(prefix='test_basic') - try: - temp_file = os.path.join(temp_dir, "foo.otio") + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, "test_basic.otio") sys.argv = [ 'otioconvert', '-i', SCREENING_EXAMPLE_PATH, @@ -191,13 +189,9 @@ def test_basic(self): with open(temp_file, 'r') as fi: self.assertIn('"name": "Example_Screening.01",', fi.read()) - finally: - shutil.rmtree(temp_dir) - def test_begin_end(self): - temp_dir = tempfile.mkdtemp(prefix='test_begin_end') - try: - temp_file = os.path.join(temp_dir, "foo.otio") + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, "test_begin_end.otio") # begin needs to be a,b sys.argv = [ @@ -259,13 +253,9 @@ def test_begin_end(self): self.assertEquals(len(result.tracks[0]), 0) self.assertEquals(result.name, "Example_Screening.01") - finally: - shutil.rmtree(temp_dir) - def test_input_argument_error(self): - temp_dir = tempfile.mkdtemp(prefix='test_input_argument_error') - try: - temp_file = os.path.join(temp_dir, "foo.otio") + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, "test_input_argument_error.otio") sys.argv = [ 'otioconvert', @@ -280,13 +270,9 @@ def test_input_argument_error(self): # read results back in self.assertIn('error: input adapter', sys.stderr.getvalue()) - finally: - shutil.rmtree(temp_dir) - def test_output_argument_error(self): - temp_dir = tempfile.mkdtemp(prefix='test_output_argument_error') - try: - temp_file = os.path.join(temp_dir, "foo.otio") + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, "test_output_argument_error.otio") sys.argv = [ 'otioconvert', @@ -302,13 +288,9 @@ def test_output_argument_error(self): # read results back in self.assertIn('error: output adapter', sys.stderr.getvalue()) - finally: - shutil.rmtree(temp_dir) - def test_media_linker_argument_error(self): - temp_dir = tempfile.mkdtemp(prefix='test_media_linker_argument_error') - try: - temp_file = os.path.join(temp_dir, "foo.otio") + with tempfile.TemporaryDirectory() as temp_dir: + temp_file = os.path.join(temp_dir, "test_media_linker_argument_error.otio") sys.argv = [ 'otioconvert', @@ -326,9 +308,6 @@ def test_media_linker_argument_error(self): # read results back in self.assertIn('error: media linker', sys.stderr.getvalue()) - finally: - shutil.rmtree(temp_dir) - OTIOConvertTests_OnShell = CreateShelloutTest(OTIOConvertTests) From 2c0714fd42529f06878e6094bb55f8c79d0c7f1d Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Wed, 17 Feb 2021 14:54:05 -0800 Subject: [PATCH 13/23] more tempfile cleanup --- tests/test_builtin_adapters.py | 1 - tests/test_cmx_3600_adapter.py | 76 ++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 31 deletions(-) diff --git a/tests/test_builtin_adapters.py b/tests/test_builtin_adapters.py index c02ebd9f5..8eb5a7790 100755 --- a/tests/test_builtin_adapters.py +++ b/tests/test_builtin_adapters.py @@ -25,7 +25,6 @@ """Test builtin adapters.""" import os -import shutil import unittest import opentimelineio as otio diff --git a/tests/test_cmx_3600_adapter.py b/tests/test_cmx_3600_adapter.py index 12a1d1dbe..7a97bd44b 100755 --- a/tests/test_cmx_3600_adapter.py +++ b/tests/test_cmx_3600_adapter.py @@ -27,13 +27,21 @@ # python import os -import tempfile import unittest import opentimelineio as otio import opentimelineio.test_utils as otio_test_utils from opentimelineio.adapters import cmx_3600 +# handle python2 vs python3 difference +try: + from tempfile import TemporaryDirectory # noqa: F401 + import tempfile +except ImportError: + # XXX: python2.7 only + from backports import tempfile + + SAMPLE_DATA_DIR = os.path.join(os.path.dirname(__file__), "sample_data") SCREENING_EXAMPLE_PATH = os.path.join(SAMPLE_DATA_DIR, "screening_example.edl") NUCODA_EXAMPLE_PATH = os.path.join(SAMPLE_DATA_DIR, "nucoda_example.edl") @@ -310,51 +318,59 @@ def test_edl_round_trip_disk2mem2disk_speed_effects(self): test_edl = SPEED_EFFECTS_TEST_SMALL timeline = otio.adapters.read_from_file(test_edl) - tmp_path = tempfile.mkstemp(suffix=".edl", text=True)[1] + with tempfile.TemporaryDirectory() as temp_dir: + tmp_path = os.path.join( + temp_dir, + "test_edl_round_trip_disk2mem2disk_speed_effects.edl" + ) - otio.adapters.write_to_file(timeline, tmp_path) + otio.adapters.write_to_file(timeline, tmp_path) - result = otio.adapters.read_from_file(tmp_path) + result = otio.adapters.read_from_file(tmp_path) - # When debugging, you can use this to see the difference in the OTIO - # otio.adapters.otio_json.write_to_file(timeline, "/tmp/original.otio") - # otio.adapters.otio_json.write_to_file(result, "/tmp/output.otio") - # os.system("xxdiff /tmp/{original,output}.otio") + # When debugging, you can use this to see the difference in the OTIO + # otio.adapters.otio_json.write_to_file(timeline, "/tmp/original.otio") + # otio.adapters.otio_json.write_to_file(result, "/tmp/output.otio") + # os.system("xxdiff /tmp/{original,output}.otio") - # When debugging, use this to see the difference in the EDLs on disk - # os.system("xxdiff {} {}&".format(test_edl, tmp_path)) + # When debugging, use this to see the difference in the EDLs on disk + # os.system("xxdiff {} {}&".format(test_edl, tmp_path)) - # The in-memory OTIO representation should be the same - self.assertJsonEqual(timeline, result) + # The in-memory OTIO representation should be the same + self.assertJsonEqual(timeline, result) def test_edl_round_trip_disk2mem2disk(self): timeline = otio.adapters.read_from_file(SCREENING_EXAMPLE_PATH) - tmp_path = tempfile.mkstemp(suffix=".edl", text=True)[1] + with tempfile.TemporaryDirectory() as temp_dir: + tmp_path = os.path.join( + temp_dir, + "test_edl_round_trip_disk2mem2disk.edl" + ) - otio.adapters.write_to_file(timeline, tmp_path) + otio.adapters.write_to_file(timeline, tmp_path) - result = otio.adapters.read_from_file(tmp_path) + result = otio.adapters.read_from_file(tmp_path) - # When debugging, you can use this to see the difference in the OTIO - # otio.adapters.otio_json.write_to_file(timeline, "/tmp/original.otio") - # otio.adapters.otio_json.write_to_file(result, "/tmp/output.otio") - # os.system("opendiff /tmp/{original,output}.otio") + # When debugging, you can use this to see the difference in the OTIO + # otio.adapters.otio_json.write_to_file(timeline, "/tmp/original.otio") + # otio.adapters.otio_json.write_to_file(result, "/tmp/output.otio") + # os.system("opendiff /tmp/{original,output}.otio") - original_json = otio.adapters.otio_json.write_to_string(timeline) - output_json = otio.adapters.otio_json.write_to_string(result) - self.assertMultiLineEqual(original_json, output_json) + original_json = otio.adapters.otio_json.write_to_string(timeline) + output_json = otio.adapters.otio_json.write_to_string(result) + self.assertMultiLineEqual(original_json, output_json) - # The in-memory OTIO representation should be the same - self.assertIsOTIOEquivalentTo(timeline, result) + # The in-memory OTIO representation should be the same + self.assertIsOTIOEquivalentTo(timeline, result) - # When debugging, use this to see the difference in the EDLs on disk - # os.system("opendiff {} {}".format(SCREENING_EXAMPLE_PATH, tmp_path)) + # When debugging, use this to see the difference in the EDLs on disk + # os.system("opendiff {} {}".format(SCREENING_EXAMPLE_PATH, tmp_path)) - # But the EDL text on disk are *not* byte-for-byte identical - with open(SCREENING_EXAMPLE_PATH, "r") as original_file: - with open(tmp_path, "r") as output_file: - self.assertNotEqual(original_file.read(), output_file.read()) + # But the EDL text on disk are *not* byte-for-byte identical + with open(SCREENING_EXAMPLE_PATH, "r") as original_file: + with open(tmp_path, "r") as output_file: + self.assertNotEqual(original_file.read(), output_file.read()) def test_regex_flexibility(self): timeline = otio.adapters.read_from_file(SCREENING_EXAMPLE_PATH) From 072a5c0381b043dcb9287b6d05f9041d3f02aaf0 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Wed, 17 Feb 2021 15:39:41 -0800 Subject: [PATCH 14/23] whoops missed import --- tests/test_console.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/test_console.py b/tests/test_console.py index e38bafa0b..b8c608759 100755 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -27,7 +27,6 @@ import unittest import sys import os -import tempfile import subprocess try: @@ -37,6 +36,15 @@ # python3 import io + +# handle python2 vs python3 difference +try: + from tempfile import TemporaryDirectory # noqa: F401 + import tempfile +except ImportError: + # XXX: python2.7 only + from backports import tempfile + import opentimelineio as otio import opentimelineio.test_utils as otio_test_utils import opentimelineio.console as otio_console From bc0b5541f8a48fb306c07bf677d07c3fa1087fd9 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 09:09:36 -0800 Subject: [PATCH 15/23] testing if this is specific to the generators xml --- tests/test_fcp7_xml_adapter.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_fcp7_xml_adapter.py b/tests/test_fcp7_xml_adapter.py index 9ff56ab46..52a3ffdf6 100644 --- a/tests/test_fcp7_xml_adapter.py +++ b/tests/test_fcp7_xml_adapter.py @@ -1384,6 +1384,8 @@ def test_xml_with_empty_elements(self): self.assertEqual(len(timeline.video_tracks()), 12) self.assertEqual(len(timeline.video_tracks()[0]), 34) + # @TODO: remove this + @unittest.skipIf(True, "file is broken on windows?") def test_read_generators(self): timeline = adapters.read_from_file(GENERATOR_XML_EXAMPLE_PATH) From 29c8012082684f914f0ae459de59439487fa52de Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 09:32:48 -0800 Subject: [PATCH 16/23] only remove windows slashes from sanitized paths - by swapping all the paths out the logic that was isolating certain manifests was skipping _all_ the manifests --- .../console/autogen_plugin_documentation.py | 21 +++++++++---------- tests/test_serialized_schema.py | 5 ++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py index ff06d460a..d8e5ef87c 100644 --- a/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py +++ b/src/py-opentimelineio/opentimelineio/console/autogen_plugin_documentation.py @@ -31,7 +31,6 @@ import argparse import tempfile import textwrap -import os try: # python2 @@ -43,6 +42,10 @@ import opentimelineio as otio +# force using the same path separator regardless of what the OS says +# this ensures same behavior on windows and linux +PATH_SEP = "/" + ALL_PLUGINS_TEXT = """This documents all the plugins that otio could find.""" PUBLIC_ONLY_TEXT = """This documents all the plugins that ship with in the open @@ -343,26 +346,22 @@ def generate_and_write_documentation_plugins( public_only=False, sanitized_paths=False ): - plugin_info_map = otio.plugins.plugin_info_map() + md_out = io.StringIO() - # force using the same path separator regardless of what the OS says - # this ensures same behavior on windows and linux - PATH_SEP = "/" + plugin_info_map = otio.plugins.plugin_info_map() # start with the manifest list - md_out = io.StringIO() - - manifest_path_list = [ - p.replace(os.path.sep, "/") for p in plugin_info_map['manifests'] - ] + manifest_path_list = plugin_info_map['manifests'][:] if public_only: manifest_path_list = manifest_path_list[:2] sanitized_paths = manifest_path_list[:] if sanitized_paths: + # conform all paths to unix-style path separators and leave relative + # paths (relative to root of OTIO directory) sanitized_paths = [ - PATH_SEP.join(p.split(PATH_SEP)[-3:]) + PATH_SEP.join(p.replace("\\", PATH_SEP).split(PATH_SEP)[-3:]) for p in manifest_path_list ] diff --git a/tests/test_serialized_schema.py b/tests/test_serialized_schema.py index 1c2d4bbb9..fd7bed3ae 100644 --- a/tests/test_serialized_schema.py +++ b/tests/test_serialized_schema.py @@ -65,7 +65,10 @@ def test_plugin_documentation(self): with open(fp) as fi: baseline_text = fi.read() - test_text = apd.generate_and_write_documentation_plugins(True, True) + test_text = apd.generate_and_write_documentation_plugins( + public_only=True, + sanitized_paths=True + ) self.maxDiff = None self.longMessage = True From dfc66bdfff98e394eb225fab8710932a872419e6 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 09:33:34 -0800 Subject: [PATCH 17/23] only run windows ci while I iterate --- .github/workflows/python-package.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 039cc9b89..d99f4a068 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -19,7 +19,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + # os: [ubuntu-latest, windows-latest, macos-latest] + # temporarily just running builds on windows while iterating + os: [windows-latest] python-version: [2.7, 3.7, 3.8] env: From eeb94fb7495933ec0c56a906aecce66271883707 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 09:53:52 -0800 Subject: [PATCH 18/23] run the broken test --- tests/test_fcp7_xml_adapter.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_fcp7_xml_adapter.py b/tests/test_fcp7_xml_adapter.py index 52a3ffdf6..9ff56ab46 100644 --- a/tests/test_fcp7_xml_adapter.py +++ b/tests/test_fcp7_xml_adapter.py @@ -1384,8 +1384,6 @@ def test_xml_with_empty_elements(self): self.assertEqual(len(timeline.video_tracks()), 12) self.assertEqual(len(timeline.video_tracks()[0]), 34) - # @TODO: remove this - @unittest.skipIf(True, "file is broken on windows?") def test_read_generators(self): timeline = adapters.read_from_file(GENERATOR_XML_EXAMPLE_PATH) From e2a6ea024b4ed8cfd94d69c3ed4ca42d922a61a9 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 10:52:43 -0800 Subject: [PATCH 19/23] remove BOM from example xml file --- tests/sample_data/premiere_generators.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sample_data/premiere_generators.xml b/tests/sample_data/premiere_generators.xml index 20eeb0b71..a9a452a6c 100644 --- a/tests/sample_data/premiere_generators.xml +++ b/tests/sample_data/premiere_generators.xml @@ -1,4 +1,4 @@ - + From 85c958cd5739adadd9e935f919e2bdcdd5f58956 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 13:31:20 -0800 Subject: [PATCH 20/23] replace more unit test tempfile handling to be more windows compatible --- .../tests/test_hls_playlist_adapter.py | 165 ++++++++++-------- 1 file changed, 88 insertions(+), 77 deletions(-) diff --git a/contrib/opentimelineio_contrib/adapters/tests/test_hls_playlist_adapter.py b/contrib/opentimelineio_contrib/adapters/tests/test_hls_playlist_adapter.py index af4ac0858..4b2cca05c 100644 --- a/contrib/opentimelineio_contrib/adapters/tests/test_hls_playlist_adapter.py +++ b/contrib/opentimelineio_contrib/adapters/tests/test_hls_playlist_adapter.py @@ -23,12 +23,19 @@ # import os -import tempfile import unittest import opentimelineio as otio +# handle python2 vs python3 difference +try: + from tempfile import TemporaryDirectory # noqa: F401 + import tempfile +except ImportError: + # XXX: python2.7 only + from backports import tempfile + # Reference data SAMPLE_DATA_DIR = os.path.join(os.path.dirname(__file__), "sample_data") HLS_EXAMPLE_PATH = os.path.join(SAMPLE_DATA_DIR, "v1_prog_index.m3u8") @@ -162,13 +169,15 @@ def test_media_pl_from_mem(self): track.append(segment1) # Write out and validate the playlist - media_pl_tmp_path = tempfile.mkstemp(suffix=".m3u8", text=True)[1] - otio.adapters.write_to_file(t, media_pl_tmp_path) - - with open(media_pl_tmp_path) as f: - pl_string = f.read() + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "test_media_pl_from_mem.m3u8" + ) + otio.adapters.write_to_file(t, media_pl_tmp_path) - os.remove(media_pl_tmp_path) + with open(media_pl_tmp_path) as f: + pl_string = f.read() # Compare against the reference value self.assertEqual(pl_string, MEM_PLAYLIST_REF_VALUE) @@ -243,21 +252,22 @@ def test_media_roundtrip(self): self._validate_sample_playlist(timeline) # Write out and validate both playlists have the same lines - media_pl_tmp_path = tempfile.mkstemp(suffix=".m3u8", text=True)[1] - otio.adapters.write_to_file(timeline, media_pl_tmp_path) - - # Read in both playlists - with open(hls_path) as f: - reference_lines = f.readlines() + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "test_media_roundtrip.m3u8" + ) + otio.adapters.write_to_file(timeline, media_pl_tmp_path) - with open(media_pl_tmp_path) as f: - adapter_out_lines = f.readlines() + # Read in both playlists + with open(hls_path) as f: + reference_lines = f.readlines() - # Using otio as well - in_timeline = otio.adapters.read_from_file(media_pl_tmp_path) + with open(media_pl_tmp_path) as f: + adapter_out_lines = f.readlines() - # Remove the temp out file - os.remove(media_pl_tmp_path) + # Using otio as well + in_timeline = otio.adapters.read_from_file(media_pl_tmp_path) # Strip newline chars reference_lines = [line.strip('\n') for line in reference_lines] @@ -287,12 +297,15 @@ def test_media_segment_size(self): timeline_streaming_md['max_segment_duration'] = seg_max_duration # Write out the playlist - media_pl_tmp_path = tempfile.mkstemp(suffix=".m3u8", text=True)[1] - otio.adapters.write_to_file(timeline, media_pl_tmp_path) + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "test_media_segment_size.m3u8" + ) + otio.adapters.write_to_file(timeline, media_pl_tmp_path) - # Read in the playlist - in_timeline = otio.adapters.read_from_file(media_pl_tmp_path) - os.remove(media_pl_tmp_path) + # Read in the playlist + in_timeline = otio.adapters.read_from_file(media_pl_tmp_path) # Pick a duration that segments won't exceed but is less than max seg_upper_duration = otio.opentime.RationalTime(7, 1) @@ -339,15 +352,18 @@ def test_iframe_segment_size(self): track_hls_metadata['EXT-X-I-FRAMES-ONLY'] = None # Write out the playlist - media_pl_tmp_path = tempfile.mkstemp(suffix=".m3u8", text=True)[1] - otio.adapters.write_to_file(timeline, media_pl_tmp_path) + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "test_iframe_segment_size.m3u8" + ) + otio.adapters.write_to_file(timeline, media_pl_tmp_path) - # Read in the playlist - in_timeline = otio.adapters.read_from_file(media_pl_tmp_path) - with open(media_pl_tmp_path) as f: - pl_lines = f.readlines() - pl_lines = [line.strip('\n') for line in pl_lines] - os.remove(media_pl_tmp_path) + # Read in the playlist + in_timeline = otio.adapters.read_from_file(media_pl_tmp_path) + with open(media_pl_tmp_path) as f: + pl_lines = f.readlines() + pl_lines = [line.strip('\n') for line in pl_lines] # validate the TARGETDURATION value is correct self.assertTrue('#EXT-X-TARGETDURATION:6' in pl_lines) @@ -420,16 +436,15 @@ def test_simple_master_pl_from_mem(self): t.tracks.append(atrack) # Write out and validate the playlist - media_pl_tmp_path = tempfile.mkstemp( - suffix="master.m3u8", - text=True - )[1] - otio.adapters.write_to_file(t, media_pl_tmp_path) - - with open(media_pl_tmp_path) as f: - pl_string = f.read() + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "master.m3u8" + ) + otio.adapters.write_to_file(t, media_pl_tmp_path) - os.remove(media_pl_tmp_path) + with open(media_pl_tmp_path) as f: + pl_string = f.read() # Drop blank lines before comparing pl_string = '\n'.join((line for line in pl_string.split('\n') if line)) @@ -483,16 +498,15 @@ def test_master_pl_with_iframe_pl_from_mem(self): t.tracks.append(atrack) # Write out and validate the playlist - media_pl_tmp_path = tempfile.mkstemp( - suffix="master.m3u8", - text=True - )[1] - otio.adapters.write_to_file(t, media_pl_tmp_path) - - with open(media_pl_tmp_path) as f: - pl_string = f.read() + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "master.m3u8" + ) + otio.adapters.write_to_file(t, media_pl_tmp_path) - os.remove(media_pl_tmp_path) + with open(media_pl_tmp_path) as f: + pl_string = f.read() # Drop blank lines before comparing pl_string = '\n'.join(line for line in pl_string.split('\n') if line) @@ -568,16 +582,15 @@ def test_master_pl_complex_from_mem(self): t.tracks.append(atrack) # Write out and validate the playlist - media_pl_tmp_path = tempfile.mkstemp( - suffix="master.m3u8", - text=True - )[1] - otio.adapters.write_to_file(t, media_pl_tmp_path) - - with open(media_pl_tmp_path) as f: - pl_string = f.read() + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "master.m3u8" + ) + otio.adapters.write_to_file(t, media_pl_tmp_path) - os.remove(media_pl_tmp_path) + with open(media_pl_tmp_path) as f: + pl_string = f.read() # Drop blank lines before comparing pl_string = '\n'.join(line for line in pl_string.split('\n') if line) @@ -610,16 +623,15 @@ def test_master_playlist_hint_metadata(self): ) # Write out and validate the playlist - media_pl_tmp_path = tempfile.mkstemp( - suffix="master.m3u8", - text=True - )[1] - otio.adapters.write_to_file(timeline, media_pl_tmp_path) - - with open(media_pl_tmp_path) as f: - pl_string = f.read() + with tempfile.TemporaryDirectory() as temp_dir: + media_pl_tmp_path = os.path.join( + temp_dir, + "test_media_pl_from_mem.m3u8" + ) + otio.adapters.write_to_file(timeline, media_pl_tmp_path) - os.remove(media_pl_tmp_path) + with open(media_pl_tmp_path) as f: + pl_string = f.read() # ensure metadata that wasn't supposed to didn't leak out for line in pl_string.split('\n'): @@ -696,16 +708,15 @@ def test_explicit_master_pl_from_mem(self): track.append(segment1) # Write out and validate the playlist - master_pl_tmp_path = tempfile.mkstemp( - suffix='master.m3u8', - text=True - )[1] - otio.adapters.write_to_file(t, master_pl_tmp_path) - - with open(master_pl_tmp_path) as f: - pl_string = f.read() + with tempfile.TemporaryDirectory() as temp_dir: + master_pl_tmp_path = os.path.join( + temp_dir, + "master.m3u8" + ) + otio.adapters.write_to_file(t, master_pl_tmp_path) - os.remove(master_pl_tmp_path) + with open(master_pl_tmp_path) as f: + pl_string = f.read() # Drop blank lines before comparing pl_string = '\n'.join((line for line in pl_string.split('\n') if line)) From bc66af1cb46a0abc84e25a692ee0b9eb6edd3ad5 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 13:44:35 -0800 Subject: [PATCH 21/23] only run XGES unit tests on linux --- .../opentimelineio_contrib/adapters/tests/tests_xges_adapter.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py b/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py index a2b0e47ac..6bcda8dd1 100644 --- a/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py +++ b/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py @@ -23,6 +23,7 @@ # import os +import platform import tempfile import unittest from fractions import Fraction @@ -1018,6 +1019,7 @@ def assertXgesTimelineMarkerListEqual(self, ges_el, marker_list): timeline, "markers", "GESMarkerList", marker_list) +@unittest.skipIf(platform.system() != 'Linux', "XGES only suppported on Linux") class AdaptersXGESTest( unittest.TestCase, otio_test_utils.OTIOAssertions, CustomOtioAssertions, CustomXgesAssertions): From 6ebee232ccd845c82b02871c49537f94b7044c6d Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Thu, 18 Feb 2021 14:03:05 -0800 Subject: [PATCH 22/23] turning MacOS and Linux builds back on. --- .github/workflows/python-package.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index d99f4a068..039cc9b89 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -19,9 +19,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - # os: [ubuntu-latest, windows-latest, macos-latest] - # temporarily just running builds on windows while iterating - os: [windows-latest] + os: [ubuntu-latest, windows-latest, macos-latest] python-version: [2.7, 3.7, 3.8] env: From 215de621348cdf09409e0ccc88ab519142e9b721 Mon Sep 17 00:00:00 2001 From: ssteinbach Date: Mon, 22 Feb 2021 15:53:16 -0800 Subject: [PATCH 23/23] Also disable xges for python < 3. --- .../adapters/tests/tests_xges_adapter.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py b/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py index 6bcda8dd1..59241d2e7 100644 --- a/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py +++ b/contrib/opentimelineio_contrib/adapters/tests/tests_xges_adapter.py @@ -24,6 +24,7 @@ import os import platform +import sys import tempfile import unittest from fractions import Fraction @@ -1019,7 +1020,10 @@ def assertXgesTimelineMarkerListEqual(self, ges_el, marker_list): timeline, "markers", "GESMarkerList", marker_list) -@unittest.skipIf(platform.system() != 'Linux', "XGES only suppported on Linux") +@unittest.skipIf( + platform.system() != 'Linux' or sys.version_info[0] < 3, + "XGES only suppported on Linux in Python3." +) class AdaptersXGESTest( unittest.TestCase, otio_test_utils.OTIOAssertions, CustomOtioAssertions, CustomXgesAssertions):