[Git][debian-gis-team/pydecorate][upstream] New upstream version 0.3.4

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sun Jun 11 15:01:52 BST 2023



Antonio Valentino pushed to branch upstream at Debian GIS Project / pydecorate


Commits:
9386807b by Antonio Valentino at 2023-06-10T09:40:16+00:00
New upstream version 0.3.4
- - - - -


10 changed files:

- .git_archival.txt
- + .github/dependabot.yml
- .github/workflows/ci.yaml
- .github/workflows/deploy-sdist.yaml
- .pre-commit-config.yaml
- CHANGELOG.md
- RELEASING.md
- pydecorate/decorator_base.py
- pydecorate/tests/test_decorator_agg.py
- setup.py


Changes:

=====================================
.git_archival.txt
=====================================
@@ -1 +1 @@
-ref-names: HEAD -> main, tag: v0.3.3
+ref-names: tag: v0.3.4


=====================================
.github/dependabot.yml
=====================================
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+  - package-ecosystem: "github-actions" # See documentation for possible values
+    directory: "/" # Location of package manifests
+    schedule:
+      interval: "weekly"


=====================================
.github/workflows/ci.yaml
=====================================
@@ -8,40 +8,19 @@ concurrency:
 on: [push, pull_request]
 
 jobs:
-  lint:
-    name: lint and style checks
-    runs-on: ubuntu-latest
-    steps:
-      - name: Checkout source
-        uses: actions/checkout at v2
-      - name: Set up Python
-        uses: actions/setup-python at v2
-        with:
-          python-version: 3.9
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          pip install flake8 flake8-docstrings flake8-debugger flake8-bugbear pytest
-      - name: Install Pydecorate
-        run: |
-          pip install -e .
-      - name: Run linting
-        run: |
-          flake8 pydecorate/
-
   website:
     name: build website
     runs-on: ubuntu-latest
     steps:
       - name: Checkout source
-        uses: actions/checkout at v2
+        uses: actions/checkout at v3
         with:
           fetch-depth: 0
 
       - name: Set up Python
-        uses: actions/setup-python at v2
+        uses: actions/setup-python at v4
         with:
-          python-version: 3.9
+          python-version: 3.11
 
       - name: Install Pydecorate
         shell: bash -l {0}
@@ -57,15 +36,14 @@ jobs:
   test:
     runs-on: ${{ matrix.os }}
     continue-on-error: ${{ matrix.experimental }}
-    needs: [lint]
     strategy:
       fail-fast: true
       matrix:
         os: ["windows-latest", "ubuntu-latest", "macos-latest"]
-        python-version: ["3.7", "3.10"]
+        python-version: ["3.9", "3.11"]
         experimental: [false]
         include:
-          - python-version: "3.10"
+          - python-version: "3.11"
             os: "ubuntu-latest"
             experimental: true
 
@@ -77,12 +55,7 @@ jobs:
 
     steps:
       - name: Checkout source
-        uses: actions/checkout at v2
-
-#      - name: Set up Python
-#        uses: actions/setup-python at v2
-#        with:
-#          python-version: "${{ matrix.python-version }}"
+        uses: actions/checkout at v3
 
       - name: Setup Conda Environment
         uses: conda-incubator/setup-miniconda at v2


=====================================
.github/workflows/deploy-sdist.yaml
=====================================
@@ -11,7 +11,7 @@ jobs:
 
     steps:
       - name: Checkout source
-        uses: actions/checkout at v2
+        uses: actions/checkout at v3
 
       - name: Create sdist
         shell: bash -l {0}
@@ -21,7 +21,7 @@ jobs:
 
       - name: Publish package to PyPI
         if: github.event.action == 'published'
-        uses: pypa/gh-action-pypi-publish at v1.4.1
+        uses: pypa/gh-action-pypi-publish at v1.6.4
         with:
           user: __token__
           password: ${{ secrets.pypi_password }}


=====================================
.pre-commit-config.yaml
=====================================
@@ -2,7 +2,7 @@ exclude: '^$'
 fail_fast: false
 repos:
   - repo: https://github.com/psf/black
-    rev: 22.1.0
+    rev: 23.1.0
     hooks:
       - id: black
         language_version: python3
@@ -10,25 +10,25 @@ repos:
         args:
           - --target-version=py38
   - repo: https://github.com/PyCQA/flake8
-    rev: 4.0.1
+    rev: 6.0.0
     hooks:
       - id: flake8
         additional_dependencies: [flake8-docstrings, flake8-debugger, flake8-bugbear, mccabe]
         args: [--max-complexity, "10"]
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.1.0
+    rev: v4.4.0
     hooks:
       - id: trailing-whitespace
       - id: end-of-file-fixer
       - id: check-yaml
         args: [--unsafe]
   - repo: https://github.com/PyCQA/bandit
-    rev: '1.7.2' # Update me!
+    rev: '1.7.4' # Update me!
     hooks:
       - id: bandit
         args: [--ini, .bandit]
   - repo: https://github.com/pre-commit/mirrors-mypy
-    rev: 'v0.931'  # Use the sha / tag you want to point at
+    rev: 'v1.0.0'  # Use the sha / tag you want to point at
     hooks:
       - id: mypy
         additional_dependencies:
@@ -37,7 +37,7 @@ repos:
           - types-PyYAML
           - types-requests
   - repo: https://github.com/pycqa/isort
-    rev: 5.10.1
+    rev: 5.12.0
     hooks:
       - id: isort
         language_version: python3


=====================================
CHANGELOG.md
=====================================
@@ -1,3 +1,20 @@
+## Version 0.3.4 (2023/02/15)
+
+### Issues Closed
+
+* [Issue 26](https://github.com/pytroll/pydecorate/issues/26) - Unittests are failing with unstable builds
+
+In this release 1 issue was closed.
+
+### Pull Requests Merged
+
+#### Bugs fixed
+
+* [PR 27](https://github.com/pytroll/pydecorate/pull/27) - Fix colorbar orientation to always be min->max
+
+In this release 1 pull request was closed.
+
+
 ## Version 0.3.3 (2022/02/17)
 
 ### Pull Requests Merged


=====================================
RELEASING.md
=====================================
@@ -6,7 +6,7 @@
 4. run `loghub` and update the `CHANGELOG.md` file:
 
    ```
-   loghub pytroll/pydecorate --token $LOGHUB_GITHUB_TOKEN -st v<previous version> -plg bug "Bugs fixed" -plg enhancement "Features added" -plg documentation "Documentation changes" -plg backwards-incompatibility "Backward incompatible changes" -plg refactor "Refactoring"
+   loghub pytroll/pydecorate --token $LOGHUB_GITHUB_TOKEN -st $(git tag --sort=-version:refname --list 'v*' | head -n 1) -plg bug "Bugs fixed" -plg enhancement "Features added" -plg documentation "Documentation changes" -plg backwards-incompatibility "Backward incompatible changes" -plg refactor "Refactoring"
    ```
 
    This uses a `LOGHUB_GITHUB_TOKEN` environment variable. This must be created


=====================================
pydecorate/decorator_base.py
=====================================
@@ -431,9 +431,16 @@ class DecoratorBase(object):
 
         # generate color scale image obj inset by margin size mx my,
         # TODO: THIS PART TO BE INGESTED INTO A COLORMAP FUNCTION
-        minval, maxval = colormap.values[0], colormap.values[-1]
+        first_cmap_value, last_cmap_value = colormap.values[0], colormap.values[-1]
+        min_cmap_value = min(first_cmap_value, last_cmap_value)
+        max_cmap_value = max(first_cmap_value, last_cmap_value)
         scale = _create_colorbar_image(
-            colormap, minval, maxval, scale_height, scale_width, is_vertical
+            colormap,
+            min_cmap_value,
+            max_cmap_value,
+            scale_height,
+            scale_width,
+            is_vertical,
         )
         ###########################################################
 
@@ -448,8 +455,8 @@ class DecoratorBase(object):
         draw = self._get_canvas(self.image)
         self._draw_colorbar_ticks(
             draw,
-            minval,
-            maxval,
+            min_cmap_value,
+            max_cmap_value,
             is_vertical,
             scale_width,
             scale_height,
@@ -748,7 +755,7 @@ class DecoratorBase(object):
 
 
 def _create_colorbar_image(
-    colormap, minval, maxval, scale_height, scale_width, is_vertical
+    colormap, min_cmap_value, max_cmap_value, scale_height, scale_width, is_vertical
 ):
     if TImage is None:
         raise ImportError(
@@ -756,13 +763,20 @@ def _create_colorbar_image(
         )
 
     if is_vertical:
-        linedata = np.ones((scale_width, 1)) * np.arange(
-            minval, maxval, float(maxval - minval) / scale_height
+        # Image arrays have row 0 being the top of the image, so we must flip all calculations
+        linedata = np.ones((scale_width, 1)) * np.linspace(
+            max_cmap_value,
+            min_cmap_value,
+            scale_height,
+            endpoint=False,
         )
         linedata = linedata.transpose()
     else:
-        linedata = np.ones((scale_height, 1)) * np.arange(
-            minval, maxval, float(maxval - minval) / scale_width
+        linedata = np.ones((scale_height, 1)) * np.linspace(
+            min_cmap_value,
+            max_cmap_value,
+            scale_width,
+            endpoint=False,
         )
 
     timg = TImage(linedata, mode="L")


=====================================
pydecorate/tests/test_decorator_agg.py
=====================================
@@ -17,8 +17,11 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """Tests for the aggdraw-based decorator."""
 
+from unittest import mock
+
 import numpy as np
 import pytest
+from numpy.typing import NDArray
 from PIL import Image
 from trollimage.colormap import rdbu
 
@@ -34,35 +37,121 @@ from pydecorate import DecoratorAGG
 @pytest.mark.parametrize("clims", [(-90, 10), (10, -90)])
 def test_colorbar(tmp_path, orientation_func_name, align_func_name, clims):
     fn = tmp_path / "test_colorbar.png"
-    img = Image.fromarray(np.zeros((200, 100, 3), dtype=np.uint8))
+    shape = (
+        (400, 100, 3) if orientation_func_name == "write_vertically" else (100, 400, 3)
+    )
+    img = Image.fromarray(np.zeros(shape, dtype=np.uint8))
     dc = DecoratorAGG(img)
     getattr(dc, align_func_name)()
     getattr(dc, orientation_func_name)()
     cmap = rdbu.set_range(*clims, inplace=False)
-    dc.add_scale(cmap, extend=True, tick_marks=5.0, line_opacity=100, unit="K")
+    with mock.patch.object(dc, "_draw_text", wraps=dc._draw_text) as draw_text_wrapper:
+        dc.add_scale(
+            cmap,
+            extend=True,
+            tick_marks=40.0,
+            minor_tick_marks=20.0,
+            line_opacity=100,
+            unit="K",
+        )
     img.save(fn)
+    assert_colorbar_increasing_tick_order(draw_text_wrapper)
 
     # check results
     output_img = Image.open(fn)
     arr = np.array(output_img)
-    _assert_colorbar_orientation_alignment(arr, orientation_func_name, align_func_name)
+    clims_flipped = clims[0] > clims[1]
+    assert_colorbar_orientation_alignment(
+        arr, orientation_func_name, align_func_name, clims_flipped
+    )
+
+
+def assert_colorbar_increasing_tick_order(draw_text_wrapper) -> None:
+    last_float_text = None
+    for call_args in draw_text_wrapper.call_args_list:
+        if call_args.args[1] == (0, 0):
+            # skip call to draw text for size reference
+            continue
+
+        try:
+            txt_as_float = float(call_args.args[2])
+        except ValueError:
+            continue
 
+        if last_float_text is None:
+            last_float_text = txt_as_float
+            continue
 
-def _assert_colorbar_orientation_alignment(
-    img_arr, orientation_func_name, align_func_name
-):
+        assert last_float_text <= txt_as_float
+        last_float_text = txt_as_float
+
+
+def assert_colorbar_orientation_alignment(
+    img_arr: NDArray,
+    orientation_func_name: str,
+    align_func_name: str,
+    clims_flipped: bool,
+) -> None:
     cbar_size = 60
+    check_idx = int(cbar_size // 2.5)  # not likely to run into ticks or tick labels
+    cbar_len_start_offset = 5
+    cbar_len_stop_offset = 45
+    cbar_offset_slice = slice(cbar_len_start_offset, -cbar_len_stop_offset)
+    # NOTE: "top" of image is row 0
     if orientation_func_name == "write_vertically":
         if align_func_name in ("align_left", "align_top", "align_bottom"):
-            assert np.unique(img_arr[:, :cbar_size]).size >= 100
+            assert np.unique(img_arr[cbar_offset_slice, check_idx]).size >= 100
             np.testing.assert_allclose(img_arr[:, cbar_size:], 0)
+            _check_color_orientation(
+                img_arr[-cbar_len_stop_offset - 20, check_idx],  # bottom pixel
+                img_arr[cbar_len_start_offset + 25, check_idx],  # top pixel
+                clims_flipped,
+            )
         else:
-            assert np.unique(img_arr[:, -cbar_size:]).size >= 100
+            assert np.unique(img_arr[:, -check_idx]).size >= 100
             np.testing.assert_allclose(img_arr[:, :-cbar_size], 0)
+            _check_color_orientation(
+                img_arr[-cbar_len_stop_offset - 20, -check_idx],  # bottom pixel
+                img_arr[cbar_len_start_offset + 25, -check_idx],  # top pixel
+                clims_flipped,
+            )
     else:
         if align_func_name in ("align_top", "align_left", "align_right"):
-            assert np.unique(img_arr[:cbar_size, :]).size >= 100
-            np.testing.assert_allclose(img_arr[-cbar_size:, :], 0)
+            assert np.unique(img_arr[check_idx, :]).size >= 100
+            np.testing.assert_allclose(img_arr[cbar_size:, :], 0)
+            _check_color_orientation(
+                img_arr[check_idx, cbar_len_start_offset + 25],  # left pixel
+                img_arr[check_idx, -cbar_len_stop_offset - 20],  # right pixel
+                clims_flipped,
+            )
         else:
-            assert np.unique(img_arr[-cbar_size:, :]).size >= 100
-            np.testing.assert_allclose(img_arr[:cbar_size, :], 0)
+            assert np.unique(img_arr[-check_idx:, :]).size >= 100
+            np.testing.assert_allclose(img_arr[:-cbar_size, :], 0)
+            _check_color_orientation(
+                img_arr[-check_idx, cbar_len_start_offset + 25],  # left pixel
+                img_arr[-check_idx, -cbar_len_stop_offset - 20],  # right pixel
+                clims_flipped,
+            )
+
+
+def _check_color_orientation(
+    first_pixel: NDArray, last_pixel: NDArray, clims_flipped: bool
+) -> None:
+    if clims_flipped:
+        _check_expected_blue_colorbar_pixel(first_pixel)
+        _check_expected_red_colorbar_pixel(last_pixel)
+    else:
+        _check_expected_red_colorbar_pixel(first_pixel)
+        _check_expected_blue_colorbar_pixel(last_pixel)
+
+
+def _check_expected_red_colorbar_pixel(red_pixel: NDArray) -> None:
+    assert red_pixel[0] > 140  # decently red
+    assert red_pixel[1] < 64  # not a lot of green
+    assert red_pixel[2] < 64  # not a lot of blue
+
+
+def _check_expected_blue_colorbar_pixel(blue_pixel: NDArray) -> None:
+    assert blue_pixel[0] < 32  # not a lot of red
+    assert blue_pixel[1] < 100  # not a lot of green
+    assert blue_pixel[2] > 128  # decently blue


=====================================
setup.py
=====================================
@@ -61,7 +61,7 @@ setup(
     setup_requires=["setuptools_scm", "setuptools_scm_git_archive"],
     scripts=[],
     data_files=[],
-    python_requires=">=3.7",
+    python_requires=">=3.9",
     extras_require={
         "tests": tests_require,
         "docs": ["sphinx", "sphinx_rtd_theme", "sphinxcontrib-apidoc", "trollimage"],



View it on GitLab: https://salsa.debian.org/debian-gis-team/pydecorate/-/commit/9386807b04cf8f1c1192aa9e5b45e11dee729f7f

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pydecorate/-/commit/9386807b04cf8f1c1192aa9e5b45e11dee729f7f
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20230611/307520d8/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list