diff --git a/.github/workflows/run-tests-on-mr.yml b/.github/workflows/run-tests-on-mr.yml index ecbe09b..0a2e6a2 100644 --- a/.github/workflows/run-tests-on-mr.yml +++ b/.github/workflows/run-tests-on-mr.yml @@ -2,35 +2,30 @@ name: Run tests on Pull Request on: [pull_request] jobs: - run-tests-on-py310: + check: runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Check out repo code - uses: actions/checkout@v2 - with: - submodules: true - - name: Install Python - uses: actions/setup-python@v2 - with: - python-version: "3.10" - - name: Install dependencies - run: python -m pip install -r dev-requirements.txt - - name: Run Tests - run: pytest tests - run-tests-on-py314: - runs-on: ubuntu-latest - timeout-minutes: 10 + + strategy: + fail-fast: false + matrix: + python-version: ["3.10", "3.14"] + steps: - name: Check out repo code - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: submodules: true - - name: Install Python - uses: actions/setup-python@v2 + + - name: Install Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 with: - python-version: "3.14" - - name: Install dependencies - run: python -m pip install -r dev-requirements.txt + python-version: ${{matrix.python-version}} + + - name: Install project + run: python3 -m pip install . + + - name: Install dev dependencies + run: python3 -m pip install -e '.[test]' + - name: Run Tests run: pytest tests diff --git a/README.md b/README.md index c011dfc..9bef0dd 100644 --- a/README.md +++ b/README.md @@ -15,24 +15,27 @@ That's why I've written this very small python module (currently ~360 LOCs) that # Dependencies Optional, for tests: -`pytest==4.2.0` +`pytest==9.0.3` Optional, for formatting: -`yapf==0.30.0` +`yapf==0.43.0` # Support ## Python version -This repo now supports both Python2.7 and also Python3.8. -Thanks to [jonaskluger](https://github.com/jonaskluger) for providing python3 support. +This project is compatible with Python3.7+, although officially it requires 3.10 (because it's 2026 and 3.7 should really be a thing of the past given its EOL date). The CI runs tests against Python 3.10 and 3.14. +Thanks to [jonaskluger](https://github.com/jonaskluger) for providing original support for Python 3. ## Multipart files Support for multipart files is on its way but it will need a bit of work since the original design of this hobby project was a bit naive. A PR is currently pending. # Install -This script is not packaged in any fancy way. Just grab the `parse_metadata.py` and put it wherever you want. +This project uses the `pyproject.toml` (with setuptools as its build backend). +Once you cloned the repo, you can install it via pip into the venv of your choice: `python3 -m pip install /path/where/you/cloned/this`. -_Update (2021/12/27)_: Now there is also a tiny cli (`bin/vv-exr-metadata`) that you can use, if you want, to list the metadata of a file from a shell session. It supports the wildcard notation (*) if you want to look at multiple files at once. +But you can also just grab the `parse_metadata.py` and put it wherever you want, since it's a single file library. + +_Update (2021/12/27)_: Now there is also a small cli (`vv-exr-metadata`) that you can use, if you want, to list the metadata of a file from a shell session. It supports the wildcard notation (*) if you want to look at multiple files at once. # Tests I'm not a TDD guy (yet) - so there are very few tests. I'm planning to write more of them as soon as I can breathe a little. diff --git a/dev-requirements.txt b/dev-requirements.txt deleted file mode 100644 index 5e0b0c4..0000000 --- a/dev-requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -pytest==9.0.3 -# attrs is required by pytest, see https://stackoverflow.com/a/58189684 -attrs==19.1.0 -yapf==0.30.0 \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a36d4f8 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,21 @@ +[project] +name = "parse-exr-header" +version = "0.1.0" +description = "Pure python module to read metadata files from the header of OpenEXR files." +readme = "README.md" +requires-python = ">=3.10" +dependencies = [] + +[project.scripts] +vv-exr-metadata = "parse_exr_header.cli:main" + +[build-system] +requires = ["setuptools >= 77.0.3"] +build-backend = "setuptools.build_meta" + +[project.optional-dependencies] +test = [ + "attrs>=26.1.0", + "pytest==9.0.3", + "yapf>=0.43.0", +] diff --git a/src/__init__.py b/src/parse_exr_header/__init__.py similarity index 100% rename from src/__init__.py rename to src/parse_exr_header/__init__.py diff --git a/src/bin/vv-exr-metadata.py b/src/parse_exr_header/cli.py similarity index 78% rename from src/bin/vv-exr-metadata.py rename to src/parse_exr_header/cli.py index 5bff744..8d12e25 100755 --- a/src/bin/vv-exr-metadata.py +++ b/src/parse_exr_header/cli.py @@ -1,21 +1,17 @@ -#!/usr/bin/env python from __future__ import print_function import os -import sys import pprint import logging import argparse +import parse_exr_header.lib + log = logging.getLogger('vvzen.parse_metadata') log.setLevel(logging.INFO) console_handler = logging.StreamHandler() log.addHandler(console_handler) -CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) - -sys.path.append(os.path.join(CURRENT_DIR, "..")) -import parse_metadata def main(): parser = argparse.ArgumentParser() @@ -33,7 +29,7 @@ def main(): log.error("Source Path was not found on disk: %s", path) continue - metadata = parse_metadata.read_exr_header(path) + metadata = parse_exr_header.lib.read_exr_header(path) print(pprint.pformat(metadata)) if len(paths) > 1: print("-"*80) diff --git a/src/parse_metadata.py b/src/parse_exr_header/lib.py similarity index 100% rename from src/parse_metadata.py rename to src/parse_exr_header/lib.py diff --git a/tests/openexr-images b/tests/openexr-images index 6e32d0f..e38ffb0 160000 --- a/tests/openexr-images +++ b/tests/openexr-images @@ -1 +1 @@ -Subproject commit 6e32d0f2f56189bc20a6b3958c322c4ff6340633 +Subproject commit e38ffb0790f62f05a6f083a6fa4cac150b3b7452 diff --git a/tests/test_exr.py b/tests/test_exr.py index 681c326..658b54b 100644 --- a/tests/test_exr.py +++ b/tests/test_exr.py @@ -1,26 +1,13 @@ #-*- coding: utf-8 -*- import os -import sys import pytest """ -The tests are ment to work with Python 2 and Python 3. -Please remember that Python 2 works with byte strings as default -and with the change of Python 3 unicode strings are used. - -Python 2 default string -foo = b'bar' - -Python 3 default string: -foo = u'bar' +The tests are meant to work with Python 3.10+. """ -# Append the required module -sys.path.append( - os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', 'src')) - -import parse_metadata +import parse_exr_header.lib EXR_IMAGES_DIR_PATH = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'openexr-images') @@ -31,13 +18,13 @@ def test_oserror_thrown_if_file_does_not_exist(): with pytest.raises(OSError): - parse_metadata.read_exr_header('pippo.exr') + parse_exr_header.lib.read_exr_header('pippo.exr') @pytest.mark.parametrize("input_path,expected_lineorder", [ pytest.param(REC709_TEST_IMAGE_PATH, 'INCREASING_Y') ]) def test_exr_meta_lineOrder(input_path, expected_lineorder): - metadata = parse_metadata.read_exr_header(input_path) + metadata = parse_exr_header.lib.read_exr_header(input_path) assert metadata['lineOrder'] == expected_lineorder @pytest.mark.parametrize("input_path,expected_compression", [ @@ -49,15 +36,15 @@ def test_exr_meta_lineOrder(input_path, expected_lineorder): pytest.param(os.path.join(EXR_IMAGES_DIR_PATH, 'TestImages', 'SquaresSwirls.exr'), 'PXR24_COMPRESSION'), ]) def test_exr_meta_compression(input_path,expected_compression): - metadata = parse_metadata.read_exr_header(input_path) + metadata = parse_exr_header.lib.read_exr_header(input_path) assert metadata['compression'] == expected_compression def test_exr_meta_pixelAspectRatio(): - metadata = parse_metadata.read_exr_header(REC709_TEST_IMAGE_PATH) + metadata = parse_exr_header.lib.read_exr_header(REC709_TEST_IMAGE_PATH) assert metadata['pixelAspectRatio'] == 1 def test_exr_meta_owner(): - metadata = parse_metadata.read_exr_header(REC709_TEST_IMAGE_PATH) + metadata = parse_exr_header.lib.read_exr_header(REC709_TEST_IMAGE_PATH) assert metadata['owner'] == 'Copyright 2006 Industrial Light & Magic' @pytest.mark.parametrize("input_path,expected_metadata", [ @@ -107,5 +94,5 @@ def test_exr_meta_owner(): }) ]) def test_exr_meta_all(input_path, expected_metadata): - result = parse_metadata.read_exr_header(input_path) + result = parse_exr_header.lib.read_exr_header(input_path) assert result == expected_metadata