From a114b7005cafb27a88151c1aa4ba5990678060d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Tue, 24 Sep 2024 00:33:38 +0000 Subject: [PATCH 1/9] CI(Ubuntu): Install latest version of Python for full config --- .github/workflows/ubuntu.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 57b0821eec4..3ad145115e7 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -99,6 +99,14 @@ jobs: }}:g' .gunittest.cfg > .gunittest.extra.cfg cat .gunittest.extra.cfg + - name: Set up Python + if: ${{ matrix.config == 'ubuntu-22.04' }} + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + with: + python-version: 3.13 + cache: pip + allow-prereleases: true + - name: Get dependencies run: | sudo apt-get update -y @@ -106,6 +114,12 @@ jobs: xargs -a <(awk '! /^ *(#|$)/' ".github/workflows/apt.txt") -r -- \ sudo apt-get install -y --no-install-recommends --no-install-suggests + - name: Install Python dependencies + if: ${{ matrix.config == 'ubuntu-22.04' }} + run: | + python -m pip install --upgrade pip + pip install -r .github/workflows/python_requirements.txt + - name: Create installation directory run: | mkdir $HOME/install @@ -132,7 +146,6 @@ jobs: # TODO: -pedantic-errors here won't compile CXXFLAGS: -fPIC run: .github/workflows/build_${{ matrix.config }}.sh $HOME/install -Werror - - name: Add the bin directory to PATH run: | echo "$HOME/install/bin" >> $GITHUB_PATH From 9b05e37aa005a13589d4900e90439068a8d6b632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Tue, 24 Sep 2024 01:06:51 +0000 Subject: [PATCH 2/9] CI(Ubuntu): Install packages from pip --- .github/workflows/ubuntu.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 3ad145115e7..aea97c989fd 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -119,6 +119,7 @@ jobs: run: | python -m pip install --upgrade pip pip install -r .github/workflows/python_requirements.txt + pip install -r .github/workflows/optional_requirements.txt - name: Create installation directory run: | From 7a80afc92037740fbf78239051c7c44023222c71 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 07:47:22 -0500 Subject: [PATCH 3/9] CI(deps): Update codecov/codecov-action action to v5.1.2 (#4860) --- .github/workflows/pytest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index ed12ef42a23..6f107e82807 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -115,7 +115,7 @@ jobs: coverage html - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@7f8b4b4bde536c465e797be725718b88c5d95e0e # v5.1.1 + uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 with: verbose: true flags: pytest-python-${{ matrix.python-version }} From 0341d878b06f8d930f20c348b876d74edc1ab36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Thu, 19 Dec 2024 11:04:04 -0500 Subject: [PATCH 4/9] style: Define `import grass.temporal as tgis` as an import convention (#4839) --- pyproject.toml | 1 + .../testsuite/test_temporal_doctests.py | 53 +++++++++---------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 358ab047112..bd1da6c3029 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -394,6 +394,7 @@ ignore = [ [tool.ruff.lint.flake8-import-conventions.extend-aliases] # Declare a custom aliases, checked with rule ICN001 "grass.script" = "gs" +"grass.temporal" = "tgis" [tool.pytest.ini_options] minversion = "6.0" diff --git a/python/grass/temporal/testsuite/test_temporal_doctests.py b/python/grass/temporal/testsuite/test_temporal_doctests.py index cc80c3225cb..608bf9fff38 100644 --- a/python/grass/temporal/testsuite/test_temporal_doctests.py +++ b/python/grass/temporal/testsuite/test_temporal_doctests.py @@ -8,8 +8,7 @@ import grass.gunittest.case import grass.gunittest.main import grass.gunittest.utils - -import grass.temporal +import grass.temporal as tgis doctest.DocFileCase = type( "DocFileCase", (grass.gunittest.case.TestCase,), dict(doctest.DocFileCase.__dict__) @@ -23,35 +22,31 @@ def load_tests(loader, tests, ignore): grass.gunittest.utils.do_doctest_gettext_workaround() - tests.addTests(doctest.DocTestSuite(grass.temporal.abstract_dataset)) - tests.addTests(doctest.DocTestSuite(grass.temporal.abstract_map_dataset)) - tests.addTests(doctest.DocTestSuite(grass.temporal.abstract_space_time_dataset)) - tests.addTests(doctest.DocTestSuite(grass.temporal.base)) - tests.addTests(doctest.DocTestSuite(grass.temporal.core)) - tests.addTests(doctest.DocTestSuite(grass.temporal.datetime_math)) + tests.addTests(doctest.DocTestSuite(tgis.abstract_dataset)) + tests.addTests(doctest.DocTestSuite(tgis.abstract_map_dataset)) + tests.addTests(doctest.DocTestSuite(tgis.abstract_space_time_dataset)) + tests.addTests(doctest.DocTestSuite(tgis.base)) + tests.addTests(doctest.DocTestSuite(tgis.core)) + tests.addTests(doctest.DocTestSuite(tgis.datetime_math)) # Unexpected error here - # tests.addTests(doctest.DocTestSuite(grass.temporal.list_stds)) - tests.addTests(doctest.DocTestSuite(grass.temporal.metadata)) - tests.addTests(doctest.DocTestSuite(grass.temporal.register)) - tests.addTests(doctest.DocTestSuite(grass.temporal.space_time_datasets)) - tests.addTests(doctest.DocTestSuite(grass.temporal.spatial_extent)) - tests.addTests( - doctest.DocTestSuite(grass.temporal.spatial_topology_dataset_connector) - ) - tests.addTests(doctest.DocTestSuite(grass.temporal.spatio_temporal_relationships)) - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_extent)) - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_granularity)) - tests.addTests( - doctest.DocTestSuite(grass.temporal.temporal_topology_dataset_connector) - ) + # tests.addTests(doctest.DocTestSuite(tgis.list_stds)) + tests.addTests(doctest.DocTestSuite(tgis.metadata)) + tests.addTests(doctest.DocTestSuite(tgis.register)) + tests.addTests(doctest.DocTestSuite(tgis.space_time_datasets)) + tests.addTests(doctest.DocTestSuite(tgis.spatial_extent)) + tests.addTests(doctest.DocTestSuite(tgis.spatial_topology_dataset_connector)) + tests.addTests(doctest.DocTestSuite(tgis.spatio_temporal_relationships)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_extent)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_granularity)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_topology_dataset_connector)) # Algebra is still very experimental - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_algebra)) - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_raster3d_algebra)) - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_raster_algebra)) - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_raster_base_algebra)) - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_operator)) - tests.addTests(doctest.DocTestSuite(grass.temporal.temporal_vector_algebra)) - tests.addTests(doctest.DocTestSuite(grass.temporal.c_libraries_interface)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_algebra)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_raster3d_algebra)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_raster_algebra)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_raster_base_algebra)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_operator)) + tests.addTests(doctest.DocTestSuite(tgis.temporal_vector_algebra)) + tests.addTests(doctest.DocTestSuite(tgis.c_libraries_interface)) return tests From d088c57f69087fb3bf82fe58c9e619c512255e09 Mon Sep 17 00:00:00 2001 From: Ondrej Pesek Date: Thu, 19 Dec 2024 17:33:54 +0100 Subject: [PATCH 5/9] CQ: follow 80-character paradigm in doc/notebooks/README (#4862) --- doc/notebooks/README.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/doc/notebooks/README.md b/doc/notebooks/README.md index 4a200b0f4f6..d07b8f826bb 100644 --- a/doc/notebooks/README.md +++ b/doc/notebooks/README.md @@ -5,24 +5,28 @@ ### Using the notebooks locally Clone this repository with `git clone` first. Then, locally start the Jupyter -notebook server from the command line in the `doc/notebooks/` directory containing -the `*.ipynb` files with: -`jupyter notebook` +notebook server from the command line in the `doc/notebooks/` directory +containing the `*.ipynb` files with: `jupyter notebook` -This will open a new browser tab or window with a list of the contents of the current -working directory. Clicking on one of the `*.ipynb` files will start the notebook. +This will open a new browser tab or window with a list of the contents of the +current working directory. Clicking on one of the `*.ipynb` files will start +the notebook. -See also the official documentation for [The Jupyter Notebook](https://jupyter-notebook.readthedocs.io/en/latest/). +See also the official documentation for +[The Jupyter Notebook](https://jupyter-notebook.readthedocs.io/en/latest/). ### Introductory notebooks to GRASS GIS and Jupyter -* GRASS GIS in Jupyter Notebook with Python and grass.jupyter: [jupyter_example.ipynb](jupyter_example.ipynb) +* GRASS GIS in Jupyter Notebook with Python and grass.jupyter: + [jupyter_example.ipynb](jupyter_example.ipynb) * The grass.jupyter Package: [jupyter_tutorial.ipynb](jupyter_tutorial.ipynb) ## Thematic Jupyter notebooks * Viewshed Analysis: [viewshed_analysis.ipynb](viewshed_analysis.ipynb) * Spatio-Temporal Analysis with grass.jupyter: [temporal.ipynb](temporal.ipynb) -* Solar Energy Potential Analysis: [solar_potential.ipynb](solar_potential.ipynb) -* GRASS GIS Scripting with Python: [scripting_example.ipynb](scripting_example.ipynb) +* Solar Energy Potential Analysis: + [solar_potential.ipynb](solar_potential.ipynb) +* GRASS GIS Scripting with Python: + [scripting_example.ipynb](scripting_example.ipynb) * Hydrology with GRASS GIS: [hydrology.ipynb](hydrology.ipynb) From c14e4ae256bb6524717a2d762b02894fe9839d42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:47:59 +0000 Subject: [PATCH 6/9] CI(deps): Update ruff to v0.8.4 (#4863) --- .github/workflows/python-code-quality.yml | 2 +- .pre-commit-config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml index 1fcc73001cd..e6aaeebe371 100644 --- a/.github/workflows/python-code-quality.yml +++ b/.github/workflows/python-code-quality.yml @@ -36,7 +36,7 @@ jobs: # renovate: datasource=pypi depName=bandit BANDIT_VERSION: "1.8.0" # renovate: datasource=pypi depName=ruff - RUFF_VERSION: "0.8.3" + RUFF_VERSION: "0.8.4" runs-on: ${{ matrix.os }} permissions: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2138c36642f..e5cdc24adf3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -37,7 +37,7 @@ repos: ) - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.8.3 + rev: v0.8.4 hooks: # Run the linter. - id: ruff From 0d56ab40cb558c6afee9830797fb5605081bd996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:28:43 -0500 Subject: [PATCH 7/9] temporal: Use ScriptError from grass.exceptions in grass.temporal.gui_support (#4841) --- python/grass/temporal/gui_support.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/grass/temporal/gui_support.py b/python/grass/temporal/gui_support.py index 07097946652..e7c52d6788d 100644 --- a/python/grass/temporal/gui_support.py +++ b/python/grass/temporal/gui_support.py @@ -11,6 +11,7 @@ """ import grass.script as gs +from grass.exceptions import ScriptError from .core import get_available_temporal_mapsets, init_dbif from .factory import dataset_factory @@ -45,7 +46,7 @@ def tlist_grouped(type, group_type: bool = False, dbif=None): for type_ in types: try: tlist_result = tlist(type=type_, dbif=dbif) - except gs.ScriptError as e: + except ScriptError as e: gs.warning(e) continue From 2b88ebb1b7db41ffdcecea9718d17350aa857fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:50:10 -0500 Subject: [PATCH 8/9] temporal: Adjust typing annotation for `datetime_to_grass_datetime_string()` (#4840) `grass.temporal.datetime_math.datetime_to_grass_datetime_string()` checks for `None`, and handles the case where it is `None`, so the `dt` argument can safely be `None`. This fixes some pylance type checking errors in `_pretifyTimeLabels()` of gui/wxpython/animation/temporal_manager.py, which rightfully detected that the result of `tgis.string_to_datetime(start)` can be either `datetime` or `None` and that `None` wouldn't be accepted into `datetime_to_grass_datetime_string()`. --- python/grass/temporal/datetime_math.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/grass/temporal/datetime_math.py b/python/grass/temporal/datetime_math.py index 2ce435ccf9f..40450151a4b 100644 --- a/python/grass/temporal/datetime_math.py +++ b/python/grass/temporal/datetime_math.py @@ -836,7 +836,7 @@ def string_to_datetime(time_string: str) -> datetime | None: return time_object -def datetime_to_grass_datetime_string(dt: datetime) -> str: +def datetime_to_grass_datetime_string(dt: datetime | None) -> str: """Convert a python datetime object into a GRASS datetime string .. code-block:: python From 6930424824bb19ce98c16eb1bafea0ff8132ec64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:50:41 -0500 Subject: [PATCH 9/9] temporal: Rename duplicate test name in unittests_temporal_raster_algebra.py (#4842) Fixes the following Pylance error: Method declaration "test_temporal_select" is obscured by a declaration of the same name --- .../temporal/testsuite/unittests_temporal_raster_algebra.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/grass/temporal/testsuite/unittests_temporal_raster_algebra.py b/python/grass/temporal/testsuite/unittests_temporal_raster_algebra.py index ad4114d4e3e..6dcf9267632 100644 --- a/python/grass/temporal/testsuite/unittests_temporal_raster_algebra.py +++ b/python/grass/temporal/testsuite/unittests_temporal_raster_algebra.py @@ -677,8 +677,8 @@ def test_map_function2(self) -> None: self.assertEqual(D.check_temporal_topology(), True) self.assertEqual(D.get_granularity(), "1 day") - def test_temporal_select(self) -> None: - """Testing the temporal select operator.""" + def test_temporal_select_same_left_right(self) -> None: + """Testing the temporal select operator with the same map for left and right.""" tra = tgis.TemporalRasterAlgebraParser(run=True, debug=True) tra.parse(expression="R = A : A", basename="r", overwrite=True)