diff --git a/.flake8 b/.flake8 index 9786c9775a3..7019d947c03 100644 --- a/.flake8 +++ b/.flake8 @@ -39,7 +39,7 @@ per-file-ignores = doc/python/vector_example_ctypes.py: F403, F405 doc/python/m.distance.py: F403, F405, E501 doc/gui/wxpython/example/dialogs.py: F401 - locale/grass_po_stats.py: E122, E128, E231, E401, E722, E741 + locale/grass_po_stats.py: E122, E128, E231, E401, E722 gui/scripts/d.wms.py: E501 gui/wxpython/core/gcmd.py: E402 gui/wxpython/core/gthread.py: F841 @@ -126,7 +126,6 @@ per-file-ignores = python/grass/pygrass/vector/__init__.py: E402 python/grass/pygrass/modules/interface/*.py: F401 python/grass/pygrass/modules/grid/*.py: F401 - python/grass/pygrass/raster/rowio.py: E741 python/grass/pygrass/raster/category.py: E721 python/grass/pygrass/rpc/__init__.py: F401, F403 python/grass/pygrass/utils.py: E402 @@ -136,13 +135,11 @@ per-file-ignores = python/grass/temporal/datetime_math.py: F841, E722 python/grass/temporal/open_stds.py: F841 python/grass/temporal/spatial_topology_dataset_connector.py: E722 - python/grass/temporal/temporal_algebra.py: E741, F841, E722 + python/grass/temporal/temporal_algebra.py: F841, E722 python/grass/temporal/temporal_granularity.py: F841, E722 - python/grass/temporal/temporal_raster_algebra.py: E741 python/grass/temporal/temporal_raster_base_algebra.py: F841, E722 - python/grass/temporal/temporal_raster3d_algebra.py: E741 python/grass/temporal/temporal_topology_dataset_connector.py: E722 - python/grass/temporal/temporal_vector_algebra.py: E741, F841 + python/grass/temporal/temporal_vector_algebra.py: F841 python/grass/temporal/univar_statistics.py: E231 # Current benchmarks/tests are changing sys.path before import. # Possibly, a different approach should be taken there anyway. @@ -161,7 +158,7 @@ per-file-ignores = # E402 module level import not at top of file scripts/d.polar/d.polar.py: F841 scripts/r.in.wms/wms_gdal_drv.py: F841, E722 - scripts/r.in.wms/wms_cap_parsers.py: F841, E741 + scripts/r.in.wms/wms_cap_parsers.py: F841 scripts/r.in.wms/wms_drv.py: E402, E722 scripts/r.in.wms/srs.py: E722 scripts/r.semantic.label/r.semantic.label.py: F841, E501 @@ -170,8 +167,7 @@ per-file-ignores = scripts/g.extension/g.extension.py: F841, E722, E501 scripts/v.unpack/v.unpack.py: F841, E722, E501 scripts/v.import/v.import.py: F841, E722, E501 - scripts/db.univar/db.univar.py: E741, E501 - scripts/d.rast.leg/d.rast.leg.py: E741 + scripts/db.univar/db.univar.py: E501 scripts/d.frame/d.frame.py: E722 scripts/i.pansharpen/i.pansharpen.py: E722, E501 scripts/r.in.srtm/r.in.srtm.py: E722 diff --git a/.github/actions/create-upload-suggestions/action.yml b/.github/actions/create-upload-suggestions/action.yml index 7d105a5fbd4..8ac14895db8 100644 --- a/.github/actions/create-upload-suggestions/action.yml +++ b/.github/actions/create-upload-suggestions/action.yml @@ -177,7 +177,7 @@ runs: echo "diff-file-name=${INPUT_DIFF_FILE_NAME}" >> "${GITHUB_OUTPUT}" env: INPUT_DIFF_FILE_NAME: ${{ steps.tool-name-safe.outputs.diff-file-name }} - - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 id: upload-diff if: >- ${{ (steps.files_changed.outputs.files_changed == 'true') && @@ -200,7 +200,7 @@ runs: echo 'Suggestions can only be added near to lines changed in this PR.' echo 'If any fixes can be added as code suggestions, they will be added shortly from another workflow.' } >> "${GITHUB_STEP_SUMMARY}" - - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 id: upload-changes if: >- ${{ always() && diff --git a/.github/workflows/additional_checks.yml b/.github/workflows/additional_checks.yml index 98ceb8cab8c..74602e7910b 100644 --- a/.github/workflows/additional_checks.yml +++ b/.github/workflows/additional_checks.yml @@ -43,7 +43,7 @@ jobs: exclude: mswindows .*\.bat .*/testsuite/data/.* - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: '3.10' diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3ce82c218fb..5317047188a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -42,7 +42,7 @@ jobs: - name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: '3.x' - name: Install non-Python dependencies @@ -52,11 +52,11 @@ jobs: sudo apt-get install -y wget git gawk findutils xargs -a <(awk '! /^ *(#|$)/' ".github/workflows/apt.txt") -r -- \ sudo apt-get install -y --no-install-recommends --no-install-suggests - - uses: rui314/setup-mold@65685f45207903d37d006cd402c397653c57660e # v1 + - uses: rui314/setup-mold@2e332a0b602c2fc65d2d3995941b1b29a5f554a0 # v1 if: ${{ matrix.language == 'c-cpp' }} - name: Initialize CodeQL - uses: github/codeql-action/init@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11 + uses: github/codeql-action/init@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -81,6 +81,6 @@ jobs: run: .github/workflows/build_ubuntu-22.04.sh "${HOME}/install" - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11 + uses: github/codeql-action/analyze@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/create_release_draft.yml b/.github/workflows/create_release_draft.yml index 11f806e2f55..a802b0b7059 100644 --- a/.github/workflows/create_release_draft.yml +++ b/.github/workflows/create_release_draft.yml @@ -35,7 +35,7 @@ jobs: ref: ${{ github.ref }} fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: '3.11' - name: Create output directory @@ -73,7 +73,7 @@ jobs: sha256sum ${{ env.GRASS }}.tar.xz > ${{ env.GRASS }}.tar.xz.sha256 - name: Publish draft distribution to GitHub (for tags only) if: startsWith(github.ref, 'refs/tags/') - uses: softprops/action-gh-release@a74c6b72af54cfa997e81df42d94703d6313a2d0 # v2.0.6 + uses: softprops/action-gh-release@fb2d03176f42a1f0dd433ca263f314051d3edd44 # v2.0.7 with: name: GRASS GIS ${{ github.ref_name }} body: | diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 61942fa6df0..89c3baec8c6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -66,9 +66,9 @@ jobs: latest=false suffix=-${{ matrix.os }} - name: Set up QEMU - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + uses: docker/setup-qemu-action@5927c834f5b4fdf503fca6f4c7eccda82949e1ee # v3.1.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 + uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4 # v3.4.0 - name: Login to DockerHub uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 with: @@ -76,7 +76,7 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push id: docker_build - uses: docker/build-push-action@15560696de535e4014efeff63c48f16952e52dd1 # v6.2.0 + uses: docker/build-push-action@1ca370b3a9802c92e886402e0dd88098a2533b12 # v6.4.1 with: push: true pull: true diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index b56aab0039c..da6a1a4d295 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -72,7 +72,7 @@ jobs: nc_spm_full_v2alpha2.tar.gz" - name: Make HTML test report available if: ${{ always() }} - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: testreport-macOS path: testreport diff --git a/.github/workflows/osgeo4w.yml b/.github/workflows/osgeo4w.yml index 0aa84bcbb1a..d96cd0c3ff8 100644 --- a/.github/workflows/osgeo4w.yml +++ b/.github/workflows/osgeo4w.yml @@ -83,7 +83,7 @@ jobs: - name: Make HTML test report available if: ${{ always() }} - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: testreport-${{ matrix.os }} path: testreport diff --git a/.github/workflows/post-pr-reviews.yml b/.github/workflows/post-pr-reviews.yml index 7bfa9b9091f..afd9726ee34 100644 --- a/.github/workflows/post-pr-reviews.yml +++ b/.github/workflows/post-pr-reviews.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Create a .git directory needed by reviewdog run: git init - - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 id: diff continue-on-error: true with: @@ -47,6 +47,7 @@ jobs: INPUT_TOOL_NAMES: >- black clang-format + ruff - name: Post Black suggestions if: ${{ steps.tools.outputs.black == 'true' }} run: | @@ -83,3 +84,21 @@ jobs: CI_REPO_OWNER: ${{ github.event.workflow_run.repository.owner.login }} CI_REPO_NAME: ${{ github.event.workflow_run.repository.name }} # CI_PULL_REQUEST: "" # Populated from reviewdog's "-guess" flag since hard to get + - name: Post Ruff suggestions + if: ${{ steps.tools.outputs.ruff == 'true' }} + run: | + TMPFILE="diff-${INPUT_TOOL_NAME}.patch" + GITHUB_ACTIONS="" reviewdog \ + -name="${INPUT_TOOL_NAME:-reviewdog-suggester}" \ + -f=diff \ + -f.diff.strip=1 \ + -filter-mode=nofilter \ + -guess \ + -reporter="github-pr-review" < "${TMPFILE}" + env: + INPUT_TOOL_NAME: ruff + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CI_COMMIT: ${{ github.event.workflow_run.head_sha }} + CI_REPO_OWNER: ${{ github.event.workflow_run.repository.owner.login }} + CI_REPO_NAME: ${{ github.event.workflow_run.repository.name }} + # CI_PULL_REQUEST: "" # Populated from reviewdog's "-guess" flag since hard to get diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 52b0cd8a808..1600be8fda6 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -34,7 +34,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: ${{ matrix.python-version }} cache: pip @@ -46,7 +46,7 @@ jobs: xargs -a <(awk '! /^ *(#|$)/' ".github/workflows/apt.txt") -r -- \ sudo apt-get install -y --no-install-recommends --no-install-suggests - - uses: rui314/setup-mold@65685f45207903d37d006cd402c397653c57660e # v1 + - uses: rui314/setup-mold@2e332a0b602c2fc65d2d3995941b1b29a5f554a0 # v1 - name: Install Python dependencies run: | diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml index fa78fdadf6f..3e5c454d59c 100644 --- a/.github/workflows/python-code-quality.yml +++ b/.github/workflows/python-code-quality.yml @@ -35,6 +35,8 @@ jobs: PYLINT_VERSION: "2.12.2" # renovate: datasource=pypi depName=bandit BANDIT_VERSION: "1.7.9" + # renovate: datasource=pypi depName=ruff + RUFF_VERSION: "0.5.2" runs-on: ${{ matrix.os }} permissions: @@ -50,17 +52,33 @@ jobs: echo Flake8: ${{ env.FLAKE8_VERSION }} echo Pylint: ${{ env.PYLINT_VERSION }} echo Bandit: ${{ env.BANDIT_VERSION }} + echo Ruff: ${{ env.RUFF_VERSION }} - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: ${{ env.PYTHON_VERSION }} cache: pip - name: Upgrade pip run: python -m pip install --upgrade pip + - name: Install Ruff + run: pip install ruff==${{ env.RUFF_VERSION }} + - name: Run Ruff + run: ruff check --output-format=github . --preview --fix --unsafe-fixes + - name: Create and uploads code suggestions to apply for Ruff + # Will fail fast here if there are changes required + id: diff-ruff + # To run after ruff step exits with failure when rules don't have fixes available + if: ${{ !cancelled() }} + uses: ./.github/actions/create-upload-suggestions + with: + tool-name: ruff + # To keep repo's file structure in formatted changes artifact + extra-upload-changes: pyproject.toml + - name: Install Black only run: pip install black[jupyter]==${{ env.BLACK_VERSION }} @@ -108,13 +126,13 @@ jobs: bandit -c pyproject.toml -iii -r . -f sarif -o bandit.sarif --exit-zero - name: Upload Bandit Scan Results - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: bandit.sarif path: bandit.sarif - name: Upload SARIF File into Security Tab - uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11 + uses: github/codeql-action/upload-sarif@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12 with: sarif_file: bandit.sarif @@ -126,7 +144,7 @@ jobs: run: | echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV - - uses: rui314/setup-mold@65685f45207903d37d006cd402c397653c57660e # v1 + - uses: rui314/setup-mold@2e332a0b602c2fc65d2d3995941b1b29a5f554a0 # v1 - name: Build run: .github/workflows/build_${{ matrix.os }}.sh $HOME/install @@ -181,7 +199,7 @@ jobs: cp -rp dist.$ARCH/docs/html/libpython sphinx-grass - name: Make Sphinx documentation available - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: sphinx-grass path: sphinx-grass diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index 460b5e02fe3..95a9d8329c0 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -31,7 +31,7 @@ jobs: # list of files that changed across commits fetch-depth: 0 - name: Lint code base - uses: super-linter/super-linter/slim@88ea3923a7e1f89dd485d079f6eb5f5e8f937589 # v6.6.0 + uses: super-linter/super-linter/slim@3fe03abab2eafb293ace16d4a3b07aeabcb3f1a0 # v6.7.0 env: DEFAULT_BRANCH: main # To report GitHub Actions status checks diff --git a/.github/workflows/test-nix.yml b/.github/workflows/test-nix.yml index 42b5eee93a5..f9d5297bef6 100644 --- a/.github/workflows/test-nix.yml +++ b/.github/workflows/test-nix.yml @@ -7,6 +7,12 @@ on: push: tags: - '*' + pull_request: + paths: + - 'flake.nix' + - 'flake.lock' + - 'package.nix' + - '.github/workflows/test-nix.yml' workflow_dispatch: concurrency: diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index fa113ad7d22..e6f2899c2ce 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -147,7 +147,7 @@ jobs: - name: Make HTML test report available if: ${{ always() }} - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: testreport-${{ matrix.os }}-${{ matrix.config }}-${{ matrix.extra-include }} path: testreport diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d596da4f85c..9843a6f6616 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,6 +35,14 @@ repos: python/libgrass_interface_generator/ctypesgen/| lib/fonts/fonts/.* ) + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.5.2 + hooks: + # Run the linter. + - id: ruff + types_or: [python, pyi, jupyter] + args: [--fix, --preview] - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.41.0 hooks: diff --git a/Dockerfile b/Dockerfile index 605fdbee4ec..48c57ff5d6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.8@sha256:e87caa74dcb7d46cd820352bfea12591f3dba3ddc4285e19c7dcd13359f7cefd +# syntax=docker/dockerfile:1.9@sha256:fe40cf4e92cd0c467be2cfc30657a680ae2398318afd50b0c80585784c604f28 # Note: This file must be kept in sync in ./Dockerfile and ./docker/ubuntu/Dockerfile. # Changes to this file must be copied over to the other file. diff --git a/display/CMakeLists.txt b/display/CMakeLists.txt index 4369a442a6a..3fc11e8674c 100644 --- a/display/CMakeLists.txt +++ b/display/CMakeLists.txt @@ -81,7 +81,7 @@ if(WITH_DOCS) DESTINATION ${GRASS_INSTALL_DOCDIR}) endif() build_program_in_subdir(d.grid DEPENDS grass_gis grass_symb grass_gproj - grass_display LIBM) + grass_display GDAL LIBM) build_program_in_subdir(d.his DEPENDS grass_gis grass_display grass_raster) build_program_in_subdir(d.histogram DEPENDS grass_gis grass_display grass_raster LIBM) @@ -103,7 +103,7 @@ if(WITH_DOCS) install(DIRECTORY ${OUTDIR}/${GRASS_INSTALL_DOCDIR}/northarrows DESTINATION ${GRASS_INSTALL_DOCDIR}) endif() -build_program_in_subdir(d.path DEPENDS grass_gis grass_display grass_vector) +build_program_in_subdir(d.path DEPENDS grass_gis grass_display grass_vector GDAL) build_program_in_subdir(d.profile DEPENDS grass_gis grass_display grass_raster LIBM) build_program_in_subdir(d.rast DEPENDS grass_gis grass_display grass_raster) build_program_in_subdir(d.rast.arrow DEPENDS grass_gis grass_raster @@ -125,6 +125,7 @@ build_program_in_subdir( grass_raster grass_symb grass_vector + GDAL LIBM) build_program_in_subdir( d.vect.chart @@ -136,6 +137,7 @@ build_program_in_subdir( grass_gis grass_symb grass_vector + GDAL LIBM) build_program_in_subdir( d.vect.thematic @@ -147,5 +149,6 @@ build_program_in_subdir( grass_display grass_gis grass_symb - grass_vector) -build_program_in_subdir(d.where DEPENDS grass_gis grass_display grass_gproj) + grass_vector + GDAL) +build_program_in_subdir(d.where DEPENDS grass_gis grass_display grass_gproj GDAL) diff --git a/display/d.labels/main.c b/display/d.labels/main.c index 75dfed09fd0..301469710f7 100644 --- a/display/d.labels/main.c +++ b/display/d.labels/main.c @@ -28,7 +28,7 @@ int main(int argc, char **argv) struct Cell_head window; char *label_name; const char *mapset; - double minreg, maxreg, reg, dx, dy; + double reg, dx, dy; FILE *infile; struct Option *opt1; struct Option *maxreg_opt, *minreg_opt; @@ -91,7 +91,7 @@ int main(int argc, char **argv) dy = window.north - window.south; reg = sqrt(dx * dx + dy * dy); if (minreg_opt->answer) { - minreg = atof(minreg_opt->answer); + double minreg = atof(minreg_opt->answer); if (reg < minreg) { G_warning( _("Region size is lower than minreg, nothing displayed.")); @@ -100,7 +100,7 @@ int main(int argc, char **argv) } } if (maxreg_opt->answer) { - maxreg = atof(maxreg_opt->answer); + double maxreg = atof(maxreg_opt->answer); if (reg > maxreg) { G_warning( _("Region size is greater than maxreg, nothing displayed.")); diff --git a/display/d.legend.vect/draw.c b/display/d.legend.vect/draw.c index 6f23c0f4924..3de72c7f2a9 100644 --- a/display/d.legend.vect/draw.c +++ b/display/d.legend.vect/draw.c @@ -43,7 +43,7 @@ void draw(char *file_name, double LL, double LT, char *title, int cols, double symb_h, symb_w, def_symb_h, def_symb_w; int item_count, item; double it_per_col; - double margin, bg_h, bg_w; + double margin, bg_h; char **tokens; D_get_src(&dt, &db, &dl, &dr); @@ -264,7 +264,7 @@ void draw(char *file_name, double LL, double LT, char *title, int cols, /* Draw background */ if (do_bg) { double x0bg, y0bg, x1bg, y1bg; - + double bg_w; if (title_w > offs_x + maxlblw) bg_w = title_w; else diff --git a/display/d.text/test.py b/display/d.text/test.py index ffc50cfc8aa..6e7fe676a65 100755 --- a/display/d.text/test.py +++ b/display/d.text/test.py @@ -2,6 +2,7 @@ # Author: Owen Smith - Rewritten from test.pl by Huidae Cho # Run: d.mon start=wx0 && ./test.py | d.text at=0,100 import math +from pathlib import Path import re # Quiet black syntax checking for fonts and colors to keep the code printed to @@ -55,8 +56,8 @@ def text(in_text): rotate(i * 10) color(colors[i % len(colors)]) xy( - (80 + 10 * math.cos(i * 10 / 180 * 3.141593)), - (50 + 10 * 640 / 480 * math.sin(i * 10 / 180 * 3.141593)), + (80 + 10 * math.cos(i * 10 / 180 * math.pi)), + (50 + 10 * 640 / 480 * math.sin(i * 10 / 180 * math.pi)), ) text(fonts[int(i % len(fonts))]) @@ -66,8 +67,8 @@ def text(in_text): color("gray") rc(1, 1) -with open(__file__) as f: - src = f.read() + +src = Path(__file__).read_text() print( ".L 0\n" diff --git a/doc/NIX.md b/doc/NIX.md new file mode 100644 index 00000000000..412e75d5a1a --- /dev/null +++ b/doc/NIX.md @@ -0,0 +1,103 @@ +# How to use Nix + +## What is Nix + +[Nix](https://nixos.org/) is a powerful package manager and system configuration +tool that aims to make software deployment fully reproducible. + +## Nix installation + +- Install Nix + [(learn more about this installer)](https://zero-to-nix.com/start/install) + + ```bash + curl --proto '=https' --tlsv1.2 -sSf \ + -L https://install.determinate.systems/nix \ + | sh -s -- install + ``` + +## Create GRASS GIS development environment + +Nix provides a development environment containing all required dependencies. + +- Launch development environment + + ```bash + nix develop + ``` + +- Optionally, use [direnv](https://direnv.net) to activate environment + automatically when entering the source code directory + + ```bash + echo "use flake" > .envrc + direnv allow + ``` + +## Launch GRASS GIS directly from the source code + +Nix allows to run a program directly from git source code repository using +following command: + +```bash +nix run \ + github://# -- +``` + +- Launch latest version of GRASS from `main` branch + + ```bash + nix run github:OSGeo/grass#grass + ``` + +- Launch GRASS from specific Git revision, branch or tag + + ```bash + nix run github:OSGeo/grass/#grass + ``` + +- Launch GRASS from pull request + + ```bash + nix run github:/grass/#grass + ``` + +## Install GRASS GIS directly from the source code + +To install a program permanently, use following command: + +```bash +nix profile install \ + github://# -- +``` + +- Install latest version of GRASS from `main` branch + + ```bash + nix profile install github:OSGeo/grass#grass + ``` + +- Install GRASS from specific Git revision, branch or tag + + ```bash + nix profile install github:OSGeo/grass/#grass + ``` + +## Uninstall GRASS GIS + +- List installed programs + + ```bash + nix profile list + ``` + +- Uninstall a program + + ```bash + nix profile remove + ``` + +## Nix documentation + +- [nix.dev](https://nix.dev) +- [Zero to Nix](https://zero-to-nix.com) diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile index 605fdbee4ec..48c57ff5d6a 100644 --- a/docker/ubuntu/Dockerfile +++ b/docker/ubuntu/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.8@sha256:e87caa74dcb7d46cd820352bfea12591f3dba3ddc4285e19c7dcd13359f7cefd +# syntax=docker/dockerfile:1.9@sha256:fe40cf4e92cd0c467be2cfc30657a680ae2398318afd50b0c80585784c604f28 # Note: This file must be kept in sync in ./Dockerfile and ./docker/ubuntu/Dockerfile. # Changes to this file must be copied over to the other file. diff --git a/flake.lock b/flake.lock index ff511760ebb..c30f9b90775 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1717285511, - "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=", + "lastModified": 1719994518, + "narHash": "sha256-pQMhCCHyQGRzdfAkdJ4cIWiw+JNuWsTX7f0ZYSyz0VY=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8", + "rev": "9227223f6d922fee3c7b190b2cc238a99527bbb7", "type": "github" }, "original": { @@ -19,11 +19,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1718428119, - "narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=", + "lastModified": 1720955038, + "narHash": "sha256-GaliJqfFwyYxReFywxAa8orCO+EnDq2NK2F+5aSc8vo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5", + "rev": "aa247c0c90ecf4ae7a032c54fdc21b91ca274062", "type": "github" }, "original": { @@ -35,14 +35,14 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1717284937, - "narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=", + "lastModified": 1719876945, + "narHash": "sha256-Fm2rDDs86sHy0/1jxTOKB1118Q0O3Uc7EC0iXvXKpbI=", "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" + "url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz" }, "original": { "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" + "url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz" } }, "root": { diff --git a/flake.nix b/flake.nix index 49bd16561b7..51174e1da74 100644 --- a/flake.nix +++ b/flake.nix @@ -21,37 +21,42 @@ packages.grass = pkgs.callPackage ./package.nix { }; - devShells.default = pkgs.mkShell { - inputsFrom = [ self'.packages.grass ]; - - # additional packages - buildInputs = with pkgs.python3Packages; [ - pytest - ]; - - shellHook = '' - function dev-help { - echo -e "\nWelcome to a GRASS development environment !" - echo "Build GRASS using following commands:" - echo - echo " 1. ./configure --prefix=\$(pwd)/app" - echo " 2. make -j$(nproc)" - echo " 3. make install" - echo - echo "Run tests:" - echo - echo " 1. export PYTHONPATH=\$(app/bin/grass --config python_path):\$PYTHONPATH" - echo " 2. export LD_LIBRARY_PATH=\$(app/bin/grass --config path)/lib:\$LD_LIBRARY_PATH" - echo " 3. pytest" - echo - echo "Note: run 'nix flake update' from time to time to update dependencies." - echo - echo "Run 'dev-help' to see this message again." - } - - dev-help - ''; - }; + devShells.default = + let + pyPackages = pkgs.python311Packages; + + in + pkgs.mkShell { + inputsFrom = [ self'.packages.grass ]; + + # additional packages + buildInputs = with pyPackages; [ + pytest + ]; + + shellHook = '' + function dev-help { + echo -e "\nWelcome to a GRASS development environment !" + echo "Build GRASS using following commands:" + echo + echo " 1. ./configure --prefix=\$(pwd)/app" + echo " 2. make -j$(nproc)" + echo " 3. make install" + echo + echo "Run tests:" + echo + echo " 1. export PYTHONPATH=\$(app/bin/grass --config python_path):\$PYTHONPATH" + echo " 2. export LD_LIBRARY_PATH=\$(app/bin/grass --config path)/lib:\$LD_LIBRARY_PATH" + echo " 3. pytest" + echo + echo "Note: run 'nix flake update' from time to time to update dependencies." + echo + echo "Run 'dev-help' to see this message again." + } + + dev-help + ''; + }; }; flake = { }; diff --git a/general/CMakeLists.txt b/general/CMakeLists.txt index a3fe869592b..b6d83d6265b 100644 --- a/general/CMakeLists.txt +++ b/general/CMakeLists.txt @@ -35,6 +35,7 @@ build_program_in_subdir( grass_raster3d grass_gmath PROJ + GDAL LIBM) build_program_in_subdir(g.rename DEPENDS grass_gis grass_manage grass_raster) @@ -72,7 +73,8 @@ build_program_in_subdir( grass_manage grass_raster grass_raster3d - grass_vector) + grass_vector + GDAL) add_dependencies(g.list cell vector) build_program_in_subdir(g.remove DEPENDS grass_gis grass_manage grass_raster) diff --git a/general/manage/lister/CMakeLists.txt b/general/manage/lister/CMakeLists.txt index b167af6082a..a7e9359bcd7 100644 --- a/general/manage/lister/CMakeLists.txt +++ b/general/manage/lister/CMakeLists.txt @@ -22,6 +22,7 @@ build_program( grass_dbmibase grass_gis grass_raster + GDAL RUNTIME_OUTPUT_DIR "${GRASS_INSTALL_ETCDIR}/lister" NO_DOCS) diff --git a/gui/wxpython/animation/anim.py b/gui/wxpython/animation/anim.py index 1ac3140d36e..591bbff151c 100644 --- a/gui/wxpython/animation/anim.py +++ b/gui/wxpython/animation/anim.py @@ -119,7 +119,7 @@ def _arrivedToEnd(self): self.orientation = Orientation.BACKWARD self.currentIndex = self.count - 2 # -1 self.callbackOrientationChanged(Orientation.BACKWARD) - else: + else: # noqa: PLR5501 if self.replayMode == ReplayMode.REPEAT: self.currentIndex = self.count - 1 elif self.replayMode == ReplayMode.REVERSE: diff --git a/gui/wxpython/animation/controller.py b/gui/wxpython/animation/controller.py index 3e914e68112..1a920f77de7 100644 --- a/gui/wxpython/animation/controller.py +++ b/gui/wxpython/animation/controller.py @@ -36,6 +36,7 @@ HashCmds, ) from animation.data import AnimationData +from itertools import starmap class AnimationController(wx.EvtHandler): @@ -119,7 +120,7 @@ def PauseAnimation(self, paused): if self.timer.IsRunning(): self.timer.Stop() self.DisableSliderIfNeeded() - else: + else: # noqa: PLR5501 if not self.timer.IsRunning(): self.timer.Start(int(self.timeTick)) self.DisableSliderIfNeeded() @@ -368,10 +369,7 @@ def _updateAnimations(self, activeIndices, mapNamesDict=None): if anim.viewMode == "3d": regions = [None] * len(regions) self.animations[i].SetFrames( - [ - HashCmds(cmdList, region) - for cmdList, region in zip(anim.cmdMatrix, regions) - ] + list(starmap(HashCmds, zip(anim.cmdMatrix, regions))) ) self.animations[i].SetActive(True) else: @@ -557,9 +555,8 @@ def _export(self, exportInfo, decorations): if frameId is not None: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap - else: - if i not in lastBitmaps: - lastBitmaps[i] = wx.NullBitmap() + elif i not in lastBitmaps: + lastBitmaps[i] = wx.NullBitmap() else: bitmap = self.bitmapProvider.GetBitmap(frameId) lastBitmaps[i] = bitmap @@ -595,17 +592,15 @@ def _export(self, exportInfo, decorations): "dash": "\u2013", "to": timeLabel[1], } + elif ( + self.temporalManager.GetTemporalType() == TemporalType.ABSOLUTE + ): + text = timeLabel[0] else: - if ( - self.temporalManager.GetTemporalType() - == TemporalType.ABSOLUTE - ): - text = timeLabel[0] - else: - text = _("%(start)s %(unit)s") % { - "start": timeLabel[0], - "unit": timeLabel[2], - } + text = _("%(start)s %(unit)s") % { + "start": timeLabel[0], + "unit": timeLabel[2], + } decImage = RenderText( text, decoration["font"], bgcolor, fgcolor diff --git a/gui/wxpython/animation/dialogs.py b/gui/wxpython/animation/dialogs.py index d9130d41e3e..91b67429858 100644 --- a/gui/wxpython/animation/dialogs.py +++ b/gui/wxpython/animation/dialogs.py @@ -671,9 +671,8 @@ def GetOptData(self, dcmd, layer, params, propwin): if not self.legend.IsChecked(): self.legend.SetValue(True) - else: - if not self._tmpLegendCmd and not self.animationData.legendCmd: - self.legend.SetValue(False) + elif not self._tmpLegendCmd and not self.animationData.legendCmd: + self.legend.SetValue(False) def _update(self): if self.nDChoice.GetSelection() == 1 and len(self._layerList) > 1: @@ -1623,9 +1622,8 @@ def SetStdsProperties(self, layer): else: signal = self.cmdChanged signal.emit(index=self._layerList.GetLayerIndex(layer), layer=layer) - else: - if hidden: - self._layerList.RemoveLayer(layer) + elif hidden: + self._layerList.RemoveLayer(layer) dlg.Destroy() self._update() self.anyChange.emit() diff --git a/gui/wxpython/animation/frame.py b/gui/wxpython/animation/frame.py index 4fe0457ee66..cec08546366 100644 --- a/gui/wxpython/animation/frame.py +++ b/gui/wxpython/animation/frame.py @@ -22,7 +22,7 @@ import wx import wx.aui -import grass.script as gcore +import grass.script as gs import grass.temporal as tgis from grass.exceptions import FatalError from core import globalvar @@ -42,7 +42,7 @@ MAX_COUNT = 4 TMP_DIR = None -gcore.set_raise_on_error(True) +gs.set_raise_on_error(True) class AnimationFrame(wx.Frame): @@ -71,7 +71,7 @@ def __init__( # create temporal directory and ensure it's deleted after programs ends # (stored in MAPSET/.tmp/) global TMP_DIR - TMP_DIR = gcore.tempdir() + TMP_DIR = gs.tempdir() self.animations = [Animation() for i in range(MAX_COUNT)] self.windows = [] @@ -642,7 +642,7 @@ def _updateFrameIndex(self, index): } else: label = _("to %(to)s") % {"to": self.timeLabels[index][1]} - else: + else: # noqa: PLR5501 if self.temporalType == TemporalType.ABSOLUTE: label = start else: diff --git a/gui/wxpython/animation/g.gui.animation.py b/gui/wxpython/animation/g.gui.animation.py index f8bedae83eb..911c6c472dd 100644 --- a/gui/wxpython/animation/g.gui.animation.py +++ b/gui/wxpython/animation/g.gui.animation.py @@ -51,12 +51,12 @@ # % guisection: Input # %end -import grass.script as gscript +import grass.script as gs from grass.exceptions import FatalError def main(): - options, flags = gscript.parser() + options, flags = gs.parser() # import wx only after running parser # to avoid issues when only interface is needed @@ -89,7 +89,7 @@ def main(): numInputs += 1 if numInputs > 1: - gscript.fatal( + gs.fatal( _("%s=, %s=, %s= and %s= are mutually exclusive.") % ("raster", "vector", "strds", "stvds") ) diff --git a/gui/wxpython/animation/nviztask.py b/gui/wxpython/animation/nviztask.py index fb3dfe501a1..92a6e767ce0 100644 --- a/gui/wxpython/animation/nviztask.py +++ b/gui/wxpython/animation/nviztask.py @@ -111,11 +111,10 @@ def _processSurface(self, surface, mapName): mapname = surface["attribute"][attr]["value"] else: const = surface["attribute"][attr]["value"] - else: - if attr == "transp": - const = 0 - elif attr == "color": - mapname = mapName + elif attr == "transp": + const = 0 + elif attr == "color": + mapname = mapName if mapname: self._setMultiTaskParam(params[0], mapname) @@ -194,21 +193,19 @@ def _processVolume(self, volume, mapName): mapname = isosurface[attr]["value"] else: const = float(isosurface[attr]["value"]) - else: - if attr == "transp": - const = 0 - elif attr == "color": - mapname = mapName + elif attr == "transp": + const = 0 + elif attr == "color": + mapname = mapName if mapname: self._setMultiTaskParam(params[0], mapname) + elif attr == "topo": + # TODO: we just assume it's the first volume, what + # to do else? + self._setMultiTaskParam(params[1], "1:" + str(const)) else: - if attr == "topo": - # TODO: we just assume it's the first volume, what - # to do else? - self._setMultiTaskParam(params[1], "1:" + str(const)) - else: - self._setMultiTaskParam(params[1], const) + self._setMultiTaskParam(params[1], const) if isosurface["inout"]["value"]: self.task.set_flag("n", True) # slices diff --git a/gui/wxpython/animation/temporal_manager.py b/gui/wxpython/animation/temporal_manager.py index fc1be449fb7..2273ccfd9d6 100644 --- a/gui/wxpython/animation/temporal_manager.py +++ b/gui/wxpython/animation/temporal_manager.py @@ -19,7 +19,7 @@ import datetime -import grass.script as grass +import grass.script as gs import grass.temporal as tgis from core.gcmd import GException from core.settings import UserSettings @@ -116,8 +116,7 @@ def _setTemporalState(self): # check for units for relative type if relative: units = set() - for infoDict in self.timeseriesInfo.values(): - units.add(infoDict["unit"]) + units.update(infoDict["unit"] for infoDict in self.timeseriesInfo.values()) if len(units) > 1: message = _( "It is not allowed to display data with different units (%s)." @@ -296,20 +295,19 @@ def _getLabelsAndMaps(self, timeseries): # map exists, stop point mode listOfMaps.append(series) afterPoint = False - else: + elif afterPoint: # check point mode - if afterPoint: - if followsPoint: - # skip this one, already there - followsPoint = False - continue - else: - # append the last one (of point time) - listOfMaps.append(lastTimeseries) - end = None + if followsPoint: + # skip this one, already there + followsPoint = False + continue else: - # append series which is None - listOfMaps.append(series) + # append the last one (of point time) + listOfMaps.append(lastTimeseries) + end = None + else: + # append series which is None + listOfMaps.append(series) timeLabels.append((start, end, unit)) return timeLabels, listOfMaps @@ -389,7 +387,7 @@ def test(): def createAbsoluteInterval(): - grass.run_command( + gs.run_command( "g.region", s=0, n=80, @@ -403,21 +401,21 @@ def createAbsoluteInterval(): quiet=True, ) - grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) - grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) - grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) - grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) - grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) - grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) - - grass.mapcalc(exp="temp_1 = rand(0, 550)", overwrite=True) - grass.mapcalc(exp="temp_2 = rand(0, 450)", overwrite=True) - grass.mapcalc(exp="temp_3 = rand(0, 320)", overwrite=True) - grass.mapcalc(exp="temp_4 = rand(0, 510)", overwrite=True) - grass.mapcalc(exp="temp_5 = rand(0, 300)", overwrite=True) - grass.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) - - n1 = grass.read_command("g.tempfile", pid=1, flags="d").strip() + gs.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) + gs.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) + gs.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) + gs.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) + gs.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) + gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) + + gs.mapcalc(exp="temp_1 = rand(0, 550)", overwrite=True) + gs.mapcalc(exp="temp_2 = rand(0, 450)", overwrite=True) + gs.mapcalc(exp="temp_3 = rand(0, 320)", overwrite=True) + gs.mapcalc(exp="temp_4 = rand(0, 510)", overwrite=True) + gs.mapcalc(exp="temp_5 = rand(0, 300)", overwrite=True) + gs.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) + + n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() fd = open(n1, "w") fd.write( "prec_1|2001-01-01|2001-02-01\n" @@ -429,7 +427,7 @@ def createAbsoluteInterval(): ) fd.close() - n2 = grass.read_command("g.tempfile", pid=2, flags="d").strip() + n2 = gs.read_command("g.tempfile", pid=2, flags="d").strip() fd = open(n2, "w") fd.write( "temp_1|2000-10-01|2001-01-01\n" @@ -442,14 +440,14 @@ def createAbsoluteInterval(): fd.close() name1 = "absinterval1" name2 = "absinterval2" - grass.run_command( + gs.run_command( "t.unregister", type="raster", maps="prec_1,prec_2,prec_3,prec_4,prec_5,prec_6," "temp_1,temp_2,temp_3,temp_4,temp_5,temp_6", ) for name, fname in zip((name1, name2), (n1, n2)): - grass.run_command( + gs.run_command( "t.create", overwrite=True, type="strds", @@ -458,15 +456,13 @@ def createAbsoluteInterval(): title="A test with input files", descr="A test with input files", ) - grass.run_command( - "t.register", flags="i", input=name, file=fname, overwrite=True - ) + gs.run_command("t.register", flags="i", input=name, file=fname, overwrite=True) return name1, name2 def createRelativeInterval(): - grass.run_command( + gs.run_command( "g.region", s=0, n=80, @@ -480,21 +476,21 @@ def createRelativeInterval(): quiet=True, ) - grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) - grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) - grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) - grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) - grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) - grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) - - grass.mapcalc(exp="temp_1 = rand(0, 550)", overwrite=True) - grass.mapcalc(exp="temp_2 = rand(0, 450)", overwrite=True) - grass.mapcalc(exp="temp_3 = rand(0, 320)", overwrite=True) - grass.mapcalc(exp="temp_4 = rand(0, 510)", overwrite=True) - grass.mapcalc(exp="temp_5 = rand(0, 300)", overwrite=True) - grass.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) - - n1 = grass.read_command("g.tempfile", pid=1, flags="d").strip() + gs.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) + gs.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) + gs.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) + gs.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) + gs.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) + gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) + + gs.mapcalc(exp="temp_1 = rand(0, 550)", overwrite=True) + gs.mapcalc(exp="temp_2 = rand(0, 450)", overwrite=True) + gs.mapcalc(exp="temp_3 = rand(0, 320)", overwrite=True) + gs.mapcalc(exp="temp_4 = rand(0, 510)", overwrite=True) + gs.mapcalc(exp="temp_5 = rand(0, 300)", overwrite=True) + gs.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) + + n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() fd = open(n1, "w") fd.write( "prec_1|1|4\n" @@ -506,7 +502,7 @@ def createRelativeInterval(): ) fd.close() - n2 = grass.read_command("g.tempfile", pid=2, flags="d").strip() + n2 = gs.read_command("g.tempfile", pid=2, flags="d").strip() fd = open(n2, "w") fd.write( "temp_1|5|6\n" @@ -519,14 +515,14 @@ def createRelativeInterval(): fd.close() name1 = "relinterval1" name2 = "relinterval2" - grass.run_command( + gs.run_command( "t.unregister", type="raster", maps="prec_1,prec_2,prec_3,prec_4,prec_5,prec_6," "temp_1,temp_2,temp_3,temp_4,temp_5,temp_6", ) for name, fname in zip((name1, name2), (n1, n2)): - grass.run_command( + gs.run_command( "t.create", overwrite=True, type="strds", @@ -535,7 +531,7 @@ def createRelativeInterval(): title="A test with input files", descr="A test with input files", ) - grass.run_command( + gs.run_command( "t.register", flags="i", input=name, @@ -547,7 +543,7 @@ def createRelativeInterval(): def createAbsolutePoint(): - grass.run_command( + gs.run_command( "g.region", s=0, n=80, @@ -561,14 +557,14 @@ def createAbsolutePoint(): quiet=True, ) - grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) - grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) - grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) - grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) - grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) - grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) + gs.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) + gs.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) + gs.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) + gs.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) + gs.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) + gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) - n1 = grass.read_command("g.tempfile", pid=1, flags="d").strip() + n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() fd = open(n1, "w") fd.write( "prec_1|2001-01-01\n" @@ -580,7 +576,7 @@ def createAbsolutePoint(): ) fd.close() name = "abspoint" - grass.run_command( + gs.run_command( "t.create", overwrite=True, type="strds", @@ -590,12 +586,12 @@ def createAbsolutePoint(): descr="A test with input files", ) - grass.run_command("t.register", flags="i", input=name, file=n1, overwrite=True) + gs.run_command("t.register", flags="i", input=name, file=n1, overwrite=True) return name def createRelativePoint(): - grass.run_command( + gs.run_command( "g.region", s=0, n=80, @@ -609,19 +605,19 @@ def createRelativePoint(): quiet=True, ) - grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) - grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) - grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) - grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) - grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) - grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) + gs.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) + gs.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) + gs.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) + gs.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) + gs.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) + gs.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) - n1 = grass.read_command("g.tempfile", pid=1, flags="d").strip() + n1 = gs.read_command("g.tempfile", pid=1, flags="d").strip() fd = open(n1, "w") fd.write("prec_1|1\nprec_2|3\nprec_3|5\nprec_4|7\nprec_5|11\nprec_6|13\n") fd.close() name = "relpoint" - grass.run_command( + gs.run_command( "t.create", overwrite=True, type="strds", @@ -631,7 +627,7 @@ def createRelativePoint(): descr="A test with input files", ) - grass.run_command("t.register", unit="day", input=name, file=n1, overwrite=True) + gs.run_command("t.register", unit="day", input=name, file=n1, overwrite=True) return name diff --git a/gui/wxpython/animation/utils.py b/gui/wxpython/animation/utils.py index 23d8f23b444..9e5f685545e 100644 --- a/gui/wxpython/animation/utils.py +++ b/gui/wxpython/animation/utils.py @@ -31,7 +31,7 @@ hasPIL = False import grass.temporal as tgis -import grass.script as grass +import grass.script as gs from grass.script.utils import encode from gui_core.wrap import EmptyBitmap @@ -87,7 +87,7 @@ def validateMapNames(names, etype): Input is list of map names. Raises GException if map doesn't exist. """ - mapDict = grass.list_grouped(etype) + mapDict = gs.list_grouped(etype) newNames = [] for name in names: @@ -214,8 +214,7 @@ def checkSeriesCompatibility(mapSeriesList=None, timeseriesList=None): if mapSeriesList: count = set() - for mapSeries in mapSeriesList: - count.add(len(mapSeries)) + count.update(len(mapSeries) for mapSeries in mapSeriesList) if len(count) > 1: raise GException( _( diff --git a/gui/wxpython/core/debug.py b/gui/wxpython/core/debug.py index 86bb006d603..cf642d1df4c 100644 --- a/gui/wxpython/core/debug.py +++ b/gui/wxpython/core/debug.py @@ -22,7 +22,7 @@ import os import sys -import grass.script as grass +import grass.script as gs class DebugMsg: @@ -41,7 +41,7 @@ def __init__(self): def SetLevel(self): """Initialize gui debug level""" try: - self.debuglevel = int(grass.gisenv().get("WX_DEBUG", 0)) + self.debuglevel = int(gs.gisenv().get("WX_DEBUG", 0)) if self.debuglevel < 0 or self.debuglevel > 5: raise ValueError(_("Wx debug level {0}.").format(self.debuglevel)) except ValueError as e: diff --git a/gui/wxpython/core/gcmd.py b/gui/wxpython/core/gcmd.py index 5d845193938..7d4ed678d79 100644 --- a/gui/wxpython/core/gcmd.py +++ b/gui/wxpython/core/gcmd.py @@ -201,7 +201,7 @@ def kill(self): import win32api handle = win32api.OpenProcess(1, 0, self.pid) - return 0 != win32api.TerminateProcess(handle, 0) + return win32api.TerminateProcess(handle, 0) != 0 else: try: os.kill(-self.pid, signal.SIGTERM) # kill whole group diff --git a/gui/wxpython/core/gconsole.py b/gui/wxpython/core/gconsole.py index ff566cdef88..671e71d1548 100644 --- a/gui/wxpython/core/gconsole.py +++ b/gui/wxpython/core/gconsole.py @@ -35,7 +35,7 @@ import wx from wx.lib.newevent import NewEvent -import grass.script as grass +import grass.script as gs from grass.script import task as gtask from grass.pydispatch.signal import Signal @@ -401,7 +401,7 @@ def __init__(self, guiparent=None, giface=None, ignoredCmdPattern=None): def Redirect(self): """Redirect stdout/stderr""" - if Debug.GetLevel() == 0 and grass.debug_level(force=True) == 0: + if Debug.GetLevel() == 0 and gs.debug_level(force=True) == 0: # don't redirect when debugging is enabled sys.stdout = self.cmdStdOut sys.stderr = self.cmdStdErr @@ -664,7 +664,7 @@ def RunCmd( if os.path.splitext(command[0])[1] in {".py", ".sh"}: try: with open(command[0], "r") as sfile: - for line in sfile.readlines(): + for line in sfile: if len(line) < 3: continue if line.startswith(("#%", "# %")): @@ -825,12 +825,12 @@ def OnCmdDone(self, event): lnames = [p.get("value")] for lname in lnames: if "@" not in lname: - lname += "@" + grass.gisenv()["MAPSET"] - if grass.find_file(lname, element=p.get("element"))["fullname"]: + lname += "@" + gs.gisenv()["MAPSET"] + if gs.find_file(lname, element=p.get("element"))["fullname"]: self.mapCreated.emit( name=lname, ltype=prompt, add=event.addLayer ) - gisenv = grass.gisenv() + gisenv = gs.gisenv() self._giface.grassdbChanged.emit( grassdb=gisenv["GISDBASE"], location=gisenv["LOCATION_NAME"], @@ -844,7 +844,7 @@ def OnCmdDone(self, event): for p in task.get_options()["flags"]: if p.get("name") == "r" and p.get("value"): action = "delete" - gisenv = grass.gisenv() + gisenv = gs.gisenv() self._giface.grassdbChanged.emit( grassdb=gisenv["GISDBASE"], location=gisenv["LOCATION_NAME"], diff --git a/gui/wxpython/core/giface.py b/gui/wxpython/core/giface.py index 951c9cb42dd..f226d44eae9 100644 --- a/gui/wxpython/core/giface.py +++ b/gui/wxpython/core/giface.py @@ -18,7 +18,7 @@ import os import sys -import grass.script as grass +import grass.script as gs from grass.pydispatch.signal import Signal @@ -275,7 +275,7 @@ def _onCmdOutput(self, event): def _onCmdProgress(self, event): """Update progress message info""" - grass.percent(event.value, 100, 1) + gs.percent(event.value, 100, 1) event.Skip() def RunCmd( @@ -306,18 +306,18 @@ def Help(self, entry): self._gconsole.RunCmd(["g.manual", "entry=%s" % entry]) def WriteLog(self, text, wrap=None, notification=Notification.HIGHLIGHT): - self._write(grass.message, text) + self._write(gs.message, text) def WriteCmdLog(self, text, pid=None, notification=Notification.MAKE_VISIBLE): if pid: text = "(" + str(pid) + ") " + text - self._write(grass.message, text) + self._write(gs.message, text) def WriteWarning(self, text): - self._write(grass.warning, text) + self._write(gs.warning, text) def WriteError(self, text): - self._write(grass.error, text) + self._write(gs.error, text) def _write(self, function, text): orig = os.getenv("GRASS_MESSAGE_FORMAT") diff --git a/gui/wxpython/core/globalvar.py b/gui/wxpython/core/globalvar.py index 2ada52b76c3..60fdf7077ba 100644 --- a/gui/wxpython/core/globalvar.py +++ b/gui/wxpython/core/globalvar.py @@ -230,11 +230,10 @@ def UpdateGRASSAddOnCommands(eList=None): and name not in grassScripts[ext] ): grassScripts[ext].append(name) - else: - if fname not in grassCmd: - grassCmd.add(fname) - Debug.msg(3, "AddOn commands: %s", fname) - nCmd += 1 + elif fname not in grassCmd: + grassCmd.add(fname) + Debug.msg(3, "AddOn commands: %s", fname) + nCmd += 1 Debug.msg(1, "Number of GRASS AddOn commands: %d", nCmd) @@ -251,7 +250,7 @@ def UpdateGRASSAddOnCommands(eList=None): hasAgw = CheckWxVersion([2, 8, 11, 0]) wxPythonPhoenix = CheckWxPhoenix() -gtk3 = True if "gtk3" in wx.PlatformInfo else False +gtk3 = "gtk3" in wx.PlatformInfo """@Add GUIDIR/scripts into path""" os.environ["PATH"] = os.path.join(GUIDIR, "scripts") + os.pathsep + os.environ["PATH"] diff --git a/gui/wxpython/core/render.py b/gui/wxpython/core/render.py index 40cd82defc2..6e74ade9dc1 100644 --- a/gui/wxpython/core/render.py +++ b/gui/wxpython/core/render.py @@ -22,6 +22,7 @@ """ import os +from pathlib import Path import sys import glob import math @@ -263,14 +264,13 @@ def GetName(self, fullyQualified=True): """ if fullyQualified: return self.name - else: - if "@" in self.name: - return { - "name": self.name.split("@")[0], - "mapset": self.name.split("@")[1], - } - else: - return {"name": self.name, "mapset": ""} + + if "@" in self.name: + return { + "name": self.name.split("@")[0], + "mapset": self.name.split("@")[1], + } + return {"name": self.name, "mapset": ""} def GetRenderedSize(self): """Get currently rendered size of layer as tuple, None if not rendered""" @@ -725,10 +725,9 @@ def OnRenderDone(self, env): continue if os.path.isfile(layer._legrow) and not layer.hidden: - with open(layer._legrow) as infile: - line = infile.read() - outfile.write(line) - new_legend.append(line) + line = Path(layer._legrow).read_text() + outfile.write(line) + new_legend.append(line) self._rendering = False if wx.IsBusy(): @@ -882,8 +881,8 @@ def _projInfo(self): for line in ret.splitlines(): if ":" in line: - key, val = map(lambda x: x.strip(), line.split(":", 1)) - if key in {"units"}: + key, val = (x.strip() for x in line.split(":", 1)) + if key == "units": val = val.lower() projinfo[key] = val elif "XY location (unprojected)" in line: @@ -908,7 +907,7 @@ def GetWindow(self): % {"file": filename, "ret": e} ) - for line in windfile.readlines(): + for line in windfile: line = line.strip() try: key, value = line.split(":", 1) diff --git a/gui/wxpython/core/settings.py b/gui/wxpython/core/settings.py index a4f2b60e3fd..45620220aed 100644 --- a/gui/wxpython/core/settings.py +++ b/gui/wxpython/core/settings.py @@ -951,7 +951,7 @@ def _readLegacyFile(self, settings=None): try: line = "" - for line in fd.readlines(): + for line in fd: line = line.rstrip("%s" % os.linesep) group, key = line.split(self.sep)[0:2] kv = line.split(self.sep)[2:] @@ -1032,7 +1032,7 @@ def _parseValue(self, value, read=False): value = float(value) except ValueError: pass - else: # -> write settings + else: # -> write settings # noqa: PLR5501 if isinstance(value, type(())): # -> color value = str(value[0]) + ":" + str(value[1]) + ":" + str(value[2]) @@ -1062,13 +1062,13 @@ def Get(self, group, key=None, subkey=None, settings_type="user"): if subkey is None: if key is None: return settings[group] - else: - return settings[group][key] - else: - if isinstance(subkey, tuple) or isinstance(subkey, list): - return settings[group][key][subkey[0]][subkey[1]] - else: - return settings[group][key][subkey] + + return settings[group][key] + + if isinstance(subkey, (list, tuple)): + return settings[group][key][subkey[0]][subkey[1]] + + return settings[group][key][subkey] except KeyError: print( @@ -1099,13 +1099,16 @@ def Set(self, group, value, key=None, subkey=None, settings_type="user"): if subkey is None: if key is None: settings[group] = value - else: - settings[group][key] = value - else: - if isinstance(subkey, tuple) or isinstance(subkey, list): - settings[group][key][subkey[0]][subkey[1]] = value - else: - settings[group][key][subkey] = value + return + settings[group][key] = value + return + + if isinstance(subkey, (list, tuple)): + settings[group][key][subkey[0]][subkey[1]] = value + return + settings[group][key][subkey] = value + return + except KeyError: raise GException( "%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey) @@ -1221,14 +1224,15 @@ def GetDisplayVectSettings(): else: settings.append("fcolor=none") - settings.append( - "width=%s" % UserSettings.Get(group="vectorLayer", key="line", subkey="width") - ) - settings.append( - "icon=%s" % UserSettings.Get(group="vectorLayer", key="point", subkey="symbol") - ) - settings.append( - "size=%s" % UserSettings.Get(group="vectorLayer", key="point", subkey="size") + settings.extend( + ( + "width=%s" + % UserSettings.Get(group="vectorLayer", key="line", subkey="width"), + "icon=%s" + % UserSettings.Get(group="vectorLayer", key="point", subkey="symbol"), + "size=%s" + % UserSettings.Get(group="vectorLayer", key="point", subkey="size"), + ) ) types = [] for ftype in ["point", "line", "boundary", "centroid", "area", "face"]: diff --git a/gui/wxpython/core/toolboxes.py b/gui/wxpython/core/toolboxes.py index 1d58d59f867..2fca91f8a90 100644 --- a/gui/wxpython/core/toolboxes.py +++ b/gui/wxpython/core/toolboxes.py @@ -13,6 +13,7 @@ """ import os +from pathlib import Path import sys import copy import shutil @@ -82,7 +83,7 @@ def getMessages(): def clearMessages(): - del _MESSAGES[:] + _MESSAGES.clear() def _debug(level, message): @@ -342,13 +343,12 @@ def _indent(elem, level=0): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i - for elem in elem: - _indent(elem, level + 1) + for _elem in elem: + _indent(_elem, level + 1) if not elem.tail or not elem.tail.strip(): elem.tail = i - else: - if level and (not elem.tail or not elem.tail.strip()): - elem.tail = i + elif level and (not elem.tail or not elem.tail.strip()): + elem.tail = i def expandAddons(tree): @@ -846,8 +846,7 @@ def module_test(): return 0 menudataFile = "data/test_toolboxes_menudata_ref.xml" - with open(menudataFile) as correctMenudata: - correct = str(correctMenudata.read()) + correct = str(Path(menudataFile).read_text()) import difflib diff --git a/gui/wxpython/core/treemodel.py b/gui/wxpython/core/treemodel.py index 4c5de36f701..3bcbd6c6ae2 100644 --- a/gui/wxpython/core/treemodel.py +++ b/gui/wxpython/core/treemodel.py @@ -95,7 +95,7 @@ def AppendNode(self, parent, **kwargs): def SearchNodes(self, parent=None, **kwargs): """Search nodes according to specified attributes.""" nodes = [] - parent = parent if parent else self.root + parent = parent or self.root self._searchNodes(node=parent, foundNodes=nodes, **kwargs) return nodes @@ -291,7 +291,7 @@ class ModuleNode(DictNode): def __init__(self, label=None, data=None): super().__init__(data=data) - self._label = label if label else "" + self._label = label or "" if not data: self.data = {} @@ -322,11 +322,10 @@ def match(self, key, value, case_sensitive=False): # start supported but unused, so testing last if value in text or value == "*": return True - else: + elif value.lower() in text.lower() or value == "*": # this works fully only for English and requires accents # to be exact match (even Python 3 casefold() does not help) - if value.lower() in text.lower() or value == "*": - return True + return True return False diff --git a/gui/wxpython/core/units.py b/gui/wxpython/core/units.py index 3947d205760..46b8f91266b 100644 --- a/gui/wxpython/core/units.py +++ b/gui/wxpython/core/units.py @@ -110,7 +110,7 @@ def ConvertValue(value, type, units): f = 6.21371192237334e-4 elif units == "ft": f = 3.28083989501312 - else: # -> area + else: # -> area # noqa: PLR5501 if units == "me": f = 1.0 elif units == "km": diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py index 58faad45253..5e52fc0532d 100644 --- a/gui/wxpython/core/utils.py +++ b/gui/wxpython/core/utils.py @@ -100,7 +100,7 @@ def GetLayerNameFromCmd(dcmd, fullyQualified=False, param=None, layerType=None): if len(dcmd) < 1: return mapname, False - if "d.grid" == dcmd[0]: + if dcmd[0] == "d.grid": mapname = "grid" elif "d.geodesic" in dcmd[0]: mapname = "geodesic" @@ -288,7 +288,7 @@ def ListOfMapsets(get="ordered"): :return: list of mapsets :return: [] on error """ - if get == "all" or get == "ordered": + if get in {"all", "ordered"}: ret = RunCommand("g.mapsets", read=True, quiet=True, flags="l", sep="newline") if not ret: return [] @@ -297,7 +297,7 @@ def ListOfMapsets(get="ordered"): if get == "all": return mapsets_all - if get == "accessible" or get == "ordered": + if get in {"accessible", "ordered"}: ret = RunCommand("g.mapsets", read=True, quiet=True, flags="p", sep="newline") if not ret: return [] @@ -572,17 +572,14 @@ def GetListOfLocations(dbase): """ listOfLocations = [] - try: - for location in glob.glob(os.path.join(dbase, "*")): - try: - if os.path.join(location, "PERMANENT") in glob.glob( - os.path.join(location, "*") - ): - listOfLocations.append(os.path.basename(location)) - except: - pass - except (UnicodeEncodeError, UnicodeDecodeError) as e: - raise e + for location in glob.glob(os.path.join(dbase, "*")): + try: + if os.path.join(location, "PERMANENT") in glob.glob( + os.path.join(location, "*") + ): + listOfLocations.append(os.path.basename(location)) + except: + pass ListSortLower(listOfLocations) @@ -662,7 +659,7 @@ def _parseFormats(output, writableOnly=False): patt = re.compile(r"\(rw\+?\)$", re.IGNORECASE) for line in output.splitlines(): - key, name = map(lambda x: x.strip(), line.strip().split(":", 1)) + key, name = (x.strip() for x in line.strip().split(":", 1)) if writableOnly and not patt.search(key): continue @@ -843,10 +840,10 @@ def StoreEnvVariable(key, value=None, envFile=None): except OSError as e: sys.stderr.write(_("Unable to open file '%s'\n") % envFile) return - for line in fd.readlines(): + for line in fd: line = line.rstrip(os.linesep) try: - k, v = map(lambda x: x.strip(), line.split(" ", 1)[1].split("=", 1)) + k, v = (x.strip() for x in line.split(" ", 1)[1].split("=", 1)) except Exception as e: sys.stderr.write( _("%s: line skipped - unable to parse '%s'\nReason: %s\n") @@ -1182,8 +1179,7 @@ def unregisterPid(pid): def get_shell_pid(env=None): """Get shell PID from the GIS environment or None""" try: - shell_pid = int(grass.gisenv(env=env)["PID"]) - return shell_pid + return int(grass.gisenv(env=env)["PID"]) except (KeyError, ValueError) as error: Debug.msg( 1, "No PID for GRASS shell (assuming no shell running): {}".format(error) diff --git a/gui/wxpython/core/watchdog.py b/gui/wxpython/core/watchdog.py index 06cf8f3d4a5..9315a1010d6 100644 --- a/gui/wxpython/core/watchdog.py +++ b/gui/wxpython/core/watchdog.py @@ -68,7 +68,7 @@ def on_modified(self, event): time.sleep(0.1) with open(event.src_path, "r") as f: gisrc = {} - for line in f.readlines(): + for line in f: key, val = line.split(":") gisrc[key.strip()] = val.strip() new = os.path.join( @@ -94,9 +94,7 @@ def __init__(self, patterns, element, event_handler): self.event_handler = event_handler def on_created(self, event): - if ( - self.element == "vector" or self.element == "raster_3d" - ) and not event.is_directory: + if (self.element in {"vector", "raster_3d"}) and not event.is_directory: return evt = updateMapset( src_path=event.src_path, @@ -107,9 +105,7 @@ def on_created(self, event): wx.PostEvent(self.event_handler, evt) def on_deleted(self, event): - if ( - self.element == "vector" or self.element == "raster_3d" - ) and not event.is_directory: + if (self.element in {"vector", "raster_3d"}) and not event.is_directory: return evt = updateMapset( src_path=event.src_path, @@ -120,9 +116,7 @@ def on_deleted(self, event): wx.PostEvent(self.event_handler, evt) def on_moved(self, event): - if ( - self.element == "vector" or self.element == "raster_3d" - ) and not event.is_directory: + if (self.element in {"vector", "raster_3d"}) and not event.is_directory: return evt = updateMapset( src_path=event.src_path, diff --git a/gui/wxpython/core/workspace.py b/gui/wxpython/core/workspace.py index 12fd08247a9..7e5f85d6649 100644 --- a/gui/wxpython/core/workspace.py +++ b/gui/wxpython/core/workspace.py @@ -92,9 +92,7 @@ def __filterValue(self, value): :param value: """ value = value.replace("<", "<") - value = value.replace(">", ">") - - return value + return value.replace(">", ">") def __getNodeText(self, node, tag, default=""): """Get node text""" @@ -1043,9 +1041,7 @@ def __filterValue(self, value): """Make value XML-valid""" value = value.replace("<", "<") value = value.replace(">", ">") - value = value.replace("&", "&") - - return value + return value.replace("&", "&") def __writeLayer(self, mapTree, item): """Write bunch of layers to GRASS Workspace XML file""" @@ -1757,7 +1753,7 @@ def read(self, parent): return [] line_id = 1 - for line in file.readlines(): + for line in file: self.process_line(line.rstrip("\n"), line_id) line_id += 1 diff --git a/gui/wxpython/datacatalog/dialogs.py b/gui/wxpython/datacatalog/dialogs.py index 5e463e83543..aef9aead7bd 100644 --- a/gui/wxpython/datacatalog/dialogs.py +++ b/gui/wxpython/datacatalog/dialogs.py @@ -210,13 +210,17 @@ def _estimateResampling(self): def OnReproject(self, event): cmd = [] if self.etype == "raster": - cmd.append("r.proj") - cmd.append("dbase=" + self.iGisdbase) - cmd.append("project=" + self.iLocation) - cmd.append("mapset=" + self.iMapset) - cmd.append("input=" + self.iLayer) - cmd.append("output=" + self.oLayer) - cmd.append("method=" + self.resampling.GetStringSelection()) + cmd.extend( + ( + "r.proj", + "dbase=" + self.iGisdbase, + "project=" + self.iLocation, + "mapset=" + self.iMapset, + "input=" + self.iLayer, + "output=" + self.oLayer, + "method=" + self.resampling.GetStringSelection(), + ) + ) self.oEnv["GRASS_REGION"] = region_env( n=self.params["n"], @@ -228,13 +232,17 @@ def OnReproject(self, event): env=self.oEnv, ) else: - cmd.append("v.proj") - cmd.append("dbase=" + self.iGisdbase) - cmd.append("project=" + self.iLocation) - cmd.append("mapset=" + self.iMapset) - cmd.append("input=" + self.iLayer) - cmd.append("output=" + self.oLayer) - cmd.append("smax=" + self.vsplit.GetValue()) + cmd.extend( + ( + "v.proj", + "dbase=" + self.iGisdbase, + "project=" + self.iLocation, + "mapset=" + self.iMapset, + "input=" + self.iLayer, + "output=" + self.oLayer, + "smax=" + self.vsplit.GetValue(), + ) + ) self._giface.RunCmd( cmd, diff --git a/gui/wxpython/datacatalog/g.gui.datacatalog.py b/gui/wxpython/datacatalog/g.gui.datacatalog.py index 3241398bb09..d9dab11d095 100644 --- a/gui/wxpython/datacatalog/g.gui.datacatalog.py +++ b/gui/wxpython/datacatalog/g.gui.datacatalog.py @@ -25,11 +25,11 @@ # % keyword: map management # %end -import grass.script as gscript +import grass.script as gs def main(): - options, flags = gscript.parser() + options, flags = gs.parser() # import wx only after running parser # to avoid issues when only interface is needed diff --git a/gui/wxpython/datacatalog/tree.py b/gui/wxpython/datacatalog/tree.py index f9c3b0a827b..9ea22c1c327 100644 --- a/gui/wxpython/datacatalog/tree.py +++ b/gui/wxpython/datacatalog/tree.py @@ -64,7 +64,7 @@ from grass.pydispatch.signal import Signal -import grass.script as gscript +import grass.script as gs from grass.script import gisenv from grass.grassdb.data import map_exists from grass.grassdb.checks import ( @@ -79,14 +79,14 @@ def getLocationTree(gisdbase, location, queue, mapsets=None, lazy=False): """Creates dictionary with mapsets, elements, layers for given location. Returns tuple with the dictionary and error (or None)""" - tmp_gisrc_file, env = gscript.create_environment(gisdbase, location, "PERMANENT") + tmp_gisrc_file, env = gs.create_environment(gisdbase, location, "PERMANENT") env["GRASS_SKIP_MAPSET_OWNER_CHECK"] = "1" maps_dict = {} elements = ["raster", "raster_3d", "vector"] try: if not mapsets: - mapsets = gscript.read_command( + mapsets = gs.read_command( "g.mapsets", flags="l", separator="comma", quiet=True, env=env ).strip() except CalledModuleError: @@ -96,7 +96,7 @@ def getLocationTree(gisdbase, location, queue, mapsets=None, lazy=False): _("Failed to read mapsets from project <{l}>.").format(l=location), ) ) - gscript.try_remove(tmp_gisrc_file) + gs.try_remove(tmp_gisrc_file) return else: mapsets = mapsets.split(",") @@ -107,7 +107,7 @@ def getLocationTree(gisdbase, location, queue, mapsets=None, lazy=False): queue.put((maps_dict, None)) return try: - maplist = gscript.read_command( + maplist = gs.read_command( "g.list", flags="mt", type=elements, @@ -122,7 +122,7 @@ def getLocationTree(gisdbase, location, queue, mapsets=None, lazy=False): _("Failed to read maps from project <{l}>.").format(l=location), ) ) - gscript.try_remove(tmp_gisrc_file) + gs.try_remove(tmp_gisrc_file) return else: # fill dictionary @@ -134,7 +134,7 @@ def getLocationTree(gisdbase, location, queue, mapsets=None, lazy=False): maps_dict[mapset].append({"name": name, "type": ltype}) queue.put((maps_dict, None)) - gscript.try_remove(tmp_gisrc_file) + gs.try_remove(tmp_gisrc_file) class NameEntryDialog(TextEntryDialog): @@ -181,7 +181,7 @@ def __init__(self, data=None): def label(self): data = self.data if data["type"] == "mapset": - owner = data["owner"] if data["owner"] else _("name unknown") + owner = data["owner"] or _("name unknown") if data["current"]: return _("{name} (current)").format(**data) elif data["is_different_owner"] and data["lock"]: @@ -254,7 +254,7 @@ def __init__( self.current_location_node = None self.current_mapset_node = None self.UpdateCurrentDbLocationMapsetNode() - self._lastWatchdogUpdate = gscript.clock() + self._lastWatchdogUpdate = gs.clock() self._updateMapsetWhenIdle = None # mapset watchdog @@ -359,8 +359,7 @@ def _getValidSavedGrassDBs(self): dbs = UserSettings.Get( group="datacatalog", key="grassdbs", subkey="listAsString" ) - dbs = [db for db in dbs.split(",") if os.path.isdir(db)] - return dbs + return [db for db in dbs.split(",") if os.path.isdir(db)] def _saveGrassDBs(self): """Save current grass dbs in tree to settings""" @@ -619,7 +618,7 @@ def _onUpdateMapsetWhenIdle(self, event): def _onWatchdogMapsetReload(self, event_path): """Reload mapset node associated with watchdog event. Check if events come to quickly and skip them.""" - time = gscript.clock() + time = gs.clock() time_diff = time - self._lastWatchdogUpdate self._lastWatchdogUpdate = time if (time_diff) < 0.5: @@ -719,7 +718,7 @@ def _quickLoading(self): something when loading for the first time""" if self._model.root.children: return - gisenv = gscript.gisenv() + gisenv = gs.gisenv() for grassdatabase in self.grassdatabases: grassdb_node = self._model.AppendNode( parent=self._model.root, data={"type": "grassdb", "name": grassdatabase} @@ -910,7 +909,7 @@ def OnDoubleClick(self, node): def ExpandCurrentLocation(self): """Expand current location""" - location = gscript.gisenv()["LOCATION_NAME"] + location = gs.gisenv()["LOCATION_NAME"] item = self._model.SearchNodes(name=location, type="location") if item: self.Select(item[0], select=True) @@ -988,7 +987,7 @@ def SetRestriction(self, restrict): self._restricted = restrict def _runCommand(self, prog, **kwargs): - cmdString = " ".join(gscript.make_command(prog, **kwargs)) + cmdString = " ".join(gs.make_command(prog, **kwargs)) ret = RunCommand(prog, parent=self, **kwargs) return ret, cmdString @@ -1026,7 +1025,7 @@ def OnCopyMap(self, event): def OnRenameMap(self, event): """Rename layer with dialog""" old_name = self.selected_layer[0].data["name"] - gisrc, env = gscript.create_environment( + gisrc, env = gs.create_environment( self.selected_grassdb[0].data["name"], self.selected_location[0].data["name"], self.selected_mapset[0].data["name"], @@ -1227,7 +1226,7 @@ def OnEditLabel(self, node, event): def Rename(self, old, new): """Rename layer""" string = old + "," + new - gisrc, env = gscript.create_environment( + gisrc, env = gs.create_environment( self.selected_grassdb[0].data["name"], self.selected_location[0].data["name"], self.selected_mapset[0].data["name"], @@ -1240,7 +1239,7 @@ def Rename(self, old, new): renamed, cmd = self._runCommand("g.rename", raster=string, env=env) else: renamed, cmd = self._runCommand("g.rename", raster3d=string, env=env) - gscript.try_remove(gisrc) + gs.try_remove(gisrc) if renamed == 0: self.showNotification.emit(message=_("{cmd} -- completed").format(cmd=cmd)) Debug.msg(1, "LAYER RENAMED TO: " + new) @@ -1264,12 +1263,12 @@ def OnPasteMap(self, event): return for i in range(len(self.copy_layer)): - gisrc, env = gscript.create_environment( + gisrc, env = gs.create_environment( self.selected_grassdb[0].data["name"], self.selected_location[0].data["name"], self.selected_mapset[0].data["name"], ) - gisrc2, env2 = gscript.create_environment( + gisrc2, env2 = gs.create_environment( self.copy_grassdb[i].data["name"], self.copy_location[i].data["name"], self.copy_mapset[i].data["name"], @@ -1294,25 +1293,24 @@ def OnPasteMap(self, event): if not new_name: return # within one location, different mapsets - else: - if map_exists( - new_name, - element=self.copy_layer[i].data["type"], + elif map_exists( + new_name, + element=self.copy_layer[i].data["type"], + env=env, + mapset=self.selected_mapset[0].data["name"], + ): + new_name = self._getNewMapName( + _("New name for <{n}>").format( + n=self.copy_layer[i].data["name"] + ), + _("Select new name"), + self.copy_layer[i].data["name"], env=env, mapset=self.selected_mapset[0].data["name"], - ): - new_name = self._getNewMapName( - _("New name for <{n}>").format( - n=self.copy_layer[i].data["name"] - ), - _("Select new name"), - self.copy_layer[i].data["name"], - env=env, - mapset=self.selected_mapset[0].data["name"], - element=self.copy_layer[i].data["type"], - ) - if not new_name: - return + element=self.copy_layer[i].data["type"], + ) + if not new_name: + return string = ( self.copy_layer[i].data["name"] @@ -1355,8 +1353,8 @@ def OnPasteMap(self, event): action="new", ) - gscript.try_remove(gisrc) - gscript.try_remove(gisrc2) + gs.try_remove(gisrc) + gs.try_remove(gisrc2) # expand selected mapset else: if self.copy_layer[i].data["type"] == "raster_3d": @@ -1423,8 +1421,8 @@ def _onDoneReprojection( ) if not cMode: self._removeMapAfterCopy(cLayer, cMapset, iEnv) - gscript.try_remove(iGisrc) - gscript.try_remove(oGisrc) + gs.try_remove(iGisrc) + gs.try_remove(oGisrc) self.ExpandNode(sMapset, recursive=True) def _removeMapAfterCopy(self, cLayer, cMapset, env): @@ -1526,7 +1524,7 @@ def OnDeleteMap(self, event): label = _("Deleting {name}...").format(name=names) self.showNotification.emit(message=label) for i in range(len(self.selected_layer)): - gisrc, env = gscript.create_environment( + gisrc, env = gs.create_environment( self.selected_grassdb[i].data["name"], self.selected_location[i].data["name"], self.selected_mapset[i].data["name"], @@ -1538,7 +1536,7 @@ def OnDeleteMap(self, event): name=self.selected_layer[i].data["name"], env=env, ) - gscript.try_remove(gisrc) + gs.try_remove(gisrc) if removed == 0: self._giface.grassdbChanged.emit( grassdb=self.selected_grassdb[i].data["name"], @@ -1886,7 +1884,7 @@ def OnMetadata(self, event): """Show metadata of any raster/vector/3draster""" def done(event): - gscript.try_remove(event.userData) + gs.try_remove(event.userData) for i in range(len(self.selected_layer)): if self.selected_layer[i].data["type"] == "raster": @@ -1903,7 +1901,7 @@ def done(event): ) ) - gisrc, env = gscript.create_environment( + gisrc, env = gs.create_environment( self.selected_grassdb[i].data["name"], self.selected_location[i].data["name"], self.selected_mapset[i].data["name"], @@ -2092,10 +2090,8 @@ def _popupMenuLayer(self): if not isinstance(self._giface, StandaloneGrassInterface): if all( - [ - each.data["name"] == genv["LOCATION_NAME"] - for each in self.selected_location - ] + each.data["name"] == genv["LOCATION_NAME"] + for each in self.selected_location ): if len(self.selected_layer) > 1: item = wx.MenuItem(menu, wx.ID_ANY, _("&Display layers")) diff --git a/gui/wxpython/dbmgr/base.py b/gui/wxpython/dbmgr/base.py index d0af1b18a0a..5aa5011ce9a 100644 --- a/gui/wxpython/dbmgr/base.py +++ b/gui/wxpython/dbmgr/base.py @@ -50,7 +50,7 @@ import wx.lib.flatnotebook as FN import wx.lib.scrolledpanel as scrolled -import grass.script as grass +import grass.script as gs from grass.script.utils import decode from dbmgr.sqlbuilder import SQLBuilderSelect, SQLBuilderUpdate @@ -783,8 +783,8 @@ def __init__( # the current mapset mapInfo = None if self.dbMgrData["vectName"]: - mapInfo = grass.find_file(name=self.dbMgrData["vectName"], element="vector") - if not mapInfo or mapInfo["mapset"] != grass.gisenv()["MAPSET"]: + mapInfo = gs.find_file(name=self.dbMgrData["vectName"], element="vector") + if not mapInfo or mapInfo["mapset"] != gs.gisenv()["MAPSET"]: self.dbMgrData["editable"] = False else: self.dbMgrData["editable"] = True @@ -818,8 +818,8 @@ def ChangeVectorMap(self, vectorName): # vector attributes can be changed only if vector map is in # the current mapset - mapInfo = grass.find_file(name=self.dbMgrData["vectName"], element="vector") - if not mapInfo or mapInfo["mapset"] != grass.gisenv()["MAPSET"]: + mapInfo = gs.find_file(name=self.dbMgrData["vectName"], element="vector") + if not mapInfo or mapInfo["mapset"] != gs.gisenv()["MAPSET"]: self.dbMgrData["editable"] = False else: self.dbMgrData["editable"] = True @@ -2165,11 +2165,10 @@ def OnApplySqlStatement(self, event): # sort by key column if sql and "order by" in sql.lower(): pass # don't order by key column + elif keyColumn > -1: + listWin.SortListItems(col=keyColumn, ascending=True) else: - if keyColumn > -1: - listWin.SortListItems(col=keyColumn, ascending=True) - else: - listWin.SortListItems(col=0, ascending=True) + listWin.SortListItems(col=0, ascending=True) wx.EndBusyCursor() @@ -3117,12 +3116,12 @@ def __init__(self, parent, id, parentDialog, style=wx.BK_DEFAULT): # get default values # self.defaultConnect = {} - genv = grass.gisenv() - vectMap = grass.find_file( + genv = gs.gisenv() + vectMap = gs.find_file( name=vectName, element="vector", ) - vectGisrc, vectEnv = grass.create_environment( + vectGisrc, vectEnv = gs.create_environment( gisdbase=genv["GISDBASE"], location=genv["LOCATION_NAME"], mapset=vectMap["mapset"], @@ -3134,7 +3133,7 @@ def __init__(self, parent, id, parentDialog, style=wx.BK_DEFAULT): read=True, quiet=True, ) - grass.utils.try_remove(vectGisrc) + gs.utils.try_remove(vectGisrc) for line in connect.splitlines(): item, value = line.split(":", 1) diff --git a/gui/wxpython/dbmgr/dialogs.py b/gui/wxpython/dbmgr/dialogs.py index 5512ca7349c..c5b63d0fe13 100644 --- a/gui/wxpython/dbmgr/dialogs.py +++ b/gui/wxpython/dbmgr/dialogs.py @@ -250,21 +250,19 @@ def GetSQLString(self, updateValues=False): ) sqlCommands.append(None) continue - else: - if self.action == "add": - continue + elif self.action == "add": + continue if newvalue != value: updatedColumns.append(name) if newvalue == "": updatedValues.append("NULL") + elif ctype != str: + updatedValues.append(str(newvalue)) else: - if ctype != str: - updatedValues.append(str(newvalue)) - else: - updatedValues.append( - "'" + newvalue.replace("'", "''") + "'" - ) + updatedValues.append( + "'" + newvalue.replace("'", "''") + "'" + ) columns[name]["values"][idx] = newvalue if self.action != "add" and len(updatedValues) == 0: diff --git a/gui/wxpython/dbmgr/g.gui.dbmgr.py b/gui/wxpython/dbmgr/g.gui.dbmgr.py index 920ffebb7d8..ba96b3d44c1 100755 --- a/gui/wxpython/dbmgr/g.gui.dbmgr.py +++ b/gui/wxpython/dbmgr/g.gui.dbmgr.py @@ -28,11 +28,11 @@ # %option G_OPT_V_MAP # %end -import grass.script as gscript +import grass.script as gs def main(): - options, flags = gscript.parser() + options, flags = gs.parser() import wx @@ -42,13 +42,13 @@ def main(): from dbmgr.manager import AttributeManager - mapName = gscript.find_file(options["map"], element="vector")["fullname"] + mapName = gs.find_file(options["map"], element="vector")["fullname"] if not mapName: - gscript.set_raise_on_error(False) - gscript.fatal(_("Vector map <%s> not found") % options["map"]) + gs.set_raise_on_error(False) + gs.fatal(_("Vector map <%s> not found") % options["map"]) app = wx.App() - gscript.message(_("Loading attribute data for vector map <%s>...") % mapName) + gs.message(_("Loading attribute data for vector map <%s>...") % mapName) f = AttributeManager( parent=None, id=wx.ID_ANY, diff --git a/gui/wxpython/dbmgr/sqlbuilder.py b/gui/wxpython/dbmgr/sqlbuilder.py index 44542c90ded..92867b9ec82 100644 --- a/gui/wxpython/dbmgr/sqlbuilder.py +++ b/gui/wxpython/dbmgr/sqlbuilder.py @@ -45,7 +45,7 @@ StaticBox, ) -import grass.script as grass +import grass.script as gs class SQLBuilder(wx.Frame): @@ -67,9 +67,9 @@ def __init__(self, parent, title, vectmap, modeChoices=[], id=wx.ID_ANY, layer=1 # variables self.vectmap = vectmap # fullname if "@" not in self.vectmap: - self.vectmap = grass.find_file(self.vectmap, element="vector")["fullname"] + self.vectmap = gs.find_file(self.vectmap, element="vector")["fullname"] if not self.vectmap: - grass.fatal(_("Vector map <%s> not found") % vectmap) + gs.fatal(_("Vector map <%s> not found") % vectmap) self.mapname, self.mapset = self.vectmap.split("@", 1) # db info @@ -371,7 +371,7 @@ def OnUniqueValues(self, event, justsample=False): ) if justsample: sql += " LIMIT {}".format(255) - data = grass.db_select( + data = gs.db_select( sql=sql, database=self.database, driver=self.driver, sep="{_sep_}" ) if not data: @@ -454,7 +454,7 @@ def OnAddMark(self, event): elif self.btn_arithmeticpanel and self.btn_arithmeticpanel.IsShown(): btns = self.btn_arithmetic - for key, value in btns.items(): + for value in btns.values(): if event.GetId() == value[1]: mark = value[0] break diff --git a/gui/wxpython/dbmgr/vinfo.py b/gui/wxpython/dbmgr/vinfo.py index 7c3d92dd6c0..afb0a716063 100644 --- a/gui/wxpython/dbmgr/vinfo.py +++ b/gui/wxpython/dbmgr/vinfo.py @@ -22,7 +22,7 @@ from gui_core.wrap import StaticText from core.gcmd import RunCommand, GError from core.settings import UserSettings -import grass.script as grass +import grass.script as gs def GetUnicodeValue(value): @@ -106,12 +106,12 @@ def SelectByPoint(self, queryCoords, qdist): nselected = 0 try: - data = grass.vector_what( + data = gs.vector_what( map=self.map, coord=(float(queryCoords[0]), float(queryCoords[1])), distance=float(qdist), ) - except grass.ScriptError: + except gs.ScriptError: GError( parent=None, message=_( @@ -136,11 +136,10 @@ def SelectByPoint(self, queryCoords, qdist): for key, value in record["Attributes"].items(): if len(value) < 1: value = None + elif self.tables[table][key]["ctype"] != str: + value = self.tables[table][key]["ctype"](value) else: - if self.tables[table][key]["ctype"] != str: - value = self.tables[table][key]["ctype"](value) - else: - value = GetUnicodeValue(value) + value = GetUnicodeValue(value) self.tables[table][key]["values"].append(value) for key, value in record.items(): diff --git a/gui/wxpython/gcp/g.gui.gcp.py b/gui/wxpython/gcp/g.gui.gcp.py index 1c991856c2a..32ef2c4fc0d 100755 --- a/gui/wxpython/gcp/g.gui.gcp.py +++ b/gui/wxpython/gcp/g.gui.gcp.py @@ -36,7 +36,7 @@ import os -import grass.script as gscript +import grass.script as gs def main(): @@ -45,7 +45,7 @@ def main(): .. todo:: use command line options as an alternative to wizard """ - options, flags = gscript.parser() + options, flags = gs.parser() import wx diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index 33696be3b4a..afc3b239037 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -43,7 +43,7 @@ else: from wx import wizard as wiz -import grass.script as grass +import grass.script as gs from core import utils @@ -73,9 +73,7 @@ # # global variables # -global src_map -global tgt_map -global maptype +global maptype, src_map, tgt_map src_map = "" tgt_map = {"raster": "", "vector": ""} @@ -113,7 +111,7 @@ def __init__(self, parent, giface): # # get environmental variables # - self.grassdatabase = grass.gisenv()["GISDBASE"] + self.grassdatabase = gs.gisenv()["GISDBASE"] # # read original environment settings @@ -122,7 +120,7 @@ def __init__(self, parent, giface): self.gisrc_dict = {} try: f = open(self.target_gisrc, "r") - for line in f.readlines(): + for line in f: line = line.replace("\n", "").strip() if len(line) < 1: continue @@ -138,9 +136,7 @@ def __init__(self, parent, giface): # mapset for xy map to georectify self.newmapset = "" - global maptype - global src_map - global tgt_map + global maptype, src_map, tgt_map # src_map = '' # tgt_map = '' @@ -875,8 +871,7 @@ def __init__(self, wizard, parent): def OnSrcSelection(self, event): """Source map to display selected""" - global src_map - global maptype + global maptype, src_map src_map = self.srcselection.GetValue() @@ -912,8 +907,7 @@ def OnTgtVectSelection(self, event): tgt_map["vector"] = self.tgtvectselection.GetValue() def OnPageChanging(self, event=None): - global src_map - global tgt_map + global src_map, tgt_map if event.GetDirection() and (src_map == ""): GMessage( @@ -925,9 +919,7 @@ def OnPageChanging(self, event=None): self.parent.SwitchEnv("target") def OnEnterPage(self, event=None): - global maptype - global src_map - global tgt_map + global maptype, src_map, tgt_map self.srcselection.SetElementList(maptype) @@ -978,7 +970,7 @@ def OnEnterPage(self, event=None): try: with open(vgrpfile) as f: - for vect in f.readlines(): + for vect in f: vect = vect.strip("\n") if len(vect) < 1: continue @@ -1460,11 +1452,10 @@ def SetGCPSatus(self, item, itemIndex): wxPen = "highest" else: wxPen = "default" + elif self.mapcoordlist[key][5] > self.rmsthresh: + wxPen = "highest" else: - if self.mapcoordlist[key][5] > self.rmsthresh: - wxPen = "highest" - else: - wxPen = "default" + wxPen = "default" if itemIndex == self.list.selectedkey: wxPen = "selected" @@ -1616,7 +1607,7 @@ def ReadGCPs(self): f = open(self.file["points"], "r") GCPcnt = 0 - for line in f.readlines(): + for line in f: if line[0] == "#" or line == "": continue line = line.replace("\n", "").strip() @@ -1761,7 +1752,7 @@ def _getOverWriteDialog(self, maptype, overwrite): """ if maptype == "raster": self.grwiz.SwitchEnv("source") - maps = grass.read_command( + maps = gs.read_command( "i.group", flags="gl", group=self.xygroup, @@ -1773,7 +1764,7 @@ def _getOverWriteDialog(self, maptype, overwrite): for map in maps: if map: map_name = map.split("@")[0] + self.extension - found = grass.find_file( + found = gs.find_file( name=map_name, element="cell", mapset=self.currentmapset, @@ -1783,7 +1774,7 @@ def _getOverWriteDialog(self, maptype, overwrite): map_name = ", ".join(found_maps) else: self.grwiz.SwitchEnv("target") - found = grass.find_file( + found = gs.find_file( name=self.outname, element="vector", mapset=self.currentmapset, @@ -1792,7 +1783,7 @@ def _getOverWriteDialog(self, maptype, overwrite): map_name = "<{}>".format(found["name"]) if found["name"] and not overwrite: - overwrite_dlg = wx.MessageDialog( + return wx.MessageDialog( self.GetParent(), message=_( "The {map_type} map {map_name} exists. " @@ -1804,7 +1795,6 @@ def _getOverWriteDialog(self, maptype, overwrite): caption=_("Overwrite?"), style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION, ) - return overwrite_dlg def OnGeorect(self, event): """ @@ -1868,7 +1858,7 @@ def OnGeorect(self, event): f = open(self.file["vgrp"]) vectlist = [] try: - for vect in f.readlines(): + for vect in f: vect = vect.strip("\n") if len(vect) < 1: continue @@ -2366,13 +2356,13 @@ def OnZoomMenuGCP(self, event): def OnSize(self, event): """Adjust Map Windows after GCP Map Display has been resized""" # re-render image on idle - self.resize = grass.clock() + self.resize = gs.clock() super(MapPanel, self).OnSize(event) def OnIdle(self, event): """GCP Map Display resized, adjust Map Windows""" if self.GetMapToolbar(): - if self.resize and self.resize + 0.2 < grass.clock(): + if self.resize and self.resize + 0.2 < gs.clock(): srcwidth, srcheight = self.SrcMapWindow.GetSize() tgtwidth, tgtheight = self.TgtMapWindow.GetSize() srcwidth = (srcwidth + tgtwidth) / 2 @@ -2736,7 +2726,7 @@ def __init__( f = open(self.vgrpfile) try: checked = [] - for line in f.readlines(): + for line in f: line = line.replace("\n", "") if len(line) < 1: continue @@ -2909,10 +2899,14 @@ def GetValues(self, columns=None): except ValueError: return valuelist - valuelist.append(self.xcoord.GetValue()) - valuelist.append(self.ycoord.GetValue()) - valuelist.append(self.ecoord.GetValue()) - valuelist.append(self.ncoord.GetValue()) + valuelist.extend( + ( + self.xcoord.GetValue(), + self.ycoord.GetValue(), + self.ecoord.GetValue(), + self.ncoord.GetValue(), + ) + ) return valuelist @@ -3366,9 +3360,7 @@ def OnExtension(self, event): self.parent.extension = self.ext_txt.GetValue() def UpdateSettings(self): - global src_map - global tgt_map - global maptype + global maptype, src_map, tgt_map layers = None @@ -3545,7 +3537,7 @@ def UpdateSettings(self): self.parent.activemap.SetSelection(0) self.parent.activemap.Enable(False) self.parent.GetMapToolbar().Enable("zoommenu", enable=False) - else: + else: # noqa: PLR5501 if not self.parent.show_target: self.parent.show_target = True self.parent._mgr.GetPane("target").Show() diff --git a/gui/wxpython/gmodeler/canvas.py b/gui/wxpython/gmodeler/canvas.py index ddd21f7a848..ab49ab770d1 100644 --- a/gui/wxpython/gmodeler/canvas.py +++ b/gui/wxpython/gmodeler/canvas.py @@ -167,7 +167,7 @@ def OnLeftClick(self, x, y, keys=0, attachment=0): del self.frame.defineRelation # select object - self._onSelectShape(shape, append=True if keys == 1 else False) + self._onSelectShape(shape, append=keys == 1) if hasattr(shape, "GetLog"): self.log.SetStatusText(shape.GetLog(), 0) diff --git a/gui/wxpython/gmodeler/dialogs.py b/gui/wxpython/gmodeler/dialogs.py index 044dedff680..10729b83289 100644 --- a/gui/wxpython/gmodeler/dialogs.py +++ b/gui/wxpython/gmodeler/dialogs.py @@ -944,15 +944,11 @@ def Populate(self, data): items = self.frame.GetModel().GetItems(objType=ModelAction) if isinstance(self.shape, ModelCondition): if self.GetLabel() == "ElseBlockList": - shapeItems = map( - lambda x: x.GetId(), self.shape.GetItems(items)["else"] - ) + shapeItems = (x.GetId() for x in self.shape.GetItems(items)["else"]) else: - shapeItems = map( - lambda x: x.GetId(), self.shape.GetItems(items)["if"] - ) + shapeItems = (x.GetId() for x in self.shape.GetItems(items)["if"]) else: - shapeItems = map(lambda x: x.GetId(), self.shape.GetItems(items)) + shapeItems = (x.GetId() for x in self.shape.GetItems(items)) else: shapeItems = [] diff --git a/gui/wxpython/gmodeler/g.gui.gmodeler.py b/gui/wxpython/gmodeler/g.gui.gmodeler.py index c2f24752583..01d15afbcfa 100755 --- a/gui/wxpython/gmodeler/g.gui.gmodeler.py +++ b/gui/wxpython/gmodeler/g.gui.gmodeler.py @@ -34,11 +34,11 @@ # % guisection: Model # %end -import grass.script as gscript +import grass.script as gs def main(): - options, flags = gscript.parser() + options, flags = gs.parser() import wx diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 9c4e1cf9899..72e1e0419d3 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -493,7 +493,7 @@ def Validate(self): cmd = action.GetLog(string=False) task = GUI(show=None).ParseCommand(cmd=cmd) - errList += map(lambda x: cmd[0] + ": " + x, task.get_cmd_error()) + errList += (cmd[0] + ": " + x for x in task.get_cmd_error()) # check also variables for opt in cmd[1:]: @@ -695,7 +695,7 @@ def Run(self, log, onDone, parent=None): parent=parent, message=_("Variables below not defined:") + "\n\n" - + "\n".join(map(lambda x: "%s: %s (%s)" % (x[0], x[1], x[2]), err)), + + "\n".join(f"{x[0]}: {x[1]} ({x[2]})" for x in err), ) return @@ -735,9 +735,7 @@ def Run(self, log, onDone, parent=None): # split condition # TODO: this part needs some better solution - condVar, condText = map( - lambda x: x.strip(), re.split(r"\s* in \s*", cond) - ) + condVar, condText = (x.strip() for x in re.split(r"\s* in \s*", cond)) pattern = re.compile("%" + condVar) # for vars()[condVar] in eval(condText): ? vlist = [] @@ -949,12 +947,10 @@ def GetRelations(self, fdir=None): result = [] for rel in self.rels: - if fdir == "from": - if rel.GetFrom() == self: - result.append(rel) - else: - if rel.GetTo() == self: - result.append(rel) + if fdir == "from" and rel.GetFrom() == self: + result.append(rel) + elif rel.GetTo() == self: + result.append(rel) return result @@ -1042,10 +1038,7 @@ def __init__( if cmd: self.task = GUI(show=None).ParseCommand(cmd=cmd) else: - if task: - self.task = task - else: - self.task = None + self.task = task or None self.propWin = None @@ -2029,9 +2022,7 @@ def _filterValue(self, value): :param value: """ value = value.replace("<", "<") - value = value.replace(">", ">") - - return value + return value.replace(">", ">") def _getNodeText(self, node, tag, default=""): """Get node text""" @@ -2166,9 +2157,9 @@ def _processData(self): prompt = param.get("prompt", None) value = self._filterValue(self._getNodeText(param, "value")) - intermediate = False if data.find("intermediate") is None else True + intermediate = data.find("intermediate") is not None - display = False if data.find("display") is None else True + display = data.find("display") is not None rels = [] for rel in data.findall("relation"): @@ -2344,8 +2335,7 @@ def _filterValue(self, value): :param value: string to be escaped as XML :return: a XML-valid string """ - value = saxutils.escape(value) - return value + return saxutils.escape(value) def _header(self): """Write header""" @@ -2668,9 +2658,7 @@ def _writeItem(self, item, ignoreBlock=True, variables={}): value = '"' + value + '"' cond = pattern.sub(value, cond) if isinstance(item, ModelLoop): - condVar, condText = map( - lambda x: x.strip(), re.split(r"\s* in \s*", cond) - ) + condVar, condText = (x.strip() for x in re.split(r"\s* in \s*", cond)) cond = "%sfor %s in " % (" " * self.indent, condVar) if condText[0] == "`" and condText[-1] == "`": task = GUI(show=None).ParseCommand(cmd=utils.split(condText[1:-1])) @@ -3499,21 +3487,21 @@ def cleanup(): r""" %s("g.remove", flags="f", type="raster", name=%s) """ - % (run_command, ",".join(map(lambda x: '"' + x + '"', rast))) + % (run_command, ",".join(f'"{x}"' for x in rast3d)) ) if vect: self.fd.write( r""" %s("g.remove", flags="f", type="vector", name=%s) """ - % (run_command, ",".join(map(lambda x: '"' + x + '"', vect))) + % (run_command, ",".join(('"' + x + '"' for x in vect))) ) if rast3d: self.fd.write( r""" %s("g.remove", flags="f", type="raster_3d", name=%s) """ - % (run_command, ",".join(map(lambda x: '"' + x + '"', rast3d))) + % (run_command, ",".join(f'"{x}"' for x in rast3d)) ) if not rast and not vect and not rast3d: self.fd.write(" pass\n") diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index 6c0c75f5507..05bb71ed7fa 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -1208,8 +1208,7 @@ def _filter(self, data): """Apply filter for strings in data list""" flt_data = [] if len(self.flt_pattern) == 0: - flt_data = data[:] - return flt_data + return data[:] for dt in data: try: @@ -1331,7 +1330,7 @@ def ShowResult(self, group, returnCode, create): label = _("Group <%s> was successfully created.") % group else: label = _("Group <%s> was successfully changed.") % group - else: + else: # noqa: PLR5501 if create: label = _("Creating of new group <%s> failed.") % group else: @@ -1872,8 +1871,7 @@ def __init__( def GetOpacity(self): """Button 'OK' pressed""" # return opacity value - opacity = float(self.value.GetValue()) / 100 - return opacity + return float(self.value.GetValue()) / 100 def OnApply(self, event): self.applyOpacity.emit(value=self.GetOpacity()) @@ -2334,7 +2332,7 @@ def __init__( label = StaticText(self, label=message) sizer.Add(label, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=10) - hyperlinkLabel = hyperlinkLabel if hyperlinkLabel else hyperlink + hyperlinkLabel = hyperlinkLabel or hyperlink hyperlinkCtrl = HyperlinkCtrl( self, id=wx.ID_ANY, diff --git a/gui/wxpython/gui_core/forms.py b/gui/wxpython/gui_core/forms.py index 14b21515478..89aa24c5844 100644 --- a/gui/wxpython/gui_core/forms.py +++ b/gui/wxpython/gui_core/forms.py @@ -322,16 +322,12 @@ def run(self): native = False break # TODO: update only if needed - if native: - if map: - self.data[win.InsertLayers] = {"vector": map} - else: - self.data[win.InsertLayers] = {} + if map: + self.data[win.InsertLayers] = ( + {"vector": map} if native else {"dsn": map.rstrip("@OGR")} + ) else: - if map: - self.data[win.InsertLayers] = {"dsn": map.rstrip("@OGR")} - else: - self.data[win.InsertLayers] = {} + self.data[win.InsertLayers] = {} elif name == "TableSelect": self.data[win.InsertTables] = {"driver": driver, "database": db} @@ -351,17 +347,17 @@ def run(self): "layer": layer, "dbInfo": cparams[map]["dbInfo"], } - else: # table - if driver and db: - self.data[win.GetParent().InsertTableColumns] = { - "table": pTable.get("value"), - "driver": driver, - "database": db, - } - elif pTable: - self.data[win.GetParent().InsertTableColumns] = { - "table": pTable.get("value") - } + # table + elif driver and db: + self.data[win.GetParent().InsertTableColumns] = { + "table": pTable.get("value"), + "driver": driver, + "database": db, + } + elif pTable: + self.data[win.GetParent().InsertTableColumns] = { + "table": pTable.get("value") + } elif name == "SubGroupSelect": self.data[win.Insert] = {"group": p.get("value", "")} @@ -995,7 +991,7 @@ def __init__(self, parent, giface, task, id=wx.ID_ANY, frame=None, *args, **kwar not_hidden = [ p for p in self.task.params + self.task.flags - if not p.get("hidden", False) is True + if p.get("hidden", False) is not True ] self.label_id = [] # wrap titles on resize @@ -1057,7 +1053,7 @@ def __init__(self, parent, giface, task, id=wx.ID_ANY, frame=None, *args, **kwar # flags # visible_flags = [ - f for f in self.task.flags if not f.get("hidden", False) is True + f for f in self.task.flags if f.get("hidden", False) is not True ] for f in visible_flags: # we don't want another help (checkbox appeared in r58783) @@ -1124,7 +1120,7 @@ def __init__(self, parent, giface, task, id=wx.ID_ANY, frame=None, *args, **kwar # parameters # visible_params = [ - p for p in self.task.params if not p.get("hidden", False) is True + p for p in self.task.params if p.get("hidden", False) is not True ] try: @@ -2490,7 +2486,7 @@ def OnCheckItem(index=None, flag=None, event=None): tab[section].SetupScrolling(True, True, 10, 10) tab[section].Layout() minsecsizes = tabsizer[section].GetSize() - maxsizes = list(map(lambda x: max(maxsizes[x], minsecsizes[x]), (0, 1))) + maxsizes = [max(maxsizes[x], minsecsizes[x]) for x in (0, 1)] # TODO: be less arbitrary with these 600 self.panelMinHeight = 100 @@ -2762,14 +2758,12 @@ def OnVerbosity(self, event): verbose = self.FindWindowById(self.task.get_flag("verbose")["wxId"][0]) quiet = self.FindWindowById(self.task.get_flag("quiet")["wxId"][0]) if event.IsChecked(): - if event.GetId() == verbose.GetId(): - if quiet.IsChecked(): - quiet.SetValue(False) - self.task.get_flag("quiet")["value"] = False - else: - if verbose.IsChecked(): - verbose.SetValue(False) - self.task.get_flag("verbose")["value"] = False + if event.GetId() == verbose.GetId() and quiet.IsChecked(): + quiet.SetValue(False) + self.task.get_flag("quiet")["value"] = False + elif verbose.IsChecked(): + verbose.SetValue(False) + self.task.get_flag("verbose")["value"] = False event.Skip() @@ -2925,15 +2919,14 @@ def OnSetValue(self, event): pLayer = self.task.get_param("layer", element="name", raiseError=False) if pLayer: pLayer["value"] = "" + elif isinstance(me, SpinCtrl): + porf["value"] = str(me.GetValue()) + elif isinstance(me, wx.ComboBox): + porf["value"] = me.GetValue() + elif isinstance(me, wx.Choice): + porf["value"] = me.GetStringSelection() else: - if isinstance(me, SpinCtrl): - porf["value"] = str(me.GetValue()) - elif isinstance(me, wx.ComboBox): - porf["value"] = me.GetValue() - elif isinstance(me, wx.Choice): - porf["value"] = me.GetStringSelection() - else: - porf["value"] = me.GetValue() + porf["value"] = me.GetValue() self.OnUpdateValues(event) @@ -3062,8 +3055,7 @@ def AddBitmapToImageList(self, section, imageList): image = wx.Image(iconSectionDict[section]).Scale( 16, 16, wx.IMAGE_QUALITY_HIGH ) - idx = imageList.Add(BitmapFromImage(image)) - return idx + return imageList.Add(BitmapFromImage(image)) return -1 diff --git a/gui/wxpython/gui_core/ghelp.py b/gui/wxpython/gui_core/ghelp.py index 1d0a74d19ad..0602aeaea0c 100644 --- a/gui/wxpython/gui_core/ghelp.py +++ b/gui/wxpython/gui_core/ghelp.py @@ -37,7 +37,7 @@ from wx import AboutDialogInfo from wx import AboutBox -import grass.script as grass +import grass.script as gs from grass.exceptions import CalledModuleError # needed just for testing @@ -111,7 +111,7 @@ def _doLayout(self): def _pageInfo(self): """Info page""" # get version and web site - vInfo = grass.version() + vInfo = gs.version() if not vInfo: sys.stderr.write(_("Unable to get GRASS version\n")) @@ -245,7 +245,7 @@ def _pageInfo(self): pos=(row, 0), flag=wx.ALIGN_RIGHT, ) - self.langUsed = grass.gisenv().get("LANG", None) + self.langUsed = gs.gisenv().get("LANG", None) if not self.langUsed: import locale @@ -329,10 +329,7 @@ def _pageLicense(self): def _pageCitation(self): """Citation information""" try: - # import only when needed - import grass.script as gscript - - text = gscript.read_command("g.version", flags="x") + text = gs.read_command("g.version", flags="x") except CalledModuleError as error: text = _( "Unable to provide citation suggestion," @@ -633,7 +630,7 @@ def _langPanel(self, lang, js): # panel.Collapse(True) pageSizer = wx.BoxSizer(wx.VERTICAL) for k, v in js.items(): - if k != "total" and k != "name": + if k not in {"total", "name"}: box = self._langBox(win, k, v) pageSizer.Add(box, proportion=1, flag=wx.EXPAND | wx.ALL, border=3) @@ -812,7 +809,7 @@ def fillContentsFromFile(self, htmlFile, skipDescription=True): try: contents = [] skip = False - for line in open(htmlFile, "rb").readlines(): + for line in open(htmlFile, "rb"): if "DESCRIPTION" in line: skip = False if not skip: @@ -973,7 +970,7 @@ def ShowAboutDialog(prgName, startYear): def _grassDevTeam(start): try: - end = grass.version()["date"] + end = gs.version()["date"] except KeyError: sys.stderr.write(_("Unable to get GRASS version\n")) diff --git a/gui/wxpython/gui_core/goutput.py b/gui/wxpython/gui_core/goutput.py index b26f6611f3d..6aca497f365 100644 --- a/gui/wxpython/gui_core/goutput.py +++ b/gui/wxpython/gui_core/goutput.py @@ -573,9 +573,8 @@ def AddTextWrapped(self, txt, wrap=None): if wrap: txt = textwrap.fill(txt, wrap) + "\n" - else: - if txt[-1] != "\n": - txt += "\n" + elif txt[-1] != "\n": + txt += "\n" if "\r" in txt: self.linePos = -1 diff --git a/gui/wxpython/gui_core/gselect.py b/gui/wxpython/gui_core/gselect.py index ae2d3669146..215a7bba23d 100644 --- a/gui/wxpython/gui_core/gselect.py +++ b/gui/wxpython/gui_core/gselect.py @@ -54,7 +54,7 @@ import wx.lib.filebrowsebutton as filebrowse -import grass.script as grass +import grass.script as gs from grass.script import task as gtask from grass.exceptions import CalledModuleError @@ -212,7 +212,7 @@ def __init__(self, parent, ftype, **kwargs): def _isElement(self, vectorName): """Check if element should be filtered out""" try: - if int(grass.vector_info_topo(vectorName)[self.ftype]) < 1: + if int(gs.vector_info_topo(vectorName)[self.ftype]) < 1: return False except KeyError: return False @@ -495,7 +495,7 @@ def _getElementList(self, element, mapsets=None, elements=None, exclude=False): :param exclude: True to exclude, False for forcing the list (elements) """ # get current mapset - curr_mapset = grass.gisenv()["MAPSET"] + curr_mapset = gs.gisenv()["MAPSET"] # map element types to g.list types elementdict = { @@ -533,7 +533,7 @@ def _getElementList(self, element, mapsets=None, elements=None, exclude=False): else: filesdict = None else: - filesdict = grass.list_grouped(renamed_elements, check_search_path=False) + filesdict = gs.list_grouped(renamed_elements, check_search_path=False) # add extra items first if self.extraItems: @@ -546,7 +546,7 @@ def _getElementList(self, element, mapsets=None, elements=None, exclude=False): # list of mapsets in current location if mapsets is None: - mapsets = grass.mapsets(search_path=True) + mapsets = gs.mapsets(search_path=True) # current mapset first if curr_mapset in mapsets and mapsets[0] != curr_mapset: @@ -635,7 +635,7 @@ def _addItems(self, elist, elements, mapset, exclude, node): :param exclude: True to exclude, False for forcing the list :param node: parent node """ - elist = grass.naturally_sorted(elist) + elist = gs.naturally_sorted(elist) for elem in elist: if elem != "": fullqElem = elem + "@" + mapset @@ -663,8 +663,7 @@ def AddItem(self, value, mapset=None, node=True, parent=None): data = {"node": node, "mapset": mapset} - item = self.seltree.AppendItem(parent, text=value, data=data) - return item + return self.seltree.AppendItem(parent, text=value, data=data) def OnKeyUp(self, event): """Enables to select items using keyboard @@ -754,14 +753,13 @@ def _selectTreeItem(self, item): if self.multiple: self.value.append(fullName) - else: - if self.nmaps > 1: # see key_desc - if len(self.value) >= self.nmaps: - self.value = [fullName] - else: - self.value.append(fullName) - else: + elif self.nmaps > 1: # see key_desc + if len(self.value) >= self.nmaps: self.value = [fullName] + else: + self.value.append(fullName) + else: + self.value = [fullName] def _onItemConfirmed(self, event): item = event.GetItem() @@ -838,7 +836,7 @@ def _CheckDBConnection(self): # if map is not defined (happens with vnet initialization) or it # doesn't exist try: - self.layers = grass.vector_db(map=self.map, stderr=nuldev) + self.layers = gs.vector_db(map=self.map, stderr=nuldev) except CalledModuleError: return False finally: # always close nuldev @@ -862,7 +860,7 @@ def _DescribeTables(self): self.layers[layer]["database"], ), ) - for item in grass.db_describe( + for item in gs.db_describe( table=self.layers[layer]["table"], driver=self.layers[layer]["driver"], database=self.layers[layer]["database"], @@ -1066,7 +1064,7 @@ def InsertTables(self, driver=None, database=None): items = [] if not driver or not database: - connect = grass.db_connection() + connect = gs.db_connection() driver = connect["driver"] database = connect["database"] @@ -1233,7 +1231,7 @@ def __init__(self, parent, **kwargs): labelText="", dialogTitle=_("Choose GIS Data Directory"), buttonText=_("Browse"), - startDirectory=grass.gisenv()["GISDBASE"], + startDirectory=gs.gisenv()["GISDBASE"], **kwargs, ) @@ -1253,7 +1251,7 @@ def __init__( self.SetName("LocationSelect") if not gisdbase: - self.gisdbase = grass.gisenv()["GISDBASE"] + self.gisdbase = gs.gisenv()["GISDBASE"] else: self.gisdbase = gisdbase @@ -1300,12 +1298,12 @@ def __init__( self.value = "" self.multiple = multiple if not gisdbase: - self.gisdbase = grass.gisenv()["GISDBASE"] + self.gisdbase = gs.gisenv()["GISDBASE"] else: self.gisdbase = gisdbase if not location: - self.location = grass.gisenv()["LOCATION_NAME"] + self.location = gs.gisenv()["LOCATION_NAME"] else: self.location = location @@ -1351,7 +1349,7 @@ def _getMapsets(self): else: mlist = GetListOfMapsets(self.gisdbase, self.location, selectable=False) - gisenv = grass.gisenv() + gisenv = gs.gisenv() if ( self.skipCurrent and gisenv["LOCATION_NAME"] == self.location @@ -1375,7 +1373,7 @@ def Insert(self, group): """Insert subgroups for defined group""" if not group: return - gisenv = grass.gisenv() + gisenv = gs.gisenv() try: name, mapset = group.split("@", 1) except ValueError: @@ -1700,7 +1698,7 @@ def __init__( "v.external.out", parent=self, read=True, - parse=grass.parse_key_val, + parse=gs.parse_key_val, flags="g", ) if current["format"] == "native": @@ -2199,9 +2197,9 @@ def SetDatabase(self, db): if dbNames is not None: self.dbWidgets["choice"].SetItems(sorted(dbNames)) self.dbWidgets["choice"].SetSelection(0) - elif grass.find_program(self._psql, "--help"): + elif gs.find_program(self._psql, "--help"): if not self.dbWidgets["choice"].GetItems(): - p = grass.Popen([self._psql, "-ltA"], stdout=grass.PIPE) + p = gs.Popen([self._psql, "-ltA"], stdout=gs.PIPE) ret = p.communicate()[0] if ret: dbNames = [] @@ -2243,7 +2241,7 @@ def hasRastSameProjAsLocation(dsn, table=None): if "PG:" in dsn: dsn = dsn.replace("PG:", "") - p = grass.Popen( + p = gs.Popen( [ self._psql, "-t", @@ -2252,7 +2250,7 @@ def hasRastSameProjAsLocation(dsn, table=None): "-c", f"SELECT ST_SRID(rast) AS srid FROM {table} WHERE rid=1;", ], - stdout=grass.PIPE, + stdout=gs.PIPE, ) ret, error = p.communicate() if error: @@ -2271,13 +2269,13 @@ def hasRastSameProjAsLocation(dsn, table=None): dsn, conn_param="host", ), - error=grass.utils.decode(error), + error=gs.utils.decode(error), ), ), ) if ret: - raster_srid = grass.utils.decode(ret).replace(os.linesep, "") - location_srid = grass.parse_command("g.proj", flags="g") + raster_srid = gs.utils.decode(ret).replace(os.linesep, "") + location_srid = gs.parse_command("g.proj", flags="g") if raster_srid == location_srid["srid"].split(":")[-1]: projectionMatch = "1" else: @@ -2291,8 +2289,8 @@ def hasRastSameProjAsLocation(dsn, table=None): lines = ret.splitlines() projectionMatch = "0" if lines: - bandNumber, bandType, projectionMatch = map( - lambda x: x.strip(), lines[0].split(",") + bandNumber, bandType, projectionMatch = ( + x.strip() for x in lines[0].split(",") ) return projectionMatch @@ -2321,8 +2319,8 @@ def getProjMatchCaption(projectionMatch): layerId = 1 for line in ret.splitlines(): - layerName, featureType, projectionMatch, geometryColumn = map( - lambda x: x.strip(), line.split(",") + layerName, featureType, projectionMatch, geometryColumn = ( + x.strip() for x in line.split(",") ) projectionMatchCaption = getProjMatchCaption(projectionMatch) grassName = GetValidLayerName(layerName) @@ -2335,52 +2333,43 @@ def getProjMatchCaption(projectionMatch): (layerId, layerName, featureType, int(projectionMatch), grassName) ) layerId += 1 - else: - if self._sourceType == "file": - baseName = os.path.basename(dsn) + elif self._sourceType == "file": + baseName = os.path.basename(dsn) + grassName = GetValidLayerName(baseName.split(".", -1)[0]) + projectionMatch = hasRastSameProjAsLocation(dsn) + projectionMatchCaption = getProjMatchCaption(projectionMatch) + listData.append((layerId, baseName, projectionMatchCaption, grassName)) + data.append((layerId, baseName, int(projectionMatch), grassName)) + elif self._sourceType == "dir": + ext = self.dirWidgets["extension"].GetValue() + for filename in glob.glob( + os.path.join(dsn, "%s") % self._getExtPatternGlob(ext) + ): + baseName = os.path.basename(filename) grassName = GetValidLayerName(baseName.split(".", -1)[0]) - projectionMatch = hasRastSameProjAsLocation(dsn) + projectionMatch = hasRastSameProjAsLocation(filename) projectionMatchCaption = getProjMatchCaption(projectionMatch) listData.append((layerId, baseName, projectionMatchCaption, grassName)) data.append((layerId, baseName, int(projectionMatch), grassName)) - elif self._sourceType == "dir": - ext = self.dirWidgets["extension"].GetValue() - for filename in glob.glob( - os.path.join(dsn, "%s") % self._getExtPatternGlob(ext) - ): - baseName = os.path.basename(filename) - grassName = GetValidLayerName(baseName.split(".", -1)[0]) - projectionMatch = hasRastSameProjAsLocation(filename) - projectionMatchCaption = getProjMatchCaption(projectionMatch) - listData.append( - (layerId, baseName, projectionMatchCaption, grassName) - ) - data.append((layerId, baseName, int(projectionMatch), grassName)) - layerId += 1 - elif ( - self.dbWidgets["format"].GetStringSelection() == "PostGIS Raster driver" - ): - rasters = self._getPGDBRasters(dsn) - for raster in rasters: - grassName = GetValidLayerName(raster) - projectionMatch = hasRastSameProjAsLocation(dsn, table=raster) - projectionMatchCaption = getProjMatchCaption(projectionMatch) - listData.append( - (layerId, raster, projectionMatchCaption, grassName) - ) - data.append((layerId, raster, int(projectionMatch), grassName)) - layerId += 1 - elif self.dbWidgets["format"].GetStringSelection() == "Rasterlite": - rasters = self._getRasterliteDBRasters(dsn) - for raster in rasters: - grassName = GetValidLayerName(raster) - projectionMatch = hasRastSameProjAsLocation(dsn) - projectionMatchCaption = getProjMatchCaption(projectionMatch) - listData.append( - (layerId, raster, projectionMatchCaption, grassName) - ) - data.append((layerId, raster, int(projectionMatch), grassName)) - layerId += 1 + layerId += 1 + elif self.dbWidgets["format"].GetStringSelection() == "PostGIS Raster driver": + rasters = self._getPGDBRasters(dsn) + for raster in rasters: + grassName = GetValidLayerName(raster) + projectionMatch = hasRastSameProjAsLocation(dsn, table=raster) + projectionMatchCaption = getProjMatchCaption(projectionMatch) + listData.append((layerId, raster, projectionMatchCaption, grassName)) + data.append((layerId, raster, int(projectionMatch), grassName)) + layerId += 1 + elif self.dbWidgets["format"].GetStringSelection() == "Rasterlite": + rasters = self._getRasterliteDBRasters(dsn) + for raster in rasters: + grassName = GetValidLayerName(raster) + projectionMatch = hasRastSameProjAsLocation(dsn) + projectionMatchCaption = getProjMatchCaption(projectionMatch) + listData.append((layerId, raster, projectionMatchCaption, grassName)) + data.append((layerId, raster, int(projectionMatch), grassName)) + layerId += 1 # emit signal self.reloadDataRequired.emit(listData=listData, data=data) @@ -2461,17 +2450,15 @@ def OnHelp(self, event): cmd = "v.external.out" else: cmd = "r.external.out" - else: - if self.link: - if self.ogr: - cmd = "v.external" - else: - cmd = "r.external" + elif self.link: + if self.ogr: + cmd = "v.external" else: - if self.ogr: - cmd = "v.in.ogr" - else: - cmd = "r.in.gdal" + cmd = "r.external" + elif self.ogr: + cmd = "v.in.ogr" + else: + cmd = "r.in.gdal" RunCommand("g.manual", entry=cmd) @@ -2518,7 +2505,7 @@ def _getPGDBtables(self, dsn): AND schemaname != 'pg_catalog'; """ # Get tables list - p = grass.Popen( + p = gs.Popen( [ self._psql, "-t", @@ -2527,7 +2514,7 @@ def _getPGDBtables(self, dsn): "-c", f"{tables_list_sql}", ], - stdout=grass.PIPE, + stdout=gs.PIPE, ) ret, error = p.communicate() if error: @@ -2544,12 +2531,12 @@ def _getPGDBtables(self, dsn): dsn, conn_param="host", ), - error=grass.utils.decode(error), + error=gs.utils.decode(error), ), ), ) if ret: - ret = grass.utils.decode(ret) + ret = gs.utils.decode(ret) tables = [i.strip() for i in ret.split(os.linesep) if i] Debug.msg(3, f"GdalSelect._getPGDBtables(): return {tables}") return tables @@ -2599,7 +2586,7 @@ def _getPGDBRasters(self, dsn): field_sep = "," dsn = dsn.replace("PG:", "") - if grass.find_program(self._psql, "--help"): + if gs.find_program(self._psql, "--help"): tables = self._getPGDBtables(dsn) # Get tables columns data types list if tables: @@ -2607,7 +2594,7 @@ def _getPGDBRasters(self, dsn): tables_cols_data_types_sql = self._getPGDBTablesColumnsTypesSql( tables=tables_with_quotes, ) - p = grass.Popen( + p = gs.Popen( [ self._psql, "-t", @@ -2618,7 +2605,7 @@ def _getPGDBRasters(self, dsn): "-c", f"{tables_cols_data_types_sql}", ], - stdout=grass.PIPE, + stdout=gs.PIPE, ) ret, error = p.communicate() if error: @@ -2636,14 +2623,14 @@ def _getPGDBRasters(self, dsn): dsn, conn_param="host", ), - error=grass.utils.decode(error), + error=gs.utils.decode(error), ), ), ) if ret: import re - tables_cols = grass.utils.decode(ret) + tables_cols = gs.utils.decode(ret) rasters_cols = re.findall( rf".*.{raster_col_type}", tables_cols, @@ -2704,9 +2691,9 @@ def __init__( def UpdateItems(self, dbase, location, mapset): """Update list of maps""" if not dbase: - dbase = grass.gisenv()["GISDBASE"] + dbase = gs.gisenv()["GISDBASE"] if not mapset: - mapset = grass.gisenv()["MAPSET"] + mapset = gs.gisenv()["MAPSET"] if self.isRaster: ret = RunCommand( "r.proj", @@ -2888,12 +2875,11 @@ def _onClick(self, event): self.registered = True self._giface.GetMapDisplay().Raise() - else: - if self.mapWin and self.mapWin.UnregisterMouseEventHandler( - wx.EVT_LEFT_DOWN, self._onMapClickHandler - ): - self.registered = False - return + elif self.mapWin and self.mapWin.UnregisterMouseEventHandler( + wx.EVT_LEFT_DOWN, self._onMapClickHandler + ): + self.registered = False + return def drawCleanUp(self): if self.drawMapWin: @@ -3041,27 +3027,22 @@ def _chckMap(self): return False def _onClick(self, evt=None): - if self.task is not None: - if not self._chckMap(): - self.buttonVecSelect.SetValue(False) - return - else: - if not self._isMapSelected(): - self.buttonVecSelect.SetValue(False) + if (self.task is not None and not self._chckMap()) or not self._isMapSelected(): + self.buttonVecSelect.SetValue(False) + return + + if self._vectorSelect is None and self.mapdisp: + if self.buttonVecSelect.IsEnabled(): + switcher = self.mapdisp.GetToolSwitcher() + switcher.ToolChanged(self.buttonVecSelect.GetId()) + + self._vectorSelect = VectorSelectBase(self.mapdisp, self.giface) + if not self.mapdisp.GetWindow().RegisterMouseEventHandler( + wx.EVT_LEFT_DOWN, self._onMapClickHandler, "cross" + ): return - if self._vectorSelect is None: - if self.mapdisp: - if self.buttonVecSelect.IsEnabled(): - switcher = self.mapdisp.GetToolSwitcher() - switcher.ToolChanged(self.buttonVecSelect.GetId()) - - self._vectorSelect = VectorSelectBase(self.mapdisp, self.giface) - if not self.mapdisp.GetWindow().RegisterMouseEventHandler( - wx.EVT_LEFT_DOWN, self._onMapClickHandler, "cross" - ): - return - self.registered = True - self.mapdisp.Raise() + self.registered = True + self.mapdisp.Raise() else: self.OnClose() @@ -3082,16 +3063,10 @@ def _onMapClickHandler(self, event): if event == "unregistered": return - if self.task is None: - if not self._isMapSelected(): - self.OnClose() - else: - self.catsField.SetValue(self._vectorSelect.GetLineStringSelectedCats()) + if (self.task is None and not self._isMapSelected()) or not self._chckMap(): + self.OnClose() else: - if not self._chckMap(): - self.OnClose() - else: - self.catsField.SetValue(self._vectorSelect.GetLineStringSelectedCats()) + self.catsField.SetValue(self._vectorSelect.GetLineStringSelectedCats()) def GetTextWin(self): return self.catsField @@ -3176,7 +3151,7 @@ def _append_mapset_signatures(self, mapset, element, items): sig_list = list_ptr() count = I_signatures_list_by_type(sig_type, mapset, ctypes.byref(sig_list)) for n in range(count): - items.append(grass.decode(sig_list[n])) + items.append(gs.decode(sig_list[n])) I_free_signatures_list(count, ctypes.byref(sig_list)) diff --git a/gui/wxpython/gui_core/mapdisp.py b/gui/wxpython/gui_core/mapdisp.py index e74f526fa71..4fe1c25ac18 100644 --- a/gui/wxpython/gui_core/mapdisp.py +++ b/gui/wxpython/gui_core/mapdisp.py @@ -720,7 +720,7 @@ def SetBindRegions(self, on): self.firstMapWindow.zoomChanged.connect(self.OnZoomChangedFirstMap) else: self.secondMapWindow.zoomChanged.connect(self.OnZoomChangedSecondMap) - else: + else: # noqa: PLR5501 if self.MapWindow == self.firstMapWindow: self.firstMapWindow.zoomChanged.disconnect(self.OnZoomChangedFirstMap) else: diff --git a/gui/wxpython/gui_core/preferences.py b/gui/wxpython/gui_core/preferences.py index 030e0ddba6e..3c3df8e8e42 100644 --- a/gui/wxpython/gui_core/preferences.py +++ b/gui/wxpython/gui_core/preferences.py @@ -42,7 +42,7 @@ import wx.lib.scrolledpanel as SP from grass.pydispatch.signal import Signal -import grass.script as grass +import grass.script as gs from grass.exceptions import OpenError from core import globalvar @@ -1300,7 +1300,7 @@ def _createCmdPage(self, notebook): self.nprocs = TextCtrl( parent=panel, id=wx.ID_ANY, - value=grass.gisenv().get("NPROCS", ""), + value=gs.gisenv().get("NPROCS", ""), validator=IntegerValidator(), name="NumberOfProcs", ) @@ -1324,7 +1324,7 @@ def _createCmdPage(self, notebook): self.memorymb = TextCtrl( parent=panel, id=wx.ID_ANY, - value=grass.gisenv().get("MEMORYMB", ""), + value=gs.gisenv().get("MEMORYMB", ""), validator=IntegerValidator(), name="MemorySizeMB", ) @@ -2288,18 +2288,18 @@ def OnSave(self, event): group="language", key="locale", subkey="lc_all", value=None ) lang = None - env = grass.gisenv() + env = gs.gisenv() # Set gisenv MEMORYMB var value memorydb_gisenv = "MEMORYMB" memorymb = self.memorymb.GetValue() if memorymb: - grass.run_command( + gs.run_command( "g.gisenv", set=f"{memorydb_gisenv}={memorymb}", ) elif env.get(memorydb_gisenv): - grass.run_command( + gs.run_command( "g.gisenv", unset=memorydb_gisenv, ) @@ -2307,12 +2307,12 @@ def OnSave(self, event): nprocs_gisenv = "NPROCS" nprocs = self.nprocs.GetValue() if nprocs: - grass.run_command( + gs.run_command( "g.gisenv", set=f"{nprocs_gisenv}={nprocs}", ) elif env.get(nprocs_gisenv): - grass.run_command( + gs.run_command( "g.gisenv", unset=nprocs_gisenv, ) @@ -2338,7 +2338,7 @@ def __init__( self.all_mapsets_ordered = ListOfMapsets(get="ordered") self.accessible_mapsets = ListOfMapsets(get="accessible") - self.curr_mapset = grass.gisenv()["MAPSET"] + self.curr_mapset = gs.gisenv()["MAPSET"] # make a checklistbox from available mapsets and check those that are # active @@ -2422,7 +2422,7 @@ def LoadData(self): self.InsertColumn(0, _("Mapset")) self.InsertColumn(1, _("Owner")) ### self.InsertColumn(2, _('Group')) - gisenv = grass.gisenv() + gisenv = gs.gisenv() locationPath = os.path.join(gisenv["GISDBASE"], gisenv["LOCATION_NAME"]) for mapset in self.parent.all_mapsets_ordered: diff --git a/gui/wxpython/gui_core/pyedit.py b/gui/wxpython/gui_core/pyedit.py index d590c5fbc8b..9fa75fa74c1 100644 --- a/gui/wxpython/gui_core/pyedit.py +++ b/gui/wxpython/gui_core/pyedit.py @@ -10,6 +10,7 @@ :authors: Martin Landa """ +from pathlib import Path import sys import os import stat @@ -19,7 +20,7 @@ import wx -import grass.script as gscript +import grass.script as gs from grass.script.utils import try_remove # needed just for testing @@ -300,9 +301,7 @@ def _openFile(self, file_path): :return str or None: file content or None """ try: - with open(file_path, "r") as f: - content = f.read() - return content + return Path(file_path).read_text() except PermissionError: GError( message=_( @@ -328,9 +327,8 @@ def _writeFile(self, file_path, content, additional_err_message=""): :return None or True: file written or None """ try: - with open(file_path, "w") as f: - f.write(content) - return True + Path(file_path).write_text(content) + return True except PermissionError: GError( message=_( @@ -356,7 +354,7 @@ def _writeFile(self, file_path, content, additional_err_message=""): def OnRun(self, event): """Run Python script""" if not self.filename: - self.filename = gscript.tempfile() + ".py" + self.filename = gs.tempfile() + ".py" self.tempfile = True file_is_written = self._writeFile( file_path=self.filename, @@ -516,14 +514,15 @@ def OpenRecentFile(self, path, file_exists, file_history): ), parent=self.guiparent, ) - else: - if self.CanReplaceContent(by_message="file"): - self.filename = path - content = self._openFile(file_path=path) - if content: - self.body.SetText(content) - file_history.AddFileToHistory(filename=path) # move up the list - self.tempfile = False + return + + if self.CanReplaceContent(by_message="file"): + self.filename = path + content = self._openFile(file_path=path) + if content: + self.body.SetText(content) + file_history.AddFileToHistory(filename=path) # move up the list + self.tempfile = False def IsEmpty(self): """Check if python script is empty""" @@ -623,7 +622,7 @@ def OnHelp(self, event): # inspired by g.manual but simple not using GRASS_HTML_BROWSER # not using g.manual because it does not show entry = "libpython/script_intro.html" - major, minor, patch = gscript.version()["version"].split(".") + major, minor, patch = gs.version()["version"].split(".") url = "https://grass.osgeo.org/grass%s%s/manuals/%s" % (major, minor, entry) open_url(url) diff --git a/gui/wxpython/gui_core/pystc.py b/gui/wxpython/gui_core/pystc.py index bf268f88f33..00db4d8a0c8 100644 --- a/gui/wxpython/gui_core/pystc.py +++ b/gui/wxpython/gui_core/pystc.py @@ -373,9 +373,8 @@ def Expand(self, line, doExpand, force=False, visLevels=0, level=-1): self.ShowLines(line, line) else: self.HideLines(line, line) - else: - if doExpand: - self.ShowLines(line, line) + elif doExpand: + self.ShowLines(line, line) if level == -1: level = self.GetFoldLevel(line) @@ -388,11 +387,10 @@ def Expand(self, line, doExpand, force=False, visLevels=0, level=-1): self.SetFoldExpanded(line, False) line = self.Expand(line, doExpand, force, visLevels - 1) + elif doExpand and self.GetFoldExpanded(line): + line = self.Expand(line, True, force, visLevels - 1) else: - if doExpand and self.GetFoldExpanded(line): - line = self.Expand(line, True, force, visLevels - 1) - else: - line = self.Expand(line, False, force, visLevels - 1) + line = self.Expand(line, False, force, visLevels - 1) else: line = line + 1 diff --git a/gui/wxpython/gui_core/query.py b/gui/wxpython/gui_core/query.py index 3a250af4d42..0dfd21d8765 100644 --- a/gui/wxpython/gui_core/query.py +++ b/gui/wxpython/gui_core/query.py @@ -127,9 +127,13 @@ def ShowContextMenu(self, node): col1 = "\n".join([val[1] for val in values if val[1]]) col2 = "\n".join([val[0] for val in values if val[0]]) table = "\n".join([val[0] + ": " + val[1] for val in values]) - texts.append((_("Copy from '%s' column") % self._colNames[1], col1)) - texts.append((_("Copy from '%s' column") % self._colNames[0], col2)) - texts.append((_("Copy selected lines"), table)) + texts.extend( + ( + (_("Copy from '%s' column") % self._colNames[1], col1), + (_("Copy from '%s' column") % self._colNames[0], col2), + (_("Copy selected lines"), table), + ) + ) else: label1 = nodes[0].label texts.append((_("Copy '%s'" % self._cutLabel(label1)), label1)) diff --git a/gui/wxpython/gui_core/simplelmgr.py b/gui/wxpython/gui_core/simplelmgr.py index d59a443c9b0..9f03a49396e 100644 --- a/gui/wxpython/gui_core/simplelmgr.py +++ b/gui/wxpython/gui_core/simplelmgr.py @@ -377,31 +377,27 @@ def GetOptData(self, dcmd, layer, params, propwin): def AddRaster(self, name, cmd, hidden, dialog): """Ads new raster layer.""" - layer = self._layerList.AddNewLayer( + return self._layerList.AddNewLayer( name=name, mapType="raster", active=True, cmd=cmd, hidden=hidden ) - return layer def AddRast3d(self, name, cmd, hidden, dialog): """Ads new raster3d layer.""" - layer = self._layerList.AddNewLayer( + return self._layerList.AddNewLayer( name=name, mapType="raster_3d", active=True, cmd=cmd, hidden=hidden ) - return layer def AddVector(self, name, cmd, hidden, dialog): """Ads new vector layer.""" - layer = self._layerList.AddNewLayer( + return self._layerList.AddNewLayer( name=name, mapType="vector", active=True, cmd=cmd, hidden=hidden ) - return layer def AddRGB(self, name, cmd, hidden, dialog): """Ads new vector layer.""" - layer = self._layerList.AddNewLayer( + return self._layerList.AddNewLayer( name=name, mapType="rgb", active=True, cmd=cmd, hidden=hidden ) - return layer def GetLayerInfo(self, layer, key): """Just for compatibility, should be removed in the future""" diff --git a/gui/wxpython/gui_core/toolbars.py b/gui/wxpython/gui_core/toolbars.py index 02e4fdecad5..47c00fd36fc 100644 --- a/gui/wxpython/gui_core/toolbars.py +++ b/gui/wxpython/gui_core/toolbars.py @@ -173,13 +173,10 @@ def EnableLongHelp(self, enable): if isinstance(tool[0], tuple): if tool[0][0] == "": # separator continue - else: - internal_label = tool[0][0] - else: - if tool[0] == "": # separator - continue - else: - internal_label = tool[0] + internal_label = tool[0][0] + elif tool[0] == "": # separator + continue + internal_label = tool[0] label = vars(self.widget)[internal_label] if enable: diff --git a/gui/wxpython/gui_core/treeview.py b/gui/wxpython/gui_core/treeview.py index 01bbe87d493..4c20885599c 100644 --- a/gui/wxpython/gui_core/treeview.py +++ b/gui/wxpython/gui_core/treeview.py @@ -91,8 +91,7 @@ def OnGetItemText(self, index, column=0): """ node = self._model.GetNodeByIndex(index) # remove & because of & needed in menu (&Files) - label = node.label.replace("&", "") - return label + return node.label.replace("&", "") def OnGetChildrenCount(self, index): """Overridden method necessary to communicate with tree model.""" @@ -258,8 +257,7 @@ def OnGetItemText(self, index, column=0): if column > 0: return node.data.get(self._columns[column], "") else: - label = node.label.replace("&", "") - return label + return node.label.replace("&", "") def OnRightClick(self, event): """Select item on right click. diff --git a/gui/wxpython/gui_core/vselect.py b/gui/wxpython/gui_core/vselect.py index 6800773c6c6..cefcc596628 100644 --- a/gui/wxpython/gui_core/vselect.py +++ b/gui/wxpython/gui_core/vselect.py @@ -29,7 +29,7 @@ from core.gcmd import RunCommand from gui_core.wrap import Button, ListCtrl -import grass.script as grass +import grass.script as gs from grass.pydispatch.signal import Signal @@ -299,13 +299,13 @@ def QuerySelectedMap(self): mapInfo = self.mapWin.GetMap() threshold = 10.0 * ((mapInfo.region["e"] - mapInfo.region["w"]) / mapInfo.width) try: - query = grass.vector_what( + query = gs.vector_what( map=[self.mapName], coord=self.mapWin.GetLastEN(), distance=threshold, skip_attributes=True, ) - except grass.ScriptError: + except gs.ScriptError: GError( parent=self, message=_("Failed to query vector map(s) <%s>.") % self.map ) @@ -358,7 +358,7 @@ def OnExportMap(self, event): if ret == 0: tree = self._giface.GetLayerTree() if tree: - outMap = f"{outMap}@{grass.gisenv()['MAPSET']}" + outMap = f"{outMap}@{gs.gisenv()['MAPSET']}" tree.AddLayer( ltype="vector", lname=outMap, diff --git a/gui/wxpython/gui_core/widgets.py b/gui/wxpython/gui_core/widgets.py index 61225b8c21f..3196ff173db 100644 --- a/gui/wxpython/gui_core/widgets.py +++ b/gui/wxpython/gui_core/widgets.py @@ -1338,11 +1338,7 @@ def _searchModule(self, keys, value): nodes.sort(key=self._model.GetIndexOfNode) self._results = nodes self._resultIndex = -1 - commands = sorted( - [node.data["command"] for node in nodes if node.data["command"]] - ) - - return commands + return sorted([node.data["command"] for node in nodes if node.data["command"]]) def OnSelectModule(self, event=None): """Module selected from choice, update command prompt""" diff --git a/gui/wxpython/gui_core/wrap.py b/gui/wxpython/gui_core/wrap.py index 41ab1486c46..29299bbbbe2 100644 --- a/gui/wxpython/gui_core/wrap.py +++ b/gui/wxpython/gui_core/wrap.py @@ -144,7 +144,7 @@ def SetToolTip(self, tip): wx.Window.UnsetToolTip(self) else: wx.Window.SetToolTip(self, tipString=tip) - else: + else: # noqa: PLR5501 if tip is None: wx.Window.SetToolTip(self, tip) else: diff --git a/gui/wxpython/history/browser.py b/gui/wxpython/history/browser.py index 9bf5620d12f..6a31523d51f 100644 --- a/gui/wxpython/history/browser.py +++ b/gui/wxpython/history/browser.py @@ -165,12 +165,10 @@ def _createRegionSettingsBox(self): def _general_info_filter(self, key, value): filter_keys = ["timestamp", "runtime", "status"] - return key in filter_keys or ( - (key == "mask2d" or key == "mask3d") and value is True - ) + return key in filter_keys or ((key in {"mask2d", "mask3d"}) and value is True) def _region_settings_filter(self, key): - return (key != "projection") and (key != "zone") and (key != "cells") + return key not in {"projection", "zone", "cells"} def _updateGeneralInfoBox(self, command_info): """Update a static box for displaying general info about the command. diff --git a/gui/wxpython/history/tree.py b/gui/wxpython/history/tree.py index 2ab158c45c5..98ab8eb0994 100644 --- a/gui/wxpython/history/tree.py +++ b/gui/wxpython/history/tree.py @@ -215,12 +215,10 @@ def _timestampToDay(self, timestamp=None): return OLD_DATE timestamp_datetime = datetime.datetime.fromisoformat(timestamp) - day_midnight = datetime.datetime( + return datetime.datetime( timestamp_datetime.year, timestamp_datetime.month, timestamp_datetime.day ).date() - return day_midnight - def _initHistoryModel(self): """Fill tree history model based on the current history log.""" content_list = self.ReadFromHistory() @@ -246,24 +244,21 @@ def _initHistoryModel(self): if day: day = day[0] + # Create time period node if not found + elif not entry["command_info"]: + # Prepare it for entries without command info + day = self._model.AppendNode( + parent=self._model.root, + data={"type": TIME_PERIOD, "day": self._timestampToDay()}, + ) else: - # Create time period node if not found - if not entry["command_info"]: - # Prepare it for entries without command info - day = self._model.AppendNode( - parent=self._model.root, - data={"type": TIME_PERIOD, "day": self._timestampToDay()}, - ) - else: - day = self._model.AppendNode( - parent=self._model.root, - data={ - "type": TIME_PERIOD, - "day": self._timestampToDay( - entry["command_info"]["timestamp"] - ), - }, - ) + day = self._model.AppendNode( + parent=self._model.root, + data={ + "type": TIME_PERIOD, + "day": self._timestampToDay(entry["command_info"]["timestamp"]), + }, + ) # Determine status and create command node status = ( @@ -279,7 +274,7 @@ def _initHistoryModel(self): data={ "type": COMMAND, "name": entry["command"].strip(), - "timestamp": timestamp if timestamp else None, + "timestamp": timestamp or None, "status": status, }, ) @@ -545,8 +540,9 @@ def OnDoubleClick(self, node): self.DefineItems([node]) if self.selected_command[0]: self.Run(node) + return + + if self.IsNodeExpanded(node): + self.CollapseNode(node, recursive=False) else: - if self.IsNodeExpanded(node): - self.CollapseNode(node, recursive=False) - else: - self.ExpandNode(node, recursive=False) + self.ExpandNode(node, recursive=False) diff --git a/gui/wxpython/iclass/dialogs.py b/gui/wxpython/iclass/dialogs.py index 05a03504b14..8aaac14c4c8 100644 --- a/gui/wxpython/iclass/dialogs.py +++ b/gui/wxpython/iclass/dialogs.py @@ -43,7 +43,7 @@ ListCtrl, ) -import grass.script as grass +import grass.script as gs class IClassGroupDialog(SimpleDialog): @@ -71,7 +71,7 @@ def __init__( self.groupSelect = gselect.Select( parent=self.panel, type="group", - mapsets=[grass.gisenv()["MAPSET"]], + mapsets=[gs.gisenv()["MAPSET"]], size=globalvar.DIALOG_GSELECT_SIZE, validator=SimpleValidator(callback=self.ValidatorCallback), ) @@ -186,7 +186,7 @@ def GetGroupBandsErr(self, parent): """ gr, s = self.GetData() - group = grass.find_file(name=gr, element="group") + group = gs.find_file(name=gr, element="group") bands = [] g = group["name"] @@ -617,7 +617,7 @@ def __init__( self.fileName = file - env = grass.gisenv() + env = gs.gisenv() # inconsistent group and subgroup name # path: @@ -785,7 +785,7 @@ def __layout(self): self.vectorNameCtrl = gselect.Select( parent=self.panel, type="vector", - mapsets=[grass.gisenv()["MAPSET"]], + mapsets=[gs.gisenv()["MAPSET"]], size=globalvar.DIALOG_GSELECT_SIZE, ) if self.vectorName: @@ -830,7 +830,7 @@ def OnOK(self, event): """Checks if map exists and can be overwritten.""" overwrite = UserSettings.Get(group="cmd", key="overwrite", subkey="enabled") vName = self.GetVectorName() - res = grass.find_file(vName, element="vector") + res = gs.find_file(vName, element="vector") if res["fullname"] and overwrite is False: qdlg = wx.MessageDialog( parent=self, diff --git a/gui/wxpython/iclass/digit.py b/gui/wxpython/iclass/digit.py index 1564c5ef445..85334993db1 100644 --- a/gui/wxpython/iclass/digit.py +++ b/gui/wxpython/iclass/digit.py @@ -30,7 +30,7 @@ except ImportError: pass -import grass.script as grass +import grass.script as gs class IClassVDigitWindow(VDigitWindow): @@ -53,7 +53,7 @@ def _onLeftDown(self, event): if not action: return - region = grass.region() + region = gs.region() e, n = self.Pixel2Cell(event.GetPosition()) if not ( (region["s"] <= n <= region["n"]) and (region["w"] <= e <= region["e"]) @@ -126,8 +126,7 @@ def _getNewFeaturesLayer(self): return 1 def _getNewFeaturesCat(self): - cat = self.mapWindow.GetCurrentCategory() - return cat + return self.mapWindow.GetCurrentCategory() def DeleteAreasByCat(self, cats): """Delete areas (centroid+boundaries) by categories @@ -161,7 +160,7 @@ def CopyMap(self, name, tmp=False, update=False): open_fn = Vect_open_update else: open_fn = Vect_open_new - else: + else: # noqa: PLR5501 if update: open_fn = Vect_open_tmp_update else: diff --git a/gui/wxpython/iclass/frame.py b/gui/wxpython/iclass/frame.py index 5f383a7e058..3aede6480c8 100644 --- a/gui/wxpython/iclass/frame.py +++ b/gui/wxpython/iclass/frame.py @@ -36,7 +36,7 @@ haveIClass = False errMsg = _("Loading imagery lib failed.\n%s") % e -import grass.script as grass +import grass.script as gs from mapdisp import statusbar as sb from mapdisp.main import StandaloneMapDisplayGrassInterface @@ -225,7 +225,7 @@ def _cleanup(self): def _getTempVectorName(self): """Return new name for temporary vector map (training areas)""" - vectorPath = grass.tempfile(create=False) + vectorPath = gs.tempfile(create=False) return "trAreas" + os.path.basename(vectorPath).replace(".", "") @@ -603,7 +603,7 @@ def AddBands(self): if dlg.ShowModal() == wx.ID_OK: if dlg.GetGroupBandsErr(parent=self): g, s = dlg.GetData() - group = grass.find_file(name=g, element="group") + group = gs.find_file(name=g, element="group") self.g["group"] = group["name"] self.g["subgroup"] = s self.groupSet.emit( @@ -644,7 +644,7 @@ def _checkImportedTopo(self, vector): :return: warning message (empty if topology is ok) """ - topo = grass.vector_info_topo(map=vector) + topo = gs.vector_info_topo(map=vector) warning = "" if topo["areas"] == 0: @@ -857,14 +857,15 @@ def ExportAreas(self, vectorName, withTable): % {"band": i + 1, "stat": statistic, "format": format} ) - if 0 != RunCommand( - "v.db.addtable", map=vectorName, columns=columns, parent=self + if ( + RunCommand("v.db.addtable", map=vectorName, columns=columns, parent=self) + != 0 ): wx.EndBusyCursor() return False try: - dbInfo = grass.vector_db(vectorName)[1] + dbInfo = gs.vector_db(vectorName)[1] except KeyError: wx.EndBusyCursor() return False @@ -958,9 +959,8 @@ def OnCategoryManager(self, event): dlg.CenterOnParent() dlg.Show() self.dialogs["classManager"] = dlg - else: - if not self.dialogs["classManager"].IsShown(): - self.dialogs["classManager"].Show() + elif not self.dialogs["classManager"].IsShown(): + self.dialogs["classManager"].Show() def CategoryChanged(self, currentCat): """Updates everything which depends on current category. @@ -1302,13 +1302,13 @@ def CheckInput(self, group, vector): regionBox = bound_box() Vect_get_map_box(self.poMapInfo, byref(regionBox)) - rasterInfo = grass.raster_info(groupLayers[0]) + rasterInfo = gs.raster_info(groupLayers[0]) if ( - regionBox.N > rasterInfo["north"] - or regionBox.S < rasterInfo["south"] - or regionBox.E > rasterInfo["east"] - or regionBox.W < rasterInfo["west"] + rasterInfo["north"] < regionBox.N + or rasterInfo["south"] > regionBox.S + or rasterInfo["east"] < regionBox.E + or rasterInfo["west"] > regionBox.W ): GMessage( parent=self, diff --git a/gui/wxpython/iclass/g.gui.iclass.py b/gui/wxpython/iclass/g.gui.iclass.py index a452754bfb9..abf96a5f404 100755 --- a/gui/wxpython/iclass/g.gui.iclass.py +++ b/gui/wxpython/iclass/g.gui.iclass.py @@ -50,12 +50,12 @@ # %end import os -import grass.script as gscript +import grass.script as gs def main(): - gscript.set_raise_on_error(False) - options, flags = gscript.parser() + gs.set_raise_on_error(False) + options, flags = gs.parser() import wx @@ -71,28 +71,28 @@ def main(): if options["group"]: if not options["subgroup"]: - gscript.fatal(_("Name of subgroup required")) - group_name = gscript.find_file(name=options["group"], element="group")["name"] + gs.fatal(_("Name of subgroup required")) + group_name = gs.find_file(name=options["group"], element="group")["name"] if not group_name: - gscript.fatal(_("Group <%s> not found") % options["group"]) - subgroups = gscript.read_command( + gs.fatal(_("Group <%s> not found") % options["group"]) + subgroups = gs.read_command( "i.group", group=group_name, flags="sg" ).splitlines() if options["subgroup"] not in subgroups: - gscript.fatal(_("Subgroup <%s> not found") % options["subgroup"]) + gs.fatal(_("Subgroup <%s> not found") % options["subgroup"]) subgroup_name = options["subgroup"] if options["map"]: - map_name = gscript.find_file(name=options["map"], element="cell")["fullname"] + map_name = gs.find_file(name=options["map"], element="cell")["fullname"] if not map_name: - gscript.fatal(_("Raster map <%s> not found") % options["map"]) + gs.fatal(_("Raster map <%s> not found") % options["map"]) if options["trainingmap"]: - trainingmap_name = gscript.find_file( - name=options["trainingmap"], element="vector" - )["fullname"] + trainingmap_name = gs.find_file(name=options["trainingmap"], element="vector")[ + "fullname" + ] if not trainingmap_name: - gscript.fatal(_("Vector map <%s> not found") % options["trainingmap"]) + gs.fatal(_("Vector map <%s> not found") % options["trainingmap"]) # define display driver driver = UserSettings.Get(group="display", key="driver", subkey="type") diff --git a/gui/wxpython/iclass/statistics.py b/gui/wxpython/iclass/statistics.py index c083912988c..059ce5e6b03 100644 --- a/gui/wxpython/iclass/statistics.py +++ b/gui/wxpython/iclass/statistics.py @@ -20,7 +20,7 @@ import os from ctypes import * -import grass.script as grass +import grass.script as gs try: from grass.lib.imagery import * @@ -114,7 +114,7 @@ def SetBaseStatistics(self, cat, name, color): self.name = name self.color = color - rasterPath = grass.tempfile(create=False) + rasterPath = gs.tempfile(create=False) name = name.replace(" ", "_") self.rasterName = name + "_" + os.path.basename(rasterPath) @@ -135,12 +135,12 @@ def SetFromcStatistics(self, cStatistics): name = c_char_p() I_iclass_statistics_get_name(cStatistics, byref(name)) if self.name != name.value: - set_stats["name"] = grass.decode(name.value) + set_stats["name"] = gs.decode(name.value) color = c_char_p() I_iclass_statistics_get_color(cStatistics, byref(color)) if self.color != color.value: - set_stats["color"] = grass.decode(color.value) + set_stats["color"] = gs.decode(color.value) nbands = c_int() I_iclass_statistics_get_nbands(cStatistics, byref(nbands)) diff --git a/gui/wxpython/iclass/toolbars.py b/gui/wxpython/iclass/toolbars.py index 6ba1db44ae5..4ca67656fb9 100644 --- a/gui/wxpython/iclass/toolbars.py +++ b/gui/wxpython/iclass/toolbars.py @@ -26,7 +26,7 @@ from gui_core.forms import GUI from gui_core.wrap import StaticText -import grass.script as grass +import grass.script as gs iClassIcons = { "opacity": MetaIcon(img="layer-opacity", label=_("Set opacity level")), @@ -398,7 +398,7 @@ def OnSelectLayer(self, event): def OnAddRast(self, event): dlg = IClassMapDialog(self, title=_("Add raster map"), element="raster") if dlg.ShowModal() == wx.ID_OK: - raster = grass.find_file(name=dlg.GetMap(), element="cell") + raster = gs.find_file(name=dlg.GetMap(), element="cell") if raster["fullname"]: self.mapManager.AddLayer(name=raster["fullname"]) diff --git a/gui/wxpython/icons/icon.py b/gui/wxpython/icons/icon.py index c87e5af5e24..77ef956278b 100644 --- a/gui/wxpython/icons/icon.py +++ b/gui/wxpython/icons/icon.py @@ -57,11 +57,10 @@ def __init__(self, img, label=None, desc=None): self.imagepath = iconSet.get(img, wx.ART_MISSING_IMAGE) if not self.imagepath: self.type = "unknown" + elif self.imagepath.find("wxART_") > -1: + self.type = "wx" else: - if self.imagepath.find("wxART_") > -1: - self.type = "wx" - else: - self.type = "img" + self.type = "img" self.label = label diff --git a/gui/wxpython/image2target/g.gui.image2target.py b/gui/wxpython/image2target/g.gui.image2target.py index d78ff78ae95..97c67b20354 100755 --- a/gui/wxpython/image2target/g.gui.image2target.py +++ b/gui/wxpython/image2target/g.gui.image2target.py @@ -104,14 +104,14 @@ import os -import grass.script as gscript +import grass.script as gs def main(): """ Sets the GRASS display driver """ - options, flags = gscript.parser() + options, flags = gs.parser() import wx diff --git a/gui/wxpython/image2target/ii2t_gis_set.py b/gui/wxpython/image2target/ii2t_gis_set.py index d7985f915da..e3cb0257af1 100644 --- a/gui/wxpython/image2target/ii2t_gis_set.py +++ b/gui/wxpython/image2target/ii2t_gis_set.py @@ -542,7 +542,7 @@ def _readGisRC(self): if gisrc and os.path.isfile(gisrc): try: rc = open(gisrc, "r") - for line in rc.readlines(): + for line in rc: try: key, val = line.split(":", 1) except ValueError as e: diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index 2740d5c09a0..b4bc3d60f97 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -49,7 +49,7 @@ else: from wx import wizard as wiz -import grass.script as grass +import grass.script as gs from core import utils @@ -79,9 +79,7 @@ # # global variables # -global src_map -global tgt_map -global maptype +global src_map, tgt_map, maptype src_map = "" tgt_map = {"raster": "", "vector": ""} @@ -153,7 +151,7 @@ def __init__(self, parent, giface): # # get environmental variables # - self.grassdatabase = grass.gisenv()["GISDBASE"] + self.grassdatabase = gs.gisenv()["GISDBASE"] # # read original environment settings @@ -162,7 +160,7 @@ def __init__(self, parent, giface): self.gisrc_dict = {} try: f = open(self.target_gisrc, "r") - for line in f.readlines(): + for line in f: line = line.replace("\n", "").strip() if len(line) < 1: continue @@ -178,9 +176,7 @@ def __init__(self, parent, giface): # mapset for xy map to georectify self.newmapset = "" - global maptype - global src_map - global tgt_map + global maptype, src_map, tgt_map # src_map = '' # tgt_map = '' @@ -879,8 +875,7 @@ def __init__(self, wizard, parent): def OnSrcSelection(self, event): """Source map to display selected""" - global src_map - global maptype + global src_map, maptype src_map = self.srcselection.GetValue() @@ -916,8 +911,7 @@ def OnTgtVectSelection(self, event): tgt_map["vector"] = self.tgtvectselection.GetValue() def OnPageChanging(self, event=None): - global src_map - global tgt_map + global src_map, tgt_map if event.GetDirection() and (src_map == ""): GMessage( @@ -929,9 +923,7 @@ def OnPageChanging(self, event=None): self.parent.SwitchEnv("target") def OnEnterPage(self, event=None): - global maptype - global src_map - global tgt_map + global maptype, src_map, tgt_map self.srcselection.SetElementList(maptype) @@ -974,7 +966,7 @@ def OnEnterPage(self, event=None): f = open(vgrpfile) try: - for vect in f.readlines(): + for vect in f: vect = vect.strip("\n") if len(vect) < 1: continue @@ -1443,11 +1435,10 @@ def SetGCPSatus(self, item, itemIndex): wxPen = "highest" else: wxPen = "default" + elif self.mapcoordlist[key][7] > self.rmsthresh: + wxPen = "highest" else: - if self.mapcoordlist[key][7] > self.rmsthresh: - wxPen = "highest" - else: - wxPen = "default" + wxPen = "default" if itemIndex == self.list.selectedkey: wxPen = "selected" @@ -1640,7 +1631,7 @@ def ReadGCPs(self): f = open(self.file["control_points"], "r") GCPcnt = 0 - for line in f.readlines(): + for line in f: if line[0] == "#" or line == "": continue line = line.replace("\n", "").strip() @@ -1821,7 +1812,7 @@ def OnGeorect(self, event): f = open(self.file["vgrp"]) vectlist = [] try: - for vect in f.readlines(): + for vect in f: vect = vect.strip("\n") if len(vect) < 1: continue @@ -2304,13 +2295,13 @@ def OnZoomMenuGCP(self, event): def OnSize(self, event): """Adjust Map Windows after GCP Map Display has been resized""" # re-render image on idle - self.resize = grass.clock() + self.resize = gs.clock() super(MapPanel, self).OnSize(event) def OnIdle(self, event): """GCP Map Display resized, adjust Map Windows""" if self.GetMapToolbar(): - if self.resize and self.resize + 0.2 < grass.clock(): + if self.resize and self.resize + 0.2 < gs.clock(): srcwidth, srcheight = self.SrcMapWindow.GetSize() tgtwidth, tgtheight = self.TgtMapWindow.GetSize() srcwidth = (srcwidth + tgtwidth) / 2 @@ -2682,7 +2673,7 @@ def __init__( f = open(self.vgrpfile) try: checked = [] - for line in f.readlines(): + for line in f: line = line.replace("\n", "") if len(line) < 1: continue @@ -2855,12 +2846,16 @@ def GetValues(self, columns=None): except ValueError: return valuelist - valuelist.append(self.xcoord.GetValue()) - valuelist.append(self.ycoord.GetValue()) - valuelist.append(self.zcoord.GetValue()) - valuelist.append(self.ecoord.GetValue()) - valuelist.append(self.ncoord.GetValue()) - valuelist.append(self.hcoord.GetValue()) + valuelist.extend( + ( + self.xcoord.GetValue(), + self.ycoord.GetValue(), + self.zcoord.GetValue(), + self.ecoord.GetValue(), + self.ncoord.GetValue(), + self.hcoord.GetValue(), + ) + ) return valuelist @@ -3314,9 +3309,7 @@ def OnExtension(self, event): self.parent.extension = self.ext_txt.GetValue() def UpdateSettings(self): - global src_map - global tgt_map - global maptype + global src_map, tgt_map, maptype layers = None @@ -3465,7 +3458,7 @@ def UpdateSettings(self): self.parent.activemap.SetSelection(0) self.parent.activemap.Enable(False) self.parent.GetMapToolbar().Enable("zoommenu", enable=False) - else: + else: # noqa: PLR5501 if not self.parent.show_target: self.parent.show_target = True self.parent._mgr.GetPane("target").Show() diff --git a/gui/wxpython/iscatt/controllers.py b/gui/wxpython/iscatt/controllers.py index 3ebfa1a875b..38e61e34133 100644 --- a/gui/wxpython/iscatt/controllers.py +++ b/gui/wxpython/iscatt/controllers.py @@ -40,7 +40,7 @@ from iscatt.dialogs import AddScattPlotDialog, ExportCategoryRaster from iclass.dialogs import IClassGroupDialog -import grass.script as grass +import grass.script as gs from grass.pydispatch.signal import Signal @@ -109,7 +109,7 @@ def CleanUp(self): self.core.CleanUp() def CleanUpDone(self): - for scatt_id, scatt in self.plots.items(): + for scatt in self.plots.values(): if scatt["scatt"]: scatt["scatt"].CleanUp() @@ -969,7 +969,7 @@ def SetData(self): bands = dlg.GetGroupBandsErr(parent=self.scatt_mgr.guiparent) if bands: name, s = dlg.GetData() - group = grass.find_file(name=name, element="group") + group = gs.find_file(name=name, element="group") self.set_g["group"] = group["name"] self.set_g["subg"] = s @@ -988,7 +988,7 @@ def EmptyCategories(self): def UpdateCategoryRaster(self, cat_id, attrs, render=True): cat_rast = self.scatt_mgr.core.GetCatRast(cat_id) - if not grass.find_file(cat_rast, element="cell", mapset=".")["file"]: + if not gs.find_file(cat_rast, element="cell", mapset=".")["file"]: return cats_attrs = self.cats_mgr.GetCategoryAttrs(cat_id) @@ -1063,7 +1063,7 @@ def UpdateCategoryRaster(self, cat_id, attrs, render=True): if not cat_rast: return - if not grass.find_file(cat_rast, element="cell", mapset=".")["file"]: + if not gs.find_file(cat_rast, element="cell", mapset=".")["file"]: return cats_attrs = self.cats_mgr.GetCategoryAttrs(cat_id) train_mgr, preview_mgr = self.iclass_frame.GetMapManagers() diff --git a/gui/wxpython/iscatt/dialogs.py b/gui/wxpython/iscatt/dialogs.py index 5ac172515fe..4129015e88d 100644 --- a/gui/wxpython/iscatt/dialogs.py +++ b/gui/wxpython/iscatt/dialogs.py @@ -22,7 +22,7 @@ from gui_core.gselect import Select import wx.lib.colourselect as csel -import grass.script as grass +import grass.script as gs from core import globalvar from core.gcmd import GMessage @@ -286,7 +286,7 @@ def __layout(self): self.vectorNameCtrl = Select( parent=self.panel, type="raster", - mapsets=[grass.gisenv()["MAPSET"]], + mapsets=[gs.gisenv()["MAPSET"]], size=globalvar.DIALOG_GSELECT_SIZE, ) if self.rasterName: @@ -322,7 +322,7 @@ def OnOK(self, event): """Checks if map exists and can be overwritten.""" overwrite = UserSettings.Get(group="cmd", key="overwrite", subkey="enabled") rast_name = self.GetRasterName() - res = grass.find_file(rast_name, element="cell") + res = gs.find_file(rast_name, element="cell") if res["fullname"] and overwrite is False: qdlg = wx.MessageDialog( parent=self, diff --git a/gui/wxpython/iscatt/frame.py b/gui/wxpython/iscatt/frame.py index bf5dfac91e4..6d87a90e273 100644 --- a/gui/wxpython/iscatt/frame.py +++ b/gui/wxpython/iscatt/frame.py @@ -330,8 +330,7 @@ def _newScatterPlotName(self, scatt_id): return name def _getScatterPlotName(self, i): - name = "scatter plot %d" % i - return name + return "scatter plot %d" % i def NewScatterPlot(self, scatt_id, transpose): # TODO needs to be resolved (should be in this class) diff --git a/gui/wxpython/iscatt/iscatt_core.py b/gui/wxpython/iscatt/iscatt_core.py index caa2916acce..2eaa463940d 100644 --- a/gui/wxpython/iscatt/iscatt_core.py +++ b/gui/wxpython/iscatt/iscatt_core.py @@ -30,7 +30,7 @@ from core.gcmd import GException, RunCommand -import grass.script as grass +import grass.script as gs from iscatt.core_c import CreateCatRast, ComputeScatts, UpdateCatRast, Rasterize @@ -361,7 +361,7 @@ def _create_grass_region_env(self, bbox): new_r["nsres"] = r["nsres"] new_r["ewres"] = r["ewres"] - return {"GRASS_REGION": grass.region_env(**new_r)} + return {"GRASS_REGION": gs.region_env(**new_r)} class AnalyzedData: @@ -446,7 +446,7 @@ def DeleteCategory(self, cat_id): return False for scatt in self.cats[cat_id].values(): - grass.try_remove(scatt["np_vals"]) + gs.try_remove(scatt["np_vals"]) del scatt["np_vals"] del self.cats[cat_id] @@ -476,7 +476,7 @@ def AddScattPlot(self, cat_id, scatt_id): b_i["b1"]["max"] - b_i["b1"]["min"] + 1, ) - np_vals = np.memmap(grass.tempfile(), dtype=self.dtype, mode="w+", shape=shape) + np_vals = np.memmap(gs.tempfile(), dtype=self.dtype, mode="w+", shape=shape) self.cats[cat_id][scatt_id] = {"np_vals": np_vals} @@ -488,9 +488,7 @@ def GetBandsInfo(self, scatt_id): b1_info = self.an_data.GetBandInfo(b1) b2_info = self.an_data.GetBandInfo(b2) - bands_info = {"b1": b1_info, "b2": b2_info} - - return bands_info + return {"b1": b1_info, "b2": b2_info} def DeleScattPlot(self, cat_id, scatt_id): if cat_id not in self.cats: @@ -580,7 +578,7 @@ def AddCategory(self, cat_id): self.cats_rasts_conds[cat_id] = None self.cats_rasts[cat_id] = None else: - self.cats_rasts_conds[cat_id] = grass.tempfile() + self.cats_rasts_conds[cat_id] = gs.tempfile() self.cats_rasts[cat_id] = "temp_cat_rast_%d_%d" % (cat_id, os.getpid()) region = self.an_data.GetRegion() CreateCatRast(region, self.cats_rasts_conds[cat_id]) @@ -590,7 +588,7 @@ def AddCategory(self, cat_id): def DeleteCategory(self, cat_id): ScattPlotsCondsData.DeleteCategory(self, cat_id) - grass.try_remove(self.cats_rasts_conds[cat_id]) + gs.try_remove(self.cats_rasts_conds[cat_id]) del self.cats_rasts_conds[cat_id] RunCommand("g.remove", flags="f", type="raster", name=self.cats_rasts[cat_id]) @@ -695,7 +693,7 @@ def eigsorted(cov): def CleanUp(self): ScattPlotsCondsData.CleanUp(self) for tmp in self.cats_rasts_conds.values(): - grass.try_remove(tmp) + gs.try_remove(tmp) for tmp in self.cats_rasts.values(): RunCommand("g.remove", flags="f", type="raster", name=tmp, getErrorMsg=True) @@ -784,15 +782,13 @@ def idBandsToidScatt(band_1_id, band_2_id, n_bands): n_b1 = n_bands - 1 - scatt_id = int( + return int( (band_1_id * (2 * n_b1 + 1) - band_1_id * band_1_id) / 2 + band_2_id - band_1_id - 1 ) - return scatt_id - def GetRegion(): ret, region, msg = RunCommand("g.region", flags="gp", getErrorMsg=True, read=True) diff --git a/gui/wxpython/iscatt/plots.py b/gui/wxpython/iscatt/plots.py index a955250db10..f9cad136314 100644 --- a/gui/wxpython/iscatt/plots.py +++ b/gui/wxpython/iscatt/plots.py @@ -29,9 +29,9 @@ from gui_core.wrap import Menu, NewId try: - import matplotlib + import matplotlib as mpl - matplotlib.use("WXAgg") + mpl.use("WXAgg") from matplotlib.figure import Figure from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanvas from matplotlib.lines import Line2D @@ -47,7 +47,7 @@ ).format(e) ) -import grass.script as grass +import grass.script as gs from grass.pydispatch.signal import Signal @@ -241,8 +241,9 @@ def Plot(self, cats_order, scatts, ellipses, styles): aspect="equal", ) - callafter_list.append([self.axes.draw_artist, [img]]) - callafter_list.append([grass.try_remove, [merged_img.filename]]) + callafter_list.extend( + ([self.axes.draw_artist, [img]], [gs.try_remove, [merged_img.filename]]) + ) for cat_id in cats_order: if cat_id == 0: @@ -448,7 +449,7 @@ def MergeImg(cats_order, scatts, styles, rend_dt, output_queue): init = True merged_img = None - merge_tmp = grass.tempfile() + merge_tmp = gs.tempfile() for cat_id in cats_order: if cat_id not in scatts: continue @@ -496,7 +497,7 @@ def MergeImg(cats_order, scatts, styles, rend_dt, output_queue): rend_dt[cat_id]["color"] = styles[cat_id]["color"] rend_dt[cat_id]["dt"] = np.memmap( - grass.tempfile(), dtype="uint8", mode="w+", shape=(sh[0], sh[1], 4) + gs.tempfile(), dtype="uint8", mode="w+", shape=(sh[0], sh[1], 4) ) # colored_cat = np.zeros(dtype='uint8', ) @@ -580,7 +581,7 @@ def _renderCat(cat_id, rend_dt, scatt, styles): def _getColorMap(cat_id, styles): - cmap = matplotlib.cm.jet + cmap = mpl.cm.jet if cat_id == 0: cmap.set_bad("w", 1.0) cmap._init() @@ -710,8 +711,7 @@ def GetCoords(self): if self.empty_pol: return None - coords = deepcopy(self.pol.xy) - return coords + return deepcopy(self.pol.xy) def SetEmpty(self): self._setEmptyPol(True) @@ -1035,7 +1035,7 @@ def imshow( if norm is not None: assert isinstance(norm, mcolors.Normalize) if aspect is None: - aspect = matplotlib.rcParams["image.aspect"] + aspect = mpl.rcParams["image.aspect"] axes.set_aspect(aspect) if extent: diff --git a/gui/wxpython/lmgr/frame.py b/gui/wxpython/lmgr/frame.py index 752f50bf597..ddb91789508 100644 --- a/gui/wxpython/lmgr/frame.py +++ b/gui/wxpython/lmgr/frame.py @@ -1981,8 +1981,8 @@ def AddOrUpdateMap(self, mapName, ltype): self.AddMaps([mapName], ltype, check=True) else: display = self.GetMapDisplay() - mapLayers = map( - lambda x: x.GetName(), display.GetMap().GetListOfLayers(ltype=ltype) + mapLayers = ( + x.GetName() for x in display.GetMap().GetListOfLayers(ltype=ltype) ) if mapName in mapLayers: display.GetWindow().UpdateMap(render=True) @@ -2336,13 +2336,12 @@ def MsgDisplayResolution(self, limitText=None): ) if limitText: message += "\n\n%s" % _(limitText) - dlg = wx.MessageDialog( + return wx.MessageDialog( parent=self, message=message, caption=_("Constrain map to region geometry?"), style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION | wx.CENTRE, ) - return dlg def _onMapsetWatchdog(self, map_path, map_dest): """Current mapset watchdog event handler diff --git a/gui/wxpython/lmgr/layertree.py b/gui/wxpython/lmgr/layertree.py index 1fe8e31cfb8..e2204555415 100644 --- a/gui/wxpython/lmgr/layertree.py +++ b/gui/wxpython/lmgr/layertree.py @@ -1093,7 +1093,7 @@ def OnCopyMap(self, event): return kwargs = {key: "%s,%s" % (lnameSrc, lnameDst)} - if 0 != RunCommand("g.copy", overwrite=True, **kwargs): + if RunCommand("g.copy", overwrite=True, **kwargs) != 0: GError(_("Unable to make copy of <%s>") % lnameSrc, parent=self) return @@ -1502,34 +1502,33 @@ def AddLayer( if not parent: parent = self.root layer = self.AppendItem(parentId=parent, text="", ct_type=1, wnd=ctrl) - else: - if selectedLayer and selectedLayer != self.GetRootItem(): - if ( - selectedLayer - and self.GetLayerInfo(selectedLayer, key="type") == "group" - ): - # add to group (first child of self.layer_selected) - layer = self.PrependItem( - parent=selectedLayer, text="", ct_type=1, wnd=ctrl - ) - else: - # -> previous sibling of selected layer - parent = self.GetItemParent(selectedLayer) - layer = self.InsertItem( - parentId=parent, - input=self.GetPrevSibling(selectedLayer), - text="", - ct_type=1, - wnd=ctrl, - ) - else: # add first layer to the layer tree (first child of root) - layer = self.PrependItem(parent=self.root, text="", ct_type=1, wnd=ctrl) + elif selectedLayer and selectedLayer != self.GetRootItem(): + if ( + selectedLayer + and self.GetLayerInfo(selectedLayer, key="type") == "group" + ): + # add to group (first child of self.layer_selected) + layer = self.PrependItem( + parent=selectedLayer, text="", ct_type=1, wnd=ctrl + ) + else: + # -> previous sibling of selected layer + parent = self.GetItemParent(selectedLayer) + layer = self.InsertItem( + parentId=parent, + input=self.GetPrevSibling(selectedLayer), + text="", + ct_type=1, + wnd=ctrl, + ) + else: # add first layer to the layer tree (first child of root) + layer = self.PrependItem(parent=self.root, text="", ct_type=1, wnd=ctrl) # layer is initially unchecked as inactive (beside 'command') # use predefined value if given if lchecked is not None: checked = lchecked - render = True if checked else False + render = bool(checked) else: checked = False render = False @@ -1543,21 +1542,20 @@ def AddLayer( self.SetItemImage(layer, self.folder, CT.TreeItemIcon_Normal) self.SetItemImage(layer, self.folder_open, CT.TreeItemIcon_Expanded) self.SetItemText(layer, grouptext) + elif ltype in self._icon: + self.SetItemImage(layer, self._icon[ltype]) + # do not use title() - will not work with ltype == 'raster_3d' + self.SetItemText( + layer, + "%s %s" + % ( + LMIcons["layer" + ltype[0].upper() + ltype[1:]].GetLabel(), + _("(double click to set properties)") + " " * 15, + ), + ) else: - if ltype in self._icon: - self.SetItemImage(layer, self._icon[ltype]) - # do not use title() - will not work with ltype == 'raster_3d' - self.SetItemText( - layer, - "%s %s" - % ( - LMIcons["layer" + ltype[0].upper() + ltype[1:]].GetLabel(), - _("(double click to set properties)") + " " * 15, - ), - ) - else: - self.SetItemImage(layer, self._icon["cmd"]) - self.SetItemText(layer, ltype) + self.SetItemImage(layer, self._icon["cmd"]) + self.SetItemText(layer, ltype) if ltype != "group": if lcmd and len(lcmd) > 1: @@ -1659,9 +1657,8 @@ def AddLayer( ctrl.SetValue(lname) else: self.SetItemText(layer, self._getLayerName(layer, lname)) - else: - if ltype == "group": - self.OnRenameLayer(None) + elif ltype == "group": + self.OnRenameLayer(None) return layer @@ -1849,7 +1846,7 @@ def OnLayerChecked(self, event): if (vInfo["lines"] + vInfo["boundaries"]) > 0: self.mapdisplay.MapWindow.LoadVector(item, points=False) - else: # disable + else: # disable # noqa: PLR5501 if mapLayer.type == "raster": self.mapdisplay.MapWindow.UnloadRaster(item) elif mapLayer.type == "raster_3d": @@ -2094,22 +2091,21 @@ def RecreateItem(self, dragItem, dropTarget, parent=None): image=image, data=data, ) - else: + elif self.flag & wx.TREE_HITTEST_ABOVE: # if dragItem not dropped on a layer or group, append or prepend it # to the layer tree - if self.flag & wx.TREE_HITTEST_ABOVE: - newItem = self.PrependItem( - self.root, text=text, ct_type=1, wnd=newctrl, image=image, data=data - ) - elif ( - (self.flag & wx.TREE_HITTEST_BELOW) - or (self.flag & wx.TREE_HITTEST_NOWHERE) - or (self.flag & wx.TREE_HITTEST_TOLEFT) - or (self.flag & wx.TREE_HITTEST_TORIGHT) - ): - newItem = self.AppendItem( - self.root, text=text, ct_type=1, wnd=newctrl, image=image, data=data - ) + newItem = self.PrependItem( + self.root, text=text, ct_type=1, wnd=newctrl, image=image, data=data + ) + elif ( + (self.flag & wx.TREE_HITTEST_BELOW) + or (self.flag & wx.TREE_HITTEST_NOWHERE) + or (self.flag & wx.TREE_HITTEST_TOLEFT) + or (self.flag & wx.TREE_HITTEST_TORIGHT) + ): + newItem = self.AppendItem( + self.root, text=text, ct_type=1, wnd=newctrl, image=image, data=data + ) # update new layer self.SetPyData(newItem, self.GetPyData(dragItem)) @@ -2428,7 +2424,7 @@ def _createCommandCtrl(self): height = 25 if sys.platform in {"win32", "darwin"}: height = 40 - ctrl = TextCtrl( + return TextCtrl( self, id=wx.ID_ANY, value="", @@ -2436,4 +2432,3 @@ def _createCommandCtrl(self): size=(self.GetSize()[0] - 100, height), style=wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP, ) - return ctrl diff --git a/gui/wxpython/lmgr/pyshell.py b/gui/wxpython/lmgr/pyshell.py index 5bb1cb2d0dd..ffbb8f67a92 100644 --- a/gui/wxpython/lmgr/pyshell.py +++ b/gui/wxpython/lmgr/pyshell.py @@ -26,7 +26,7 @@ from wx.py.shell import Shell as PyShell from wx.py.version import VERSION -import grass.script as grass +import grass.script as gs from gui_core.wrap import Button, ClearButton, IsDark from gui_core.pystc import SetDarkMode @@ -58,7 +58,7 @@ def __init__( "parent": self, "id": wx.ID_ANY, "introText": self.intro, - "locals": {"gs": grass, "AddLayer": self.AddLayer, "help": self.Help}, + "locals": {"gs": gs, "AddLayer": self.AddLayer, "help": self.Help}, } # useStockId (available since wxPython 4.0.2) should be False on macOS if sys.platform == "darwin" and CheckWxVersion([4, 0, 2]): @@ -119,14 +119,14 @@ def AddLayer(self, name, ltype="auto"): fname = None if ltype == "raster" or ltype != "vector": # check for raster - fname = grass.find_file(name, element="cell")["fullname"] + fname = gs.find_file(name, element="cell")["fullname"] if fname: ltype = "raster" lcmd = "d.rast" if not fname and (ltype == "vector" or ltype != "raster"): # if not found check for vector - fname = grass.find_file(name, element="vector")["fullname"] + fname = gs.find_file(name, element="vector")["fullname"] if fname: ltype = "vector" lcmd = "d.vect" diff --git a/gui/wxpython/lmgr/statusbar.py b/gui/wxpython/lmgr/statusbar.py index e8c62c36ede..ac4748bfe1f 100644 --- a/gui/wxpython/lmgr/statusbar.py +++ b/gui/wxpython/lmgr/statusbar.py @@ -94,7 +94,7 @@ def dbChanged(self, map=None, newname=None): :param str map: map that is changed :param str newname: new map """ - if map == self.mask_layer or newname == self.mask_layer: + if self.mask_layer in {map, newname}: self.Refresh() self.giface.updateMap.emit() diff --git a/gui/wxpython/location_wizard/dialogs.py b/gui/wxpython/location_wizard/dialogs.py index da706b96599..aa3954dab25 100644 --- a/gui/wxpython/location_wizard/dialogs.py +++ b/gui/wxpython/location_wizard/dialogs.py @@ -757,11 +757,11 @@ def GetTransform(self): def testRegionDef(): import wx.lib.inspection - import grass.script as gscript + import grass.script as gs app = wx.App() - dlg = RegionDef(None, location=gscript.gisenv()["LOCATION_NAME"]) + dlg = RegionDef(None, location=gs.gisenv()["LOCATION_NAME"]) dlg.Show() wx.lib.inspection.InspectionTool().Show() app.MainLoop() diff --git a/gui/wxpython/location_wizard/wizard.py b/gui/wxpython/location_wizard/wizard.py index bea1f424f0a..bdd955a7d30 100644 --- a/gui/wxpython/location_wizard/wizard.py +++ b/gui/wxpython/location_wizard/wizard.py @@ -75,14 +75,7 @@ from grass.script import core as grass from grass.exceptions import OpenError -global coordsys -global north -global south -global east -global west -global resolution -global wizerror -global translist +global coordsys, north, south, east, west, resolution, wizerror, translist if globalvar.CheckWxVersion(version=[4, 1, 0]): search_cancel_evt = wx.EVT_SEARCH_CANCEL @@ -743,8 +736,7 @@ def GetSortImages(self): def OnGetItemText(self, item, col): """Get item text""" index = self.itemIndexMap[item] - s = str(self.itemDataMap[index][col]) - return s + return str(self.itemDataMap[index][col]) def OnGetItemImage(self, item): return -1 @@ -811,11 +803,10 @@ def Search(self, index, pattern, firstOnly=True): return data[0] else: return data + elif firstOnly: + return None else: - if firstOnly: - return None - else: - return [] + return [] class ProjParamsPage(TitledPage): @@ -905,25 +896,24 @@ def OnPageChange(self, event=None): """Go to next page""" if event.GetDirection(): self.p4projparams = "" - for id, param in self.pparam.items(): + for param in self.pparam.values(): if param["type"] == "bool": if param["value"] is False: continue else: self.p4projparams += " +" + param["proj4"] + elif param["value"] is None: + wx.MessageBox( + parent=self, + message=_("You must enter a value for %s") % param["desc"], + caption=_("Error"), + style=wx.ICON_ERROR | wx.CENTRE, + ) + event.Veto() else: - if param["value"] is None: - wx.MessageBox( - parent=self, - message=_("You must enter a value for %s") % param["desc"], - caption=_("Error"), - style=wx.ICON_ERROR | wx.CENTRE, - ) - event.Veto() - else: - self.p4projparams += ( - " +" + param["proj4"] + "=" + str(param["value"]) - ) + self.p4projparams += ( + " +" + param["proj4"] + "=" + str(param["value"]) + ) def OnEnterPage(self, event): """Page entered""" @@ -1497,9 +1487,8 @@ def OnText(self, event): if len(self.georeffile) > 0 and os.path.isfile(self.georeffile): if not nextButton.IsEnabled(): nextButton.Enable(True) - else: - if nextButton.IsEnabled(): - nextButton.Enable(False) + elif nextButton.IsEnabled(): + nextButton.Enable(False) event.Skip() @@ -1574,9 +1563,8 @@ def OnText(self, event): if len(self.wktstring) == 0: if nextButton.IsEnabled(): nextButton.Enable(False) - else: - if not nextButton.IsEnabled(): - nextButton.Enable() + elif not nextButton.IsEnabled(): + nextButton.Enable() class EPSGPage(TitledPage): @@ -2168,9 +2156,8 @@ def GetProjstring(self, event): if len(self.customstring) == 0: if nextButton.IsEnabled(): nextButton.Enable(False) - else: - if not nextButton.IsEnabled(): - nextButton.Enable() + elif not nextButton.IsEnabled(): + nextButton.Enable() class SummaryPage(TitledPage): @@ -2540,14 +2527,7 @@ def __init__(self, parent, grassdatabase): self.__cleanUp() def __cleanUp(self): - global coordsys - global north - global south - global east - global west - global resolution - global wizerror - global translist + global coordsys, north, south, east, west, resolution, wizerror, translist coordsys = None north = None @@ -2563,7 +2543,7 @@ def __readData(self): f = open(os.path.join(globalvar.ETCDIR, "proj", "parms.table"), "r") self.projections = {} self.projdesc = {} - for line in f.readlines(): + for line in f: line = line.strip() try: proj, projdesc, params = line.split(":") @@ -2586,7 +2566,7 @@ def __readData(self): f = open(os.path.join(globalvar.ETCDIR, "proj", "datum.table"), "r") self.datums = {} paramslist = [] - for line in f.readlines(): + for line in f: line = line.expandtabs(1) line = line.strip() if line == "" or line[0] == "#": @@ -2603,7 +2583,7 @@ def __readData(self): # read Earth-based ellipsiod definitions f = open(os.path.join(globalvar.ETCDIR, "proj", "ellipse.table"), "r") self.ellipsoids = {} - for line in f.readlines(): + for line in f: line = line.expandtabs(1) line = line.strip() if line == "" or line[0] == "#": @@ -2621,7 +2601,7 @@ def __readData(self): os.path.join(globalvar.ETCDIR, "proj", "ellipse.table.solar.system"), "r" ) self.planetary_ellipsoids = {} - for line in f.readlines(): + for line in f: line = line.expandtabs(1) line = line.strip() if line == "" or line[0] == "#": @@ -2637,7 +2617,7 @@ def __readData(self): # read projection parameter description and parsing table f = open(os.path.join(globalvar.ETCDIR, "proj", "desc.table"), "r") self.paramdesc = {} - for line in f.readlines(): + for line in f: line = line.strip() try: pparam, datatype, proj4term, desc = line.split(":") @@ -2795,9 +2775,7 @@ def CreateProj4String(self): for item in datumparams: proj4string = "%s +%s" % (proj4string, item) - proj4string = "%s +no_defs" % proj4string - - return proj4string + return "%s +no_defs" % proj4string def OnHelp(self, event): """'Help' button clicked""" diff --git a/gui/wxpython/main_window/frame.py b/gui/wxpython/main_window/frame.py index 361111d389f..6b9a9be640f 100644 --- a/gui/wxpython/main_window/frame.py +++ b/gui/wxpython/main_window/frame.py @@ -1058,11 +1058,11 @@ def _closePageNoEvent(self, pgnum_dict, is_docked): def _focusPage(self, notification): """Focus the 'Console' notebook page according to event notification.""" - if ( - notification == Notification.HIGHLIGHT - or notification == Notification.MAKE_VISIBLE - or notification == Notification.RAISE_WINDOW - ): + if notification in { + Notification.HIGHLIGHT, + Notification.MAKE_VISIBLE, + Notification.RAISE_WINDOW, + }: self.FocusPage("Console") def FocusPage(self, page_text): @@ -2129,8 +2129,8 @@ def AddOrUpdateMap(self, mapName, ltype): self.AddMaps([mapName], ltype, check=True) else: display = self.GetMapDisplay() - mapLayers = map( - lambda x: x.GetName(), display.GetMap().GetListOfLayers(ltype=ltype) + mapLayers = ( + x.GetName() for x in display.GetMap().GetListOfLayers(ltype=ltype) ) if mapName in mapLayers: display.GetWindow().UpdateMap(render=True) @@ -2430,13 +2430,12 @@ def MsgDisplayResolution(self, limitText=None): ) if limitText: message += "\n\n%s" % _(limitText) - dlg = wx.MessageDialog( + return wx.MessageDialog( parent=self, message=message, caption=_("Constrain map to region geometry?"), style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION | wx.CENTRE, ) - return dlg def _onMapsetWatchdog(self, map_path, map_dest): """Current mapset watchdog event handler diff --git a/gui/wxpython/mapdisp/frame.py b/gui/wxpython/mapdisp/frame.py index 7f3a1d519d5..96f147c3cb0 100644 --- a/gui/wxpython/mapdisp/frame.py +++ b/gui/wxpython/mapdisp/frame.py @@ -58,7 +58,7 @@ from mapdisp import statusbar as sb from main_window.page import MainPageBase -import grass.script as grass +import grass.script as gs from grass.pydispatch.signal import Signal @@ -830,12 +830,12 @@ def _DToRastDone(): self._giface.WriteError(_("Failed to run d.to.rast:\n") + messages) return # set region for composite - grass.use_temp_region() + gs.use_temp_region() returncode, messages = RunCommand( "g.region", raster=tmpName + ".red", quiet=True, getErrorMsg=True ) if not returncode == 0: - grass.del_temp_region() + gs.del_temp_region() self._giface.WriteError(_("Failed to run d.to.rast:\n") + messages) return # composite @@ -849,7 +849,7 @@ def _DToRastDone(): overwrite=overwrite, getErrorMsg=True, ) - grass.del_temp_region() + gs.del_temp_region() RunCommand( "g.remove", type="raster", @@ -859,7 +859,7 @@ def _DToRastDone(): ) if not returncode == 0: self._giface.WriteError(_("Failed to run d.to.rast:\n") + messages) - grass.try_remove(pngFile) + gs.try_remove(pngFile) return # alignExtent changes only region variable @@ -876,7 +876,7 @@ def _DToRastDone(): w=region["w"], quiet=True, ) - grass.try_remove(pngFile) + gs.try_remove(pngFile) if self.IsPaneShown("3d"): self._giface.WriteError(_("d.to.rast can be used only in 2D mode.")) @@ -896,7 +896,7 @@ def _DToRastDone(): return # output file as PNG tmpName = "d_to_rast_tmp" - pngFile = grass.tempfile(create=False) + ".png" + pngFile = gs.tempfile(create=False) + ".png" dOutFileCmd = ["d.out.file", "output=" + pngFile, "format=png"] self.DOutFile(dOutFileCmd, callback=_DToRastDone) @@ -1082,21 +1082,21 @@ def QueryMap(self, east, north, qdist, rast, vect): vectQuery = [] env = os.environ.copy() for raster in rast: - env["GRASS_REGION"] = grass.region_env(raster=raster) - rastQuery += grass.raster_what( + env["GRASS_REGION"] = gs.region_env(raster=raster) + rastQuery += gs.raster_what( map=raster, coord=(east, north), localized=True, env=env ) if vect: encoding = UserSettings.Get(group="atm", key="encoding", subkey="value") try: - vectQuery = grass.vector_what( + vectQuery = gs.vector_what( map=vect, coord=(east, north), distance=qdist, encoding=encoding, multiple=True, ) - except grass.ScriptError: + except gs.ScriptError: GError( parent=self, message=_( @@ -1628,7 +1628,7 @@ def AddRDigit(self): ), ) rasters = self.GetMap().GetListOfLayers( - ltype="raster", mapset=grass.gisenv()["MAPSET"] + ltype="raster", mapset=gs.gisenv()["MAPSET"] ) self.toolbars["rdigit"].UpdateRasterLayers(rasters) self.toolbars["rdigit"].SelectDefault() @@ -1659,7 +1659,7 @@ def AddRDigit(self): self.rdigit.Start() def _updateRDigitLayers(self, layer): - mapset = grass.gisenv()["MAPSET"] + mapset = gs.gisenv()["MAPSET"] self.toolbars["rdigit"].UpdateRasterLayers( rasters=self.GetMap().GetListOfLayers(ltype="raster", mapset=mapset) ) diff --git a/gui/wxpython/mapdisp/statusbar.py b/gui/wxpython/mapdisp/statusbar.py index 3c819c2d765..0c5bac10124 100644 --- a/gui/wxpython/mapdisp/statusbar.py +++ b/gui/wxpython/mapdisp/statusbar.py @@ -637,20 +637,19 @@ def GetCenterString(self, map): return "%.*f; %.*f" % (precision, coord[0], precision, coord[1]) else: raise SbException(_("Error in projection (check the settings)")) + elif self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": + return "%s" % utils.Deg2DMS( + region["center_easting"], + region["center_northing"], + precision=precision, + ) else: - if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": - return "%s" % utils.Deg2DMS( - region["center_easting"], - region["center_northing"], - precision=precision, - ) - else: - return "%.*f; %.*f" % ( - precision, - region["center_easting"], - precision, - region["center_northing"], - ) + return "%.*f; %.*f" % ( + precision, + region["center_easting"], + precision, + region["center_northing"], + ) def SetCenter(self): """Set current map center as item value""" @@ -813,11 +812,10 @@ def ReprojectENFromMap(self, e, n, useDefinedProjection, precision, format): return "%.*f; %.*f" % (precision, e, precision, n) else: raise SbException(_("Error in projection (check the settings)")) + elif self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": + return utils.Deg2DMS(e, n, precision=precision) else: - if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": - return utils.Deg2DMS(e, n, precision=precision) - else: - return "%.*f; %.*f" % (precision, e, precision, n) + return "%.*f; %.*f" % (precision, e, precision, n) class SbRegionExtent(SbTextItem): @@ -930,25 +928,24 @@ def ReprojectRegionFromMap(self, region, useDefinedProjection, precision, format else: raise SbException(_("Error in projection (check the settings)")) + elif self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": + w, s = utils.Deg2DMS( + region["w"], region["s"], string=False, precision=precision + ) + e, n = utils.Deg2DMS( + region["e"], region["n"], string=False, precision=precision + ) + ewres, nsres = utils.Deg2DMS( + region["ewres"], region["nsres"], string=False, precision=precision + ) + return self._formatRegion(w=w, s=s, e=e, n=n, ewres=ewres, nsres=nsres) else: - if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS": - w, s = utils.Deg2DMS( - region["w"], region["s"], string=False, precision=precision - ) - e, n = utils.Deg2DMS( - region["e"], region["n"], string=False, precision=precision - ) - ewres, nsres = utils.Deg2DMS( - region["ewres"], region["nsres"], string=False, precision=precision - ) - return self._formatRegion(w=w, s=s, e=e, n=n, ewres=ewres, nsres=nsres) - else: - w, s = region["w"], region["s"] - e, n = region["e"], region["n"] - ewres, nsres = region["ewres"], region["nsres"] - return self._formatRegion( - w=w, s=s, e=e, n=n, ewres=ewres, nsres=nsres, precision=precision - ) + w, s = region["w"], region["s"] + e, n = region["e"], region["n"] + ewres, nsres = region["ewres"], region["nsres"] + return self._formatRegion( + w=w, s=s, e=e, n=n, ewres=ewres, nsres=nsres, precision=precision + ) class SbCompRegionExtent(SbRegionExtent): diff --git a/gui/wxpython/mapdisp/test_mapdisp.py b/gui/wxpython/mapdisp/test_mapdisp.py index d3b6850eba7..7a61e196ba9 100755 --- a/gui/wxpython/mapdisp/test_mapdisp.py +++ b/gui/wxpython/mapdisp/test_mapdisp.py @@ -53,7 +53,7 @@ import sys import wx -import grass.script as grass +import grass.script as gs from grass.script.setup import set_gui_path @@ -88,7 +88,7 @@ def GetMapWindow(self): # this is a copy of method from some frame class def copyOfInitMap(map_, width, height): """Initialize map display, set dimensions and map region""" - if not grass.find_program("g.region", "--help"): + if not gs.find_program("g.region", "--help"): sys.exit( _("GRASS module '%s' not found. Unable to start map display window.") % "g.region" @@ -306,7 +306,7 @@ def main(): # TODO: should messages here be translatable? # (for test its great, for translator not) - options, flags = grass.parser() + options, flags = gs.parser() test = options["test"] app = wx.App() @@ -356,9 +356,7 @@ def main(): tester.testMapWindowRlisetup(map_) else: # TODO: this should not happen but happens - import grass.script as sgrass - - sgrass.fatal(_("Unknown value %s of test parameter." % test)) + gs.fatal(_("Unknown value %s of test parameter." % test)) app.MainLoop() diff --git a/gui/wxpython/mapswipe/frame.py b/gui/wxpython/mapswipe/frame.py index ad9c54118c9..14c1fd91e28 100644 --- a/gui/wxpython/mapswipe/frame.py +++ b/gui/wxpython/mapswipe/frame.py @@ -19,7 +19,7 @@ import os import wx -import grass.script as grass +import grass.script as gs from gui_core.mapdisp import DoubleMapPanel, FrameMixin from gui_core.dialogs import GetImageHandlers @@ -222,11 +222,11 @@ def OnSashChanged(self, event): def OnSize(self, event): Debug.msg(4, "SwipeMapPanel.OnSize()") - self.resize = grass.clock() + self.resize = gs.clock() super().OnSize(event) def OnIdle(self, event): - if self.resize and grass.clock() - self.resize > 0.2: + if self.resize and gs.clock() - self.resize > 0.2: w1 = self.GetFirstWindow() w2 = self.GetSecondWindow() @@ -424,12 +424,11 @@ def OnSelectLayers(self, event): self._inputDialog = dlg dlg.CentreOnParent() dlg.Show() + elif self._inputDialog.IsShown(): + self._inputDialog.Raise() + self._inputDialog.SetFocus() else: - if self._inputDialog.IsShown(): - self._inputDialog.Raise() - self._inputDialog.SetFocus() - else: - self._inputDialog.Show() + self._inputDialog.Show() def _connectSimpleLmgr(self, lmgr, renderer): converter = LayerListToRendererConverter(renderer) @@ -472,7 +471,7 @@ def OnApplyInputChanges(self): def SetFirstRaster(self, name): """Set raster map to first Map""" if name: - raster = grass.find_file(name=name, element="cell") + raster = gs.find_file(name=name, element="cell") if raster.get("fullname"): self.rasters["first"] = raster["fullname"] self.SetLayer(name=raster["fullname"], mapInstance=self.GetFirstMap()) @@ -483,7 +482,7 @@ def SetFirstRaster(self, name): def SetSecondRaster(self, name): """Set raster map to second Map""" if name: - raster = grass.find_file(name=name, element="cell") + raster = gs.find_file(name=name, element="cell") if raster.get("fullname"): self.rasters["second"] = raster["fullname"] self.SetLayer(name=raster["fullname"], mapInstance=self.GetSecondMap()) @@ -536,8 +535,8 @@ def _saveToFile(self, fileName, fileType): w2 = self.splitter.GetWindow2() lineWidth = 1 # render to temporary files - filename1 = grass.tempfile(False) + "1" - filename2 = grass.tempfile(False) + "2" + filename1 = gs.tempfile(False) + "1" + filename2 = gs.tempfile(False) + "2" width, height = self.splitter.GetClientSize() class _onDone: @@ -569,7 +568,7 @@ def process(self2): im1 = wx.Image(filename1).GetSubImage((0, 0, -x, height)) im.Paste(im1, 0, 0) im.Paste(wx.Image(filename2), -x + lineWidth, -y) - else: + else: # noqa: PLR5501 if self.splitter.GetSplitMode() == wx.SPLIT_HORIZONTAL: im1 = wx.Image(filename1) im.Paste(im1, 0, 0) @@ -581,8 +580,8 @@ def process(self2): im.SaveFile(fileName, fileType) # remove temporary files - grass.try_remove(filename1) - grass.try_remove(filename2) + gs.try_remove(filename1) + gs.try_remove(filename2) callback = _onDone() if self._mode == "swipe": @@ -755,27 +754,27 @@ def Query(self, x, y): env = os.environ.copy() if rasters[0]: for raster in rasters[0]: - env["GRASS_REGION"] = grass.region_env(raster=raster) + env["GRASS_REGION"] = gs.region_env(raster=raster) result.extend( - grass.raster_what( + gs.raster_what( map=raster, coord=(east, north), localized=True, env=env ) ) if vectors[0]: result.extend( - grass.vector_what(map=vectors[0], coord=(east, north), distance=qdist) + gs.vector_what(map=vectors[0], coord=(east, north), distance=qdist) ) if rasters[1]: for raster in rasters[1]: - env["GRASS_REGION"] = grass.region_env(raster=raster) + env["GRASS_REGION"] = gs.region_env(raster=raster) result.extend( - grass.raster_what( + gs.raster_what( map=raster, coord=(east, north), localized=True, env=env ) ) if vectors[1]: result.extend( - grass.vector_what(map=vectors[1], coord=(east, north), distance=qdist) + gs.vector_what(map=vectors[1], coord=(east, north), distance=qdist) ) result = PrepareQueryResults(coordinates=(east, north), result=result) diff --git a/gui/wxpython/mapswipe/g.gui.mapswipe.py b/gui/wxpython/mapswipe/g.gui.mapswipe.py index c887be2548d..d4f19c0244a 100755 --- a/gui/wxpython/mapswipe/g.gui.mapswipe.py +++ b/gui/wxpython/mapswipe/g.gui.mapswipe.py @@ -45,11 +45,11 @@ # %end import os -import grass.script as gscript +import grass.script as gs def main(): - options, flags = gscript.parser() + options, flags = gs.parser() import wx @@ -74,9 +74,9 @@ def main(): for mapName in [first, second]: if mapName: - gfile = gscript.find_file(name=mapName) + gfile = gs.find_file(name=mapName) if not gfile["name"]: - gscript.fatal(_("Raster map <%s> not found") % mapName) + gs.fatal(_("Raster map <%s> not found") % mapName) app = wx.App() diff --git a/gui/wxpython/mapwin/base.py b/gui/wxpython/mapwin/base.py index 3a27713dfd9..e9752caf953 100644 --- a/gui/wxpython/mapwin/base.py +++ b/gui/wxpython/mapwin/base.py @@ -304,7 +304,7 @@ def UnregisterAllHandlers(self): Before each handler is unregistered it is called with string value "unregistered" of event parameter. """ - for containerEv, handlers in self.handlersContainer.items(): + for handlers in self.handlersContainer.values(): for handler in handlers: try: handler("unregistered") diff --git a/gui/wxpython/mapwin/buffered.py b/gui/wxpython/mapwin/buffered.py index 3d096031a1d..6ce7f98731e 100644 --- a/gui/wxpython/mapwin/buffered.py +++ b/gui/wxpython/mapwin/buffered.py @@ -31,7 +31,7 @@ from grass.pydispatch.signal import Signal from core.globalvar import wxPythonPhoenix -import grass.script as grass +import grass.script as gs from gui_core.dialogs import SavedRegion from gui_core.wrap import ( @@ -664,7 +664,7 @@ def OnPaint(self, event): def OnSize(self, event): """Scale map image so that it is the same size as the Window""" # re-render image on idle - self.resize = grass.clock() + self.resize = gs.clock() def OnIdle(self, event): """Only re-render a composite map image from GRASS during @@ -673,7 +673,7 @@ def OnIdle(self, event): # use OnInternalIdle() instead ? - if self.resize and self.resize + 0.2 < grass.clock(): + if self.resize and self.resize + 0.2 < gs.clock(): Debug.msg(3, "BufferedWindow.OnSize():") # set size of the input image @@ -1072,11 +1072,15 @@ def DrawCompRegionExtent(self): reg = dispReg if utils.isInRegion(dispReg, compReg) else compReg regionCoords = [] - regionCoords.append((reg["w"], reg["n"])) - regionCoords.append((reg["e"], reg["n"])) - regionCoords.append((reg["e"], reg["s"])) - regionCoords.append((reg["w"], reg["s"])) - regionCoords.append((reg["w"], reg["n"])) + regionCoords.extend( + ( + (reg["w"], reg["n"]), + (reg["e"], reg["n"]), + (reg["e"], reg["s"]), + (reg["w"], reg["s"]), + (reg["w"], reg["n"]), + ) + ) # draw region extent self.polypen = wx.Pen( @@ -1526,7 +1530,7 @@ def OnDragging(self, event): self.mouse["end"] = event.GetPosition() if event.LeftIsDown() and not ( digitToolbar - and digitToolbar.GetAction() in {"moveLine"} + and digitToolbar.GetAction() == "moveLine" and len(self.digit.GetDisplay().GetSelected()) > 0 ): self.MouseDraw(pdc=self.pdcTmp) @@ -2129,7 +2133,7 @@ def SetRegion(self, zoomOnly=True): return region = dlg.GetName() - if not grass.find_file(name=region, element="windows")["name"]: + if not gs.find_file(name=region, element="windows")["name"]: GError( parent=self, message=_("Region <%s> not found. Operation canceled.") % region, @@ -2171,7 +2175,7 @@ def SaveRegion(self, display=True): return # test to see if it already exists and ask permission to overwrite - if grass.find_file(name=dlg.GetName(), element="windows")["name"]: + if gs.find_file(name=dlg.GetName(), element="windows")["name"]: overwrite = wx.MessageBox( parent=self, message=_( diff --git a/gui/wxpython/mapwin/decorations.py b/gui/wxpython/mapwin/decorations.py index 9e2051a435d..fef02581715 100644 --- a/gui/wxpython/mapwin/decorations.py +++ b/gui/wxpython/mapwin/decorations.py @@ -211,9 +211,8 @@ def CmdIsValid(self): param = param.split("=") if len(param) == 1: inputs += 1 - else: - if param[0] == "text" and len(param) == 2: - inputs += 1 + elif param[0] == "text" and len(param) == 2: + inputs += 1 if inputs >= 1: return True return False @@ -318,11 +317,10 @@ def CmdIsValid(self): param = param.split("=") if len(param) == 1: inputs += 1 - else: - if param[0] == "raster" and len(param) == 2: - inputs += 1 - elif param[0] == "raster_3d" and len(param) == 2: - inputs += 1 + elif param[0] == "raster" and len(param) == 2: + inputs += 1 + elif param[0] == "raster_3d" and len(param) == 2: + inputs += 1 if inputs == 1: return True return False diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index 2fb97ae3aab..569bb4e5d7d 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -32,7 +32,7 @@ import wx.lib.scrolledpanel as scrolled import wx.lib.filebrowsebutton as filebrowse -import grass.script as grass +import grass.script as gs from grass.script.task import cmdlist_to_tuple from core import globalvar @@ -713,7 +713,7 @@ def ReadColorTable(self, ctable): minim = maxim = count = 0 for line in ctable.splitlines(): try: - value, color = map(lambda x: x.strip(), line.split(" ")) + value, color = (x.strip() for x in line.split(" ")) except ValueError: GMessage(parent=self, message=_("Invalid color table format")) self.rulesPanel.Clear() @@ -941,7 +941,7 @@ def OnSelectionInput(self, event): self.saveRules.SetValue("") if self.inmap: - if not grass.find_file(name=self.inmap, element="cell")["file"]: + if not gs.find_file(name=self.inmap, element="cell")["file"]: self.inmap = None if not self.inmap: @@ -956,7 +956,7 @@ def OnSelectionInput(self, event): self.LoadTable() return - info = grass.raster_info(map=self.inmap) + info = gs.raster_info(map=self.inmap) if info: self.properties["min"] = info["min"] @@ -1013,15 +1013,15 @@ def OnPreview(self, tmp=True): name, mapset = self.inmap.split("@") except ValueError: name = self.inmap - mapset = grass.find_file(self.inmap, element="cell")["mapset"] + mapset = gs.find_file(self.inmap, element="cell")["mapset"] if not mapset: return self._tmp = tmp self._old_colrtable = None - if mapset == grass.gisenv()["MAPSET"]: - self._old_colrtable = grass.find_file(name=name, element="colr")["file"] + if mapset == gs.gisenv()["MAPSET"]: + self._old_colrtable = gs.find_file(name=name, element="colr")["file"] else: - self._old_colrtable = grass.find_file(name=name, element="colr2/" + mapset)[ + self._old_colrtable = gs.find_file(name=name, element="colr2/" + mapset)[ "file" ] @@ -1055,7 +1055,7 @@ def __init__(self, parent, attributeType, **kwargs): self.mapType = "vector" self.attributeType = attributeType # color, size, width # in version 7 v.colors used, otherwise color column only - self.version7 = int(grass.version()["version"].split(".")[0]) >= 7 + self.version7 = int(gs.version()["version"].split(".")[0]) >= 7 self.colorTable = False self.updateColumn = True # vector properties @@ -1244,8 +1244,8 @@ def OnPaneChanged(self, event=None): def CheckMapset(self): """Check if current vector is in current mapset""" if ( - grass.find_file(name=self.inmap, element="vector")["mapset"] - == grass.gisenv()["MAPSET"] + gs.find_file(name=self.inmap, element="vector")["mapset"] + == gs.gisenv()["MAPSET"] ): return True else: @@ -1320,7 +1320,7 @@ def OnSelectionInput(self, event): self.saveRules.SetValue("") if self.inmap: - if not grass.find_file(name=self.inmap, element="vector")["file"]: + if not gs.find_file(name=self.inmap, element="vector")["file"]: self.inmap = None self.UpdateDialog() @@ -1338,7 +1338,7 @@ def UpdateDialog(self): message = _( "Selected map <%(map)s> is not in current mapset <%(mapset)s>. " "Attribute table cannot be edited." - ) % {"map": self.inmap, "mapset": grass.gisenv()["MAPSET"]} + ) % {"map": self.inmap, "mapset": gs.gisenv()["MAPSET"]} wx.CallAfter(GMessage, parent=self, message=message) self.DisableClearAll() return @@ -1695,7 +1695,7 @@ def SetRangeLabel(self): ) else: self.cr_label.SetLabel(_("Enter vector attribute values %s:") % range) - else: + else: # noqa: PLR5501 if self.colorTable: self.cr_label.SetLabel(_("Enter vector attribute values or percents:")) else: @@ -1732,17 +1732,17 @@ def OnTablePreview(self, tmp): name, mapset = self.inmap.split("@") except ValueError: name = self.inmap - mapset = grass.find_file(self.inmap, element="cell")["mapset"] + mapset = gs.find_file(self.inmap, element="cell")["mapset"] if not mapset: return old_colrtable = None - if mapset == grass.gisenv()["MAPSET"]: - old_colrtable = grass.find_file( + if mapset == gs.gisenv()["MAPSET"]: + old_colrtable = gs.find_file( name="colr", element=os.path.join("vector", name) )["file"] else: - old_colrtable = grass.find_file( + old_colrtable = gs.find_file( name=name, element=os.path.join("vcolr2", mapset) )["file"] @@ -1809,11 +1809,10 @@ def CreateColorTable(self, tmp=False): """Create color rules (color table or color column)""" if self.colorTable: ret = ColorTable.CreateColorTable(self) + elif self.updateColumn: + ret = self.UpdateColorColumn(tmp) else: - if self.updateColumn: - ret = self.UpdateColorColumn(tmp) - else: - ret = True + ret = True return ret @@ -1901,12 +1900,12 @@ def _columnWidgetEvtHandler(self, bind=True): ] for widget in widgets: if bind is True: - getattr(widget["widget"], "Bind")( + widget["widget"].Bind( widget["event"], widget["handler"], ) else: - getattr(widget["widget"], "Unbind")(widget["event"]) + widget["widget"].Unbind(widget["event"]) class ThematicVectorTable(VectorColorTable): @@ -1939,17 +1938,13 @@ def _apply(self, updatePreview=True): value = None if self.properties["storeColumn"]: value = self.properties["storeColumn"] + if self.colorTable: + value = None - if not self.colorTable: - if self.attributeType == "color": - data["vector"][self.vectorType]["thematic"]["rgbcolumn"] = value - else: - data["vector"][self.vectorType]["thematic"]["sizecolumn"] = value + if self.attributeType == "color": + data["vector"][self.vectorType]["thematic"]["rgbcolumn"] = value else: - if self.attributeType == "color": - data["vector"][self.vectorType]["thematic"]["rgbcolumn"] = None - else: - data["vector"][self.vectorType]["thematic"]["sizecolumn"] = None + data["vector"][self.vectorType]["thematic"]["sizecolumn"] = value data["vector"][self.vectorType]["thematic"]["update"] = None diff --git a/gui/wxpython/modules/extensions.py b/gui/wxpython/modules/extensions.py index 2b83bd8e040..f7822e0cb0e 100644 --- a/gui/wxpython/modules/extensions.py +++ b/gui/wxpython/modules/extensions.py @@ -84,8 +84,7 @@ def __init__( task = gtask.parse_interface("g.extension") ignoreFlags = ["l", "c", "g", "a", "f", "t", "help", "quiet"] if sys.platform == "win32": - ignoreFlags.append("d") - ignoreFlags.append("i") + ignoreFlags.extend(("d", "i")) for f in task.get_options()["flags"]: name = f.get("name", "") @@ -386,9 +385,8 @@ def Load(self, url, full=True): mainNode = self.mainNodes[self._expandPrefix(prefix)] currentNode = self.model.AppendNode(parent=mainNode, label=value) currentNode.data = {"command": value} - else: - if currentNode is not None: - currentNode.data[key] = value + elif currentNode is not None: + currentNode.data[key] = value else: try: prefix, name = line.strip().split(".", 1) diff --git a/gui/wxpython/modules/mcalc_builder.py b/gui/wxpython/modules/mcalc_builder.py index 221e5198955..e157375b4a4 100644 --- a/gui/wxpython/modules/mcalc_builder.py +++ b/gui/wxpython/modules/mcalc_builder.py @@ -20,7 +20,7 @@ import re import wx -import grass.script as grass +import grass.script as gs from core import globalvar from core.gcmd import GError, RunCommand @@ -700,14 +700,14 @@ def OnDone(self, event): """ if event.returncode != 0: return - name = self.newmaptxt.GetValue().strip(' "') + "@" + grass.gisenv()["MAPSET"] + name = self.newmaptxt.GetValue().strip(' "') + "@" + gs.gisenv()["MAPSET"] ltype = "raster" if self.rast3d: ltype = "raster_3d" self._giface.mapCreated.emit( name=name, ltype=ltype, add=self.addbox.IsChecked() ) - gisenv = grass.gisenv() + gisenv = gs.gisenv() self._giface.grassdbChanged.emit( grassdb=gisenv["GISDBASE"], location=gisenv["LOCATION_NAME"], diff --git a/gui/wxpython/nviz/mapwindow.py b/gui/wxpython/nviz/mapwindow.py index 40fb23e6a38..bbd6bcaa3bb 100644 --- a/gui/wxpython/nviz/mapwindow.py +++ b/gui/wxpython/nviz/mapwindow.py @@ -31,7 +31,7 @@ from wx import glcanvas from wx.glcanvas import WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE -import grass.script as grass +import grass.script as gs from grass.pydispatch.signal import Signal from core.gcmd import GMessage, GException, GError @@ -243,7 +243,7 @@ def GetContentScaleFactor(self): def InitFly(self): """Initialize fly through dictionary""" - fly = { + return { "interval": 10, # interval for timerFly "value": [0, 0, 0], # calculated values for navigation "mode": 0, # fly through mode (0, 1) @@ -264,8 +264,6 @@ def InitFly(self): "flySpeedStep": 2, } - return fly - def OnTimerFly(self, event): """Fly event was emitted, move the scene""" if self.mouse["use"] != "fly": @@ -569,11 +567,10 @@ def OnKeyDown(self, event): self.ProcessFlyByArrows(keyCode=key) # change speed of flight when using mouse - else: - if key == wx.WXK_UP: - self.ChangeFlySpeed(increase=True) - elif key == wx.WXK_DOWN: - self.ChangeFlySpeed(increase=False) + elif key == wx.WXK_UP: + self.ChangeFlySpeed(increase=True) + elif key == wx.WXK_DOWN: + self.ChangeFlySpeed(increase=False) elif key in {wx.WXK_HOME, wx.WXK_PAGEUP} and self.timerFly.IsRunning(): self.ChangeFlySpeed(increase=True) @@ -1190,7 +1187,7 @@ def UpdateMap(self, render=True, reRenderTool=False): if not self.parent.mapWindowProperties.autoRender and not reRenderTool: return - start = grass.clock() + start = gs.clock() self.resize = False @@ -1234,7 +1231,7 @@ def UpdateMap(self, render=True, reRenderTool=False): self._display.Start2D() self.DrawImages() - stop = grass.clock() + stop = gs.clock() if self.render["quick"] is False: if sys.platform != "darwin": @@ -1364,7 +1361,7 @@ def LoadDataLayers(self): item = self.tree.GetFirstChild(self.tree.root)[0] self._GetDataLayers(item, listOfItems) - start = grass.clock() + start = gs.clock() while len(listOfItems) > 0: item = listOfItems.pop() @@ -1382,7 +1379,7 @@ def LoadDataLayers(self): self.LoadRaster3d(item) elif type == "vector": layer = self.tree.GetLayerInfo(item, key="maplayer") - vInfo = grass.vector_info_topo(layer.GetName()) + vInfo = gs.vector_info_topo(layer.GetName()) if (vInfo["points"]) > 0: # include vInfo['centroids'] to initially load # centroids @@ -1399,7 +1396,7 @@ def LoadDataLayers(self): except: pass - stop = grass.clock() + stop = gs.clock() Debug.msg(1, "GLWindow.LoadDataLayers(): time = %f" % (stop - start)) @@ -1416,7 +1413,7 @@ def UnloadDataLayers(self, force=False): item = self.tree.GetFirstChild(self.tree.root)[0] self._GetDataLayers(item, listOfItems) - start = grass.clock() + start = gs.clock() update = False layersTmp = self.layers[:] @@ -1431,7 +1428,7 @@ def UnloadDataLayers(self, force=False): self.UnloadRaster3d(layer) elif ltype == "vector": maplayer = self.tree.GetLayerInfo(layer, key="maplayer") - vInfo = grass.vector_info_topo(maplayer.GetName()) + vInfo = gs.vector_info_topo(maplayer.GetName()) if (vInfo["points"] + vInfo["centroids"]) > 0: self.UnloadVector(layer, points=True) if (vInfo["lines"] + vInfo["boundaries"]) > 0 or vInfo["map3d"]: @@ -1447,7 +1444,7 @@ def UnloadDataLayers(self, force=False): self.lmgr.nviz.UpdateSettings() self.UpdateView(None) - stop = grass.clock() + stop = gs.clock() Debug.msg(1, "GLWindow.UnloadDataLayers(): time = %f" % (stop - start)) @@ -1883,12 +1880,12 @@ def ResetView(self): # hack for latlon projection # TODO find more precise way or better rewrite it in OGSF self.iview["z-exag"]["llRatio"] = 1 - if grass.locn_is_latlong(): + if gs.locn_is_latlong(): self.iview["z-exag"]["llRatio"] = ( math.pi / 180 * 6371000 - * math.cos((grass.region()["n"] + grass.region()["s"]) / 2) + * math.cos((gs.region()["n"] + gs.region()["s"]) / 2) ) self.view["z-exag"]["value"] = round( @@ -1996,7 +1993,7 @@ def UpdateSurfaceProperties(self, id, data): if isinstance(value, str): if len(value) == 0: # ignore empty values (TODO: warning) continue - if map and not grass.find_file(value, element="cell")["fullname"]: + if map and not gs.find_file(value, element="cell")["fullname"]: continue if attrb == "color": self._display.SetSurfaceColor(id, map, str(value)) @@ -2079,14 +2076,13 @@ def UpdateVolumeProperties(self, id, data, isosurfId=None): ) ) self._display.SetIsosurfaceMode(id, mode) - else: - if data["draw"]["shading"]["slice"]["value"] < 0: # need to calculate - mode = data["draw"]["shading"]["slice"]["value"] = ( - self.nvizDefault.GetDrawMode( - shade=data["draw"]["shading"]["slice"], string=False - ) + elif data["draw"]["shading"]["slice"]["value"] < 0: # need to calculate + mode = data["draw"]["shading"]["slice"]["value"] = ( + self.nvizDefault.GetDrawMode( + shade=data["draw"]["shading"]["slice"], string=False ) - self._display.SetSliceMode(id, mode) + ) + self._display.SetSliceMode(id, mode) data["draw"]["shading"].pop("update") # @@ -2115,10 +2111,7 @@ def UpdateVolumeProperties(self, id, data, isosurfId=None): if isinstance(value, str): if len(value) == 0: # ignore empty values (TODO: warning) continue - if ( - map - and not grass.find_file(value, element="grid3")["fullname"] - ): + if map and not gs.find_file(value, element="grid3")["fullname"]: continue if attrb == "color": self._display.SetIsosurfaceColor(id, isosurfId, map, str(value)) @@ -2387,7 +2380,7 @@ def ReloadLayersData(self): if type == "raster": self.nvizDefault.SetSurfaceDefaultProp(data["surface"]) if type == "vector": - vInfo = grass.vector_info_topo(layer.GetName()) + vInfo = gs.vector_info_topo(layer.GetName()) if (vInfo["points"] + vInfo["centroids"]) > 0: self.nvizDefault.SetVectorPointsDefaultProp( data["vector"]["points"], self._display.GetLongDim() @@ -2494,13 +2487,12 @@ def NvizCmdCommand(self): cmdColorMap += ( "%s," % self.tree.GetLayerInfo(item, key="maplayer").GetName() ) + elif nvizData["color"]["map"]: + cmdColorMap += "%s," % nvizData["color"]["value"] else: - if nvizData["color"]["map"]: - cmdColorMap += "%s," % nvizData["color"]["value"] - else: - cmdColorVal += "%s," % nvizData["color"]["value"] - # TODO - # transparency, shine, mask + cmdColorVal += "%s," % nvizData["color"]["value"] + # TODO + # transparency, shine, mask for item in self.constants: cmdColorVal += "%s," % item["constant"]["color"] if cmdColorMap.split("=")[1]: @@ -2529,7 +2521,7 @@ def NvizCmdCommand(self): ] for vector in vectors: layerName = self.tree.GetLayerInfo(vector, key="maplayer").GetName() - vInfo = grass.vector_info_topo(layerName) + vInfo = gs.vector_info_topo(layerName) nvizData = self.tree.GetLayerInfo(vector, key="nviz")["vector"] if (vInfo["lines"] + vInfo["boundaries"]) > 0: cmdLines += ( diff --git a/gui/wxpython/nviz/tools.py b/gui/wxpython/nviz/tools.py index cff26db4ca8..02341420cc3 100644 --- a/gui/wxpython/nviz/tools.py +++ b/gui/wxpython/nviz/tools.py @@ -43,7 +43,7 @@ import wx.lib.agw.floatspin as fs except ImportError: fs = None -import grass.script as grass +import grass.script as gs from core import globalvar from gui_core.gselect import VectorDBInfo @@ -2642,7 +2642,7 @@ def GetLayerData(self, nvizType, nameOnly=False): if nameOnly: return name - if nvizType == "surface" or nvizType == "fringe": + if nvizType in {"surface", "fringe"}: return self._getLayerPropertiesByName(name, mapType="raster") elif nvizType == "vector": return self._getLayerPropertiesByName(name, mapType="vector") @@ -3320,9 +3320,8 @@ def __GetWindowName(self, data, id): for win in data[name].values(): if win == id: return name - else: - if data[name] == id: - return name + elif data[name] == id: + return name return None @@ -3532,14 +3531,13 @@ def OnLookAt(self, event): self.PostViewEvent(zExag=True) self.UpdateSettings() self.mapWindow.Refresh(False) - else: # here - if self.FindWindowById(event.GetId()).GetValue(): - self.mapDisplay.Raise() - self.mapWindow.mouse["use"] = "lookHere" - self.mapWindow.SetNamedCursor("cross") - else: - self.mapWindow.mouse["use"] = "default" - self.mapWindow.SetNamedCursor("default") + elif self.FindWindowById(event.GetId()).GetValue(): + self.mapDisplay.Raise() + self.mapWindow.mouse["use"] = "lookHere" + self.mapWindow.SetNamedCursor("cross") + else: + self.mapWindow.mouse["use"] = "default" + self.mapWindow.SetNamedCursor("default") def OnResetView(self, event): """Reset to default view (view page)""" @@ -3694,14 +3692,10 @@ def EnablePage(self, name, enabled=True): for ssitem in self.win[name][key][skey].values(): if not isinstance(ssitem, bool) and isinstance(ssitem, int): self.FindWindowById(ssitem).Enable(enabled) - else: - # type(bool) != types.IntType but - # isinstance(bool) == types.IntType - if not isinstance(sitem, bool) and isinstance(sitem, int): - self.FindWindowById(sitem).Enable(enabled) - else: - if not isinstance(item, bool) and isinstance(item, int): - self.FindWindowById(item).Enable(enabled) + elif not isinstance(sitem, bool) and isinstance(sitem, int): + self.FindWindowById(sitem).Enable(enabled) + elif not isinstance(item, bool) and isinstance(item, int): + self.FindWindowById(item).Enable(enabled) def SetMapObjUseMap(self, nvizType, attrb, map=None): """Update dialog widgets when attribute type changed""" @@ -4044,7 +4038,7 @@ def UpdateVectorShow(self, vecType, enabled): :param vecType: vector type (lines, points) """ - if vecType != "lines" and vecType != "points": + if vecType not in {"lines", "points"}: return False for win in self.win["vector"][vecType].keys(): @@ -4060,11 +4054,10 @@ def UpdateVectorShow(self, vecType, enabled): self.FindWindowById( self.win["vector"][vecType][win][swin] ).Enable(False) + elif enabled: + self.FindWindowById(self.win["vector"][vecType][win]).Enable(True) else: - if enabled: - self.FindWindowById(self.win["vector"][vecType][win]).Enable(True) - else: - self.FindWindowById(self.win["vector"][vecType][win]).Enable(False) + self.FindWindowById(self.win["vector"][vecType][win]).Enable(False) return True @@ -4560,13 +4553,12 @@ def OnVolumeCheck(self, event): else: # disable -> make transparent self._display.SetIsosurfaceTransp(vid, id, False, "255") + elif list.IsChecked(index): + value = data["slice"][id]["transp"]["value"] + self._display.SetSliceTransp(vid, id, value) else: - if list.IsChecked(index): - value = data["slice"][id]["transp"]["value"] - self._display.SetSliceTransp(vid, id, value) - else: - # disable -> make transparent - self._display.SetSliceTransp(vid, id, 255) + # disable -> make transparent + self._display.SetSliceTransp(vid, id, 255) self.mapWindow.Refresh(False) @@ -4720,11 +4712,10 @@ def OnVolumeDelete(self, event): self.UpdateVolumeIsosurfPage(data["isosurface"][list.GetSelection()]) else: self.UpdateVolumeSlicePage(data["slice"][list.GetSelection()]) + elif mode == "isosurf": + self.UpdateVolumeIsosurfPage(data["attribute"]) else: - if mode == "isosurf": - self.UpdateVolumeIsosurfPage(data["attribute"]) - else: - self.UpdateVolumeSlicePage(None) + self.UpdateVolumeSlicePage(None) self.UpdateIsosurfButtons(list) self.mapWindow.Refresh(False) @@ -5377,7 +5368,7 @@ def UpdateCPlanePage(self, index): def UpdateSurfacePage(self, layer, data, updateName=True): """Update surface page""" - desc = grass.raster_info(layer.name)["title"] + desc = gs.raster_info(layer.name)["title"] if updateName: self.FindWindowById(self.win["surface"]["map"]).SetValue(layer.name) self.FindWindowById(self.win["surface"]["desc"]).SetLabel(desc) @@ -5503,7 +5494,7 @@ def UpdateSurfacePage(self, layer, data, updateName=True): def UpdateVectorPage(self, layer, data, updateName=True): """Update vector page""" - vInfo = grass.vector_info_topo(layer.GetName()) + vInfo = gs.vector_info_topo(layer.GetName()) if not vInfo: return if vInfo["map3d"]: @@ -5746,18 +5737,17 @@ def UpdateVolumeIsosurfPage(self, data): self.FindWindowById(self.win["volume"][attrb]["const"]).SetColour( color ) - else: + else: # noqa: PLR5501 if data[attrb]["map"]: self.vetoGSelectEvt = True win = self.FindWindowById(self.win["volume"][attrb]["map"]) win.SetValue(value) - else: - if value: - win = self.FindWindowById(self.win["volume"][attrb]["const"]) - if attrb == "topo": - win.SetValue(float(value)) - else: - win.SetValue(self._getPercent(value)) + elif value: + win = self.FindWindowById(self.win["volume"][attrb]["const"]) + if attrb == "topo": + win.SetValue(float(value)) + else: + win.SetValue(self._getPercent(value)) self.SetMapObjUseMap(nvizType="volume", attrb=attrb, map=data[attrb]["map"]) # set inout diff --git a/gui/wxpython/nviz/wxnviz.py b/gui/wxpython/nviz/wxnviz.py index 2ca63708f0d..8002d6f32d2 100644 --- a/gui/wxpython/nviz/wxnviz.py +++ b/gui/wxpython/nviz/wxnviz.py @@ -61,7 +61,7 @@ from core.gcmd import DecodeString from core.globalvar import wxPythonPhoenix from gui_core.wrap import Rect -import grass.script as grass +import grass.script as gs log = None progress = None @@ -2162,7 +2162,7 @@ def __del__(self): """Delete texture""" if self.textureId: Nviz_del_texture(self.textureId) - grass.try_remove(self.path) + gs.try_remove(self.path) def Resize(self): """Resize image to match 2^n""" @@ -2212,9 +2212,7 @@ def Load(self): ] wx.EndBusyCursor() - id = Nviz_load_image(im, self.width, self.height, self.image.HasAlpha()) - - return id + return Nviz_load_image(im, self.width, self.height, self.image.HasAlpha()) def Draw(self): """Draw texture as an image""" diff --git a/gui/wxpython/photo2image/g.gui.photo2image.py b/gui/wxpython/photo2image/g.gui.photo2image.py index 315f33fe6f1..21635175374 100755 --- a/gui/wxpython/photo2image/g.gui.photo2image.py +++ b/gui/wxpython/photo2image/g.gui.photo2image.py @@ -71,12 +71,12 @@ @author Vaclav Petras (standalone module) """ import os -import grass.script as gscript +import grass.script as gs def main(): """Sets the GRASS display driver""" - options, flags = gscript.parser() + options, flags = gs.parser() import wx from grass.script.setup import set_gui_path @@ -96,29 +96,29 @@ def main(): if options["group"]: group = options["group"] else: - gscript.fatal(_("Please provide a group name to process")) + gs.fatal(_("Please provide a group name to process")) if options["raster"]: raster = options["raster"] else: - gscript.fatal(_("Please provide a raster map name to process")) + gs.fatal(_("Please provide a raster map name to process")) if options["camera"]: camera = options["camera"] else: - gscript.fatal(_("Please provide a camera name (generated by i.ortho.camera)")) + gs.fatal(_("Please provide a camera name (generated by i.ortho.camera)")) if options["order"]: order = options["order"] else: - gscript.fatal( + gs.fatal( _("Please provive an order value (1 if 4 Fiducials, 2 if 8 Fiducials)") ) if options["extension"]: extension = options["extension"] else: - gscript.fatal(_("Please provive an output files extension (used by i.rectify)")) + gs.fatal(_("Please provive an output files extension (used by i.rectify)")) app = wx.App() diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index 34346f39cae..b4d24d19430 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -35,7 +35,7 @@ from wx.lib.mixins.listctrl import ColumnSorterMixin, ListCtrlAutoWidthMixin import wx.lib.colourselect as csel -import grass.script as grass +import grass.script as gs from core import utils, globalvar from core.render import Map @@ -59,9 +59,7 @@ # # global variables # -global src_map -global tgt_map -global maptype +global src_map, tgt_map, maptype src_map = "" tgt_map = "" @@ -95,9 +93,7 @@ class GCPWizard: def __init__( self, parent, giface, group, raster, raster1, camera, order, extension ): - global maptype - global src_map - global tgt_map + global maptype, src_map, tgt_map maptype = "raster" rendertype = "raster" self.parent = parent # GMFrame @@ -113,7 +109,7 @@ def __init__( # # get environmental variables # - self.grassdatabase = grass.gisenv()["GISDBASE"] + self.grassdatabase = gs.gisenv()["GISDBASE"] # # read original environment settings @@ -123,7 +119,7 @@ def __init__( self.gisrc_dict = {} try: f = open(self.target_gisrc, "r") - for line in f.readlines(): + for line in f: line = line.replace("\n", "").strip() if len(line) < 1: continue @@ -806,7 +802,7 @@ def SetGCPSatus(self, item, itemIndex): wxPen = "highest" else: wxPen = "default" - else: + else: # noqa: PLR5501 if self.mapcoordlist[key][5] > self.rmsthresh: wxPen = "highest" else: @@ -963,7 +959,7 @@ def ReadGCPs(self): f = open(self.file["points"], "r") GCPcnt = 0 - for line in f.readlines(): + for line in f: if line[0] == "#" or line == "": continue line = line.replace("\n", "").strip() @@ -1585,13 +1581,13 @@ def OnZoomMenuGCP(self, event): def OnSize(self, event): """Adjust Map Windows after GCP Map Display has been resized""" # re-render image on idle - self.resize = grass.clock() + self.resize = gs.clock() super(MapPanel, self).OnSize(event) def OnIdle(self, event): """GCP Map Display resized, adjust Map Windows""" if self.GetMapToolbar(): - if self.resize and self.resize + 0.2 < grass.clock(): + if self.resize and self.resize + 0.2 < gs.clock(): srcwidth, srcheight = self.SrcMapWindow.GetSize() tgtwidth, tgtheight = self.TgtMapWindow.GetSize() srcwidth = (srcwidth + tgtwidth) / 2 @@ -1977,10 +1973,14 @@ def GetValues(self, columns=None): except ValueError: return valuelist - valuelist.append(self.xcoord.GetValue()) - valuelist.append(self.ycoord.GetValue()) - valuelist.append(self.ecoord.GetValue()) - valuelist.append(self.ncoord.GetValue()) + valuelist.extend( + ( + self.xcoord.GetValue(), + self.ycoord.GetValue(), + self.ecoord.GetValue(), + self.ncoord.GetValue(), + ) + ) return valuelist @@ -2402,9 +2402,7 @@ def OnExtension(self, event): self.parent.extension = self.ext_txt.GetValue() def UpdateSettings(self): - global src_map - global tgt_map - global maptype + global src_map, tgt_map, maptype layers = None @@ -2529,7 +2527,7 @@ def UpdateSettings(self): self.parent.activemap.SetSelection(0) self.parent.activemap.Enable(False) self.parent.GetMapToolbar().Enable("zoommenu", enable=False) - else: + else: # noqa: PLR5501 if not self.parent.show_target: self.parent.show_target = True self.parent._mgr.GetPane("target").Show() diff --git a/gui/wxpython/psmap/dialogs.py b/gui/wxpython/psmap/dialogs.py index 7924b3d807e..42a3ef862e3 100644 --- a/gui/wxpython/psmap/dialogs.py +++ b/gui/wxpython/psmap/dialogs.py @@ -49,7 +49,7 @@ else: from wx import PyValidator as Validator -import grass.script as grass +import grass.script as gs from core.utils import PilImageToWxImage from dbmgr.vinfo import VectorDBInfo @@ -891,7 +891,7 @@ def updateDialog(self): self.mPanel.drawMap.SetValue(True) else: self.mPanel.drawMap.SetValue(False) - else: + else: # noqa: PLR5501 if "vector" in self.parent.openDialogs: found = False for each in self.parent.openDialogs["vector"].vPanel.vectorList: @@ -1376,7 +1376,7 @@ def update(self): if mapFrameDict["drawMap"]: if mapFrameDict["mapType"] == "raster": - mapFile = grass.find_file(mapFrameDict["map"], element="cell") + mapFile = gs.find_file(mapFrameDict["map"], element="cell") if mapFile["file"] == "": GMessage("Raster %s not found" % mapFrameDict["map"]) return False @@ -1390,7 +1390,7 @@ def update(self): self.instruction.AddInstruction(raster) elif mapFrameDict["mapType"] == "vector": - mapFile = grass.find_file(mapFrameDict["map"], element="vector") + mapFile = gs.find_file(mapFrameDict["map"], element="vector") if mapFile["file"] == "": GMessage("Vector %s not found" % mapFrameDict["map"]) return False @@ -1402,7 +1402,7 @@ def update(self): if each[0] == mapFrameDict["map"]: isAdded = True if not isAdded: - topoInfo = grass.vector_info_topo(map=mapFrameDict["map"]) + topoInfo = gs.vector_info_topo(map=mapFrameDict["map"]) if topoInfo: if bool(topoInfo["areas"]): topoType = "areas" @@ -1449,7 +1449,7 @@ def update(self): mapFrameDict["center"] = self.center[0] # set region if self.mapType == "raster": - self.env["GRASS_REGION"] = grass.region_env( + self.env["GRASS_REGION"] = gs.region_env( raster=mapFrameDict["map"], env=self.env ) if self.mapType == "vector": @@ -1460,13 +1460,13 @@ def update(self): rasterId = None if rasterId: - self.env["GRASS_REGION"] = grass.region_env( + self.env["GRASS_REGION"] = gs.region_env( vector=mapFrameDict["map"], raster=self.instruction[rasterId]["raster"], env=self.env, ) else: - self.env["GRASS_REGION"] = grass.region_env( + self.env["GRASS_REGION"] = gs.region_env( vector=mapFrameDict["map"], env=self.env ) @@ -1499,7 +1499,7 @@ def update(self): mapFrameDict["scale"] = self.scale[1] mapFrameDict["center"] = self.center[1] # set region - self.env["GRASS_REGION"] = grass.region_env( + self.env["GRASS_REGION"] = gs.region_env( region=mapFrameDict["region"], env=self.env ) else: @@ -1525,7 +1525,7 @@ def update(self): mapFrameDict["scale"] = self.scale[2] mapFrameDict["center"] = self.center[2] - region = grass.region(env=None) + region = gs.region(env=None) raster = self.instruction.FindInstructionByType("raster") if raster: @@ -1534,7 +1534,7 @@ def update(self): rasterId = None if rasterId: # because of resolution - self.env["GRASS_REGION"] = grass.region_env( + self.env["GRASS_REGION"] = gs.region_env( n=region["n"], s=region["s"], e=region["e"], @@ -1543,7 +1543,7 @@ def update(self): env=self.env, ) else: - self.env["GRASS_REGION"] = grass.region_env( + self.env["GRASS_REGION"] = gs.region_env( n=region["n"], s=region["s"], e=region["e"], @@ -1888,13 +1888,13 @@ def _layout(self): def OnVector(self, event): """Gets info about toplogy and enables/disables choices point/line/area""" vmap = self.select.GetValue() - if not grass.find_file( + if not gs.find_file( vmap, element="vector", )["name"]: return - topoInfo = grass.vector_info_topo(map=vmap) + topoInfo = gs.vector_info_topo(map=vmap) if topoInfo: self.vectorType.EnableItem(2, bool(topoInfo["areas"])) self.vectorType.EnableItem( @@ -2053,9 +2053,8 @@ def update(self): vLayer["label"] = item[4] vLayer["lpos"] = item[3] - else: - if self.id in self.instruction: - del self.instruction[self.id] + elif self.id in self.instruction: + del self.instruction[self.id] if "map" in self.parent.parent.openDialogs: self.parent.parent.openDialogs["map"].updateDialog() @@ -2178,7 +2177,7 @@ def __init__(self, parent, id, vectors, tmpSettings): try: self.mapDBInfo = VectorDBInfo(self.vectorName) self.layers = self.mapDBInfo.layers.keys() - except grass.ScriptError: + except gs.ScriptError: self.connection = False self.layers = [] if not self.layers: @@ -3200,8 +3199,7 @@ def getColsChoice(self, parent): else: cols = [] - choice = Choice(parent=parent, id=wx.ID_ANY, choices=cols) - return choice + return Choice(parent=parent, id=wx.ID_ANY, choices=cols) def update(self): # feature type @@ -3540,7 +3538,7 @@ def _rasterLegend(self, notebook): self.ticks.SetValue(False) # range if self.rasterId and self.instruction[self.rasterId]["raster"]: - rinfo = grass.raster_info(self.instruction[self.rasterId]["raster"]) + rinfo = gs.raster_info(self.instruction[self.rasterId]["raster"]) self.minim, self.maxim = rinfo["min"], rinfo["max"] else: self.minim, self.maxim = 0, 0 @@ -3979,7 +3977,7 @@ def OnIsLegend(self, event): if page == 0 or event is None: children = self.panelRaster.GetChildren() if self.isRLegend.GetValue(): - for i, widget in enumerate(children): + for widget in children: widget.Enable() self.OnRaster(None) self.OnRange(None) @@ -3991,7 +3989,7 @@ def OnIsLegend(self, event): if page == 1 or event is None: children = self.panelVector.GetChildren() if self.isVLegend.GetValue(): - for i, widget in enumerate(children): + for widget in children: widget.Enable() self.OnSpan(None) self.OnBorder(None) @@ -4284,7 +4282,7 @@ def updateRasterLegend(self): else: self.rLegendDict["range"] = False - if not self.id[0] in self.instruction: + if self.id[0] not in self.instruction: rasterLegend = RasterLegend(self.id[0], env=self.env) self.instruction.AddInstruction(rasterLegend) self.instruction[self.id[0]].SetInstruction(self.rLegendDict) @@ -4404,7 +4402,7 @@ def updateVectorLegend(self): else: self.vLegendDict["border"] = "none" - if not self.id[1] in self.instruction: + if self.id[1] not in self.instruction: vectorLegend = VectorLegend(self.id[1], env=self.env) self.instruction.AddInstruction(vectorLegend) self.instruction[self.id[1]].SetInstruction(self.vLegendDict) @@ -4905,20 +4903,19 @@ def _scalebarPanel(self): unitName = self.unitConv.findName(self.scalebarDict["unitsLength"]) if unitName: self.unitsLength.SetStringSelection(unitName) - else: - if self.scalebarDict["unitsLength"] == "auto": - self.unitsLength.SetSelection(0) - elif self.scalebarDict["unitsLength"] == "nautmiles": - self.unitsLength.SetStringSelection( - self.unitConv.findName("nautical miles") - ) + elif self.scalebarDict["unitsLength"] == "auto": + self.unitsLength.SetSelection(0) + elif self.scalebarDict["unitsLength"] == "nautmiles": + self.unitsLength.SetStringSelection( + self.unitConv.findName("nautical miles") + ) self.unitsHeight.SetStringSelection( self.unitConv.findName(self.scalebarDict["unitsHeight"]) ) if self.scalebarDict["length"]: self.lengthTextCtrl.SetValue(str(self.scalebarDict["length"])) else: # estimate default - reg = grass.region(env=self.env) + reg = gs.region(env=self.env) w = int((reg["e"] - reg["w"]) / 3) w = round(w, -len(str(w)) + 2) # 12345 -> 12000 self.lengthTextCtrl.SetValue(str(w)) diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index 26fa77053ef..8725a0a957d 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -28,7 +28,7 @@ except ImportError: import wx.lib.flatnotebook as FN -import grass.script as grass +import grass.script as gs from core import globalvar from gui_core.menu import Menu @@ -170,8 +170,8 @@ def __init__( self.getInitMap() # image path - env = grass.gisenv() - self.imgName = grass.tempfile() + env = gs.gisenv() + self.imgName = gs.tempfile() # canvas for preview self.previewCanvas = PsMapBufferedWindow( @@ -310,7 +310,7 @@ def OnPDFFile(self, event): """Generate PDF from PS with ps2pdf if available""" if not sys.platform == "win32": try: - p = grass.Popen(["ps2pdf"], stderr=grass.PIPE) + p = gs.Popen(["ps2pdf"], stderr=gs.PIPE) p.stderr.close() except OSError: @@ -333,7 +333,7 @@ def OnPreview(self, event): def PSFile(self, filename=None, pdf=False): """Create temporary instructions file and run ps.map with output = filename""" - instrFile = grass.tempfile() + instrFile = gs.tempfile() instrFileFd = open(instrFile, mode="wb") content = self.InstructionFile() if not content: @@ -343,7 +343,7 @@ def PSFile(self, filename=None, pdf=False): instrFileFd.close() temp = False - regOld = grass.region(env=self.env) + regOld = gs.region(env=self.env) if pdf: pdfname = filename @@ -352,7 +352,7 @@ def PSFile(self, filename=None, pdf=False): # preview or pdf if not filename or (filename and pdf): temp = True - filename = grass.tempfile() + filename = gs.tempfile() if not pdf: # lower resolution for preview if self.instruction.FindInstructionByType("map"): mapId = self.instruction.FindInstructionByType("map").id @@ -368,8 +368,7 @@ def PSFile(self, filename=None, pdf=False): cmd.append("-e") if self.instruction[self.pageId]["Orientation"] == "Landscape": cmd.append("-r") - cmd.append("input=%s" % instrFile) - cmd.append("output=%s" % filename) + cmd.extend(("input=%s" % instrFile, "output=%s" % filename)) if pdf: self.SetStatusText(_("Generating PDF..."), 0) elif not temp: @@ -398,9 +397,9 @@ def OnCmdDone(self, event): message=_("Ps.map exited with return code %s") % event.returncode, ) - grass.try_remove(event.userData["instrFile"]) + gs.try_remove(event.userData["instrFile"]) if event.userData["temp"]: - grass.try_remove(event.userData["filename"]) + gs.try_remove(event.userData["filename"]) return if event.userData["pdfname"]: @@ -452,7 +451,7 @@ def OnCmdDone(self, event): " Please install it to create PDF.\n\n " ).format(pdf_rendering_prog) try: - proc = grass.Popen(command) + proc = gs.Popen(command) ret = proc.wait() if ret > 0: GMessage( @@ -483,7 +482,7 @@ def OnCmdDone(self, event): # show preview only when user doesn't want to create ps or pdf if havePILImage and event.userData["temp"] and not event.userData["pdfname"]: - self.env["GRASS_REGION"] = grass.region_env( + self.env["GRASS_REGION"] = gs.region_env( cols=event.userData["regionOld"]["cols"], rows=event.userData["regionOld"]["rows"], env=self.env, @@ -530,9 +529,9 @@ def OnCmdDone(self, event): del busy self.SetStatusText(_("Preview generated"), 0) - grass.try_remove(event.userData["instrFile"]) + gs.try_remove(event.userData["instrFile"]) if event.userData["temp"]: - grass.try_remove(event.userData["filename"]) + gs.try_remove(event.userData["filename"]) self.delayedCall = wx.CallLater( 4000, @@ -571,7 +570,7 @@ def getFile(self, wildcard): suffix = suffix[dlg.GetFilterIndex()] if not os.path.splitext(filename)[1]: filename = filename + suffix - elif os.path.splitext(filename)[1] != suffix and suffix != "": + elif suffix not in {os.path.splitext(filename)[1], ""}: filename = os.path.splitext(filename)[0] + suffix dlg.Destroy() @@ -724,7 +723,7 @@ def OnAddMap(self, event, notebook=False): ) self.openDialogs["mapNotebook"] = dlg self.openDialogs["mapNotebook"].Show() - else: + else: # noqa: PLR5501 if "mapNotebook" in self.openDialogs: self.openDialogs["mapNotebook"].notebook.ChangeSelection(0) else: @@ -1066,7 +1065,7 @@ def getTextExtent(self, textDict): def getInitMap(self): """Create default map frame when no map is selected, needed for coordinates in map units""" - instrFile = grass.tempfile() + instrFile = gs.tempfile() instrFileFd = open(instrFile, mode="wb") content = self.InstructionFile() if not content: @@ -1079,9 +1078,9 @@ def getInitMap(self): mapInitRect = GetMapBounds( instrFile, portrait=(page["Orientation"] == "Portrait"), env=self.env ) - grass.try_remove(instrFile) + gs.try_remove(instrFile) - region = grass.region(env=self.env) + region = gs.region(env=self.env) units = UnitConversion(self) realWidth = units.convert( value=abs(region["w"] - region["e"]), fromUnit="meter", toUnit="inch" @@ -1246,11 +1245,11 @@ def DialogDataChanged(self, id): if itype in {"map", "vector", "raster", "labels"}: if itype == "raster": # set resolution try: - info = grass.raster_info(self.instruction[id]["raster"]) - self.env["GRASS_REGION"] = grass.region_env( + info = gs.raster_info(self.instruction[id]["raster"]) + self.env["GRASS_REGION"] = gs.region_env( nsres=info["nsres"], ewres=info["ewres"], env=self.env ) - except grass.CalledModuleError: # fails after switching location + except gs.CalledModuleError: # fails after switching location pass # change current raster in raster legend @@ -1353,7 +1352,7 @@ def OnCloseWindow(self, event): os.remove(self.imgName) except OSError: pass - grass.set_raise_on_error(False) + gs.set_raise_on_error(False) if hasattr(self, "delayedCall") and self.delayedCall.IsRunning(): self.delayedCall.Stop() self.Destroy() @@ -1691,11 +1690,10 @@ def OnMouseMoving(self, event): self.SetCursor(self.cursors["sizenwse"]) self.parent.SetStatusText(_("Click and drag to resize object"), 0) self.showResizeHelp = True - else: - if self.showResizeHelp: - self.parent.SetStatusText("", 0) - self.SetCursor(self.cursors["default"]) - self.showResizeHelp = False + elif self.showResizeHelp: + self.parent.SetStatusText("", 0) + self.SetCursor(self.cursors["default"]) + self.showResizeHelp = False def OnLeftDown(self, event): """Left mouse button pressed. @@ -2614,9 +2612,7 @@ def ImageRect(self): iH = iH * self.currScale x = cW / 2 - iW / 2 y = cH / 2 - iH / 2 - imageRect = Rect(int(x), int(y), int(iW), int(iH)) - - return imageRect + return Rect(int(x), int(y), int(iW), int(iH)) def RedrawSelectBox(self, id): """Redraws select box when selected object changes its size""" diff --git a/gui/wxpython/psmap/g.gui.psmap.py b/gui/wxpython/psmap/g.gui.psmap.py index 50e4518e5a3..7e855d5e143 100755 --- a/gui/wxpython/psmap/g.gui.psmap.py +++ b/gui/wxpython/psmap/g.gui.psmap.py @@ -32,11 +32,11 @@ # % required: no # %end -import grass.script as gscript +import grass.script as gs def main(): - options, flags = gscript.parser() + options, flags = gs.parser() import wx diff --git a/gui/wxpython/psmap/instructions.py b/gui/wxpython/psmap/instructions.py index 89fea9d2455..f52bad96069 100644 --- a/gui/wxpython/psmap/instructions.py +++ b/gui/wxpython/psmap/instructions.py @@ -38,7 +38,7 @@ from time import strftime, localtime import wx -import grass.script as grass +import grass.script as gs from grass.script.task import cmdlist_to_tuple from core.gcmd import GError, GMessage, GWarning @@ -65,7 +65,7 @@ def __init__(self, parent, objectsToDraw, env): def __str__(self): """Returns text for instruction file""" comment = "# timestamp: " + strftime("%Y-%m-%d %H:%M", localtime()) + "\n" - env = grass.gisenv() + env = gs.gisenv() comment += "# location: %s\n" % env["LOCATION_NAME"] comment += "# mapset: %s\n" % env["MAPSET"] comment += ( @@ -166,7 +166,7 @@ def Read(self, filename): # then run ps.map -b to get information for maploc # compute scale and center map = self.FindInstructionByType("map") - region = grass.region(env=self.env) + region = gs.region(env=self.env) map["center"] = (region["n"] + region["s"]) / 2, (region["w"] + region["e"]) / 2 mapRect = GetMapBounds( self.filename, portrait=(orientation == "Portrait"), env=self.env @@ -401,7 +401,6 @@ def Read(self, filename): else: page["Orientation"] = orientation - # return True def SendToRead(self, instruction, text, **kwargs): @@ -523,16 +522,16 @@ def SetRegion(self, regionInstruction): map["scaleType"] = 2 else: map["scaleType"] = 2 - region = grass.region(env=None) + region = gs.region(env=None) cmd = ["g.region", region] cmdString = GetCmdString(cmd).replace("g.region", "") GMessage( _("Instruction file will be loaded with following region: %s\n") % cmdString ) try: - self.env["GRASS_REGION"] = grass.region_env(env=self.env, **cmd[1]) + self.env["GRASS_REGION"] = gs.region_env(env=self.env, **cmd[1]) - except grass.ScriptError as e: + except gs.ScriptError as e: GError(_("Region cannot be set\n%s") % e) return False @@ -579,7 +578,7 @@ def Read(self, instruction, text, **kwargs): def PercentToReal(self, e, n): """Converts text coordinates from percent of region to map coordinates""" e, n = float(e.strip("%")), float(n.strip("%")) - region = grass.region(env=self.env) + region = gs.region(env=self.env) N = region["s"] + (region["n"] - region["s"]) / 100 * n E = region["w"] + (region["e"] - region["w"]) / 100 * e return E, N @@ -627,7 +626,7 @@ def __str__(self): comment = "" # region settings - region = grass.region(env=self.env) + region = gs.region(env=self.env) if self.instruction["scaleType"] == 0: # match map map = self.instruction["map"] if self.instruction["mapType"] == "raster": @@ -826,7 +825,7 @@ def Read(self, instruction, text, **kwargs): if len(line.split()) > 1: pformat = line.split()[1] availableFormats = self._toDict( - grass.read_command("ps.map", flags="p", quiet=True) + gs.read_command("ps.map", flags="p", quiet=True) ) # e.g. paper a3 try: @@ -1751,13 +1750,13 @@ def EstimateHeight(self, raster, discrete, fontsize, cols=None, height=None): else: cols = 1 - rinfo = grass.raster_info(raster) + rinfo = gs.raster_info(raster) if rinfo["datatype"] in {"DCELL", "FCELL"}: minim, maxim = rinfo["min"], rinfo["max"] rows = ceil(maxim / cols) else: cat = ( - grass.read_command("r.category", map=raster, sep=":") + gs.read_command("r.category", map=raster, sep=":") .strip() .split("\n") ) @@ -1775,7 +1774,7 @@ def EstimateWidth( """Estimate size to draw raster legend""" if discrete == "n": - rinfo = grass.raster_info(raster) + rinfo = gs.raster_info(raster) minim, maxim = rinfo["min"], rinfo["max"] if width: width = width @@ -1914,8 +1913,7 @@ def __init__(self, id, env): self.instruction = dict(self.defaultInstruction) def __str__(self): - instr = string.Template("raster $raster").substitute(self.instruction) - return instr + return string.Template("raster $raster").substitute(self.instruction) def Read(self, instruction, text): """Read instruction and save information""" @@ -1927,8 +1925,8 @@ def Read(self, instruction, text): GError(_("Failed to read instruction %s") % instruction) return False try: - info = grass.find_file(map, element="cell") - except grass.ScriptError as e: + info = gs.find_file(map, element="cell") + except gs.ScriptError as e: GError(message=e.value) return False instr["raster"] = info["fullname"] @@ -1971,8 +1969,8 @@ def Read(self, instruction, text, **kwargs): # name of vector map vmap = line.split()[1] try: - info = grass.find_file(vmap, element="vector") - except grass.ScriptError as e: + info = gs.find_file(vmap, element="vector") + except gs.ScriptError as e: GError(message=e.value) return False vmap = info["fullname"] @@ -2085,7 +2083,7 @@ def __str__(self): " rgbcolumn $rgbcolumn\n" ).substitute(dic) vInstruction += string.Template(" fcolor $fcolor\n").substitute(dic) - else: + else: # noqa: PLR5501 if dic["rgbcolumn"]: vInstruction += string.Template( " rgbcolumn $rgbcolumn\n" @@ -2143,8 +2141,8 @@ def Read(self, instruction, text, **kwargs): """Read instruction and save information""" instr = {} try: - info = grass.find_file(name=text[0].split()[1], element="vector") - except grass.ScriptError as e: + info = gs.find_file(name=text[0].split()[1], element="vector") + except gs.ScriptError as e: GError(message=e.value) return False instr["name"] = info["fullname"] diff --git a/gui/wxpython/psmap/utils.py b/gui/wxpython/psmap/utils.py index f7e4cea1ad3..d54a45a52be 100644 --- a/gui/wxpython/psmap/utils.py +++ b/gui/wxpython/psmap/utils.py @@ -26,7 +26,7 @@ except ImportError: havePILImage = False -import grass.script as grass +import grass.script as gs from core.gcmd import RunCommand, GError @@ -153,7 +153,7 @@ def convertRGB(rgb): or named color/r:g:b string to wx.Colour, depending on input""" # transform a wx.Colour tuple into an r:g:b string if isinstance(rgb, wx.Colour): - for name, color in grass.named_colors.items(): + for name, color in gs.named_colors.items(): if ( rgb.Red() == int(color[0] * 255) and rgb.Green() == int(color[1] * 255) @@ -164,9 +164,9 @@ def convertRGB(rgb): # transform a GRASS named color or an r:g:b string into a wx.Colour tuple else: color = ( - int(grass.parse_color(rgb)[0] * 255), - int(grass.parse_color(rgb)[1] * 255), - int(grass.parse_color(rgb)[2] * 255), + int(gs.parse_color(rgb)[0] * 255), + int(gs.parse_color(rgb)[1] * 255), + int(gs.parse_color(rgb)[2] * 255), ) color = wx.Colour(*color) if color.IsOk(): @@ -182,7 +182,7 @@ def PaperMapCoordinates(mapInstr, x, y, paperToMap=True, env=None): :param x,y: paper coords in inches or mapcoords in map units :param paperToMap: specify conversion direction """ - region = grass.region(env=env) + region = gs.region(env=env) mapWidthPaper = mapInstr["rect"].GetWidth() mapHeightPaper = mapInstr["rect"].GetHeight() mapWidthEN = region["e"] - region["w"] @@ -222,24 +222,22 @@ def AutoAdjust(self, scaleType, rect, env, map=None, mapType=None, region=None): res = "" if mapType == "raster": try: - res = grass.read_command( - "g.region", flags="gu", raster=map, env=env - ) - except grass.ScriptError: + res = gs.read_command("g.region", flags="gu", raster=map, env=env) + except gs.ScriptError: pass elif mapType == "vector": - res = grass.read_command("g.region", flags="gu", vector=map, env=env) - currRegionDict = grass.parse_key_val(res, val_type=float) + res = gs.read_command("g.region", flags="gu", vector=map, env=env) + currRegionDict = gs.parse_key_val(res, val_type=float) elif scaleType == 1 and region: # saved region - res = grass.read_command("g.region", flags="gu", region=region, env=env) - currRegionDict = grass.parse_key_val(res, val_type=float) + res = gs.read_command("g.region", flags="gu", region=region, env=env) + currRegionDict = gs.parse_key_val(res, val_type=float) elif scaleType == 2: # current region - currRegionDict = grass.region(env=None) + currRegionDict = gs.region(env=None) else: return None, None, None # fails after switching location - except (grass.ScriptError, grass.CalledModuleError): + except (gs.ScriptError, gs.CalledModuleError): pass if not currRegionDict: @@ -290,11 +288,11 @@ def SetResolution(dpi, width, height, env): :param width: map frame width :param height: map frame height """ - region = grass.region(env=env) + region = gs.region(env=env) if region["cols"] > width * dpi or region["rows"] > height * dpi: rows = height * dpi cols = width * dpi - env["GRASS_REGION"] = grass.region_env(rows=rows, cols=cols, env=env) + env["GRASS_REGION"] = gs.region_env(rows=rows, cols=cols, env=env) def ComputeSetRegion(self, mapDict, env): @@ -335,7 +333,7 @@ def ComputeSetRegion(self, mapDict, env): rasterId = None if rasterId: - env["GRASS_REGION"] = grass.region_env( + env["GRASS_REGION"] = gs.region_env( n=ceil(centerN + rectHalfMeter[1]), s=floor(centerN - rectHalfMeter[1]), e=ceil(centerE + rectHalfMeter[0]), @@ -344,7 +342,7 @@ def ComputeSetRegion(self, mapDict, env): env=env, ) else: - env["GRASS_REGION"] = grass.region_env( + env["GRASS_REGION"] = gs.region_env( n=ceil(centerN + rectHalfMeter[1]), s=floor(centerN - rectHalfMeter[1]), e=ceil(centerE + rectHalfMeter[0]), @@ -361,7 +359,7 @@ def projInfo(): "g.proj", flags="g", read=True, - parse=grass.parse_key_val, + parse=gs.parse_key_val, ) return ( @@ -384,7 +382,7 @@ def GetMapBounds(filename, env, portrait=True): bb = list( map( float, - grass.read_command( + gs.read_command( "ps.map", flags="b" + orient, quiet=True, input=filename, env=env ) .strip() @@ -392,7 +390,7 @@ def GetMapBounds(filename, env, portrait=True): .split(","), ) ) - except (grass.ScriptError, IndexError): + except (gs.ScriptError, IndexError): GError(message=_("Unable to run `ps.map -b`")) return None return Rect2D(bb[0], bb[3], bb[2] - bb[0], bb[1] - bb[3]) @@ -402,10 +400,9 @@ def getRasterType(map): """Returns type of raster map (CELL, FCELL, DCELL)""" if map is None: map = "" - file = grass.find_file(name=map, element="cell") + file = gs.find_file(name=map, element="cell") if file.get("file"): - rasterType = grass.raster_info(map)["datatype"] - return rasterType + return gs.raster_info(map)["datatype"] else: return None diff --git a/gui/wxpython/rdigit/g.gui.rdigit.py b/gui/wxpython/rdigit/g.gui.rdigit.py index 0a9a72e4acb..a05fdb547bb 100755 --- a/gui/wxpython/rdigit/g.gui.rdigit.py +++ b/gui/wxpython/rdigit/g.gui.rdigit.py @@ -116,7 +116,7 @@ def __init__( self._mapObj = self.GetMap() # load raster map - self._addLayer(name=new_map if new_map else edit_map) + self._addLayer(name=new_map or edit_map) # switch toolbar self.AddToolbar("rdigit", fixed=True) @@ -199,23 +199,22 @@ def OnMapCreated(self, name, ltype): ) else: kwargs["edit_map"] = edit_map - else: - if kwargs["base_map"]: - base_map = gs.find_file( - name=kwargs["base_map"], - element="raster", - mapset=mapset, - )["fullname"] - if not base_map: - gs.fatal( - _( - "Base raster map <{}> not found in " - "current mapset.".format( - options["base"], - ), + elif kwargs["base_map"]: + base_map = gs.find_file( + name=kwargs["base_map"], + element="raster", + mapset=mapset, + )["fullname"] + if not base_map: + gs.fatal( + _( + "Base raster map <{}> not found in " + "current mapset.".format( + options["base"], ), - ) - kwargs["base_map"] = base_map + ), + ) + kwargs["base_map"] = base_map # allow immediate rendering driver = UserSettings.Get( diff --git a/gui/wxpython/rlisetup/g.gui.rlisetup.py b/gui/wxpython/rlisetup/g.gui.rlisetup.py index 9b24e98696f..bed4b030f04 100644 --- a/gui/wxpython/rlisetup/g.gui.rlisetup.py +++ b/gui/wxpython/rlisetup/g.gui.rlisetup.py @@ -26,11 +26,11 @@ # % keyword: landscape structure analysis # %end -import grass.script as gscript +import grass.script as gs def main(): - gscript.parser() + gs.parser() import wx diff --git a/gui/wxpython/rlisetup/sampling_frame.py b/gui/wxpython/rlisetup/sampling_frame.py index 2526d0537f8..dcd8398d049 100644 --- a/gui/wxpython/rlisetup/sampling_frame.py +++ b/gui/wxpython/rlisetup/sampling_frame.py @@ -385,8 +385,7 @@ def writeCircle(self, circle, rasterName): grass.use_temp_region() grass.run_command("g.region", zoom=rasterName) region = grass.region() - marea = MaskedArea(region, rasterName, circle.radius) - return marea + return MaskedArea(region, rasterName, circle.radius) def _rectangleDrawn(self): """When drawing finished, get region values""" diff --git a/gui/wxpython/rlisetup/wizard.py b/gui/wxpython/rlisetup/wizard.py index d5d508b7fb4..12888948ec3 100644 --- a/gui/wxpython/rlisetup/wizard.py +++ b/gui/wxpython/rlisetup/wizard.py @@ -362,7 +362,7 @@ def _write_area(self, fil): fil.write("\nMOVINGWINDOW\n") # KUNITSC = samplingtype=units, regionbox=keyboard, shape=cirlce # KUNITSR = samplingtype=units, regionbox=keyboard, shape=rectangle - elif samtype == SamplingType.KUNITSC or samtype == SamplingType.KUNITSR: + elif samtype in {SamplingType.KUNITSC, SamplingType.KUNITSR}: if samtype == SamplingType.KUNITSC: self._circle(self.units.width, self.units.height) cl = float(self.CIR_CL) / float(self.rasterinfo["cols"]) @@ -1115,7 +1115,7 @@ def ShowExtraOptions(self, samtype): self.sizer.Hide(self.areaPanel) self.sizer.Hide(self.calculatingAreas) self.sizer.Show(self.regionNumPanel) - elif samtype == SamplingType.UNITS or samtype == SamplingType.MVWIN: + elif samtype in {SamplingType.UNITS, SamplingType.MVWIN}: self.sizer.Hide(self.regionNumPanel) self.sizer.Hide(self.areaPanel) self.sizer.Hide(self.calculatingAreas) diff --git a/gui/wxpython/startup/guiutils.py b/gui/wxpython/startup/guiutils.py index baa74fd6b68..fa4d0a8760a 100644 --- a/gui/wxpython/startup/guiutils.py +++ b/gui/wxpython/startup/guiutils.py @@ -165,9 +165,8 @@ def create_location_interactively(guiparent, grassdb): gWizard = LocationWizard(parent=guiparent, grassdatabase=grassdb) if gWizard.location is None: - gWizard_output = (None, None, None) + return (None, None, None) # Returns Nones after Cancel - return gWizard_output if gWizard.georeffile: message = _("Do you want to import {} to the newly created project?").format( @@ -586,7 +585,7 @@ def can_switch_mapset_interactive(guiparent, grassdb, location, mapset): if is_mapset_locked(mapset_path): info = get_mapset_lock_info(mapset_path) - user = info["owner"] if info["owner"] else _("unknown") + user = info["owner"] or _("unknown") lockpath = info["lockpath"] timestamp = info["timestamp"] @@ -716,7 +715,7 @@ def switch_mapset_interactively( giface.currentMapsetChanged.emit( dbase=None, location=location, mapset=mapset ) - else: + else: # noqa: PLR5501 if RunCommand("g.mapset", parent=guiparent, mapset=mapset) == 0: if show_confirmation: GMessage( diff --git a/gui/wxpython/startup/locdownload.py b/gui/wxpython/startup/locdownload.py index 5a4eddbaf9d..4592103a0f9 100644 --- a/gui/wxpython/startup/locdownload.py +++ b/gui/wxpython/startup/locdownload.py @@ -121,8 +121,7 @@ def _get_heigth(self, string): n_lines = string.count("\n") attr = self.out.GetClassDefaultAttributes() font_size = attr.font.GetPointSize() - heigth = int((n_lines + 2) * font_size // 0.75) # 1 px = 0.75 pt - return heigth + return int((n_lines + 2) * font_size // 0.75) # 1 px = 0.75 pt def _resize(self, heigth=-1): """Resize widget heigth diff --git a/gui/wxpython/timeline/frame.py b/gui/wxpython/timeline/frame.py index 48f23a0cbab..0330adbde3d 100644 --- a/gui/wxpython/timeline/frame.py +++ b/gui/wxpython/timeline/frame.py @@ -24,11 +24,11 @@ from functools import reduce try: - import matplotlib + import matplotlib as mpl # The recommended way to use wx with mpl is with the WXAgg # backend. - matplotlib.use("WXAgg") + mpl.use("WXAgg") from matplotlib import gridspec from matplotlib.figure import Figure from matplotlib.backends.backend_wxagg import ( @@ -45,7 +45,7 @@ ).format(e) ) -import grass.script as grass +import grass.script as gs import grass.temporal as tgis from core.gcmd import GError, GException, RunCommand @@ -60,7 +60,7 @@ def check_version(*version): """Checks if given version or newer is installed""" versionInstalled = [] - for i in matplotlib.__version__.split("."): + for i in mpl.__version__.split("."): try: v = int(i) versionInstalled.append(v) @@ -303,8 +303,8 @@ def _draw3dFigure(self): ) ) - params = grass.read_command("g.proj", flags="g") - params = grass.parse_key_val(params) + params = gs.read_command("g.proj", flags="g") + params = gs.parse_key_val(params) if "unit" in params: self.axes3d.set_xlabel(_("X [%s]") % params["unit"]) self.axes3d.set_ylabel(_("Y [%s]") % params["unit"]) @@ -572,9 +572,7 @@ def SetDatasets(self, datasets): GError(parent=self, message=str(error), showTraceback=False) return self.datasets = datasets - self.datasetSelect.SetValue( - ",".join(map(lambda x: x[0] + "@" + x[1], datasets)) - ) + self.datasetSelect.SetValue(",".join(f"{x[0]}@{x[1]}" for x in datasets)) self._redraw() def Show3D(self, show): @@ -630,10 +628,14 @@ def InfoFormat(timeData, datasetName, mapIndex): elif etype == "str3ds": text.append(_("Space time 3D raster dataset: %s") % name) - text.append(_("Mapset: %s") % mapset) - text.append(_("Map name: %s") % timeData[datasetName]["names"][mapIndex]) - text.append(_("Start time: %s") % timeData[datasetName]["start_datetime"][mapIndex]) - text.append(_("End time: %s") % timeData[datasetName]["end_datetime"][mapIndex]) + text.extend( + ( + _("Mapset: %s") % mapset, + _("Map name: %s") % timeData[datasetName]["names"][mapIndex], + _("Start time: %s") % timeData[datasetName]["start_datetime"][mapIndex], + _("End time: %s") % timeData[datasetName]["end_datetime"][mapIndex], + ) + ) if not timeData[datasetName]["validTopology"]: text.append(_("WARNING: invalid topology")) diff --git a/gui/wxpython/timeline/g.gui.timeline.py b/gui/wxpython/timeline/g.gui.timeline.py index d3176736bca..161c6832a92 100755 --- a/gui/wxpython/timeline/g.gui.timeline.py +++ b/gui/wxpython/timeline/g.gui.timeline.py @@ -34,11 +34,11 @@ # % description: Show also 3D plot of spatio-temporal extents # %end -import grass.script as gscript +import grass.script as gs def main(): - options, flags = gscript.parser() + options, flags = gs.parser() import wx @@ -52,7 +52,7 @@ def main(): # TODO: why do we need this special check here, the reason of error # is wrong intallation or something, no need to report this to the # user in a nice way - gscript.fatal(str(e)) + gs.fatal(str(e)) datasets = options["inputs"].strip().split(",") datasets = [data for data in datasets if data] diff --git a/gui/wxpython/tools/build_modules_xml.py b/gui/wxpython/tools/build_modules_xml.py index 8dc341d7c75..a97bdeb4627 100644 --- a/gui/wxpython/tools/build_modules_xml.py +++ b/gui/wxpython/tools/build_modules_xml.py @@ -55,7 +55,7 @@ def parse_modules(fd): indent = 4 for m in sorted(mlist): # TODO: get rid of g.mapsets_picker.py - if m == "g.mapsets_picker.py" or m == "g.parser": + if m in {"g.mapsets_picker.py", "g.parser"}: continue desc, keyw = get_module_metadata(m) fd.write('%s\n' % (" " * indent, m)) diff --git a/gui/wxpython/tplot/frame.py b/gui/wxpython/tplot/frame.py index 0750fc643cc..2f738c93644 100755 --- a/gui/wxpython/tplot/frame.py +++ b/gui/wxpython/tplot/frame.py @@ -25,15 +25,15 @@ import wx from grass.pygrass.modules import Module -import grass.script as grass +import grass.script as gs from functools import reduce try: - import matplotlib + import matplotlib as mpl # The recommended way to use wx with mpl is with the WXAgg # backend. - matplotlib.use("WXAgg") + mpl.use("WXAgg") from matplotlib.figure import Figure from matplotlib.backends.backend_wxagg import ( FigureCanvasWxAgg as FigCanvas, @@ -77,7 +77,7 @@ def check_version(*version): """Checks if given version or newer is installed""" versionInstalled = [] - for i in matplotlib.__version__.split("."): + for i in mpl.__version__.split("."): try: v = int(i) versionInstalled.append(v) @@ -513,7 +513,7 @@ def _parseVDbConn(self, mapp, layerInp): def _getExistingCategories(self, mapp, cats): """Get a list of categories for a vector map""" - vdb = grass.read_command("v.category", input=mapp, option="print") + vdb = gs.read_command("v.category", input=mapp, option="print") categories = vdb.splitlines() if not cats: return categories @@ -613,7 +613,7 @@ def _getSTVDData(self, timeseries): self.plotNameListV.append(name) # TODO set an appropriate distance, right now a big one is set # to return the closer point to the selected one - out = grass.vector_what( + out = gs.vector_what( map="pois_srvds", coord=self.poi.coords(), distance=10000000000000000, @@ -673,7 +673,7 @@ def _getSTVDData(self, timeseries): ), ) return - vals = grass.vector_db_select( + vals = gs.vector_db_select( map=row["name"], layer=lay, where=wherequery.format(key=catkey), @@ -739,11 +739,10 @@ def _setLabels(self, x): """Function to set the right labels""" if self.drawX != "": self.axes2d.set_xlabel(self.drawX) + elif self.temporalType == "absolute": + self.axes2d.set_xlabel(_("Temporal resolution: %s" % x)) else: - if self.temporalType == "absolute": - self.axes2d.set_xlabel(_("Temporal resolution: %s" % x)) - else: - self.axes2d.set_xlabel(_("Time [%s]") % self.unit) + self.axes2d.set_xlabel(_("Time [%s]") % self.unit) if self.drawY != "": self.axes2d.set_ylabel(self.drawY) else: @@ -1268,7 +1267,7 @@ def SetDatasets( except: self.coorval.SetValue(",".join(coors)) if self.datasetsV: - vdatas = ",".join(map(lambda x: x[0] + "@" + x[1], self.datasetsV)) + vdatas = ",".join(f"{x[0]}@{x[1]}" for x in self.datasetsV) self.datasetSelectV.SetValue(vdatas) if attr: self.attribute.SetValue(attr) @@ -1276,7 +1275,7 @@ def SetDatasets( self.cats.SetValue(cats) if self.datasetsR: self.datasetSelectR.SetValue( - ",".join(map(lambda x: x[0] + "@" + x[1], self.datasetsR)) + ",".join(f"{x[0]}@{x[1]}" for x in self.datasetsR) ) if title: self.title.SetValue(title) @@ -1306,7 +1305,7 @@ def OnVectorSelected(self, event): break if found: try: - vect_list = grass.read_command( + vect_list = gs.read_command( "t.vect.list", flags="u", input=dataset, column="name" ) except Exception: @@ -1368,8 +1367,9 @@ def InfoFormat(timeData, values): elif etype == "str3ds": text.append(_("Space time 3D raster dataset: %s") % key) - text.append(_("Value for {date} is {val}".format(date=val[0], val=val[1]))) - text.append("\n") + text.extend( + (_("Value for {date} is {val}".format(date=val[0], val=val[1])), "\n") + ) text.append(_("Press Del to dismiss.")) return "\n".join(text) diff --git a/gui/wxpython/tplot/g.gui.tplot.py b/gui/wxpython/tplot/g.gui.tplot.py index a4b87326e03..2cb85a565f8 100755 --- a/gui/wxpython/tplot/g.gui.tplot.py +++ b/gui/wxpython/tplot/g.gui.tplot.py @@ -109,11 +109,11 @@ # % required: no # %end -import grass.script as gscript +import grass.script as gs def main(): - options, flags = gscript.parser() + options, flags = gs.parser() import wx @@ -126,7 +126,7 @@ def main(): try: from tplot.frame import TplotFrame except ImportError as e: - gscript.fatal(e.message) + gs.fatal(e.message) rasters = None if options["strds"]: rasters = options["strds"].strip().split(",") @@ -142,20 +142,18 @@ def main(): if options["stvds"]: vectors = options["stvds"].strip().split(",") if not options["attr"]: - gscript.fatal(_("With stvds you have to set 'attr' option")) + gs.fatal(_("With stvds you have to set 'attr' option")) else: attr = options["attr"] if coords and cats: - gscript.fatal( + gs.fatal( _( "With stvds it is not possible to use 'coordinates' " "and 'cats' options together" ) ) elif not coords and not cats: - gscript.warning( - _("With stvds you have to use 'coordinates' or 'cats' option") - ) + gs.warning(_("With stvds you have to use 'coordinates' or 'cats' option")) title = None if options["title"]: title = options["title"] @@ -188,7 +186,7 @@ def main(): ylabel, csvfile, flags["h"], - gscript.overwrite, + gs.overwrite, ) if output: frame.OnRedraw() diff --git a/gui/wxpython/vdigit/g.gui.vdigit.py b/gui/wxpython/vdigit/g.gui.vdigit.py index f66793176e5..ea09f207909 100644 --- a/gui/wxpython/vdigit/g.gui.vdigit.py +++ b/gui/wxpython/vdigit/g.gui.vdigit.py @@ -35,13 +35,13 @@ # %end import os -import grass.script as grass +import grass.script as gs def main(): - grass.set_raise_on_error(False) + gs.set_raise_on_error(False) - options, flags = grass.parser() + options, flags = gs.parser() # import wx only after running parser # to avoid issues with complex imports when only interface is needed @@ -113,13 +113,13 @@ def __init__(self, parent, vectorMap): parent.Layout() if not haveVDigit: - grass.fatal(_("Vector digitizer not available. %s") % errorMsg) + gs.fatal(_("Vector digitizer not available. %s") % errorMsg) - if not grass.find_file( - name=options["map"], element="vector", mapset=grass.gisenv()["MAPSET"] + if not gs.find_file( + name=options["map"], element="vector", mapset=gs.gisenv()["MAPSET"] )["fullname"]: if not flags["c"]: - grass.fatal( + gs.fatal( _( "Vector map <%s> not found in current mapset. " "New vector map can be created by providing '-c' flag." @@ -127,13 +127,11 @@ def __init__(self, parent, vectorMap): % options["map"] ) else: - grass.verbose(_("New vector map <%s> created") % options["map"]) + gs.verbose(_("New vector map <%s> created") % options["map"]) try: - grass.run_command( - "v.edit", map=options["map"], tool="create", quiet=True - ) + gs.run_command("v.edit", map=options["map"], tool="create", quiet=True) except CalledModuleError: - grass.fatal(_("Unable to create new vector map <%s>") % options["map"]) + gs.fatal(_("Unable to create new vector map <%s>") % options["map"]) # allow immediate rendering driver = UserSettings.Get(group="display", key="driver", subkey="type") diff --git a/gui/wxpython/vdigit/mapwindow.py b/gui/wxpython/vdigit/mapwindow.py index 43841b53236..ff7e62ebaa9 100644 --- a/gui/wxpython/vdigit/mapwindow.py +++ b/gui/wxpython/vdigit/mapwindow.py @@ -534,7 +534,7 @@ def OnLeftDownDisplayCA(self, event): # highlight feature & re-draw map if not self.parent.dialogs["attributes"].IsShown(): self.parent.dialogs["attributes"].Show() - else: + else: # noqa: PLR5501 if ( self.parent.dialogs["attributes"] and self.parent.dialogs["attributes"].IsShown() @@ -561,7 +561,7 @@ def OnLeftDownDisplayCA(self, event): # highlight feature & re-draw map if not self.parent.dialogs["category"].IsShown(): self.parent.dialogs["category"].Show() - else: + else: # noqa: PLR5501 if self.parent.dialogs["category"].IsShown(): self.parent.dialogs["category"].Hide() @@ -826,29 +826,26 @@ def OnLeftUpVarious(self, event): if nselected > 0: self.digit.GetDisplay().SetSelected(selected) + # -> moveLine || deleteLine, etc. (select by point/box) + elif action == "moveLine" and len(self.digit.GetDisplay().GetSelected()) > 0: + nselected = 0 + elif action == "deleteArea": + nselected = int( + self.digit.GetDisplay().SelectAreaByPoint(pos1)["area"] != -1 + ) else: - # -> moveLine || deleteLine, etc. (select by point/box) - if action == "moveLine" and len(self.digit.GetDisplay().GetSelected()) > 0: - nselected = 0 + if action == "moveLine": + drawSeg = True else: - if action == "deleteArea": - nselected = int( - self.digit.GetDisplay().SelectAreaByPoint(pos1)["area"] != -1 - ) - else: - if action == "moveLine": - drawSeg = True - else: - drawSeg = False + drawSeg = False - nselected = self.digit.GetDisplay().SelectLinesByBox( - bbox=(pos1, pos2), drawSeg=drawSeg - ) - if nselected == 0: - nselected = int( - self.digit.GetDisplay().SelectLineByPoint(pos1)["line"] - != -1 - ) + nselected = self.digit.GetDisplay().SelectLinesByBox( + bbox=(pos1, pos2), drawSeg=drawSeg + ) + if nselected == 0: + nselected = int( + self.digit.GetDisplay().SelectLineByPoint(pos1)["line"] != -1 + ) if nselected > 0: if action in {"moveLine", "moveVertex"} and hasattr(self, "moveInfo"): @@ -891,14 +888,14 @@ def OnLeftUpVarious(self, event): # -> move line || move vertex self.UpdateMap(render=False) - else: # no vector object found - if not ( - action in {"moveLine", "moveVertex"} - and hasattr(self, "moveInfo") - and len(self.moveInfo["id"]) > 0 - ): - # avoid left-click when features are already selected - self.UpdateMap(render=False, renderVector=False) + # no vector object found + elif not ( + action in {"moveLine", "moveVertex"} + and hasattr(self, "moveInfo") + and len(self.moveInfo["id"]) > 0 + ): + # avoid left-click when features are already selected + self.UpdateMap(render=False, renderVector=False) def OnLeftUpModifyLine(self, event): """Left mouse button released - vector digitizer split line, @@ -986,10 +983,9 @@ def OnLeftUpCopyLine(self, event): ) else: self.layerTmp.SetCmd(dVectTmp) - else: - if self.layerTmp: - self.Map.DeleteLayer(self.layerTmp) - self.layerTmp = None + elif self.layerTmp: + self.Map.DeleteLayer(self.layerTmp) + self.layerTmp = None self.UpdateMap(render=True, renderVector=True) @@ -1206,14 +1202,11 @@ def _onRightUp(self, event): < 0 ): return - else: - if ( - self.digit.CopyCats( - self.copyCatsList, self.copyCatsIds, copyAttrb=True - ) - < 0 - ): - return + elif ( + self.digit.CopyCats(self.copyCatsList, self.copyCatsIds, copyAttrb=True) + < 0 + ): + return del self.copyCatsList del self.copyCatsIds diff --git a/gui/wxpython/vdigit/preferences.py b/gui/wxpython/vdigit/preferences.py index 51c14943073..b825748a025 100644 --- a/gui/wxpython/vdigit/preferences.py +++ b/gui/wxpython/vdigit/preferences.py @@ -808,11 +808,10 @@ def OnChangeSnappingValue(self, event): region = self.parent.MapWindow.Map.GetRegion() res = (region["nsres"] + region["ewres"]) / 2.0 threshold = self.digit.GetDisplay().GetThreshold(value=res) + elif self.snappingUnit.GetSelection() == 1: # map units + threshold = value else: - if self.snappingUnit.GetSelection() == 1: # map units - threshold = value - else: - threshold = self.digit.GetDisplay().GetThreshold(value=value) + threshold = self.digit.GetDisplay().GetThreshold(value=value) if value == 0: self.snappingInfo.SetLabel(_("Snapping disabled")) @@ -1011,13 +1010,12 @@ def UpdateSettings(self): "column": column, "units": unitsKey, } - else: - if ( - item - and tree.GetLayerInfo(item, key="vdigit") - and key in tree.GetLayerInfo(item, key="vdigit")["geomAttr"] - ): - del tree.GetLayerInfo(item, key="vdigit")["geomAttr"][key] + elif ( + item + and tree.GetLayerInfo(item, key="vdigit") + and key in tree.GetLayerInfo(item, key="vdigit")["geomAttr"] + ): + del tree.GetLayerInfo(item, key="vdigit")["geomAttr"][key] # query tool if self.queryLength.GetValue(): diff --git a/gui/wxpython/vdigit/toolbars.py b/gui/wxpython/vdigit/toolbars.py index d72cc3dac3c..1e8d394bddc 100644 --- a/gui/wxpython/vdigit/toolbars.py +++ b/gui/wxpython/vdigit/toolbars.py @@ -17,7 +17,7 @@ import wx -from grass import script as grass +from grass import script as gs from grass.pydispatch.signal import Signal from gui_core.toolbars import BaseToolbar, BaseIcons @@ -672,16 +672,12 @@ def EnableRedo(self, enable=True): """ self._enableTool(self.redo, enable) - def _enableTool(self, tool, enable): + def _enableTool(self, tool, enable: bool): if not self.FindById(tool): return - if enable: - if self.GetToolEnabled(tool) is False: - self.EnableTool(tool, True) - else: - if self.GetToolEnabled(tool) is True: - self.EnableTool(tool, False) + if self.GetToolEnabled(tool) is not bool(enable): + self.EnableTool(tool, bool(enable)) def GetAction(self, type="desc"): """Get current action info""" @@ -1002,7 +998,7 @@ def OnSelectMap(self, event): if dlg and dlg.GetName(): # add layer to map layer tree/map display - mapName = dlg.GetName() + "@" + grass.gisenv()["MAPSET"] + mapName = dlg.GetName() + "@" + gs.gisenv()["MAPSET"] self._giface.GetLayerList().AddLayer( ltype="vector", name=mapName, @@ -1048,10 +1044,7 @@ def StartEditing(self, mapLayer): """ # check if topology is available (skip for hidden - temporary # maps, see iclass for details) - if ( - not mapLayer.IsHidden() - and grass.vector_info(mapLayer.GetName())["level"] != 2 - ): + if not mapLayer.IsHidden() and gs.vector_info(mapLayer.GetName())["level"] != 2: dlg = wx.MessageDialog( parent=self.MapWindow, message=_( @@ -1290,7 +1283,7 @@ def UpdateListOfLayers(self, updateTool=False): # select vector map layer in the current mapset layerNameList = [] self.layers = self.Map.GetListOfLayers( - ltype="vector", mapset=grass.gisenv()["MAPSET"] + ltype="vector", mapset=gs.gisenv()["MAPSET"] ) for layer in self.layers: diff --git a/gui/wxpython/vdigit/wxdisplay.py b/gui/wxpython/vdigit/wxdisplay.py index 8891908c2cb..a318105bd9e 100644 --- a/gui/wxpython/vdigit/wxdisplay.py +++ b/gui/wxpython/vdigit/wxdisplay.py @@ -315,57 +315,56 @@ def _drawObject(self, robj): pdc.SetId(dcId) dcId += 2 self._drawCross(pdc, p) - else: - if dcId > 0 and self._drawSegments: - self.fisrtNode = True - self.lastNodeId = robj.npoints * 2 - 1 - dcId = 2 # first segment - i = 0 - while i < robj.npoints - 1: - point_beg = wx.Point(robj.point[i].x, robj.point[i].y) - point_end = wx.Point(robj.point[i + 1].x, robj.point[i + 1].y) - # set unique id & set bbox for each segment - pdc.SetId(dcId) - pdc.SetPen(pen) - pdc.SetIdBounds(dcId - 1, Rect(point_beg.x, point_beg.y, 0, 0)) - pdc.SetIdBounds( - dcId, - Rect( - point_beg.x, - point_beg.y, - point_end.x - point_beg.x, - point_end.y - point_beg.y, - ), - ) - pdc.DrawLine(point_beg.x, point_beg.y, point_end.x, point_end.y) - i += 1 - dcId += 2 + elif dcId > 0 and self._drawSegments: + self.fisrtNode = True + self.lastNodeId = robj.npoints * 2 - 1 + dcId = 2 # first segment + i = 0 + while i < robj.npoints - 1: + point_beg = wx.Point(robj.point[i].x, robj.point[i].y) + point_end = wx.Point(robj.point[i + 1].x, robj.point[i + 1].y) + # set unique id & set bbox for each segment + pdc.SetId(dcId) + pdc.SetPen(pen) + pdc.SetIdBounds(dcId - 1, Rect(point_beg.x, point_beg.y, 0, 0)) pdc.SetIdBounds( - dcId - 1, + dcId, Rect( - robj.point[robj.npoints - 1].x, - robj.point[robj.npoints - 1].y, - 0, - 0, + point_beg.x, + point_beg.y, + point_end.x - point_beg.x, + point_end.y - point_beg.y, ), ) - else: - points = [] - for i in range(robj.npoints): - p = robj.point[i] - points.append(wx.Point(p.x, p.y)) - if len(points) <= 1: - self.log.write( - _( - "WARNING: Zero-length line or boundary drawing skipped. " - "Use v.clean to remove it." - ) + pdc.DrawLine(point_beg.x, point_beg.y, point_end.x, point_end.y) + i += 1 + dcId += 2 + pdc.SetIdBounds( + dcId - 1, + Rect( + robj.point[robj.npoints - 1].x, + robj.point[robj.npoints - 1].y, + 0, + 0, + ), + ) + else: + points = [] + for i in range(robj.npoints): + p = robj.point[i] + points.append(wx.Point(p.x, p.y)) + if len(points) <= 1: + self.log.write( + _( + "WARNING: Zero-length line or boundary drawing skipped. " + "Use v.clean to remove it." ) - return - if robj.type == TYPE_AREA: - pdc.DrawPolygon(points) - else: - pdc.DrawLines(points) + ) + return + if robj.type == TYPE_AREA: + pdc.DrawPolygon(points) + else: + pdc.DrawLines(points) def _definePen(self, rtype): """Define pen/brush based on rendered object) @@ -878,10 +877,9 @@ def GetSelectedVertex(self, pos): if idx == 0: minDist = dist Gid = idx - else: - if minDist > dist: - minDist = dist - Gid = idx + elif minDist > dist: + minDist = dist + Gid = idx vx, vy = self._cell2Pixel(points.x[idx], points.y[idx], points.z[idx]) rect = Rect(vx, vy, 0, 0) @@ -925,7 +923,7 @@ def GetRegionSelected(self): if area > 0 and area <= nareas: if not Vect_get_area_box(self.poMapInfo, area, byref(lineBox)): continue - else: + else: # noqa: PLR5501 if not Vect_get_line_box(self.poMapInfo, line, byref(lineBox)): continue @@ -997,7 +995,7 @@ def OpenMap(self, name, mapset, update=True, tmp=False): open_fn = Vect_open_tmp_update else: open_fn = Vect_open_update - else: + else: # noqa: PLR5501 if tmp: open_fn = Vect_open_tmp_old else: diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py index c82bc25a157..3d829ffd7be 100644 --- a/gui/wxpython/vnet/dialogs.py +++ b/gui/wxpython/vnet/dialogs.py @@ -582,8 +582,12 @@ def OnPageChanged(self, event): """Tab switched""" if event.GetEventObject() == self.notebook: dbMgrIndxs = [] - dbMgrIndxs.append(self.notebook.GetPageIndexByName("inputDbMgr")) - dbMgrIndxs.append(self.notebook.GetPageIndexByName("resultDbMgr")) + dbMgrIndxs.extend( + ( + self.notebook.GetPageIndexByName("inputDbMgr"), + self.notebook.GetPageIndexByName("resultDbMgr"), + ) + ) if self.notebook.GetSelection() in dbMgrIndxs: self.stBar.AddStatusItem( text=_("Loading tables..."), @@ -1144,7 +1148,7 @@ def AnalysisChanged(self, analysis): if not item[1]: self.CheckItem(iItem, False) - else: + else: # noqa: PLR5501 if self.IsShown("type"): self.HideColumn("type") diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py index 97f40458008..17d85ef6ca4 100644 --- a/gui/wxpython/vnet/vnet_core.py +++ b/gui/wxpython/vnet/vnet_core.py @@ -485,11 +485,13 @@ def _vnetPathRunAn(self, analysis, output, params, flags, catPts): else: cmdParams.append("input=" + params["input"]) - cmdParams.append("file=" + self.coordsTmpFile) - - cmdParams.append("dmax=" + str(params["max_dist"])) - - cmdParams.append("--overwrite") + cmdParams.extend( + ( + "file=" + self.coordsTmpFile, + "dmax=" + str(params["max_dist"]), + "--overwrite", + ) + ) self._prepareCmd(cmd=cmdParams) if flags["t"]: @@ -697,8 +699,9 @@ def _runAn(self, analysis, output, params, flags, catPts): if not self.tmpInPtsConnected: return False - cmdParams.append("input=" + self.tmpInPtsConnected.GetVectMapName()) - cmdParams.append("--overwrite") + cmdParams.extend( + ("input=" + self.tmpInPtsConnected.GetVectMapName(), "--overwrite") + ) self._setCmdForSpecificAn(cmdParams) @@ -1027,8 +1030,7 @@ def AddTmpMapAnalysisMsg(mapName, tmp_maps): # TODO "Temporary map %s already exists.\n" + "Do you want to continue in analysis and overwrite it?" ) % (mapName + "@" + grass.gisenv()["MAPSET"]) - tmpMap = tmp_maps.AddTmpVectMap(mapName, msg) - return tmpMap + return tmp_maps.AddTmpVectMap(mapName, msg) class SnappingNodes(wx.EvtHandler): diff --git a/gui/wxpython/vnet/vnet_data.py b/gui/wxpython/vnet/vnet_data.py index 51c3d374cef..e86931ca294 100644 --- a/gui/wxpython/vnet/vnet_data.py +++ b/gui/wxpython/vnet/vnet_data.py @@ -562,8 +562,7 @@ def GetColumns(self, only_relevant=True): cols_data = deepcopy(self.cols) hidden_cols = [] - hidden_cols.append(self.cols["name"].index("e")) - hidden_cols.append(self.cols["name"].index("n")) + hidden_cols.extend((self.cols["name"].index("e"), self.cols["name"].index("n"))) analysis, valid = self.an_params.GetParam("analysis") if only_relevant and len(self.an_data[analysis]["cmdParams"]["cats"]) <= 1: @@ -667,8 +666,7 @@ def _getInvalidParams(self, params): vectMaps = grass.list_grouped("vector")[mapSet] if not params["input"] or mapName not in vectMaps: - invParams = list(params.keys())[:] - return invParams + return list(params.keys())[:] # check arc/node layer layers = utils.GetVectorNumberOfLayers(params["input"]) @@ -694,7 +692,7 @@ def _getInvalidParams(self, params): except (KeyError, ValueError): table = None - if not table or not params[col] in list(columnchoices.keys()): + if not table or params[col] not in list(columnchoices.keys()): invParams.append(col) continue @@ -1073,7 +1071,7 @@ def GetLastModified(self): ) try: head = open(headPath, "r") - for line in head.readlines(): + for line in head: i = line.find( "MAP DATE:", ) @@ -1202,11 +1200,10 @@ def _savePreviousHist(self, newHist, oldHist): else: newHist.write("%s%s%s" % ("\n", line, "\n")) self.histStepsNum = newHistStepsNum + elif newHistStepsNum >= self.maxHistSteps: + self._parseLine(line, removedHistStep) else: - if newHistStepsNum >= self.maxHistSteps: - self._parseLine(line, removedHistStep) - else: - newHist.write("%s" % line) + newHist.write("%s" % line) return removedHistData @@ -1253,8 +1250,7 @@ def _parseValue(self, value, read=False): value[0] == "[" and value[-1] == "]" ): # TODO, possible wrong interpretation value = value[1:-1].split(",") - value = map(self._castValue, value) - return value + return map(self._castValue, value) if value == "True": value = True @@ -1275,9 +1271,9 @@ def _parseValue(self, value, read=False): value = float(value) except ValueError: pass - else: # -> write data - if isinstance(value, type(())): # -> color - value = str(value[0]) + ":" + str(value[1]) + ":" + str(value[2]) + # -> write data + elif isinstance(value, type(())): # -> color + value = str(value[0]) + ":" + str(value[1]) + ":" + str(value[2]) return value @@ -1300,7 +1296,7 @@ def _getHistStepData(self, histStep): newHistStep = False isSearchedHistStep = False - for line in hist.readlines(): + for line in hist: if not line.strip() and isSearchedHistStep: break elif not line.strip(): diff --git a/gui/wxpython/web_services/dialogs.py b/gui/wxpython/web_services/dialogs.py index 3bfc1473121..904b2bb81c5 100644 --- a/gui/wxpython/web_services/dialogs.py +++ b/gui/wxpython/web_services/dialogs.py @@ -25,7 +25,7 @@ from copy import deepcopy -import grass.script as grass +import grass.script as gs from grass.script.task import cmdlist_to_tuple, cmdtuple_to_list from core import globalvar @@ -587,7 +587,7 @@ def OnAddLayer(self, event): active_ws = self.active_ws_panel.GetWebService() if "WMS" not in active_ws: cap_file = self.active_ws_panel.GetCapFile() - cmd_cap_file = grass.tempfile() + cmd_cap_file = gs.tempfile() shutil.copyfile(cap_file, cmd_cap_file) lcmd.append("capfile=" + cmd_cap_file) @@ -668,7 +668,7 @@ def __init__( self.revert_ws_cap_files[ws] = cmd[1]["capfile"] del ws_cap_files[ws] else: - self.revert_ws_cap_files[ws] = grass.tempfile() + self.revert_ws_cap_files[ws] = gs.tempfile() self._setRevertCapFiles(ws_cap_files) @@ -677,7 +677,7 @@ def __init__( def __del__(self): for f in self.revert_ws_cap_files.values(): - grass.try_remove(f) + gs.try_remove(f) def _setRevertCapFiles(self, ws_cap_files): for ws, f in ws_cap_files.items(): @@ -865,7 +865,7 @@ def _createWidgets(self): self.params["output"] = Select( parent=self, type="raster", - mapsets=[grass.gisenv()["MAPSET"]], + mapsets=[gs.gisenv()["MAPSET"]], size=globalvar.DIALOG_GSELECT_SIZE, ) @@ -1012,7 +1012,7 @@ def OnRegionType(self, event): def OnSave(self, event): """Import WMS raster data into GRASS as raster layer.""" self.thread.abort(abortall=True) - currmapset = grass.gisenv()["MAPSET"] + currmapset = gs.gisenv()["MAPSET"] self.output = self.params["output"].GetValue().strip() l_spl = self.output.strip().split("@") @@ -1027,7 +1027,7 @@ def OnSave(self, event): elif ( not self.overwrite.IsChecked() - and grass.find_file(self.output, "cell", ".")["fullname"] + and gs.find_file(self.output, "cell", ".")["fullname"] ): msg = _("Output map <%s> already exists" % self.output) @@ -1046,7 +1046,7 @@ def OnSave(self, event): reg_mapset = reg_spl[1] if self.region_types["named"].GetValue(): - if not grass.find_file(reg_spl[0], "windows", reg_mapset)["fullname"]: + if not gs.find_file(reg_spl[0], "windows", reg_mapset)["fullname"]: msg = _( "Region <%s> does not exist." % self.params["region"].GetValue() ) diff --git a/gui/wxpython/web_services/widgets.py b/gui/wxpython/web_services/widgets.py index 6e29e22e701..200d5521b70 100644 --- a/gui/wxpython/web_services/widgets.py +++ b/gui/wxpython/web_services/widgets.py @@ -59,7 +59,7 @@ TreeCtrl, ) -import grass.script as grass +import grass.script as gs rinwms_path = os.path.join(os.getenv("GISBASE"), "etc", "r.in.wms") if rinwms_path not in sys.path: @@ -131,7 +131,7 @@ def __init__(self, parent, web_service, **kwargs): self.cmdStdErr = GStderr(self) self.cmd_thread = CmdThread(self) - self.cap_file = grass.tempfile() + self.cap_file = gs.tempfile() reqDataBox = StaticBox(parent=self, label=_(" Requested data settings ")) self._nb_sizer = wx.StaticBoxSizer(reqDataBox, wx.VERTICAL) @@ -151,7 +151,7 @@ def __init__(self, parent, web_service, **kwargs): def __del__(self): self.cmd_thread.abort(abortall=True) - grass.try_remove(self.cap_file) + gs.try_remove(self.cap_file) def _layout(self): self._nb_sizer.Add(self.notebook, proportion=1, flag=wx.EXPAND) @@ -508,7 +508,7 @@ def OnCmdOutput(self, event): """Manage cmd output.""" if Debug.GetLevel() != 0: Debug.msg(1, event.text) - elif event.type != "message" and event.type != "warning": + elif event.type not in {"message", "warning"}: self.cmd_err_str += event.text + os.linesep def _prepareForNewConn(self, url, username, password): @@ -662,7 +662,7 @@ def UpdateWidgetsByCmd(self, cmd): if "bgcolor" in dcmd and self.params["bgcolor"]: bgcolor = dcmd["bgcolor"].strip().lower() - if len(bgcolor) == 8 and "0x" == bgcolor[:2]: + if len(bgcolor) == 8 and bgcolor[:2] == "0x": colour = "#" + bgcolor[2:] self.params["bgcolor"].SetColour(colour) diff --git a/gui/wxpython/wxplot/base.py b/gui/wxpython/wxplot/base.py index 3eb43fd5f43..7dfb444bd1e 100755 --- a/gui/wxpython/wxplot/base.py +++ b/gui/wxpython/wxplot/base.py @@ -29,7 +29,7 @@ from gui_core.toolbars import BaseIcons from gui_core.wrap import Menu -import grass.script as grass +import grass.script as gs PlotIcons = { "draw": MetaIcon(img="show", label=_("Draw/re-draw plot")), @@ -116,12 +116,12 @@ def _createColorDict(self): for assigning colors to images in imagery groups""" self.colorDict = {} - for clr in grass.named_colors.keys(): + for clr in gs.named_colors.keys(): if clr == "white": continue - r = int(grass.named_colors[clr][0] * 255) - g = int(grass.named_colors[clr][1] * 255) - b = int(grass.named_colors[clr][2] * 255) + r = int(gs.named_colors[clr][0] * 255) + g = int(gs.named_colors[clr][1] * 255) + b = int(gs.named_colors[clr][2] * 255) self.colorDict[clr] = (r, g, b, 255) def InitPlotOpts(self, plottype): @@ -203,7 +203,7 @@ def InitRasterOpts(self, rasterList, plottype): idx = rasterList.index(r) try: - ret = grass.raster_info(r) + ret = gs.raster_info(r) except: continue # if r.info cannot parse map, skip it @@ -267,8 +267,8 @@ def InitRasterPairs(self, rasterList, plottype): idx = rasterList.index(rpair) try: - ret0 = grass.raster_info(rpair[0]) - ret1 = grass.raster_info(rpair[1]) + ret0 = gs.raster_info(rpair[0]) + ret1 = gs.raster_info(rpair[1]) except: continue @@ -584,7 +584,7 @@ def PlotText(self, event): ) btnval = dlg.ShowModal() - if btnval == wx.ID_SAVE or btnval == wx.ID_OK or btnval == wx.ID_CANCEL: + if btnval in {wx.ID_SAVE, wx.ID_OK, wx.ID_CANCEL}: dlg.Destroy() def PlotOptions(self, event): @@ -602,7 +602,7 @@ def PlotOptions(self, event): ) btnval = dlg.ShowModal() - if btnval == wx.ID_SAVE or btnval == wx.ID_OK or btnval == wx.ID_CANCEL: + if btnval in {wx.ID_SAVE, wx.ID_OK, wx.ID_CANCEL}: dlg.Destroy() self.Update() diff --git a/gui/wxpython/wxplot/dialogs.py b/gui/wxpython/wxplot/dialogs.py index d2273d7083c..bae305a1817 100755 --- a/gui/wxpython/wxplot/dialogs.py +++ b/gui/wxpython/wxplot/dialogs.py @@ -464,9 +464,8 @@ def _do_layout(self): ) if self.rasterRadio.GetValue(): self.gselection.Disable() - else: - if self.group is not None: - self.gselection.SetValue(self.group) + elif self.group is not None: + self.gselection.SetValue(self.group) box.Add(self.gselection, pos=(2, 1)) # diff --git a/gui/wxpython/wxplot/histogram.py b/gui/wxpython/wxplot/histogram.py index 1c5c2b2de4f..1c7d4bf21d9 100644 --- a/gui/wxpython/wxplot/histogram.py +++ b/gui/wxpython/wxplot/histogram.py @@ -19,7 +19,7 @@ import wx -import grass.script as grass +import grass.script as gs from wx.lib import plot from gui_core.wrap import StockCursor from gui_core.toolbars import BaseToolbar, BaseIcons @@ -145,11 +145,10 @@ def SetupHistogram(self): # if self.maptype == "group": self.ptitle = _("Histogram of image group <%s>") % self.group + elif len(self.rasterList) == 1: + self.ptitle = _("Histogram of raster map <%s>") % self.rasterList[0] else: - if len(self.rasterList) == 1: - self.ptitle = _("Histogram of raster map <%s>") % self.rasterList[0] - else: - self.ptitle = _("Histogram of selected raster maps") + self.ptitle = _("Histogram of selected raster maps") # # set xlabel based on first raster map in list to be histogrammed @@ -259,7 +258,7 @@ def OnStats(self, event): title = _("Statistics for Map(s) Histogrammed") for rast in self.rasterList: - ret = grass.read_command("r.univar", map=rast, flags="e", quiet=True) + ret = gs.read_command("r.univar", map=rast, flags="e", quiet=True) stats = _("Statistics for raster map <%s>") % rast + ":\n%s\n" % ret message.append(stats) diff --git a/gui/wxpython/wxplot/profile.py b/gui/wxpython/wxplot/profile.py index 6d49ea3fde1..1e79379b08b 100644 --- a/gui/wxpython/wxplot/profile.py +++ b/gui/wxpython/wxplot/profile.py @@ -18,12 +18,12 @@ import os import sys import math -import numpy +import numpy as np import wx from wx.lib import plot -import grass.script as grass +import grass.script as gs from wxplot.base import BasePlotFrame, PlotIcons from gui_core.toolbars import BaseToolbar, BaseIcons from gui_core.wrap import StockCursor @@ -164,7 +164,7 @@ def SetupProfile(self): self.coordstr = "" lasteast = lastnorth = None - region = grass.region() + region = gs.region() insideRegion = True if len(self.transect) > 0: for point in self.transect: @@ -287,7 +287,7 @@ def CreateDatalist(self, raster, coords): # keep total number of transect points to 500 or less to avoid # freezing with large, high resolution maps - region = grass.region() + region = gs.region() curr_res = min(float(region["nsres"]), float(region["ewres"])) transect_rec = 0 if self.transect_length / curr_res > 500: @@ -472,19 +472,19 @@ def OnStats(self, event): statstr = "Profile of %s\n\n" % rast iterable = (i[1] for i in self.raster[r]["datalist"]) - a = numpy.fromiter(iterable, numpy.float) + a = np.fromiter(iterable, float) statstr += "n: %f\n" % a.size - statstr += "minimum: %f\n" % numpy.amin(a) - statstr += "maximum: %f\n" % numpy.amax(a) - statstr += "range: %f\n" % numpy.ptp(a) - statstr += "mean: %f\n" % numpy.mean(a) - statstr += "standard deviation: %f\n" % numpy.std(a) - statstr += "variance: %f\n" % numpy.var(a) - cv = numpy.std(a) / numpy.mean(a) + statstr += "minimum: %f\n" % np.amin(a) + statstr += "maximum: %f\n" % np.amax(a) + statstr += "range: %f\n" % np.ptp(a) + statstr += "mean: %f\n" % np.mean(a) + statstr += "standard deviation: %f\n" % np.std(a) + statstr += "variance: %f\n" % np.var(a) + cv = np.std(a) / np.mean(a) statstr += "coefficient of variation: %f\n" % cv - statstr += "sum: %f\n" % numpy.sum(a) - statstr += "median: %f\n" % numpy.median(a) + statstr += "sum: %f\n" % np.sum(a) + statstr += "median: %f\n" % np.median(a) statstr += "distance along transect: %f\n\n" % self.transect_length message.append(statstr) except: diff --git a/gui/wxpython/wxplot/scatter.py b/gui/wxpython/wxplot/scatter.py index b0063150560..c57a3e1fac9 100644 --- a/gui/wxpython/wxplot/scatter.py +++ b/gui/wxpython/wxplot/scatter.py @@ -19,7 +19,7 @@ import wx -import grass.script as grass +import grass.script as gs from wx.lib import plot from wxplot.base import BasePlotFrame, PlotIcons from gui_core.toolbars import BaseToolbar, BaseIcons @@ -275,13 +275,13 @@ def OnRegression(self, event): rast1, rast2 = rpair rast1 = rast1.split("@")[0] rast2 = rast2.split("@")[0] - ret = grass.parse_command( + ret = gs.parse_command( "r.regression.line", mapx=rast1, mapy=rast2, flags="g", quiet=True, - parse=(grass.parse_key_val, {"sep": "="}), + parse=(gs.parse_key_val, {"sep": "="}), ) eqtitle = _( "Regression equation for raster map <%(rast1)s> vs. <%(rast2)s>:\n\n" diff --git a/imagery/i.atcorr/create_iwave.py b/imagery/i.atcorr/create_iwave.py index c304ab71645..243e7a22542 100644 --- a/imagery/i.atcorr/create_iwave.py +++ b/imagery/i.atcorr/create_iwave.py @@ -35,18 +35,15 @@ def usage(): """How to use this...""" print("create_iwave.py ") - print print("Generates filter function template for iwave.cpp from csv file. Note:") print("- csv file must have wl response for each band in each column") print("- first line must be a header with wl followed by band names") print("- all following lines will be the data.") print("If spectral response is null, leave field empty in csv file. Example:") - print print("WL(nm),band 1,band 2,band 3,band 4") print("455,0.93,,,") print("485,0.94,0.00,,") print("545,0.00,0.87,0.00,") - print print("This script will interpolate the filter functions to 2.5 nm steps") print("and output a cpp template file in the IWave format to be added to iwave.cpp") @@ -178,13 +175,13 @@ def pretty_print(filter_f): """ pstring = "" for i in range(len(filter_f) + 1): - if i % 8 is 0: - if i is not 0: + if i % 8 == 0: + if i != 0: value_wo_leading_zero = ("%.4f" % (filter_f[i - 1])).lstrip("0") pstring += value_wo_leading_zero if i > 1 and i < len(filter_f): pstring += ", " - if i is not 1: + if i != 1: # trim the trailing whitespace at the end of line pstring = pstring.rstrip() pstring += "\n " @@ -194,8 +191,7 @@ def pretty_print(filter_f): if i < len(filter_f): pstring += ", " # trim starting \n and trailing , - pstring = pstring.lstrip("\n").rstrip(", ") - return pstring + return pstring.lstrip("\n").rstrip(", ") def write_cpp(bands, values, sensor, folder): @@ -207,7 +203,6 @@ def write_cpp(bands, values, sensor, folder): # keep in sync with IWave::parse() rthresh = 0.01 - print print(" > Response peaks from interpolation to 2.5 nm steps:") # getting necessary data @@ -334,7 +329,6 @@ def main(): # getting sensor name from full csv file name sensor = os.path.splitext(os.path.basename(inputfile))[0] - print print(" > Getting sensor name from csv file: %s" % (sensor)) # getting data from file @@ -344,7 +338,6 @@ def main(): # consider only wavelengths with a reasonably large response # around the peak response, keep in sync with IWave::parse() rthresh = 0.01 - print print(" > Response peaks from input file:") for b in range(1, len(bands) + 1): lowl = 0 @@ -372,7 +365,6 @@ def main(): # writing file in same folder of input file write_cpp(bands, values, sensor, os.path.dirname(inputfile)) - print print( " > Filter functions exported to %s" % ("sensors_csv/" + sensor + "_cpp_template.txt") @@ -385,7 +377,6 @@ def main(): " > Don't forget to add the necessary data to the files" " iwave.h, geomcond.h, geomcond.cpp, and to i.atcorr.html" ) - print if __name__ == "__main__": diff --git a/imagery/i.atcorr/main.cpp b/imagery/i.atcorr/main.cpp index 8b2a1779fa3..19a28e7cc35 100644 --- a/imagery/i.atcorr/main.cpp +++ b/imagery/i.atcorr/main.cpp @@ -204,8 +204,7 @@ class TICache { private: struct RBitem set_alt_vis(double alt, double vis) { - struct RBitem rbitem; - + struct RBitem rbitem = {}; /* alt and vis must be in meters */ rbitem.alt = (alt < 0 ? (int)(alt - 0.5) : (int)(alt + 0.5)); rbitem.vis = (int)(vis + 0.5); diff --git a/imagery/i.segment/mean_shift.c b/imagery/i.segment/mean_shift.c index 169ca21875a..5a6f4c5ab1c 100644 --- a/imagery/i.segment/mean_shift.c +++ b/imagery/i.segment/mean_shift.c @@ -457,6 +457,7 @@ static int find_best_neighbour(struct globals *globals, int row, int col, visited = pavl_create(cmp_rc, NULL); ngbr_rc.row = row; ngbr_rc.col = col; + ngbr_rc.next = NULL; pngbr_rc = G_malloc(sizeof(struct rc)); *pngbr_rc = ngbr_rc; pavl_insert(visited, pngbr_rc); diff --git a/imagery/i.segment/region_growing.c b/imagery/i.segment/region_growing.c index f0531927588..dc5b5bd2157 100644 --- a/imagery/i.segment/region_growing.c +++ b/imagery/i.segment/region_growing.c @@ -192,7 +192,8 @@ int region_growing(struct globals *globals) int pathflag; /* =1 if we didn't find mutually best neighbors, continue with Rk */ int candidates_only; - struct ngbr_stats Ri, Rk, Rk_bestn, /* Rk's best neighbor */ + struct ngbr_stats Ri = {0}, Rk = {0}, + Rk_bestn = {0}, /* Rk's best neighbor */ *next; int Ri_nn, Rk_nn; /* number of neighbors for Ri/Rk */ struct NB_TREE *Ri_ngbrs, *Rk_ngbrs; @@ -695,7 +696,7 @@ static int find_best_neighbor(struct ngbr_stats *Ri, struct reg_stats *Ri_rs, int clear_cand, struct globals *globals) { int n, n_ngbrs, no_check, cmp; - struct rc ngbr_rc, next, *pngbr_rc; + struct rc ngbr_rc = {0}, next = {0}, *pngbr_rc = NULL; struct rclist rilist; double tempsim; int neighbors[8][2]; @@ -892,7 +893,7 @@ double calculate_shape(struct reg_stats *rsi, struct reg_stats *rsk, double smooth, compact; int pl, pbbox, count; double bboxdiag; - int pl1, pl2, count1, count2; + int pl1 = 0, pl2 = 0, count1 = 0, count2 = 0; int e1, n1, s1, w1, e2, n2, s2, w2, ns_extent, ew_extent; pl = pl1 + pl2 - nshared; @@ -988,7 +989,7 @@ static int search_neighbors(struct ngbr_stats *Ri, struct reg_stats *Ri_rs, int update_band_vals(int row, int col, struct reg_stats *rs, struct globals *globals) { - struct rc next, ngbr_rc; + struct rc next = {0}, ngbr_rc = {0}; int neighbors[8][2]; int rid, count, n; @@ -1497,7 +1498,7 @@ static int calculate_reg_stats(int row, int col, struct reg_stats *rs, ret = 1; else if (globals->min_reg_size == 3) { int n, rid; - struct rc ngbr_rc; + struct rc ngbr_rc = {0}; int neighbors[8][2]; globals->find_neighbors(row, col, neighbors); @@ -1540,7 +1541,7 @@ static int calculate_reg_stats(int row, int col, struct reg_stats *rs, /* rs->id must be set */ struct pavl_table *rc_check_tree; /* cells already checked */ int n, rid; - struct rc ngbr_rc, *pngbr_rc, next; + struct rc ngbr_rc = {0}, *pngbr_rc = NULL, next = {0}; struct rclist rilist; int neighbors[8][2]; int no_check; diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index bf100e95d27..bb9258ac353 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -146,7 +146,7 @@ add_subdirectory(fonts) add_subdirectory(vector) -build_library_in_subdir(imagery DEPENDS grass_gis grass_vector grass_raster) +build_library_in_subdir(imagery DEPENDS grass_gis grass_vector grass_raster GDAL) build_library_in_subdir(cluster DEPENDS grass_imagery grass_gis grass_raster) @@ -168,6 +168,7 @@ build_library_in_subdir( grass_dbmidriver grass_gmath grass_segment + GDAL HEADERS "lidar.h") @@ -181,7 +182,8 @@ build_program_in_subdir( DEPENDS grass_gis grass_raster3d - grass_raster) + grass_raster + GDAL) build_library_in_subdir( gpde @@ -217,7 +219,7 @@ build_library_in_subdir(stats DEPENDS grass_gis grass_raster) build_library_in_subdir(arraystats DEPENDS grass_gis) -if(WITH_OPENGL) +if(WITH_OPENGL AND OPENGL_GLU_FOUND AND OpenGL_GLX_FOUND) build_library_in_subdir( ogsf DEPENDS @@ -229,6 +231,7 @@ if(WITH_OPENGL) grass_raster grass_raster3d grass_vector + GDAL OPENGL TIFF) @@ -250,7 +253,7 @@ add_subdirectory(temporal) build_library_in_subdir(iostream SRC_REGEX "*.cpp" DEPENDS grass_gis) build_library_in_subdir(manage DEPENDS grass_gis grass_raster grass_vector - grass_raster3d) + grass_raster3d GDAL) file(COPY manage/element_list DESTINATION ${OUTDIR}/${GRASS_INSTALL_ETCDIR}) install(FILES ${OUTDIR}/${GRASS_INSTALL_ETCDIR}/element_list DESTINATION ${GRASS_INSTALL_ETCDIR}) diff --git a/lib/cdhc/dmax.c b/lib/cdhc/dmax.c index 8b9638f0c45..8f4fb01cd73 100644 --- a/lib/cdhc/dmax.c +++ b/lib/cdhc/dmax.c @@ -7,7 +7,7 @@ double *Cdhc_dmax(double *x, int n) { static double y[2]; double *xcopy, sqrt2, mean = 0.0, sdx = 0.0, fx; - double dp, dp_max, dm, dm_max; + double dp = 0.0, dp_max = 0.0, dm = 0.0, dm_max = 0.0; int i; if ((xcopy = (double *)malloc(n * sizeof(double))) == NULL) { diff --git a/lib/cdhc/shapiroe.c b/lib/cdhc/shapiroe.c index 1a75b393597..05521183829 100644 --- a/lib/cdhc/shapiroe.c +++ b/lib/cdhc/shapiroe.c @@ -6,6 +6,7 @@ double *Cdhc_shapiro_wilk_exp(double *x, int n) static double y[2]; double mean, b, s1, xs, sum1 = 0.0, sum2 = 0.0; int i; + xs = x[0]; for (i = 0; i < n; ++i) if (i == 0 || xs > x[i]) diff --git a/lib/gis/parser_interface.c b/lib/gis/parser_interface.c index f3bab3d2aa9..fb091af9144 100644 --- a/lib/gis/parser_interface.c +++ b/lib/gis/parser_interface.c @@ -107,7 +107,7 @@ void G__usage_xml(void) char *type; char *s, *top; int i; - const char *encoding = ""; + const char *encoding = NULL; int new_prompt = 0; new_prompt = G__uses_new_gisprompt(); diff --git a/lib/imagery/testsuite/test_imagery_signature_management.py b/lib/imagery/testsuite/test_imagery_signature_management.py index 21f052372e2..7b1dc8bdc57 100644 --- a/lib/imagery/testsuite/test_imagery_signature_management.py +++ b/lib/imagery/testsuite/test_imagery_signature_management.py @@ -17,7 +17,7 @@ from grass.gunittest.main import test from grass.script.core import tempname -import grass.script as grass +import grass.script as gs from grass.pygrass import utils from grass.pygrass.gis import Mapset, make_mapset @@ -1036,13 +1036,13 @@ def test_multiple_sigs_multiple_mapsets(self): self.assertNotIn(golden[0], ret_list) I_free_signatures_list(ret, ctypes.byref(sig_list)) # Add temporary mapset to search path and re-run test - grass.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="add") + gs.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="add") # Search path is cached for this run => reset! G_reset_mapsets() ret = I_signatures_list_by_type( I_SIGFILE_TYPE_SIG, None, ctypes.byref(sig_list) ) - grass.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="remove") + gs.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="remove") G_reset_mapsets() shutil.rmtree(sig_dir1) shutil.rmtree(sig_dir2) @@ -1087,13 +1087,13 @@ def test_multiple_sigsets_multiple_mapsets(self): self.assertNotIn(golden[0], ret_list) I_free_signatures_list(ret, ctypes.byref(sig_list)) # Add temporary mapset to search path and re-run test - grass.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="add") + gs.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="add") # Search path is cached for this run => reset! G_reset_mapsets() ret = I_signatures_list_by_type( I_SIGFILE_TYPE_SIGSET, None, ctypes.byref(sig_list) ) - grass.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="remove") + gs.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="remove") G_reset_mapsets() shutil.rmtree(sig_dir1) shutil.rmtree(sig_dir2) @@ -1139,13 +1139,13 @@ def test_multiple_libsvms_multiple_mapsets(self): self.assertNotIn(golden[0], ret_list) I_free_signatures_list(ret, ctypes.byref(sig_list)) # Add temporary mapset to search path and re-run test - grass.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="add") + gs.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="add") # Search path is cached for this run => reset! G_reset_mapsets() ret = I_signatures_list_by_type( I_SIGFILE_TYPE_LIBSVM, None, ctypes.byref(sig_list) ) - grass.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="remove") + gs.run_command("g.mapsets", mapset=self.rnd_mapset_name, operation="remove") G_reset_mapsets() shutil.rmtree(sig_dir1) shutil.rmtree(sig_dir2) diff --git a/lib/init/grass.py b/lib/init/grass.py index d453865a12d..7fe8dd2da10 100755 --- a/lib/init/grass.py +++ b/lib/init/grass.py @@ -673,20 +673,18 @@ def check_gui(expected_gui): if msg: warning(_("{}\nSwitching to text based interface mode.").format(msg)) grass_gui = "text" - - else: - # Display a message if a graphical interface was expected - if expected_gui != "text": - # Set the interface mode to text - warning( - _( - "It appears that the X Windows system is not active.\n" - "A graphical based user interface is not supported.\n" - "(DISPLAY variable is not set.)\n" - "Switching to text based interface mode." - ) + # Display a message if a graphical interface was expected + elif expected_gui != "text": + # Set the interface mode to text + warning( + _( + "It appears that the X Windows system is not active.\n" + "A graphical based user interface is not supported.\n" + "(DISPLAY variable is not set.)\n" + "Switching to text based interface mode." ) - grass_gui = "text" + ) + grass_gui = "text" return grass_gui @@ -872,103 +870,96 @@ def set_mapset( else: suggestion = _("Maybe you meant a different directory.") fatal("{reason}\n{suggestion}".format(**locals())) - else: - # 'path' is not valid and the user wants to create - # mapset on the fly - # check if 'location_name' is a valid GRASS location - if not is_location_valid(gisdbase, location_name): - if not (tmp_location or tmp_mapset): - # 'location_name' is not a valid GRASS location - # and user requested its creation, so we parsed - # the path wrong and need to move one level - # and use 'PERMANENT' mapset - # (we already got that right in case of tmploc) - gisdbase = os.path.join(gisdbase, location_name) - location_name = mapset - mapset = "PERMANENT" - if tmp_mapset: - suggestion = get_location_invalid_suggestion( - gisdbase, location_name - ) - reason = get_location_invalid_reason(gisdbase, location_name) - if suggestion: - fatal("{reason}\n{suggestion}".format(**locals())) - else: - fatal(reason) - if not can_create_location(gisdbase, location_name): - fatal(cannot_create_location_reason(gisdbase, location_name)) - # create new location based on the provided EPSG/... - if not geofile: - fatal(_("Provide CRS to create a project")) - if not tmp_location: - # Report report only when new location is not temporary. - message( - _("Creating new GRASS GIS project <{}>...").format( - location_name - ) + # 'path' is not valid and the user wants to create + # mapset on the fly + # check if 'location_name' is a valid GRASS location + elif not is_location_valid(gisdbase, location_name): + if not (tmp_location or tmp_mapset): + # 'location_name' is not a valid GRASS location + # and user requested its creation, so we parsed + # the path wrong and need to move one level + # and use 'PERMANENT' mapset + # (we already got that right in case of tmploc) + gisdbase = os.path.join(gisdbase, location_name) + location_name = mapset + mapset = "PERMANENT" + if tmp_mapset: + suggestion = get_location_invalid_suggestion( + gisdbase, location_name + ) + reason = get_location_invalid_reason(gisdbase, location_name) + if suggestion: + fatal("{reason}\n{suggestion}".format(**locals())) + else: + fatal(reason) + if not can_create_location(gisdbase, location_name): + fatal(cannot_create_location_reason(gisdbase, location_name)) + # create new location based on the provided EPSG/... + if not geofile: + fatal(_("Provide CRS to create a project")) + if not tmp_location: + # Report report only when new location is not temporary. + message( + _("Creating new GRASS GIS project <{}>...").format( + location_name ) - create_location(gisdbase, location_name, geofile) + ) + create_location(gisdbase, location_name, geofile) + else: + # 'location_name' is a valid GRASS location, + # create new mapset + if os.path.isfile(path): + # not a valid mapset, but dir exists, assuming + # broken/incomplete mapset + fatal( + _( + "Unable to create new mapset <{mapset}>" + " because <{path}> is a file." + ).format(mapset=mapset, path=path) + ) + elif os.path.isdir(path): + # not a valid mapset, but dir exists, assuming + # broken/incomplete mapset + warning( + _( + "The mapset <{}> is missing the WIND file" + " (computational region). It will be" + " fixed now. Note that this warning" + " may become an error in future versions." + ).format(mapset) + ) else: - # 'location_name' is a valid GRASS location, - # create new mapset - if os.path.isfile(path): - # not a valid mapset, but dir exists, assuming - # broken/incomplete mapset + if geofile: fatal( _( - "Unable to create new mapset <{mapset}>" - " because <{path}> is a file." - ).format(mapset=mapset, path=path) - ) - elif os.path.isdir(path): - # not a valid mapset, but dir exists, assuming - # broken/incomplete mapset - warning( - _( - "The mapset <{}> is missing the WIND file" - " (computational region). It will be" - " fixed now. Note that this warning" - " may become an error in future versions." - ).format(mapset) + "No CRS is needed for creating mapset <{mapset}>, " + "but <{geofile}> was provided as CRS." + " Did you mean to create a new project?" + ).format(mapset=mapset, geofile=geofile) ) - else: - if geofile: - fatal( - _( - "No CRS is needed for creating mapset <{mapset}>, " - "but <{geofile}> was provided as CRS." - " Did you mean to create a new project?" - ).format(mapset=mapset, geofile=geofile) - ) - if not tmp_mapset: - message( - _("Creating new GRASS GIS mapset <{}>...").format( - mapset - ) - ) - # create mapset directory - os.mkdir(path) - if tmp_mapset: - # The tmp location is handled by (re-)using the - # tmpdir, but we need to take care of the tmp - # mapset which is only a subtree in an existing - # location. We simply remove the tree at exit. - # All mapset cleaning functions should succeed - # because they are called before exit or registered - # only later (and thus called before this one). - # (Theoretically, they could be disabled if that's - # just cleaning a files in the mapset directory.) - atexit.register( - lambda: shutil.rmtree(path, ignore_errors=True) - ) - # make directory a mapset, add the region - # copy PERMANENT/DEFAULT_WIND to /WIND - s = readfile( - os.path.join( - gisdbase, location_name, "PERMANENT", "DEFAULT_WIND" + if not tmp_mapset: + message( + _("Creating new GRASS GIS mapset <{}>...").format(mapset) ) - ) - writefile(os.path.join(path, "WIND"), s) + # create mapset directory + os.mkdir(path) + if tmp_mapset: + # The tmp location is handled by (re-)using the + # tmpdir, but we need to take care of the tmp + # mapset which is only a subtree in an existing + # location. We simply remove the tree at exit. + # All mapset cleaning functions should succeed + # because they are called before exit or registered + # only later (and thus called before this one). + # (Theoretically, they could be disabled if that's + # just cleaning a files in the mapset directory.) + atexit.register(lambda: shutil.rmtree(path, ignore_errors=True)) + # make directory a mapset, add the region + # copy PERMANENT/DEFAULT_WIND to /WIND + s = readfile( + os.path.join(gisdbase, location_name, "PERMANENT", "DEFAULT_WIND") + ) + writefile(os.path.join(path, "WIND"), s) add_mapset_to_gisrc(gisrc, gisdbase, location_name, mapset) else: fatal( @@ -1947,7 +1938,7 @@ def print_params(params): # check if we are dealing with parameters which require dev files dev_params = ["arch", "compiler", "build", "date"] - if any([param in dev_params for param in params]): + if any(param in dev_params for param in params): plat = gpath("include", "Make", "Platform.make") if not os.path.exists(plat): fatal(_("Please install the GRASS GIS development package")) @@ -1990,7 +1981,7 @@ def print_params(params): date_str = "#define GRASS_HEADERS_DATE " gdate = gpath("include", "grass", "version.h") with open(gdate) as filegdate: - for line in filegdate.readlines(): + for line in filegdate: if line.startswith(date_str): sys.stdout.write( "{}\n".format( @@ -2438,25 +2429,24 @@ def main(): else: # Use the last used mapset. set_mapset(gisrc=gisrc, arg=last_mapset_path) + # Mapset was specified in command line parameters. + elif params.tmp_location: + # tmp loc requires other things to be set as well + set_mapset( + gisrc=gisrc, + geofile=params.geofile, + create_new=True, + tmp_location=params.tmp_location, + tmpdir=tmpdir, + ) + elif params.create_new and params.geofile: + set_mapset( + gisrc=gisrc, arg=params.mapset, geofile=params.geofile, create_new=True + ) + elif params.tmp_mapset: + set_mapset(gisrc=gisrc, arg=params.mapset, tmp_mapset=params.tmp_mapset) else: - # Mapset was specified in command line parameters. - if params.tmp_location: - # tmp loc requires other things to be set as well - set_mapset( - gisrc=gisrc, - geofile=params.geofile, - create_new=True, - tmp_location=params.tmp_location, - tmpdir=tmpdir, - ) - elif params.create_new and params.geofile: - set_mapset( - gisrc=gisrc, arg=params.mapset, geofile=params.geofile, create_new=True - ) - elif params.tmp_mapset: - set_mapset(gisrc=gisrc, arg=params.mapset, tmp_mapset=params.tmp_mapset) - else: - set_mapset(gisrc=gisrc, arg=params.mapset, create_new=params.create_new) + set_mapset(gisrc=gisrc, arg=params.mapset, create_new=params.create_new) # Set GISDBASE, LOCATION_NAME, MAPSET, LOCATION from $GISRC # e.g. wxGUI startup screen writes to the gisrc file, @@ -2520,7 +2510,7 @@ def main(): ) if sh in {"csh", "tcsh"}: shell_process = csh_startup(mapset_settings.full_mapset, grass_env_file) - elif sh in {"zsh"}: + elif sh == "zsh": shell_process = sh_like_startup( mapset_settings.full_mapset, mapset_settings.location, diff --git a/lib/rst/CMakeLists.txt b/lib/rst/CMakeLists.txt index 61fb629e2cc..b555d701dce 100644 --- a/lib/rst/CMakeLists.txt +++ b/lib/rst/CMakeLists.txt @@ -33,6 +33,7 @@ build_library_in_subdir( grass_vector grass_qtree grass_interpdata + GDAL LIBM OPTIONAL_DEPENDS OPENMP diff --git a/lib/vector/CMakeLists.txt b/lib/vector/CMakeLists.txt index 9272e432253..083b489d8f7 100644 --- a/lib/vector/CMakeLists.txt +++ b/lib/vector/CMakeLists.txt @@ -42,7 +42,8 @@ build_library_in_subdir( grass_vector grass_dbmibase grass_dbmiclient - grass_dbmidriver) + grass_dbmidriver + GDAL) build_library_in_subdir( neta @@ -54,7 +55,8 @@ build_library_in_subdir( grass_dbmidriver grass_gis grass_dgl - grass_vector) + grass_vector + GDAL) if(WITH_DOCS) generate_html(TARGET grass_vector NAME vectorascii) diff --git a/lib/vector/vedit/break.c b/lib/vector/vedit/break.c index dd8612fa675..5387bd3f016 100644 --- a/lib/vector/vedit/break.c +++ b/lib/vector/vedit/break.c @@ -41,14 +41,12 @@ int Vedit_split_lines(struct Map_info *Map, struct ilist *List, struct line_pnts *Points, *Points2; struct line_cats *Cats; - struct ilist *List_in_box; nlines_modified = 0; Points = Vect_new_line_struct(); Points2 = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); - List_in_box = Vect_new_list(); for (i = 0; i < List->n_values; i++) { line = List->value[i]; @@ -101,7 +99,8 @@ int Vedit_split_lines(struct Map_info *Map, struct ilist *List, else newline = Vect_write_line(Map, type, Points2, Cats); if (newline < 0) { - return -1; + nlines_modified = -1; + goto free_exit; } if (List_updated) Vect_list_append(List_updated, newline); @@ -118,7 +117,8 @@ int Vedit_split_lines(struct Map_info *Map, struct ilist *List, /* rewrite the line */ newline = Vect_write_line(Map, type, Points2, Cats); if (newline < 0) { - return -1; + nlines_modified = -1; + goto free_exit; } if (List_updated) Vect_list_append(List_updated, newline); @@ -127,10 +127,10 @@ int Vedit_split_lines(struct Map_info *Map, struct ilist *List, } /* for each bounding box */ } /* for each selected line */ +free_exit: Vect_destroy_line_struct(Points); Vect_destroy_line_struct(Points2); Vect_destroy_cats_struct(Cats); - Vect_destroy_list(List_in_box); return nlines_modified; } diff --git a/lib/vector/vedit/delete.c b/lib/vector/vedit/delete.c index 7b2ead3362c..74a7358d777 100644 --- a/lib/vector/vedit/delete.c +++ b/lib/vector/vedit/delete.c @@ -94,8 +94,6 @@ int Vedit_delete_area(struct Map_info *Map, int area) int i, line, centroid, left, right; struct ilist *list; - list = Vect_new_list(); - G_debug(3, "Vedit_delete_area(): area=%d", area); centroid = Vect_get_area_centroid(Map, area); if (centroid != 0) { @@ -105,6 +103,7 @@ int Vedit_delete_area(struct Map_info *Map, int area) G_warning(_("Area %d without centroid"), area); return 0; } + list = Vect_new_list(); Vect_get_area_boundaries(Map, area, list); if (list->n_values > 0) { for (i = 0; i < list->n_values; i++) { @@ -119,6 +118,7 @@ int Vedit_delete_area(struct Map_info *Map, int area) } else { G_warning(_("Area %d has no boundaries"), area); + Vect_destroy_list(list); return 0; } diff --git a/lib/vector/vedit/merge.c b/lib/vector/vedit/merge.c index 9200c990ba1..7c752867232 100644 --- a/lib/vector/vedit/merge.c +++ b/lib/vector/vedit/merge.c @@ -184,7 +184,8 @@ int Vedit_merge_lines(struct Map_info *Map, struct ilist *List) if (Points->n_points > 0) { line = Vect_rewrite_line(Map, line1, type1, Points, Cats1); if (line < 0) { - return -1; + nlines_merged = -1; + goto free_exit; } if (line1 <= nlines) @@ -195,6 +196,7 @@ int Vedit_merge_lines(struct Map_info *Map, struct ilist *List) } } /* for each line */ +free_exit: /* destroy structures */ Vect_destroy_line_struct(Points1); Vect_destroy_line_struct(Points2); @@ -203,6 +205,8 @@ int Vedit_merge_lines(struct Map_info *Map, struct ilist *List) Vect_destroy_cats_struct(Cats1); Vect_destroy_cats_struct(Cats2); + Vect_destroy_list(List_in_box); + return nlines_merged; } diff --git a/lib/vector/vedit/render.c b/lib/vector/vedit/render.c index a1c5bd8458e..9bd5462d1d7 100644 --- a/lib/vector/vedit/render.c +++ b/lib/vector/vedit/render.c @@ -204,8 +204,10 @@ struct robject *draw_line(struct Map_info *Map, int line, int draw_flag) G_debug(3, " draw_line(): type=%d rtype=%d npoints=%d draw=%d", state.type, obj->type, state.Points->n_points, draw); - if (!draw) + if (!draw) { + G_free(obj); return NULL; + } obj->npoints = state.Points->n_points; obj->point = diff --git a/lib/vector/vedit/snap.c b/lib/vector/vedit/snap.c index c8f51ea86fb..f60a21069cf 100644 --- a/lib/vector/vedit/snap.c +++ b/lib/vector/vedit/snap.c @@ -103,13 +103,13 @@ int Vedit_snap_line(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps, struct line_cats *Cats; - Cats = Vect_new_cats_struct(); - G_debug(3, "Vedit_snap_line(): thresh=%g, to_vertex=%d", thresh, to_vertex); if (line > 0 && !Vect_line_alive(Map, line)) return -1; + Cats = Vect_new_cats_struct(); + npoints = Points->n_points; x = Points->x; y = Points->y; @@ -190,13 +190,15 @@ int Vedit_snap_lines(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps, if (Vedit_snap_line(Map, BgMap, nbgmaps, line, Points, thresh, to_vertex) == 1) { if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) { - return -1; + nlines_modified = -1; + goto free_exit; } nlines_modified++; } } +free_exit: Vect_destroy_line_struct(Points); Vect_destroy_cats_struct(Cats); diff --git a/lib/vector/vedit/vertex.c b/lib/vector/vedit/vertex.c index 851257cd874..f64a10bee8a 100644 --- a/lib/vector/vedit/vertex.c +++ b/lib/vector/vedit/vertex.c @@ -44,14 +44,13 @@ int Vedit_move_vertex(struct Map_info *Map, struct Map_info **BgMap, double *x, *y, *z; char *moved; - struct line_pnts *Points, *Points_snap; + struct line_pnts *Points; struct line_cats *Cats; nvertices_moved = nvertices_snapped = 0; moved = NULL; Points = Vect_new_line_struct(); - Points_snap = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); for (i = 0; i < List->n_values; i++) { @@ -157,16 +156,17 @@ int Vedit_move_vertex(struct Map_info *Map, struct Map_info **BgMap, if (rewrite) { if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) { - return -1; + nvertices_moved = -1; + goto free_exit; } } } /* for each selected line */ +free_exit: /* destroy structures */ Vect_destroy_line_struct(Points); - Vect_destroy_line_struct(Points_snap); Vect_destroy_cats_struct(Cats); - /* G_free ((void *) moved); */ + G_free(moved); return nvertices_moved; } diff --git a/lib/vector/vedit/zbulk.c b/lib/vector/vedit/zbulk.c index 0d24c6d4b7a..cfa0d4becdc 100644 --- a/lib/vector/vedit/zbulk.c +++ b/lib/vector/vedit/zbulk.c @@ -66,7 +66,8 @@ int Vedit_bulk_labeling(struct Map_info *Map, struct ilist *List, double x1, /* write temporary line */ temp_line = Vect_write_line(Map, GV_LINE, Points_se, Cats); if (temp_line < 0) { - return -1; + nlines_modified = -1; + goto free_exit; } Vect_line_box(Points_se, &box_se); @@ -118,7 +119,8 @@ int Vedit_bulk_labeling(struct Map_info *Map, struct ilist *List, double x1, } if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) { - return -1; + nlines_modified = -1; + goto free_exit; } nlines_modified++; @@ -126,9 +128,10 @@ int Vedit_bulk_labeling(struct Map_info *Map, struct ilist *List, double x1, } if (Vect_delete_line(Map, temp_line) < 0) { - return -1; + nlines_modified = -1; } +free_exit: db_CatValArray_free(&cv); Vect_destroy_line_struct(Points); Vect_destroy_line_struct(Points_se); diff --git a/locale/grass_po_stats.py b/locale/grass_po_stats.py index 81ccbab167d..b5f15026691 100644 --- a/locale/grass_po_stats.py +++ b/locale/grass_po_stats.py @@ -72,9 +72,9 @@ def read_msgfmt_statistics(msg, lgood, lfuzzy, lbad): def langDefinition(fil): f = codecs.open(fil, encoding="utf-8", errors="replace", mode="r") - for l in f.readlines(): - if '"Language-Team:' in l: - lang = l.split(" ")[1:-1] + for line in f.readlines(): + if '"Language-Team:' in line: + lang = line.split(" ")[1:-1] break f.close() if len(lang) == 2: @@ -136,7 +136,7 @@ def writejson(stats, outfile): # load dictionary into json format fjson = json.dumps(stats, sort_keys=True, indent=4) # write a string with pretty style - outjson = os.linesep.join([l.rstrip() for l in fjson.splitlines()]) + outjson = os.linesep.join([line.rstrip() for line in fjson.splitlines()]) # write out file fout = open(outfile, "w") fout.write(outjson) diff --git a/man/build_class_graphical.py b/man/build_class_graphical.py index 31caffcdf75..4e295bb18f5 100644 --- a/man/build_class_graphical.py +++ b/man/build_class_graphical.py @@ -128,7 +128,7 @@ def get_module_image(module, images): return image if basename == module: return image - return sorted(candidates, key=len)[0] + return min(candidates, key=len) def generate_page_for_category( diff --git a/man/build_manual_gallery.py b/man/build_manual_gallery.py index 10fdb143989..ea1ffb449c2 100755 --- a/man/build_manual_gallery.py +++ b/man/build_manual_gallery.py @@ -14,6 +14,7 @@ ############################################################################# import os +from pathlib import Path import sys import fnmatch import re @@ -97,9 +98,8 @@ def img_in_html(filename, imagename): # for some reason, calling search just once is much faster # than calling it on every line (time is spent in _compile) pattern = re.compile("".format(imagename)) - with open(filename) as file: - if re.search(pattern, file.read()): - return True + if re.search(pattern, Path(filename).read_text()): + return True return False @@ -123,8 +123,7 @@ def remove_module_name(string, module): string = string.replace(module.replace("wxGUI.", "g.gui."), "") string = string.replace(module.replace(".", "_"), "") # using _ string = string.replace(module.replace(".", ""), "") # using nothing - string = string.replace(module, "") # using original dots - return string + return string.replace(module, "") # using original dots def title_from_names(module_name, img_name): diff --git a/man/parser_standard_options.py b/man/parser_standard_options.py index 554c0846203..b6ce30b1bb2 100644 --- a/man/parser_standard_options.py +++ b/man/parser_standard_options.py @@ -72,18 +72,17 @@ def parse_glines(glines): res[key] = [ default, ] - else: - if key is not None: - if key not in res: - res[key] = [] - start, end = 0, -1 - if line.startswith("_("): - start = 2 - if line.endswith(");"): - end = -3 - elif line.endswith(";"): - end = -2 - res[key].append(line[start:end]) + elif key is not None: + if key not in res: + res[key] = [] + start, end = 0, -1 + if line.startswith("_("): + start = 2 + if line.endswith(");"): + end = -3 + elif line.endswith(";"): + end = -2 + res[key].append(line[start:end]) # pprint(glines) # pprint(res) return res @@ -138,22 +137,22 @@ def html(self, endline="\n", indent=" ", toptions="border=1"): """Return a HTML table with the options""" html = ["".format(" " + toptions if toptions else "")] # write headers - html.append(indent + "") - html.append(indent + "") - html.append(indent * 2 + "{0}".format("option")) + html.extend( + ( + indent + "", + indent + "", + indent * 2 + "{0}".format("option"), + ) + ) for col in self.columns: html.append(indent * 2 + "{0}".format(col)) - html.append(indent + "") - html.append(indent + "") - html.append(indent + "") + html.extend((indent + "", indent + "", indent + "")) for optname, options in self.options: - html.append(indent + "") - html.append(indent * 2 + "{0}".format(optname)) + html.extend((indent + "", indent * 2 + "{0}".format(optname))) for col in self.columns: html.append(indent * 2 + "{0}".format(options.get(col, ""))) html.append(indent + "") - html.append(indent + "") - html.append("") + html.extend((indent + "", "")) return endline.join(html) def _repr_html_(self): @@ -218,7 +217,7 @@ def _repr_html_(self): ) args = parser.parse_args() - cfile = args.text if args.text else urlopen(args.url, proxies=None) + cfile = args.text or urlopen(args.url, proxies=None) options = OptTable(parse_options(cfile.readlines(), startswith=args.startswith)) outform = args.format diff --git a/misc/CMakeLists.txt b/misc/CMakeLists.txt index 53f4757eb46..1319f76836d 100644 --- a/misc/CMakeLists.txt +++ b/misc/CMakeLists.txt @@ -5,7 +5,7 @@ build_program_in_subdir(m.measure DEPENDS grass_gis) build_program_in_subdir(m.transform DEPENDS grass_gis grass_imagery grass_raster grass_vector LIBM) -if(WITH_OPENGL) +if(TARGET grass_ogsf) build_program_in_subdir( m.nviz.image DEPENDS @@ -19,4 +19,4 @@ if(WITH_OPENGL) build_program_in_subdir(m.nviz.script DEPENDS grass_display grass_raster grass_gis LIBM) -endif(WITH_OPENGL) +endif(TARGET grass_ogsf) diff --git a/package.nix b/package.nix index b1b33492163..7abbb15275d 100644 --- a/package.nix +++ b/package.nix @@ -26,15 +26,19 @@ , pkg-config , postgresql , proj -, python3Packages +, python311Packages , readline , sqlite , wxGTK32 , zlib , zstd - }: + +let + pyPackages = python311Packages; + +in stdenv.mkDerivation (finalAttrs: { pname = "grass"; version = "dev"; @@ -61,7 +65,7 @@ stdenv.mkDerivation (finalAttrs: { geos # for `geos-config` netcdf # for `nc-config` pkg-config - ] ++ (with python3Packages; [ python-dateutil numpy wxPython_4_2 ]); + ] ++ (with pyPackages; [ python-dateutil numpy wxpython ]); buildInputs = [ blas @@ -137,7 +141,7 @@ stdenv.mkDerivation (finalAttrs: { postInstall = '' wrapProgram $out/bin/grass \ --set PYTHONPATH $PYTHONPATH \ - --set GRASS_PYTHON ${python3Packages.python.interpreter} \ + --set GRASS_PYTHON ${pyPackages.python.interpreter} \ --suffix LD_LIBRARY_PATH ':' '${gdal}/lib' ln -s $out/grass*/lib $out/lib ln -s $out/grass*/include $out/include diff --git a/ps/CMakeLists.txt b/ps/CMakeLists.txt index 7a714ffcc0e..fed179fe016 100644 --- a/ps/CMakeLists.txt +++ b/ps/CMakeLists.txt @@ -11,6 +11,7 @@ build_program_in_subdir( grass_dbmiclient grass_dbmidriver grass_symb + GDAL LIBM) add_custom_command( diff --git a/ps/ps.map/r_colortable.c b/ps/ps.map/r_colortable.c index 53bf62b080a..15dfb8cd149 100644 --- a/ps/ps.map/r_colortable.c +++ b/ps/ps.map/r_colortable.c @@ -37,7 +37,7 @@ int read_colortable(void) int fontsize, cols, nodata, tickbar, discrete; double w, h, x, y, lw; int range_override; - double min, max, tmpD; + double min = 0.0, max = 0.0, tmpD = 0.0; int r, g, b, ret; PSCOLOR color; diff --git a/pyproject.toml b/pyproject.toml index 659b26abcde..21afb25d782 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +[project] +name = "grass" +requires-python = ">=3.9" + [tool.black] required-version = '24' line-length = 88 @@ -9,6 +13,419 @@ extend-exclude = ''' ) ''' +[tool.ruff] +required-version = ">=0.5.0" + +builtins = ["_"] + +# In addition to the standard set of exclusions, omit the following files or folders. +extend-exclude = ["python/libgrass_interface_generator"] +# In addition to the standard set of inclusions, include `.ipynb` files. +extend-include = ["*.ipynb"] + +[tool.ruff.lint] +# See https://docs.astral.sh/ruff/rules/ +select = [ + "A", # flake8-builtins (A) + "AIR", # Airflow (AIR) + "ANN", # flake8-annotations (ANN) + "ARG", # flake8-unused-arguments (ARG) + "B", # flake8-bugbear (B) + "BLE", # flake8-blind-except (BLE) + "C4", # flake8-comprehensions (C4) + "COM", # flake8-commas (COM) + "D", # pydocstyle (D) + "DTZ", # flake8-datetimez (DTZ) + "E4", # pycodestyle (E, W) + "E7", # pycodestyle (E, W) + "E9", # pycodestyle (E, W) + "F", # Pyflakes (F) + "FA", # flake8-future-annotations (FA) + "FBT", # flake8-boolean-trap (FBT) + "FLY", # flynt (FLY) + "FURB", # refurb (FURB) + "G", # flake8-logging-format (G) + "I", # isort (I) + "ICN", # flake8-import-conventions (ICN) + "INT", # flake8-gettext (INT) + "ISC", # flake8-implicit-str-concat (ISC) + "LOG", # flake8-logging (LOG) + "NPY", # NumPy-specific rules (NPY) + "PERF", # Perflint (PERF) + "PGH", # pygrep-hooks (PGH) + "PIE", # flake8-pie (PIE) + "PLC", # Pylint (PL) Convention (C) + "PLE", # Pylint (PL) Error (E) + "PLR", # Pylint (PL) Refactor (R) + "PLW", # Pylint (PL) Warning (W) + "PT", # flake8-pytest-style (PT) + "PTH", # flake8-use-pathlib (PTH) + "PTH105", # flake8-use-pathlib (PTH) + "PYI", # flake8-pyi (PYI) + "Q", # flake8-quotes (Q) + "RET", # flake8-return (RET) + "RSE", # flake8-raise (RSE) + "RUF", # Ruff-specific rules (RUF) + "S", # flake8-bandit (S) + "SIM", # flake8-simplify (SIM) + "SLF", # flake8-self (SLF) + "SLOT", # flake8-slots (SLOT) + "T10", # flake8-debugger (T10) + "TCH", # flake8-type-checking (TCH) + "TID", # flake8-tidy-imports (TID) + "TRY", # tryceratops (TRY) + "UP", # pyupgrade (UP) + "W", # pycodestyle (E, W) + "YTT", # flake8-2020 (YTT) +] + +ignore = [ + # See https://docs.astral.sh/ruff/rules/ + # *GRASS TODO: fix the issues, or use https://docs.astral.sh/ruff/settings/#lint_per-file-ignores + "A001", # builtin-variable-shadowing + "A002", # builtin-argument-shadowing + "ANN", # flake8-annotations (ANN) + "ARG001", # unused-function-argument + "ARG002", # unused-method-argument + "ARG005", # unused-lambda-argument + "B004", # unreliable-callable-check + "B006", # mutable-argument-default + "B007", # unused-loop-control-variable + "B008", # function-call-in-default-argument + "B015", # useless-comparison + "B023", # function-uses-loop-variable + "B026", # star-arg-unpacking-after-keyword-arg + "B028", # no-explicit-stacklevel + "B034", # re-sub-positional-args + "B904", # raise-without-from-inside-except + "B909", # loop-iterator-mutation + "BLE001", # blind-except + "C400", # unnecessary-generator-list + "C401", # unnecessary-generator-set + "C403", # unnecessary-list-comprehension-set + "C404", # unnecessary-list-comprehension-dict + "C405", # unnecessary-literal-set + "C414", # unnecessary-double-cast-or-process + "C416", # unnecessary-comprehension + "COM812", # missing-trailing-comma + "COM818", # trailing-comma-on-bare-tuple + "D1", + "D2", + "D300", # triple-single-quotes + "D301", # escape-sequence-in-docstring + "D400", # ends-in-period + "D401", # non-imperative-mood + "D402", # no-signature + "D403", # first-line-capitalized + "D404", # docstring-starts-with-this + "D405", # capitalize-section-name + "D406", # new-line-after-section-name + "D407", # dashed-underline-after-section + "D409", # section-underline-matches-section-length + "D411", # no-blank-line-before-section + "D412", # blank-lines-between-header-and-content + "D413", # blank-line-after-last-section + "D415", # ends-in-punctuation + "D416", # section-name-ends-in-colon + "D419", # empty-docstring + "DTZ001", # call-datetime-without-tzinfo + "DTZ002", # call-datetime-today + "DTZ005", # call-datetime-now-without-tzinfo + "DTZ006", # call-datetime-fromtimestamp + "DTZ007", # call-datetime-strptime-without-zone + "DTZ011", # call-date-today + "E401", # multiple-imports-on-one-line + "E402", # module-import-not-at-top-of-file + "E721", # type-comparison + "E722", # bare-except + "E731", # lambda-assignment + "E741", # ambiguous-variable-name + "F401", # unused-import + "F403", # undefined-local-with-import-star + "F405", # undefined-local-with-import-star-usage + "F601", # multi-value-repeated-key-literal + "F811", # redefined-while-unused + "F821", # undefined-name + "F822", # undefined-export + "F841", # unused-variable, + "FBT001", # boolean-type-hint-positional-argument + "FBT002", # boolean-default-value-positional-argument + "FBT003", # boolean-positional-value-in-call + "FURB118", # reimplemented-operator + "I001", # unsorted-imports + "ISC003", # explicit-string-concatenation + "PERF203", # try-except-in-loop + "PERF401", # manual-list-comprehension + "PERF402", # manual-list-copy + "PERF403", # manual-dict-comprehension + "PIE790", # unnecessary-placeholder + "PIE794", # duplicate-class-field-definition + "PIE808", # unnecessary-range-start + "PIE810", # multiple-starts-ends-with + "PLC0206", # dict-index-missing-items + "PLC0414", # useless-import-alias + "PLC0415", # import-outside-top-level + "PLC1901", # compare-to-empty-string + "PLC2701", # import-private-name + "PLC2801", # unnecessary-dunder-call + "PLE0704", # misplaced-bare-raise + "PLR0124", # comparison-with-itself + "PLR0202", # no-classmethod-decorator + "PLR0904", # too-many-public-methods + "PLR0911", # too-many-return-statements + "PLR0912", # too-many-branches + "PLR0913", # too-many-arguments + "PLR0914", # too-many-locals + "PLR0915", # too-many-statements + "PLR0916", # too-many-boolean-expressions + "PLR0917", # too-many-positional + "PLR1702", # too-many-nested-blocks + "PLR1704", # redefined-argument-from-local + "PLR1733", # unnecessary-dict-index-lookup + "PLR2004", # magic-value-comparison + "PLR6104", # non-augmented-assignment + "PLR6201", # literal-membership + "PLR6301", # no-self-use + "PLW0127", # self-assigning-variable + "PLW0406", # import-self + "PLW0602", # global-variable-not-assigned + "PLW0603", # global-statement + "PLW0604", # global-at-module-level + "PLW1508", # invalid-envvar-default + "PLW1510", # subprocess-run-without-check + "PLW1514", # unspecified-encoding + "PLW1641", # eq-without-hash + "PLW2901", # redefined-loop-name + "PLW3201", # nested-min-max + "PT001", # pytest-fixture-incorrect-parentheses-style + "PT004", # pytest-missing-fixture-name-underscore + "PT006", # pytest-parametrize-names-wrong-type + "PT009", # pytest-unittest-assertion + "PT011", # pytest-raises-too-broad + "PT018", # pytest-composite-assertion + "PT023", # pytest-incorrect-mark-parentheses-style + "PTH100", # os-path-abspath + "PTH101", # os-chmod + "PTH102", # os-mkdir + "PTH103", # os-makedirs + "PTH104", # os-rename + "PTH106", # os-rmdir + "PTH107", # os-remove + "PTH108", # os-unlink + "PTH109", # os-getcwd + "PTH110", # os-path-exists + "PTH111", # os-path-expanduser + "PTH112", # os-path-isdir + "PTH113", # os-path-isfile + "PTH116", # os-stat + "PTH117", # os-path-isabs + "PTH118", # os-path-join + "PTH119", # os-path-basename + "PTH120", # os-path-dirname + "PTH122", # os-path-splitext + "PTH123", # builtin-open + "PTH202", # os-path-getsize + "PTH204", # os-path-getmtime + "PTH207", # glob + "RET501", # unnecessary-return-none + "RET502", # implicit-return-value + "RET503", # implicit-return + "RET505", # superfluous-else-return + "RET506", # superfluous-else-raise + "RET507", # superfluous-else-continue + "RET508", # superfluous-else-break + "RSE102", # unnecessary-paren-on-raise-exception + "RUF002", # ambiguous-unicode-character-docstring + "RUF003", # ambiguous-unicode-character-comment + "RUF005", # collection-literal-concatenation + "RUF012", # mutable-class-default + "RUF013", # unnecessary-iterable-allocation-for-first-element + "RUF015", # unnecessary-iterable-allocation-for-first-element + "RUF019", # unnecessary-key-check + "RUF021", # parenthesize-chained-operators + "RUF027", # missing-f-string-syntax + "RUF100", # unused-noqa + "S101", #assert + "S108", # hardcoded-temp-file + "S110", # try-except-pass + "S112", # try-except-continue + "S113", # request-without-timeout + "S202", # tarfile-unsafe-members + "S307", # suspicious-eval-usage + "S310", # suspicious-url-open-usage + "S311", # suspicious-non-cryptographic-random-usage + "S314", # suspicious-xml-element-tree-usage + "S324", # hashlib-insecure-hash-function + "S403", # suspicious-pickle-import + "S404", # suspicious-subprocess-import + "S405", # suspicious-xml-etree-import + "S406", # suspicious-xml-sax-import + "S602", # subprocess-popen-with-shell-equals-true + "S603", # subprocess-without-shell-equals-true + "S604", # call-with-shell-equals-true + "S606", # start-process-with-no-shell + "S607", # start-process-with-partial-path + "S608", # hardcoded-sql-expression + "SIM101", # duplicate-isinstance-call + "SIM102", # collapsible-if + "SIM103", # needless-bool + "SIM105", # suppressible-exception + "SIM108", # if-else-block-instead-of-if-exp + "SIM109", # compare-with-tuple + "SIM110", # reimplemented-builtin + "SIM113", # enumerate-for-loop + "SIM114", # if-with-same-arms + "SIM115", # open-file-with-context-handler + "SIM116", # if-else-block-instead-of-dict-lookup + "SIM118", # in-dict-keys + "SIM201", # negate-equal-op + "SIM223", # expr-and-false + "SIM401", # if-else-block-instead-of-dict-get + "SLF001", # private-member-access + "TRY002", # raise-vanilla-class + "TRY003", # raise-vanilla-args + "TRY004", # type-check-without-type-error + "TRY201", # verbose-raise + "TRY300", # try-consider-else + "TRY301", # raise-within-try + "UP015", # redundant-open-modes + "UP018", # native-literals + "UP030", # format-literals + "UP031", # printf-string-formatting + "UP032", # f-string + "UP034", # extraneous-parentheses + "UP036", # outdated-version-block + "W605", # invalid-escape-sequence + "YTT204", # sys-version-info-minor-cmp-int +] + + +[tool.ruff.lint.per-file-ignores] +# See https://docs.astral.sh/ruff/settings/#lint_per-file-ignores +# "INT002", # f-string-in-get-text-func-call +# "INT001", # format-in-get-text-func-call +# "INT003", # printf-in-get-text-func-call +# Ignore `E402` (import violations) in all `__init__.py` files +"*/testsuite/**.py" = ["PT009", "PT027"] +"__init__.py" = ["E402"] +"general/g.parser/test.py" = ["INT003"] +"gui/wxpython/animation/dialogs.py" = ["INT002"] +"gui/wxpython/animation/temporal_manager.py" = ["INT003"] +"gui/wxpython/core/debug.py" = ["INT002"] +"gui/wxpython/core/render.py" = ["INT003"] +"gui/wxpython/gcp/manager.py" = ["INT002"] +"gui/wxpython/gmodeler/model.py" = ["INT001"] +"gui/wxpython/gmodeler/panels.py" = ["INT002", "INT003"] +"gui/wxpython/gui_core/ghelp.py" = ["INT003"] +"gui/wxpython/gui_core/gselect.py" = ["INT002"] +"gui/wxpython/gui_core/pyedit.py" = ["INT002"] +"gui/wxpython/gui_core/pystc.py" = ["INT002"] +"gui/wxpython/gui_core/query.py" = ["INT003"] +"gui/wxpython/history/browser.py" = ["INT002"] +"gui/wxpython/iclass/dialogs.py" = ["INT003"] +"gui/wxpython/iclass/frame.py" = ["FLY002", "INT003"] +"gui/wxpython/iclass/plots.py" = ["INT003"] +"gui/wxpython/image2target/ii2t_gis_set.py" = ["INT003"] +"gui/wxpython/iscatt/controllers.py" = ["INT003"] +"gui/wxpython/iscatt/dialogs.py" = ["INT003"] +"gui/wxpython/iscatt/frame.py" = ["INT003"] +"gui/wxpython/iscatt/iscatt_core.py" = ["INT003"] +"gui/wxpython/iscatt/plots.py" = ["PLW0108"] +"gui/wxpython/lmgr/frame.py" = ["INT003"] +"gui/wxpython/lmgr/workspace.py" = ["INT002"] +"gui/wxpython/location_wizard/dialogs.py" = ["INT003"] +"gui/wxpython/location_wizard/wizard.py" = ["INT003"] +"gui/wxpython/main_window/frame.py" = ["INT003"] +"gui/wxpython/mapdisp/frame.py" = ["INT003"] +"gui/wxpython/mapdisp/test_mapdisp.py" = ["INT003"] +"gui/wxpython/mapwin/analysis.py" = ["INT003"] +"gui/wxpython/psmap/utils.py" = ["PGH004"] +"gui/wxpython/rdigit/g.gui.rdigit.py" = ["INT002"] +"gui/wxpython/rlisetup/frame.py" = ["INT002"] +"gui/wxpython/rlisetup/functions.py" = ["INT003"] +"gui/wxpython/rlisetup/wizard.py" = ["INT003"] +"gui/wxpython/startup/locdownload.py" = ["INT002"] +"gui/wxpython/timeline/frame.py" = ["FLY002", "INT003"] +"gui/wxpython/tplot/frame.py" = ["FLY002", "INT002", "INT003"] +"gui/wxpython/vnet/vnet_data.py" = ["INT003"] +"gui/wxpython/web_services/dialogs.py" = ["INT003"] +"gui/wxpython/web_services/widgets.py" = ["INT003"] +"gui/wxpython/wxgui.py" = ["INT002"] +"lib/imagery/testsuite/test_imagery_sigsetfile.py" = ["FURB152"] +"lib/init/grass.py" = ["INT003"] +"python/grass/__init__.py" = ["PYI056"] +"python/grass/exp*/tests/grass_script_mapset_session_test.py" = ["SIM117"] +"python/grass/exp*/tests/grass_script_tmp_mapset_session_test.py" = ["SIM117"] +"python/grass/gunittest/loader.py" = ["PYI024"] +"python/grass/gunittest/multireport.py" = ["PYI024"] +"python/grass/gunittest/testsu*/d*/s*/s*/subsub*/t*/test_segfaut.py" = ["B018"] +"python/grass/gunittest/testsuite/test_assertions_rast3d.py" = ["FLY002"] +"python/grass/jupyter/tests/reprojection_renderer_test.py" = ["PT013"] +"python/grass/jupyter/testsuite/interactivemap_test.py" = ["PGH004"] +"python/grass/jupyter/testsuite/map_test.py" = ["PGH004"] +"python/grass/pygrass/raster/category.py" = ["INT002"] +"python/grass/pygrass/vector/__init__.py" = ["INT003"] +"python/grass/pygrass/vector/geometry.py" = ["PYI024"] +"python/grass/pygrass/vector/sql.py" = ["FLY002"] +"python/grass/pygrass/vector/testsuite/test_table.py" = ["PLW0108"] +"python/grass/script/raster.py" = ["INT003"] +"python/grass/temporal/abstract_space_time_dataset.py" = ["INT003"] +"python/grass/temporal/aggregation.py" = ["INT003"] +"python/grass/temporal/c_libraries_interface.py" = ["INT003"] +"python/grass/temporal/core.py" = ["INT002", "INT003"] +"python/grass/temporal/datetime_math.py" = ["INT003"] +"python/grass/temporal/mapcalc.py" = ["INT003"] +"python/grass/temporal/space_time_datasets.py" = ["INT003"] +"python/grass/temporal/stds_export.py" = ["INT003"] +"python/grass/temporal/stds_import.py" = ["INT003"] +"python/grass/temporal/temporal_algebra.py" = ["INT003"] +"python/grass/temporal/temporal_raster_base_algebra.py" = ["INT003"] +"python/grass/temporal/univar_statistics.py" = ["INT002"] +"raster3d/r3.flow/testsuite/r3flow_test.py" = ["FLY002"] +"raster3d/r3.gradient/testsuite/r3gradient_test.py" = ["FLY002"] +"scripts/d.polar/d.polar.py" = ["FURB154", "INT002"] +"scripts/g.extension.all/g.extension.all.py" = ["INT002"] +"scripts/g.extension/g.extension.py" = ["INT002"] +"scripts/i.oif/i.oif.py" = ["INT003"] +"scripts/i.pansharpen/i.pansharpen.py" = ["FLY002", "INT003"] +"scripts/i.spectral/i.spectral.py" = ["FLY002", "INT002"] +"scripts/r.in.srtm/r.in.srtm.py" = ["FLY002"] +"scripts/r.in.wms/wms_base.py" = ["INT003"] +"scripts/r.in.wms/wms_cap_parsers.py" = ["INT003"] +"scripts/r.in.wms/wms_drv.py" = ["INT003"] +"scripts/r.in.wms/wms_gdal_drv.py" = ["INT003"] +"scripts/r.pack/r.pack.py" = ["INT003"] +"scripts/r.tileset/r.tileset.py" = ["INT003"] +"scripts/r.unpack/r.unpack.py" = ["INT002"] +"scripts/v.rast.stats/v.rast.stats.py" = ["INT002"] +"scripts/v.to.lines/v.to.lines.py" = ["INT003"] +"scripts/v.unpack/v.unpack.py" = ["INT002", "INT003"] +"scripts/v.what.strds/v.what.strds.py" = ["INT003"] +"temporal/t.rast.accdetect/t.rast.accdetect.py" = ["INT003"] +"temporal/t.rast.accumulate/t.rast.accumulate.py" = ["INT003"] +"temporal/t.rast.algebra/testsu*/*_algebra_arithmetic.py" = ["FLY002"] +"temporal/t.rast.export/t.rast.export.py" = ["INT002"] +"temporal/t.rast.gapfill/t.rast.gapfill.py" = ["INT003"] +"temporal/t.rast.list/t.rast.list.py" = ["INT002"] +"temporal/t.rast.out.vtk/t.rast.out.vtk.py" = ["INT003"] +"temporal/t.rast.series/t.rast.series.py" = ["INT002"] +"temporal/t.rast.to.rast3/t.rast.to.rast3.py" = ["INT003"] +"temporal/t.rast.what/t.rast.what.py" = ["INT003"] +"temporal/t.register/testsu*/*_raster_different_local.py" = ["FLY002"] +"temporal/t.register/testsu*/*_raster_mapmetadata.py" = ["FLY002"] +"temporal/t.register/testsuite/test_t_register_raster.py" = ["FLY002"] +"temporal/t.register/testsuite/test_t_register_raster_file.py" = ["FLY002"] +"temporal/t.remove/t.remove.py" = ["INT002", "INT003"] +"temporal/t.unregister/t.unregister.py" = ["INT003"] +"temporal/t.vect.observe.strds/t.vect.observe.strds.py" = ["INT003"] +"utils/generate_release_notes.py" = ["PGH004"] +"utils/mkhtml.py" = ["INT002"] +"vector/v.fill.holes/examples.ipynb" = ["PTH201"] + +[tool.ruff.lint.flake8-import-conventions.extend-aliases] +# Declare a custom aliases, checked with rule ICN001 +"grass.script" = "gs" + [tool.pytest.ini_options] minversion = "6.0" python_files = "*/tests/*_test.py" @@ -28,5 +445,10 @@ markers = [ [tool.bandit] -exclude_dirs = ["./testsuite", "*/tests/*", "*/testsuite/*", "utils/test_generate_last_commit_file.py"] -skips = ["B324","B110", "B101", "B112", "B311", "B404", "B603"] +exclude_dirs = [ + "./testsuite", + "*/tests/*", + "*/testsuite/*", + "utils/test_generate_last_commit_file.py", +] +skips = ["B324", "B110", "B101", "B112", "B311", "B404", "B603"] diff --git a/python/grass/benchmark/plots.py b/python/grass/benchmark/plots.py index 3cb66a84d45..9483fda9116 100644 --- a/python/grass/benchmark/plots.py +++ b/python/grass/benchmark/plots.py @@ -23,14 +23,14 @@ def get_pyplot(to_file): The *to_file* parameter can be set to True to avoid tkinter dependency if the interactive show method is not needed. """ - import matplotlib # pylint: disable=import-outside-toplevel + import matplotlib as mpl # pylint: disable=import-outside-toplevel if to_file: backend = "agg" else: backend = None if backend: - matplotlib.use(backend) + mpl.use(backend) import matplotlib.pyplot as plt # pylint: disable=import-outside-toplevel diff --git a/python/grass/benchmark/results.py b/python/grass/benchmark/results.py index c89d8f1c80b..123e5dd8458 100644 --- a/python/grass/benchmark/results.py +++ b/python/grass/benchmark/results.py @@ -15,6 +15,7 @@ import copy import json +from pathlib import Path from types import SimpleNamespace @@ -48,8 +49,7 @@ def save_results_to_file(results, filename): See :func:`save_results` for details. """ text = save_results(results) - with open(filename, "w", encoding="utf-8") as file: - file.write(text) + Path(filename).write_text(text, encoding="utf-8") def load_results(data): @@ -67,8 +67,7 @@ def load_results_from_file(filename): See :func:`load_results` for details. """ - with open(filename, "r", encoding="utf-8") as file: - return load_results(file.read()) + return load_results(Path(filename).read_text(encoding="utf-8")) def join_results(results, prefixes=None, select=None, prefixes_as_labels=False): diff --git a/python/grass/grassdb/checks.py b/python/grass/grassdb/checks.py index c1ef7cc76c2..b8748de9876 100644 --- a/python/grass/grassdb/checks.py +++ b/python/grass/grassdb/checks.py @@ -605,9 +605,7 @@ def get_reasons_grassdb_not_removable(grassdb): locations = [] for g_location in g_locations: locations.append((grassdb, g_location)) - messages = get_reasons_locations_not_removable(locations) - - return messages + return get_reasons_locations_not_removable(locations) def get_list_of_locations(dbase): diff --git a/python/grass/grassdb/history.py b/python/grass/grassdb/history.py index 2657632c9e1..60b5459700d 100644 --- a/python/grass/grassdb/history.py +++ b/python/grass/grassdb/history.py @@ -53,8 +53,7 @@ def get_history_file_extension(history_path): :return str extension: None (plain text) or .json """ file_path = Path(history_path) - extension = file_path.suffix - return extension + return file_path.suffix def ensure_history_file(history_path): @@ -86,8 +85,7 @@ def _read_from_plain_text(history_path): history_path, encoding="utf-8", mode="r", errors="replace" ) as file_history: content_list = [ - {"command": line.strip(), "command_info": None} - for line in file_history.readlines() + {"command": line.strip(), "command_info": None} for line in file_history ] except OSError as e: raise OSError( @@ -105,27 +103,24 @@ def _read_from_JSON(history_path): """ content_list = [] try: - with open( - history_path, encoding="utf-8", mode="r", errors="replace" - ) as file_history: - content = file_history.read() - if content: - try: - history_entries = json.loads(content) - except ValueError as ve: - raise ValueError( - _("Error decoding content of JSON history file {}").format( - history_path - ) - ) from ve - # Process the content as a list of dictionaries - content_list = [ - { - "command": entry["command"], - "command_info": entry["command_info"], - } - for entry in history_entries - ] + content = Path(history_path).read_text(encoding="utf-8", errors="replace") + if content: + try: + history_entries = json.loads(content) + except ValueError as ve: + raise ValueError( + _("Error decoding content of JSON history file {}").format( + history_path + ) + ) from ve + # Process the content as a list of dictionaries + content_list = [ + { + "command": entry["command"], + "command_info": entry["command_info"], + } + for entry in history_entries + ] except OSError as e: raise OSError( _("Unable to read from JSON history file {}").format(history_path) @@ -164,7 +159,7 @@ def filter(json_data, command, timestamp): return None -def _remove_entry_from_plain_text(history_path, index): +def _remove_entry_from_plain_text(history_path, index: int): """Remove entry from plain text history file. :param str history_path: path to the history log file @@ -176,7 +171,7 @@ def _remove_entry_from_plain_text(history_path, index): file_history.seek(0) file_history.truncate() for number, line in enumerate(lines): - if number not in [index]: + if number != index: file_history.write(line) except OSError as e: raise OSError( @@ -186,7 +181,7 @@ def _remove_entry_from_plain_text(history_path, index): ) from e -def _remove_entry_from_JSON(history_path, index): +def _remove_entry_from_JSON(history_path, index: int): """Remove entry from JSON history file. :param str history_path: path to the history log file @@ -216,7 +211,7 @@ def _remove_entry_from_JSON(history_path, index): ) from e -def remove_entry(history_path, index): +def remove_entry(history_path, index: int): """Remove entry from history file. :param str history_path: path to the history log file @@ -276,14 +271,13 @@ def get_initial_command_info(env_run): region_settings = gs.region(env=env_run) # Finalize the command info dictionary - cmd_info = { + return { "timestamp": exec_time, "mask2d": mask2d_present, "mask3d": mask3d_present, "region": region_settings, "status": Status.RUNNING.value, } - return cmd_info def _add_entry_to_JSON(history_path, entry): diff --git a/python/grass/gunittest/checkers.py b/python/grass/gunittest/checkers.py index 80ee38e5fdc..76f8100577c 100644 --- a/python/grass/gunittest/checkers.py +++ b/python/grass/gunittest/checkers.py @@ -93,14 +93,14 @@ def unify_units(dic): for n in range(len(dic["unit"])): if dic["unit"][n] in item: dic["unit"][n] = item[0] - else: + else: # noqa: PLR5501 if dic["unit"] in item: dic["unit"] = item[0] if not isinstance(dic["units"], str): for n in range(len(dic["units"])): if dic["units"][n] in item: dic["units"][n] = item[0] - else: + else: # noqa: PLR5501 if dic["units"] in item: dic["units"] = item[0] return dic @@ -222,7 +222,7 @@ def text_to_keyvalue( " Previous line's key is <%s>" ) % key raise ValueError(msg) - else: + else: # noqa: PLR5501 # line contains something but not separator if not skip_invalid: # TODO: here should go _ for translation @@ -312,9 +312,8 @@ def values_equal(value_a, value_b, precision=0.000001): # apply this function for comparison of items in the list if not values_equal(value_a[i], value_b[i], precision): return False - else: - if value_a != value_b: - return False + elif value_a != value_b: + return False return True diff --git a/python/grass/gunittest/gutils.py b/python/grass/gunittest/gutils.py index 7c1f2248089..16618e729f5 100644 --- a/python/grass/gunittest/gutils.py +++ b/python/grass/gunittest/gutils.py @@ -39,9 +39,9 @@ def is_map_in_mapset(name, type, mapset=None): # so anything accepted by g.findfile will work but this can change in the # future (the documentation is clear about what's legal) # supporting both short and full names - if type == "rast" or type == "raster": + if type in {"rast", "raster"}: type = "cell" - elif type == "rast3d" or type == "raster3d": + elif type in {"rast3d", "raster3d"}: type = "grid3" elif type == "vect": type = "vector" diff --git a/python/grass/gunittest/invoker.py b/python/grass/gunittest/invoker.py index e58127502c7..f07e8dd5a84 100644 --- a/python/grass/gunittest/invoker.py +++ b/python/grass/gunittest/invoker.py @@ -11,6 +11,7 @@ import collections import os +from pathlib import Path import shutil import subprocess import sys @@ -39,8 +40,7 @@ # TODO: this might be more extend then update def update_keyval_file(filename, module, returncode): if os.path.exists(filename): - with open(filename, "r") as keyval_file: - keyval = text_to_keyvalue(keyval_file.read(), sep="=") + keyval = text_to_keyvalue(Path(filename).read_text(), sep="=") else: keyval = {} @@ -62,8 +62,7 @@ def update_keyval_file(filename, module, returncode): keyval["returncode"] = returncode keyval["test_file_authors"] = test_file_authors - with open(filename, "w") as keyval_file: - keyval_file.write(keyvalue_to_text(keyval)) + Path(filename).write_text(keyvalue_to_text(keyval)) return keyval @@ -196,8 +195,7 @@ def _run_test_module(self, module, results_dir, gisdbase, location, timeout): args, cwd=cwd, env=env, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, timeout=timeout, check=False, ) @@ -244,16 +242,14 @@ def try_decode(data, encodings): stdout = try_decode(stdout, encodings=encodings) stderr = try_decode(stderr, encodings=encodings) - with open(stdout_path, "w") as stdout_file: - stdout_file.write(stdout) + Path(stdout_path).write_text(stdout) with open(stderr_path, "w") as stderr_file: if type(stderr) == "bytes": stderr_file.write(decode(stderr)) + elif isinstance(stderr, str): + stderr_file.write(stderr) else: - if isinstance(stderr, str): - stderr_file.write(stderr) - else: - stderr_file.write(stderr.encode("utf8")) + stderr_file.write(stderr.encode("utf8")) self._file_anonymizer.anonymize([stdout_path, stderr_path]) test_summary = update_keyval_file( @@ -338,18 +334,17 @@ def run_in_location(self, gisdbase, location, location_type, results_dir, exclud # TODO: move this to some (new?) reporter # TODO: add basic summary of linked files so that the page is not empty - with open(os.path.join(results_dir, "index.html"), "w") as main_index: - main_index.write( - "" - "

Tests for <{location}>" - " using <{type}> type tests

" - "
    " - '
  • Results by testsuites' - " (testsuite directories)
  • " - '
  • Results by test files
  • ' - "
      " - "".format(location=location, type=location_type) - ) + Path(os.path.join(results_dir, "index.html")).write_text( + "" + "

      Tests for <{location}>" + " using <{type}> type tests

      " + "
        " + '
      • Results by testsuites' + " (testsuite directories)
      • " + '
      • Results by test files
      • ' + "
          " + "".format(location=location, type=location_type) + ) testsuite_dir_reporter = TestsuiteDirReporter( main_page_name="testsuites.html", diff --git a/python/grass/gunittest/multireport.py b/python/grass/gunittest/multireport.py index 014d8296e4b..edeb98636ee 100644 --- a/python/grass/gunittest/multireport.py +++ b/python/grass/gunittest/multireport.py @@ -22,9 +22,9 @@ from grass.gunittest.reporters import success_to_html_percent # TODO: we should be able to work without matplotlib -import matplotlib +import matplotlib as mpl -matplotlib.use("Agg") +mpl.use("Agg") # This counts as code already, so silence "import not at top of file". # Perhaps in the future, switch_backend() could be used. import matplotlib.pyplot as plt # noqa: E402 diff --git a/python/grass/gunittest/reporters.py b/python/grass/gunittest/reporters.py index 4b8109ab622..21afce314e1 100644 --- a/python/grass/gunittest/reporters.py +++ b/python/grass/gunittest/reporters.py @@ -11,6 +11,7 @@ import os import datetime +from pathlib import Path from xml.sax import saxutils import xml.etree.ElementTree as et import subprocess @@ -78,9 +79,9 @@ def __init__(self, paths_to_remove, remove_gisbase=True, remove_gisdbase=False): if remove_gisdbase: # import only when really needed to avoid problems with # translations when environment is not set properly - import grass.script as gscript + import grass.script as gs - gisdbase = gscript.gisenv()["GISDBASE"] + gisdbase = gs.gisenv()["GISDBASE"] self._paths_to_remove.append(gisdbase) if paths_to_remove: self._paths_to_remove.extend(paths_to_remove) @@ -295,7 +296,7 @@ def get_html_test_authors_table(directory, tests_authors): if not not_testing_authors: not_testing_authors = ["all recent authors contributed tests"] - test_authors = ( + return ( "

          Code and test authors

          " '

          ' "Note that determination of authors is approximate and only" @@ -311,7 +312,6 @@ def get_html_test_authors_table(directory, tests_authors): not_testing=", ".join(sorted(not_testing_authors)), ) ) - return test_authors class GrassTestFilesMultiReporter: @@ -907,9 +907,8 @@ def finish(self): summary[key] = value summary_filename = os.path.join(self.result_dir, "test_keyvalue_result.txt") - with open(summary_filename, "w") as summary_file: - text = keyvalue_to_text(summary, sep="=", vsep="\n", isep=",") - summary_file.write(text) + text = keyvalue_to_text(summary, sep="=", vsep="\n", isep=",") + Path(summary_filename).write_text(text) def end_file_test( self, module, cwd, returncode, stdout, stderr, test_summary, timed_out=None @@ -1026,8 +1025,7 @@ def end_file_test( width = 72 self._stream.write(width * "=") self._stream.write("\n") - with open(stderr) as text: - self._stream.write(text.read()) + self._stream.write(Path(stderr).read_text()) self._stream.write(width * "=") self._stream.write("\n") self._stream.write(f"FAILED {module.file_path}") @@ -1117,8 +1115,7 @@ def report_for_dir(self, root, directory, test_files): root, directory, test_file_name, "test_keyvalue_result.txt" ) # if os.path.exists(summary_filename): - with open(summary_filename, "r") as keyval_file: - summary = text_to_keyvalue(keyval_file.read(), sep="=") + summary = text_to_keyvalue(Path(summary_filename).read_text(), sep="=") # else: # TODO: write else here # summary = None @@ -1212,7 +1209,7 @@ def report_for_dir(self, root, directory, test_files): page.close() status = success_to_html_text(total=file_total, successes=file_successes) - row = ( + return ( "" '{d}{status}' "{nfiles}{sfiles}{pfiles}" @@ -1231,7 +1228,6 @@ def report_for_dir(self, root, directory, test_files): ptests=dir_pass_per, ) ) - return row def report_for_dirs(self, root, directories): # TODO: this will need changes according to potential changes in diff --git a/python/grass/gunittest/runner.py b/python/grass/gunittest/runner.py index 891e1b65a5a..f1758e2e08b 100644 --- a/python/grass/gunittest/runner.py +++ b/python/grass/gunittest/runner.py @@ -269,28 +269,28 @@ def stopTestRun(self): # write test details and just write status=failed if not run: run = errored + failed + succeeded - infos.append("total=%d" % (run)) - - infos.append("failures=%d" % failed) - infos.append("errors=%d" % errored) - infos.append("successes=%d" % succeeded) - infos.append("skipped=%d" % skipped) - - # TODO: document this: if not supported by view, - # expected_failures should be counted as failures and vice versa - # or both add to skipped as unclear? - infos.append("expected_failures=%d" % expectedFails) - infos.append("unexpected_successes=%d" % unexpectedSuccesses) - - # TODO: include each module just once? list good and bad modules? - infos.append("tested_modules=%s" % ",".join(self._grass_modules)) - infos.append("supplementary_files=%s" % ",".join(self._supplementary_files)) - - # module, modules?, c, c++?, python - # TODO: include also type modules? - # TODO: include also C++ code? - # TODO: distinguish C and Python modules? - infos.append("test_type=%s" % (self.test_type)) + infos.extend( + ( + "total=%d" % (run), + "failures=%d" % failed, + "errors=%d" % errored, + "successes=%d" % succeeded, + "skipped=%d" % skipped, + # TODO: document this: if not supported by view, + # expected_failures should be counted as failures and vice versa + # or both add to skipped as unclear? + "expected_failures=%d" % expectedFails, + "unexpected_successes=%d" % unexpectedSuccesses, + # TODO: include each module just once? list good and bad modules? + "tested_modules=%s" % ",".join(self._grass_modules), + "supplementary_files=%s" % ",".join(self._supplementary_files), + # module, modules?, c, c++?, python + # TODO: include also type modules? + # TODO: include also C++ code? + # TODO: distinguish C and Python modules? + "test_type=%s" % (self.test_type), + ) + ) self._stream.write("\n".join(infos)) self._stream.write("\n") diff --git a/python/grass/gunittest/testsuite/test_assertions.py b/python/grass/gunittest/testsuite/test_assertions.py index 51720a56b76..3af538132f3 100644 --- a/python/grass/gunittest/testsuite/test_assertions.py +++ b/python/grass/gunittest/testsuite/test_assertions.py @@ -3,6 +3,7 @@ """ import os +from pathlib import Path import grass.script.core as gcore from grass.pygrass.modules import Module @@ -348,20 +349,19 @@ def setUpClass(cls): open(cls.emtpy_file, "w").close() cls.file_with_md5 = cls.__name__ + "_this_is_a_file_with_known_md5" file_content = "Content of the file with known MD5.\n" - with open(cls.file_with_md5, "w") as f: - f.write(file_content) + Path(cls.file_with_md5).write_text(file_content) # MD5 sum created using: # echo 'Content of the file with known MD5.' > some_file.txt # md5sum some_file.txt cls.file_md5 = "807bba4ffac4bb351bc3f27853009949" cls.file_with_same_content = cls.__name__ + "_file_with_same_content" - with open(cls.file_with_same_content, "w") as f: - f.write(file_content) + Path(cls.file_with_same_content).write_text(file_content) cls.file_with_different_content = cls.__name__ + "_file_with_different_content" - with open(cls.file_with_different_content, "w") as f: - f.write(file_content + " Something else here.") + Path(cls.file_with_different_content).write_text( + file_content + " Something else here." + ) @classmethod def tearDownClass(cls): diff --git a/python/grass/imaging/images2avi.py b/python/grass/imaging/images2avi.py index 6dd590e858a..f0b1904823d 100644 --- a/python/grass/imaging/images2avi.py +++ b/python/grass/imaging/images2avi.py @@ -44,7 +44,7 @@ import shutil from grass.imaging import images2ims -import grass.script as gscript +import grass.script as gs def _cleanDir(tempDir): @@ -131,16 +131,16 @@ def writeAvi( _cleanDir(tempDir) if bg_task: return ( - gscript.decode(outPut) + gs.decode(outPut) + "\n" - + gscript.decode(S.stderr.read()) + + gs.decode(S.stderr.read()) + "\n" + _("Could not write avi.") ) else: # An error occurred, show - print(gscript.decode(outPut)) - print(gscript.decode(S.stderr.read())) + print(gs.decode(outPut)) + print(gs.decode(S.stderr.read())) raise RuntimeError(_("Could not write avi.")) else: try: diff --git a/python/grass/imaging/images2gif.py b/python/grass/imaging/images2gif.py index 95d72add09a..ba681dca77d 100644 --- a/python/grass/imaging/images2gif.py +++ b/python/grass/imaging/images2gif.py @@ -72,7 +72,7 @@ pillow = True try: - PIL.__version__ # test if user has Pillow or PIL + PIL_version = PIL.__version__ # test if user has Pillow or PIL except AttributeError: pillow = False from PIL.GifImagePlugin import getheader, getdata @@ -1105,8 +1105,7 @@ def convert(self, *color): def inxsearch(self, r, g, b): """Search for BGR values 0..255 and return colour index""" dists = self.colormap[:, :3] - np.array([r, g, b]) - a = np.argmin((dists * dists).sum(1)) - return a + return np.argmin((dists * dists).sum(1)) if __name__ == "__main__": diff --git a/python/grass/imaging/images2swf.py b/python/grass/imaging/images2swf.py index 72354e751a6..e98d567d83c 100644 --- a/python/grass/imaging/images2swf.py +++ b/python/grass/imaging/images2swf.py @@ -253,7 +253,7 @@ def bitsToInt(bb, n=8): # Get value in bits for i in range(len(bb)): b = bb[i : i + 1] - tmp = bin(ord(b))[2:] + tmp = f"{ord(b):b}" # value += tmp.rjust(8,'0') value = tmp.rjust(8, "0") + value @@ -271,7 +271,7 @@ def getTypeAndLen(bb): # Get first 16 bits for i in range(2): b = bb[i : i + 1] - tmp = bin(ord(b))[2:] + tmp = f"{ord(b):b}" # value += tmp.rjust(8,'0') value = tmp.rjust(8, "0") + value @@ -285,7 +285,7 @@ def getTypeAndLen(bb): value = "" for i in range(2, 6): b = bb[i : i + 1] # becomes a single-byte bytes() on both PY3 and PY2 - tmp = bin(ord(b))[2:] + tmp = f"{ord(b):b}" # value += tmp.rjust(8,'0') value = tmp.rjust(8, "0") + value L = int(value, 2) @@ -828,8 +828,6 @@ def writeSwf(filename, images, duration=0.1, repeat=True): fp = open(filename, "wb") try: buildFile(fp, taglist, nframes=nframes, framesize=wh, fps=fps) - except Exception: - raise finally: fp.close() diff --git a/python/grass/jupyter/baseseriesmap.py b/python/grass/jupyter/baseseriesmap.py index e28572e1f3e..db915297e9c 100644 --- a/python/grass/jupyter/baseseriesmap.py +++ b/python/grass/jupyter/baseseriesmap.py @@ -1,6 +1,7 @@ """Base class for SeriesMap and TimeSeriesMap""" import os +from pathlib import Path import tempfile import weakref import shutil @@ -73,12 +74,11 @@ def __getattr__(self, name): def wrapper(**kwargs): if not self._baseseries_added: self._base_layer_calls.append((grass_module, kwargs)) + elif self._base_calls is not None: + for row in self._base_calls: + row.append((grass_module, kwargs)) else: - if self._base_calls is not None: - for row in self._base_calls: - row.append((grass_module, kwargs)) - else: - self._base_calls.append((grass_module, kwargs)) + self._base_calls.append((grass_module, kwargs)) return wrapper @@ -177,8 +177,7 @@ def change_slider(change): # Display image associated with datetime def change_image(index): filename = self._base_filename_dict[index] - with open(filename, "rb") as rfile: - out_img.value = rfile.read() + out_img.value = Path(filename).read_bytes() widgets.interactive_output(change_image, {"index": slider}) diff --git a/python/grass/jupyter/interactivemap.py b/python/grass/jupyter/interactivemap.py index f5eae8588ff..082122d24d0 100644 --- a/python/grass/jupyter/interactivemap.py +++ b/python/grass/jupyter/interactivemap.py @@ -15,6 +15,7 @@ import base64 import json +from pathlib import Path from .reprojection_renderer import ReprojectionRenderer @@ -119,9 +120,8 @@ def add_to(self, interactive_map): # ImageOverlays don't work well with local files, # they need relative address and behavior differs # for notebooks and jupyterlab - with open(self._filename, "rb") as file: - data = base64.b64encode(file.read()).decode("ascii") - url = "data:image/png;base64," + data + data = base64.b64encode(Path(self._filename).read_bytes()).decode("ascii") + url = "data:image/png;base64," + data image = ipyleaflet.ImageOverlay( url=url, bounds=self._bounds, name=self._title, **self._layer_kwargs ) diff --git a/python/grass/jupyter/region.py b/python/grass/jupyter/region.py index 67eb64104a9..fc4b406b80f 100644 --- a/python/grass/jupyter/region.py +++ b/python/grass/jupyter/region.py @@ -197,16 +197,13 @@ def set_region_from_command(self, module, **kwargs): vector=name, env=self._env ) self._extent_set = True - else: - if not self._resolution_set and not self._extent_set: - self._env["GRASS_REGION"] = gs.region_env( - raster=name, env=self._env - ) - self._extent_set = True - self._resolution_set = True - elif not self._resolution_set: - self._env["GRASS_REGION"] = gs.region_env(align=name, env=self._env) - self._resolution_set = True + elif not self._resolution_set and not self._extent_set: + self._env["GRASS_REGION"] = gs.region_env(raster=name, env=self._env) + self._extent_set = True + self._resolution_set = True + elif not self._resolution_set: + self._env["GRASS_REGION"] = gs.region_env(align=name, env=self._env) + self._resolution_set = True except CalledModuleError: return diff --git a/python/grass/jupyter/seriesmap.py b/python/grass/jupyter/seriesmap.py index c61c886aabb..9e470babb70 100644 --- a/python/grass/jupyter/seriesmap.py +++ b/python/grass/jupyter/seriesmap.py @@ -198,7 +198,7 @@ def save( self.render() tmp_files = [] - for _, file in self._base_filename_dict.items(): + for file in self._base_filename_dict.values(): tmp_files.append(file) save_gif( diff --git a/python/grass/jupyter/tests/seriesmap_test.py b/python/grass/jupyter/tests/seriesmap_test.py index 34b073308fc..14f79ccb7a8 100644 --- a/python/grass/jupyter/tests/seriesmap_test.py +++ b/python/grass/jupyter/tests/seriesmap_test.py @@ -16,6 +16,7 @@ import grass.jupyter as gj +@pytest.mark.needs_solo_run def test_default_init(space_time_raster_dataset): """Check that TimeSeriesMap init runs with default parameters""" img = gj.SeriesMap() @@ -23,6 +24,7 @@ def test_default_init(space_time_raster_dataset): assert img._labels == space_time_raster_dataset.raster_names +@pytest.mark.needs_solo_run def test_render_layers(space_time_raster_dataset): """Check that layers are rendered""" # create instance of TimeSeriesMap @@ -37,10 +39,11 @@ def test_render_layers(space_time_raster_dataset): # check files exist # We need to check values which are only in protected attributes # pylint: disable=protected-access - for unused_layer, filename in img._base_filename_dict.items(): + for filename in img._base_filename_dict.values(): assert Path(filename).is_file() +@pytest.mark.needs_solo_run @pytest.mark.skipif(IPython is None, reason="IPython package not available") @pytest.mark.skipif(ipywidgets is None, reason="ipywidgets package not available") def test_save(space_time_raster_dataset, tmp_path): diff --git a/python/grass/jupyter/tests/timeseriesmap_test.py b/python/grass/jupyter/tests/timeseriesmap_test.py index e99f03683f0..d904830b292 100644 --- a/python/grass/jupyter/tests/timeseriesmap_test.py +++ b/python/grass/jupyter/tests/timeseriesmap_test.py @@ -24,6 +24,7 @@ def test_fill_none_values(): assert fill_names == ["r1", "r1", "r3"] +@pytest.mark.needs_solo_run def test_collect_layers(space_time_raster_dataset): """Check that collect layers returns list of layers and dates""" names, dates = collect_layers( @@ -40,6 +41,7 @@ def test_collect_layers(space_time_raster_dataset): assert len(names) == len(dates) +@pytest.mark.needs_solo_run def test_default_init(space_time_raster_dataset): """Check that TimeSeriesMap init runs with default parameters""" img = gj.TimeSeriesMap() @@ -47,6 +49,7 @@ def test_default_init(space_time_raster_dataset): assert img.baseseries == space_time_raster_dataset.name +@pytest.mark.needs_solo_run @pytest.mark.parametrize("fill_gaps", [False, True]) def test_render_layers(space_time_raster_dataset, fill_gaps): """Check that layers are rendered""" @@ -63,10 +66,11 @@ def test_render_layers(space_time_raster_dataset, fill_gaps): # check files exist # We need to check values which are only in protected attributes # pylint: disable=protected-access - for unused_date, filename in img._base_filename_dict.items(): + for filename in img._base_filename_dict.values(): assert Path(filename).is_file() +@pytest.mark.needs_solo_run @pytest.mark.skipif(IPython is None, reason="IPython package not available") @pytest.mark.skipif(ipywidgets is None, reason="ipywidgets package not available") def test_save(space_time_raster_dataset, tmp_path): diff --git a/python/grass/jupyter/utils.py b/python/grass/jupyter/utils.py index f06adfa36d1..4d76b166361 100644 --- a/python/grass/jupyter/utils.py +++ b/python/grass/jupyter/utils.py @@ -113,8 +113,7 @@ def estimate_resolution(raster, mapset, location, dbase, env): output = gs.parse_key_val(output, val_type=float) cell_ns = (output["n"] - output["s"]) / output["rows"] cell_ew = (output["e"] - output["w"]) / output["cols"] - estimate = (cell_ew + cell_ns) / 2.0 - return estimate + return (cell_ew + cell_ns) / 2.0 def setup_location(name, path, epsg, src_env): diff --git a/python/grass/pydispatch/saferef.py b/python/grass/pydispatch/saferef.py index 6a65f262714..43be1175b19 100644 --- a/python/grass/pydispatch/saferef.py +++ b/python/grass/pydispatch/saferef.py @@ -28,8 +28,7 @@ def safeRef(target, onDelete=None): """but no %s, don't know how """ """to create reference""" % (target, im_self, im_func) ) - reference = BoundMethodWeakref(target=target, onDelete=onDelete) - return reference + return BoundMethodWeakref(target=target, onDelete=onDelete) if onDelete is not None: return weakref.ref(target, onDelete) else: diff --git a/python/grass/pygrass/gis/region.py b/python/grass/pygrass/gis/region.py index a4a1a1b5e03..0f736978026 100644 --- a/python/grass/pygrass/gis/region.py +++ b/python/grass/pygrass/gis/region.py @@ -7,7 +7,7 @@ import ctypes import grass.lib.gis as libgis import grass.lib.raster as libraster -import grass.script as grass +import grass.script as gs from grass.pygrass.errors import GrassError from grass.pygrass.shell.conversion import dict2html @@ -113,7 +113,7 @@ def byref(self): return ctypes.pointer(self.c_region) def _set_param(self, key, value): - grass.run_command("g.region", **{key: value}) + gs.run_command("g.region", **{key: value}) # ----------LIMITS---------- def _get_n(self): diff --git a/python/grass/pygrass/modules/grid/grid.py b/python/grass/pygrass/modules/grid/grid.py index 77fff0e2f3a..1163a8f3b6d 100644 --- a/python/grass/pygrass/modules/grid/grid.py +++ b/python/grass/pygrass/modules/grid/grid.py @@ -183,7 +183,7 @@ def rmloc(r): src = read_gisrc(gisrc_src) dst = read_gisrc(gisrc_dst) - rm = True if src[2] != dst[2] else False + rm = src[2] != dst[2] all_rasts = [r[0] for r in findmaps("raster", location=dst[1], gisdbase=dst[2])] for grp in groups: # change gisdbase to src @@ -376,7 +376,7 @@ def cmd_exe(args): src, dst = get_mapset(gisrc_src, gisrc_dst) env = os.environ.copy() env["GISRC"] = gisrc_dst - shell = True if sys.platform == "win32" else False + shell = sys.platform == "win32" if mapnames: inputs = dict(cmd["inputs"]) # reset the inputs to @@ -469,7 +469,7 @@ def __init__( self.height = height self.overlap = overlap self.processes = processes - self.region = region if region else Region() + self.region = region or Region() self.start_row = start_row self.start_col = start_col self.out_prefix = out_prefix diff --git a/python/grass/pygrass/modules/grid/split.py b/python/grass/pygrass/modules/grid/split.py index ea20a216e8e..cac604327d8 100644 --- a/python/grass/pygrass/modules/grid/split.py +++ b/python/grass/pygrass/modules/grid/split.py @@ -29,10 +29,10 @@ def get_bbox(reg, row, col, width, height, overlap): east = reg.west + ((col + 1) * width + overlap) * reg.ewres west = reg.west + (col * width - overlap) * reg.ewres return Bbox( - north=north if north <= reg.north else reg.north, - south=south if south >= reg.south else reg.south, - east=east if east <= reg.east else reg.east, - west=west if west >= reg.west else reg.west, + north=min(north, reg.north), + south=max(south, reg.south), + east=min(east, reg.east), + west=max(west, reg.west), ) @@ -93,7 +93,7 @@ def split_region_in_overlapping_tiles(region=None, width=100, height=100, overla [[Bbox(1350.0, 640.0, 1010.0, 0.0), Bbox(1350.0, 640.0, 1500.0, 990.0)], [Bbox(660.0, 0.0, 1010.0, 0.0), Bbox(660.0, 0.0, 1500.0, 990.0)]] """ - reg = region if region else Region() + reg = region or Region() ncols = (reg.cols + width - 1) // width nrows = (reg.rows + height - 1) // height box_list = [] @@ -118,7 +118,7 @@ def split_region_tiles(region=None, width=100, height=100): :param height: the width of tiles :type height: int """ - reg = region if region else Region() + reg = region or Region() ncols = (reg.cols + width - 1) // width nrows = (reg.rows + height - 1) // height box_list = [] @@ -142,7 +142,7 @@ def get_overlap_region_tiles(region=None, width=100, height=100, overlap=0): :param overlap: the value of overlap between tiles :type overlap: int """ - reg = region if region else Region() + reg = region or Region() ncols = (reg.cols + width - 1) // width nrows = (reg.rows + height - 1) // height box_list = [] diff --git a/python/grass/pygrass/modules/interface/env.py b/python/grass/pygrass/modules/interface/env.py index 4fbef04dae3..ad6e4c4800e 100644 --- a/python/grass/pygrass/modules/interface/env.py +++ b/python/grass/pygrass/modules/interface/env.py @@ -14,13 +14,12 @@ def get_env(): if gisrc is None: raise RuntimeError("You are not in a GRASS session, GISRC not found.") with open(gisrc, mode="r") as grc: - env = dict( + return dict( [ (k.strip(), v.strip()) for k, v in [row.split(":", 1) for row in grc if row] ] ) - return env def get_debug_level(): diff --git a/python/grass/pygrass/modules/interface/flag.py b/python/grass/pygrass/modules/interface/flag.py index 0fe024cd2a3..b2e78e30717 100644 --- a/python/grass/pygrass/modules/interface/flag.py +++ b/python/grass/pygrass/modules/interface/flag.py @@ -26,13 +26,11 @@ def __init__(self, xflag=None, diz=None): self.value = False diz = read.element2dict(xflag) if xflag is not None else diz self.name = diz["name"] - self.special = ( - True if self.name in {"verbose", "overwrite", "quiet", "run"} else False - ) + self.special = self.name in {"verbose", "overwrite", "quiet", "run"} self.description = diz.get("description", None) self.default = diz.get("default", None) self.guisection = diz.get("guisection", None) - self.suppress_required = True if "suppress_required" in diz else False + self.suppress_required = "suppress_required" in diz def get_bash(self): """Return the BASH representation of a flag. diff --git a/python/grass/pygrass/modules/interface/parameter.py b/python/grass/pygrass/modules/interface/parameter.py index 978372696e4..798efde56b7 100644 --- a/python/grass/pygrass/modules/interface/parameter.py +++ b/python/grass/pygrass/modules/interface/parameter.py @@ -162,8 +162,8 @@ def __init__(self, xparameter=None, diz=None): if diz is None: raise TypeError("Xparameter or diz are required") self.name = diz["name"] - self.required = True if diz["required"] == "yes" else False - self.multiple = True if diz["multiple"] == "yes" else False + self.required = diz["required"] == "yes" + self.multiple = diz["multiple"] == "yes" # check the type if diz["type"] in GETTYPE: self.type = GETTYPE[diz["type"]] @@ -216,7 +216,7 @@ def __init__(self, xparameter=None, diz=None): # if "gisprompt" in diz and diz["gisprompt"]: self.typedesc = diz["gisprompt"].get("prompt", "") - self.input = False if diz["gisprompt"]["age"] == "new" else True + self.input = not diz["gisprompt"]["age"] == "new" else: self.input = True diff --git a/python/grass/pygrass/modules/interface/testsuite/test_flag.py b/python/grass/pygrass/modules/interface/testsuite/test_flag.py index f10a94061ab..ef0f3c3678a 100644 --- a/python/grass/pygrass/modules/interface/testsuite/test_flag.py +++ b/python/grass/pygrass/modules/interface/testsuite/test_flag.py @@ -39,9 +39,9 @@ def test_bool(self): """Test magic __bool__ method""" flag = Flag(diz={"name": "a"}) flag.value = True - self.assertTrue(True if flag else False) + self.assertTrue(bool(flag)) flag.value = False - self.assertFalse(True if flag else False) + self.assertFalse(bool(flag)) if __name__ == "__main__": diff --git a/python/grass/pygrass/modules/shortcuts.py b/python/grass/pygrass/modules/shortcuts.py index bde3142e54c..f7fbdf7f04c 100644 --- a/python/grass/pygrass/modules/shortcuts.py +++ b/python/grass/pygrass/modules/shortcuts.py @@ -59,7 +59,7 @@ class MetaModule: def __init__(self, prefix, cls=None): self.prefix = prefix - self.cls = cls if cls else Module + self.cls = cls or Module def __dir__(self): return [ diff --git a/python/grass/pygrass/raster/__init__.py b/python/grass/pygrass/raster/__init__.py index c10140483d5..0356513e017 100644 --- a/python/grass/pygrass/raster/__init__.py +++ b/python/grass/pygrass/raster/__init__.py @@ -187,8 +187,8 @@ def open(self, mode=None, mtype=None, overwrite=None): * self._rows and self._cols """ - self.mode = mode if mode else self.mode - self.mtype = mtype if mtype else self.mtype + self.mode = mode or self.mode + self.mtype = mtype or self.mtype self.overwrite = overwrite if overwrite is not None else self.overwrite if self.mode == "r": @@ -509,8 +509,8 @@ def open(self, mode=None, mtype=None, overwrite=None): self._rows = libraster.Rast_window_rows() self._cols = libraster.Rast_window_cols() - self.mode = mode if mode else self.mode - self.mtype = mtype if mtype else self.mtype + self.mode = mode or self.mode + self.mtype = mtype or self.mtype self.overwrite = overwrite if overwrite is not None else self.overwrite if self.exist(): @@ -518,12 +518,12 @@ def open(self, mode=None, mtype=None, overwrite=None): self.cats.mtype = self.mtype self.cats.read() self.hist.read() - if (self.mode == "w" or self.mode == "rw") and self.overwrite is False: + if (self.mode in {"w", "rw"}) and self.overwrite is False: str_err = _("Raster map <{0}> already exists. Use overwrite.") fatal(str_err.format(self)) # We copy the raster map content into the segments - if self.mode == "rw" or self.mode == "r": + if self.mode in {"rw", "r"}: self._fd = libraster.Rast_open_old(self.name, self.mapset) self._gtype = libraster.Rast_get_map_type(self._fd) self.mtype = RTYPE_STR[self._gtype] @@ -563,7 +563,7 @@ def close(self, rm_temp_files=True): :param rm_temp_files: if True all the segments file will be removed :type rm_temp_files: bool """ - if self.mode == "w" or self.mode == "rw": + if self.mode in {"w", "rw"}: self.segment.flush() self.segment2map() if rm_temp_files: @@ -580,15 +580,11 @@ def close(self, rm_temp_files=True): def random_map_only_columns(mapname, mtype, overwrite=True, factor=100): region = Region() random_map = RasterRow(mapname) + rng = np.random.default_rng() row_buf = Buffer( (region.cols,), mtype, - buffer=( - np.random.random( - region.cols, - ) - * factor - ).data, + buffer=(rng.random(region.cols) * factor).data, ) random_map.open("w", mtype, overwrite) for _ in range(region.rows): @@ -601,16 +597,12 @@ def random_map(mapname, mtype, overwrite=True, factor=100): region = Region() random_map = RasterRow(mapname) random_map.open("w", mtype, overwrite) + rng = np.random.default_rng() for _ in range(region.rows): row_buf = Buffer( (region.cols,), mtype, - buffer=( - np.random.random( - region.cols, - ) - * factor - ).data, + buffer=(rng.random(region.cols) * factor).data, ) random_map.put_row(row_buf) random_map.close() diff --git a/python/grass/pygrass/raster/abstract.py b/python/grass/pygrass/raster/abstract.py index 3b05e69f269..616964d8f7b 100644 --- a/python/grass/pygrass/raster/abstract.py +++ b/python/grass/pygrass/raster/abstract.py @@ -431,8 +431,8 @@ def exist(self): if self.name: if self.mapset == "": mapset = utils.get_mapset_raster(self.name, self.mapset) - self.mapset = mapset if mapset else "" - return True if mapset else False + self.mapset = mapset or "" + return bool(mapset) return bool(utils.get_mapset_raster(self.name, self.mapset)) else: return False @@ -445,7 +445,7 @@ def is_open(self): False """ - return True if self._fd is not None and self._fd >= 0 else False + return bool(self._fd is not None and self._fd >= 0) @must_be_open def close(self): diff --git a/python/grass/pygrass/raster/category.py b/python/grass/pygrass/raster/category.py index 04049754954..31ef5f3ed76 100644 --- a/python/grass/pygrass/raster/category.py +++ b/python/grass/pygrass/raster/category.py @@ -6,6 +6,7 @@ import ctypes from operator import itemgetter +from pathlib import Path import grass.lib.raster as libraster from grass.exceptions import ImplementationError @@ -299,7 +300,7 @@ def read_rules(self, filename, sep=":"): """ self.reset() with open(filename, "r") as f: - for row in f.readlines(): + for row in f: cat = row.strip().split(sep) if len(cat) == 2: label, min_cat = cat @@ -325,13 +326,12 @@ def write_rules(self, filename, sep=":"): :param str filename: the name of file with categories rules :param str sep: the separator used to divide values and category """ - with open(filename, "w") as f: - cats = [] - for cat in self.__iter__(): - if cat[-1] is None: - cat = cat[:-1] - cats.append(sep.join([str(i) for i in cat])) - f.write("\n".join(cats)) + cats = [] + for cat in self.__iter__(): + if cat[-1] is None: + cat = cat[:-1] + cats.append(sep.join([str(i) for i in cat])) + Path(filename).write_text("\n".join(cats)) def sort(self): libraster.Rast_sort_cats(ctypes.byref(self.c_cats)) diff --git a/python/grass/pygrass/raster/rowio.py b/python/grass/pygrass/raster/rowio.py index 62c5683ef68..377843642a1 100644 --- a/python/grass/pygrass/raster/rowio.py +++ b/python/grass/pygrass/raster/rowio.py @@ -18,17 +18,17 @@ ) -def getmaprow_CELL(fd, buf, row, l): +def getmaprow_CELL(fd, buf, row): librast.Rast_get_c_row(fd, ctypes.cast(buf, ctypes.POINTER(librast.CELL)), row) return 1 -def getmaprow_FCELL(fd, buf, row, l): +def getmaprow_FCELL(fd, buf, row): librast.Rast_get_f_row(fd, ctypes.cast(buf, ctypes.POINTER(librast.FCELL)), row) return 1 -def getmaprow_DCELL(fd, buf, row, l): +def getmaprow_DCELL(fd, buf, row): librast.Rast_get_d_row(fd, ctypes.cast(buf, ctypes.POINTER(librast.DCELL)), row) return 1 diff --git a/python/grass/pygrass/raster/testsuite/test_numpy.py b/python/grass/pygrass/raster/testsuite/test_numpy.py index a2a6e1cdd26..5f0b2309544 100644 --- a/python/grass/pygrass/raster/testsuite/test_numpy.py +++ b/python/grass/pygrass/raster/testsuite/test_numpy.py @@ -6,7 +6,7 @@ from grass.gunittest.case import TestCase from grass.gunittest.main import test -from numpy.random import random +from numpy.random import default_rng from grass.pygrass.raster import raster2numpy, numpy2raster, RasterRow @@ -49,8 +49,8 @@ def test_len(self): self.assertTrue(len(self.numpy_obj[0]), 60) def test_write(self): - ran = random([40, 60]) - numpy2raster(ran, "FCELL", self.name, True) + rng = default_rng() + numpy2raster(rng.random([40, 60]), "FCELL", self.name, True) self.assertTrue(check_raster(self.name)) diff --git a/python/grass/pygrass/rpc/base.py b/python/grass/pygrass/rpc/base.py index 222f4dc64d1..38cf48c1581 100644 --- a/python/grass/pygrass/rpc/base.py +++ b/python/grass/pygrass/rpc/base.py @@ -154,7 +154,7 @@ def _check_restart_server(self, caller="main thread"): if self.stopped is not True: logging.warning( - "Needed to restart the libgis server, caller: %s" % (caller) + "Needed to restart the libgis server, caller: {caller}", caller=caller ) self.threadLock.release() diff --git a/python/grass/pygrass/shell/conversion.py b/python/grass/pygrass/shell/conversion.py index 76802c08ce1..b30acc3b545 100644 --- a/python/grass/pygrass/shell/conversion.py +++ b/python/grass/pygrass/shell/conversion.py @@ -83,12 +83,12 @@ def dict2html( def fun(x): return x - keys = keys if keys else sorted(dic.keys()) + keys = keys or sorted(dic.keys()) header = "" % border if border else "
          " kd = "<%s>%s" % (kdec, kfmt, kdec) if kdec else kfmt vd = "<%s>%s" % (vdec, vfmt, vdec) if vdec else vfmt - kfun = kfun if kfun else fun - vfun = vfun if vfun else fun + kfun = kfun or fun + vfun = vfun or fun content = [dcont.format(key=kd % kfun(k), value=vd % vfun(dic[k])) for k in keys] return "\n".join( [ diff --git a/python/grass/pygrass/shell/show.py b/python/grass/pygrass/shell/show.py index 94b0807debe..8465dc9e92d 100644 --- a/python/grass/pygrass/shell/show.py +++ b/python/grass/pygrass/shell/show.py @@ -4,8 +4,8 @@ @author: pietro """ +from pathlib import Path + def raw_figure(figpath): - with open(figpath, mode="rb") as data: - res = data.read() - return res + return Path(figpath).read_bytes() diff --git a/python/grass/pygrass/tests/benchmark.py b/python/grass/pygrass/tests/benchmark.py index c63dcb8d02e..75e32541a59 100644 --- a/python/grass/pygrass/tests/benchmark.py +++ b/python/grass/pygrass/tests/benchmark.py @@ -20,7 +20,7 @@ import grass.lib.gis as libgis import grass.lib.raster as libraster -import grass.script as core +import grass.script as gs import ctypes @@ -237,11 +237,11 @@ def test__RasterRow_row_access__if(): def test__mapcalc__add(): - core.mapcalc("test_c = test_a + test_b", quite=True, overwrite=True) + gs.mapcalc("test_c = test_a + test_b", quite=True, overwrite=True) def test__mapcalc__if(): - core.mapcalc("test_c = if(test_a > 50, 1, 0)", quite=True, overwrite=True) + gs.mapcalc("test_c = if(test_a > 50, 1, 0)", quite=True, overwrite=True) def mytimer(func, runs=1): @@ -260,10 +260,8 @@ def mytimer(func, runs=1): def run_benchmark(resolution_list, runs, testdict, profile): regions = [] for resolution in resolution_list: - core.use_temp_region() - core.run_command( - "g.region", e=50, w=-50, n=50, s=-50, res=resolution, flags="p" - ) + gs.use_temp_region() + gs.run_command("g.region", e=50, w=-50, n=50, s=-50, res=resolution, flags="p") # Adjust the computational region for this process region = libgis.Cell_head() @@ -281,8 +279,8 @@ def run_benchmark(resolution_list, runs, testdict, profile): libgis.G_set_window(ctypes.byref(region)) # Create two raster maps with random numbers - core.mapcalc("test_a = rand(0, 100)", quite=True, overwrite=True) - core.mapcalc("test_b = rand(0.0, 1.0)", quite=True, overwrite=True) + gs.mapcalc("test_a = rand(0, 100)", quite=True, overwrite=True) + gs.mapcalc("test_b = rand(0.0, 1.0)", quite=True, overwrite=True) result = collections.OrderedDict() result["res"] = resolution result["cols"] = region.cols @@ -305,7 +303,7 @@ def run_benchmark(resolution_list, runs, testdict, profile): del operdict["func"] regions.append(result) - core.del_temp_region() + gs.del_temp_region() return regions @@ -336,7 +334,7 @@ def print_test(testdict): print(execmode) for oper, operdict in operation.items(): print(" ", oper) - for key, value in operdict.items(): + for key in operdict.keys(): print(" ", key) diff --git a/python/grass/pygrass/utils.py b/python/grass/pygrass/utils.py index 38a78277dd0..e8f4ce68a43 100644 --- a/python/grass/pygrass/utils.py +++ b/python/grass/pygrass/utils.py @@ -332,7 +332,7 @@ def get_raster_for_points(poi_vector, raster, column=None, region=None): if column: if val is not None and not isnan(val): poi.attrs[column] = val - else: + else: # noqa: PLR5501 if val is not None and not isnan(val): result.append((poi.id, poi.x, poi.y, val)) else: @@ -348,7 +348,7 @@ def r_export(rast, output="", fmt="png", **kargs): from grass.pygrass.modules import Module if rast.exist(): - output = output if output else "%s_%s.%s" % (rast.name, rast.mapset, fmt) + output = output or "%s_%s.%s" % (rast.name, rast.mapset, fmt) Module( "r.out.%s" % fmt, input=rast.fullname(), @@ -437,7 +437,7 @@ def table_exist(cursor, table_name): except OperationalError: return False one = cursor.fetchone() if cursor else None - return True if one and one[0] else False + return bool(one and one[0]) def create_test_vector_map(map_name="test_vector"): diff --git a/python/grass/pygrass/vector/__init__.py b/python/grass/pygrass/vector/__init__.py index 44baff75300..7869b1a29b5 100644 --- a/python/grass/pygrass/vector/__init__.py +++ b/python/grass/pygrass/vector/__init__.py @@ -258,7 +258,7 @@ def has_color_table(self): """ loc = Location() path = join(loc.path(), self.mapset, "vector", self.name, "colr") - return True if exists(path) else False + return bool(exists(path)) # ============================================= @@ -310,9 +310,9 @@ def __getitem__(self, key): return [ self.read(indx) for indx in range( - key.start if key.start else 1, - key.stop if key.stop else len(self), - key.step if key.step else 1, + key.start or 1, + key.stop or len(self), + key.step or 1, ) ] elif isinstance(key, int): @@ -509,7 +509,7 @@ def cat(self, cat_id, vtype, layer=None, generator=False, geo=None): ilist = Ilist() libvect.Vect_cidx_find_all( self.c_mapinfo, - layer if layer else self.layer, + layer or self.layer, Obj.gtype, cat_id, ilist.c_ilist, diff --git a/python/grass/pygrass/vector/abstract.py b/python/grass/pygrass/vector/abstract.py index 900b1d6a2ea..3929006ef25 100644 --- a/python/grass/pygrass/vector/abstract.py +++ b/python/grass/pygrass/vector/abstract.py @@ -20,10 +20,7 @@ def is_open(c_mapinfo): """Return if the Vector is open""" - return ( - c_mapinfo.contents.open != 0 - and c_mapinfo.contents.open != libvect.VECT_CLOSED_CODE - ) + return c_mapinfo.contents.open not in {0, libvect.VECT_CLOSED_CODE} # ============================================= @@ -299,8 +296,8 @@ def exist(self): if self.name: if self.mapset == "": mapset = utils.get_mapset_vector(self.name, self.mapset) - self.mapset = mapset if mapset else "" - return True if mapset else False + self.mapset = mapset or "" + return bool(mapset) return bool(utils.get_mapset_vector(self.name, self.mapset)) else: return False @@ -358,7 +355,7 @@ def open( See more examples in the documentation of the ``read`` and ``write`` methods """ - self.mode = mode if mode else self.mode + self.mode = mode or self.mode with_z = libvect.WITH_Z if with_z else libvect.WITHOUT_Z # check if map exists or not if not self.exist() and self.mode != "w": @@ -396,8 +393,8 @@ def open( # create a link link = Link( layer, - link_name if link_name else self.name, - tab_name if tab_name else self.name, + link_name or self.name, + tab_name or self.name, link_key, link_db, link_driver, @@ -465,8 +462,8 @@ def close(self, build=False): str_err = "Error when trying to close the map with Vect_close" raise GrassError(str_err) if ( - self.c_mapinfo.contents.mode == libvect.GV_MODE_RW - or self.c_mapinfo.contents.mode == libvect.GV_MODE_WRITE + self.c_mapinfo.contents.mode + in {libvect.GV_MODE_RW, libvect.GV_MODE_WRITE} ) and build: self.build() diff --git a/python/grass/pygrass/vector/basic.py b/python/grass/pygrass/vector/basic.py index 2b8c013b433..73eb5bb5557 100644 --- a/python/grass/pygrass/vector/basic.py +++ b/python/grass/pygrass/vector/basic.py @@ -133,9 +133,7 @@ def contains(self, point): """ return bool( - libvect.Vect_point_in_box( - point.x, point.y, point.z if point.z else 0, self.c_bbox - ) + libvect.Vect_point_in_box(point.x, point.y, point.z or 0, self.c_bbox) ) def items(self): @@ -424,7 +422,7 @@ def n_cats(self): return self.c_cats.contents.n_cats def __init__(self, c_cats=None): - self.c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats()) + self.c_cats = c_cats or ctypes.pointer(libvect.line_cats()) def reset(self): """Reset the C cats struct from previous values.""" @@ -541,9 +539,7 @@ def max(self): return [max_values[i] for i in range(self.n_ranges)] def __init__(self, c_cat_list=None): - self.c_cat_list = ( - c_cat_list if c_cat_list else ctypes.pointer(libvect.cat_list()) - ) + self.c_cat_list = c_cat_list or ctypes.pointer(libvect.cat_list()) def from_string(self, string): """Converts string of categories and cat ranges separated by commas diff --git a/python/grass/pygrass/vector/find.py b/python/grass/pygrass/vector/find.py index 50599af5ab5..9333497f110 100644 --- a/python/grass/pygrass/vector/find.py +++ b/python/grass/pygrass/vector/find.py @@ -101,7 +101,7 @@ def node(self, point, maxdist): self.c_mapinfo, point.x, point.y, - point.z if point.z else 0, + point.z or 0, float(maxdist), int(not point.is2D), ) @@ -166,7 +166,7 @@ def geo(self, point, maxdist, type="all", exclude=0): self.c_mapinfo, point.x, point.y, - point.z if point.z else 0, + point.z or 0, self.vtype[type], float(maxdist), int(not point.is2D), @@ -257,7 +257,7 @@ def geos(self, point, maxdist, type="all", exclude=None): self.c_mapinfo, point.x, point.y, - point.z if point.z else 0, + point.z or 0, self.vtype[type], float(maxdist), int(not point.is2D), @@ -586,7 +586,7 @@ def areas(self, bbox, boxlist=None, bboxlist_only=False): >>> test_vect.close() """ - boxlist = boxlist if boxlist else BoxList() + boxlist = boxlist or BoxList() if libvect.Vect_select_areas_by_box( self.c_mapinfo, bbox.c_bbox, boxlist.c_boxlist ): diff --git a/python/grass/pygrass/vector/geometry.py b/python/grass/pygrass/vector/geometry.py index 855f374b47e..591ebf38978 100644 --- a/python/grass/pygrass/vector/geometry.py +++ b/python/grass/pygrass/vector/geometry.py @@ -126,15 +126,14 @@ def get_xyz(pnt): z = 0.0 else: x, y, z = pnt.x, pnt.y, pnt.z + elif len(pnt) == 2: + x, y = pnt + z = 0.0 + elif len(pnt) == 3: + x, y, z = pnt else: - if len(pnt) == 2: - x, y = pnt - z = 0.0 - elif len(pnt) == 3: - x, y, z = pnt - else: - str_error = "The the format of the point is not supported: {0!r}" - raise ValueError(str_error.format(pnt)) + str_error = "The the format of the point is not supported: {0!r}" + raise ValueError(str_error.format(pnt)) return x, y, z @@ -459,7 +458,7 @@ def __init__(self, x=0, y=0, z=None, **kargs): if self.id and self.c_mapinfo: self.read() else: - self.is2D = True if z is None else False + self.is2D = z is None z = z if z is not None else 0 libvect.Vect_append_point(self.c_points, x, y, z) @@ -792,7 +791,7 @@ def bbox(self, bbox=None): .. """ - bbox = bbox if bbox else Bbox() + bbox = bbox or Bbox() libvect.Vect_line_box(self.c_points, bbox.c_bbox) return bbox @@ -1376,12 +1375,11 @@ def __repr__(self): def _centroid(self, side, idonly=False): if side > 0: v_id = libvect.Vect_get_area_centroid(self.c_mapinfo, side) - v_id = v_id if v_id else None + v_id = v_id or None if idonly: return v_id else: - cntr = Centroid(v_id=v_id, c_mapinfo=self.c_mapinfo) - return cntr + return Centroid(v_id=v_id, c_mapinfo=self.c_mapinfo) def left_centroid(self, idonly=False): """Return left centroid @@ -1497,7 +1495,7 @@ def boundaries(self): @mapinfo_must_be_set def bbox(self, bbox=None): """Return bounding box of Isle""" - bbox = bbox if bbox else Bbox() + bbox = bbox or Bbox() libvect.Vect_get_isle_box(self.c_mapinfo, self.id, bbox.c_bbox) return bbox @@ -1700,7 +1698,7 @@ def bbox(self, bbox=None): :param bbox: a Bbox object to fill with info from bounding box of area :type bbox: a Bbox object """ - bbox = bbox if bbox else Bbox() + bbox = bbox or Bbox() libvect.Vect_get_area_box(self.c_mapinfo, self.id, bbox.c_bbox) return bbox @@ -1798,7 +1796,7 @@ def cats(self, cats=None): :param cats: a Cats object to fill with info with area categories :type cats: a Cats object """ - cats = cats if cats else Cats() + cats = cats or Cats() libvect.Vect_get_area_cats(self.c_mapinfo, self.id, cats.c_cats) return cats @@ -1820,7 +1818,7 @@ def contains_point(self, point, bbox=None): :param bbox: the bounding box where run the analysis :type bbox: a Bbox object """ - bbox = bbox if bbox else self.bbox() + bbox = bbox or self.bbox() return bool( libvect.Vect_point_in_area( point.x, point.y, self.c_mapinfo, self.id, bbox.c_bbox @@ -1897,8 +1895,8 @@ def read_next_line( if c_cats is None: free_cats = True - c_points = c_points if c_points else ctypes.pointer(libvect.line_pnts()) - c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats()) + c_points = c_points or ctypes.pointer(libvect.line_pnts()) + c_cats = c_cats or ctypes.pointer(libvect.line_cats()) ftype, v_id, c_points, c_cats = c_read_next_line(c_mapinfo, c_points, c_cats) return GV_TYPE[ftype]["obj"]( v_id=v_id, @@ -1945,8 +1943,8 @@ def read_line( if c_cats is None: free_cats = True - c_points = c_points if c_points else ctypes.pointer(libvect.line_pnts()) - c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats()) + c_points = c_points or ctypes.pointer(libvect.line_pnts()) + c_cats = c_cats or ctypes.pointer(libvect.line_cats()) feature_id, ftype, c_points, c_cats = c_read_line( feature_id, c_mapinfo, c_points, c_cats ) diff --git a/python/grass/pygrass/vector/table.py b/python/grass/pygrass/vector/table.py index 3cca5689132..dec3ffbba08 100644 --- a/python/grass/pygrass/vector/table.py +++ b/python/grass/pygrass/vector/table.py @@ -1135,7 +1135,7 @@ def drop(self, cursor=None, force=False): :type force: bool """ - cur = cursor if cursor else self.conn.cursor() + cur = cursor or self.conn.cursor() if self.exist(cursor=cur): used = db_table_in_vector(self.name) if used is not None and len(used) > 0 and not force: @@ -1194,8 +1194,8 @@ def execute(self, sql_code=None, cursor=None, many=False, values=None): """ try: - sqlc = sql_code if sql_code else self.filters.get_sql() - cur = cursor if cursor else self.conn.cursor() + sqlc = sql_code or self.filters.get_sql() + cur = cursor or self.conn.cursor() if many and values: return cur.executemany(sqlc, values) return cur.execute(sqlc, values) if values else cur.execute(sqlc) @@ -1212,7 +1212,7 @@ def exist(self, cursor=None): :param cursor: the cursor to connect, if None it use the cursor of connection table object """ - cur = cursor if cursor else self.conn.cursor() + cur = cursor or self.conn.cursor() return table_exist(cur, self.name) def insert(self, values, cursor=None, many=False): @@ -1227,7 +1227,7 @@ def insert(self, values, cursor=None, many=False): :param many: True to run executemany function :type many: bool """ - cur = cursor if cursor else self.conn.cursor() + cur = cursor or self.conn.cursor() if many: return cur.executemany(self.columns.insert_str, values) return cur.execute(self.columns.insert_str, values) @@ -1246,7 +1246,7 @@ def update(self, key, values, cursor=None): of connection table object :type cursor: Cursor object """ - cur = cursor if cursor else self.conn.cursor() + cur = cursor or self.conn.cursor() vals = list(values) + [ key, ] @@ -1266,7 +1266,7 @@ def create(self, cols, name=None, overwrite=False, cursor=None): :type cursor: Cursor object """ - cur = cursor if cursor else self.conn.cursor() + cur = cursor or self.conn.cursor() coldef = ",\n".join(["%s %s" % col for col in cols]) if name: newname = name diff --git a/python/grass/pygrass/vector/testsuite/test_geometry.py b/python/grass/pygrass/vector/testsuite/test_geometry.py index d4ad7431278..c3ad5b6cd63 100644 --- a/python/grass/pygrass/vector/testsuite/test_geometry.py +++ b/python/grass/pygrass/vector/testsuite/test_geometry.py @@ -336,17 +336,13 @@ def test_boundaries_1(self): self.assertEqual(len(boundaries), 4) string_list = [] - string_list.append( - "LINESTRING (0.0000000000000000 0.0000000000000000, 0.0000000000000000 4.0000000000000000)" - ) - string_list.append( - "LINESTRING (0.0000000000000000 4.0000000000000000, 4.0000000000000000 4.0000000000000000)" - ) - string_list.append( - "LINESTRING (4.0000000000000000 4.0000000000000000, 4.0000000000000000 0.0000000000000000)" - ) - string_list.append( - "LINESTRING (4.0000000000000000 0.0000000000000000, 0.0000000000000000 0.0000000000000000)" + string_list.extend( + ( + "LINESTRING (0.0000000000000000 0.0000000000000000, 0.0000000000000000 4.0000000000000000)", + "LINESTRING (0.0000000000000000 4.0000000000000000, 4.0000000000000000 4.0000000000000000)", + "LINESTRING (4.0000000000000000 4.0000000000000000, 4.0000000000000000 0.0000000000000000)", + "LINESTRING (4.0000000000000000 0.0000000000000000, 0.0000000000000000 0.0000000000000000)", + ) ) for boundary, i in zip(boundaries, range(4)): diff --git a/python/grass/pygrass/vector/testsuite/test_table.py b/python/grass/pygrass/vector/testsuite/test_table.py index d603817de98..1acb410a10f 100644 --- a/python/grass/pygrass/vector/testsuite/test_table.py +++ b/python/grass/pygrass/vector/testsuite/test_table.py @@ -18,11 +18,12 @@ # dictionary that generate random data +RNG = np.random.default_rng() COL2VALS = { - "INT": lambda n: np.random.randint(9, size=n), - "INTEGER": lambda n: np.random.randint(9, size=n), + "INT": lambda n: RNG.integers(low=0, high=9, size=n), + "INTEGER": lambda n: RNG.integers(low=0, high=9, size=n), "INTEGER PRIMARY KEY": lambda n: np.arange(1, n + 1, dtype=int), - "REAL": lambda n: np.random.rand(n), + "REAL": lambda n: RNG.random(n), "TEXT": lambda n: np.array([randstr() for _ in range(n)]), } diff --git a/python/grass/pygrass/vector/testsuite/test_vector3d.py b/python/grass/pygrass/vector/testsuite/test_vector3d.py index 16ee0fd969e..796f85ca529 100644 --- a/python/grass/pygrass/vector/testsuite/test_vector3d.py +++ b/python/grass/pygrass/vector/testsuite/test_vector3d.py @@ -19,11 +19,12 @@ def generate_coordinates(number, bbox=None, with_z=False): """Return 2 or 3 random arrays of coordinates""" + rng = np.random.default_rng() bbox = Region() if bbox is None else bbox - x = bbox.south + (bbox.north - bbox.south) * np.random.random(number) - y = bbox.west + (bbox.east - bbox.west) * np.random.random(number) + x = bbox.south + (bbox.north - bbox.south) * rng.random(number) + y = bbox.west + (bbox.east - bbox.west) * rng.random(number) if with_z: - z = np.random.random(number) * 1000 + z = rng.random(number) * 1000 return x, y, z return x, y diff --git a/python/grass/script/array.py b/python/grass/script/array.py index c9abafbc24c..29c99d7617c 100644 --- a/python/grass/script/array.py +++ b/python/grass/script/array.py @@ -109,7 +109,7 @@ .. sectionauthor:: Glynn Clements """ -import numpy +import numpy as np from .utils import try_remove from . import core as gcore @@ -130,8 +130,8 @@ def __del__(self): ############################################################################### -class array(numpy.memmap): - def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None): +class array(np.memmap): + def __new__(cls, mapname=None, null=None, dtype=np.double, env=None): """Define new numpy array :param cls: @@ -145,8 +145,8 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None): tempfile = _tempfile(env) if mapname: - kind = numpy.dtype(dtype).kind - size = numpy.dtype(dtype).itemsize + kind = np.dtype(dtype).kind + size = np.dtype(dtype).itemsize if kind == "f": flags = "f" @@ -170,7 +170,7 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None): env=env, ) - self = numpy.memmap.__new__( + self = np.memmap.__new__( cls, filename=tempfile.filename, dtype=dtype, mode="r+", shape=shape ) @@ -241,8 +241,8 @@ def write(self, mapname, title=None, null=None, overwrite=None, quiet=None): ############################################################################### -class array3d(numpy.memmap): - def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None): +class array3d(np.memmap): + def __new__(cls, mapname=None, null=None, dtype=np.double, env=None): """Define new 3d numpy array :param cls: @@ -257,8 +257,8 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None): tempfile = _tempfile() if mapname: - kind = numpy.dtype(dtype).kind - size = numpy.dtype(dtype).itemsize + kind = np.dtype(dtype).kind + size = np.dtype(dtype).itemsize if kind == "f": flags = None # default is double @@ -282,7 +282,7 @@ def __new__(cls, mapname=None, null=None, dtype=numpy.double, env=None): env=env, ) - self = numpy.memmap.__new__( + self = np.memmap.__new__( cls, filename=tempfile.filename, dtype=dtype, mode="r+", shape=shape ) @@ -307,7 +307,7 @@ def write(self, mapname, null=None, overwrite=None, quiet=None): flags = None if kind == "f": - if size != 4 and size != 8: + if size not in {4, 8}: raise ValueError(_("Invalid FP size <%d>") % size) elif kind in "biu": if size not in {1, 2, 4, 8}: diff --git a/python/grass/script/core.py b/python/grass/script/core.py index 6647661b379..20d3f358a82 100644 --- a/python/grass/script/core.py +++ b/python/grass/script/core.py @@ -124,11 +124,11 @@ def _make_unicode(val, enc): """ if val is None or enc is None: return val + + if enc == "default": + return decode(val) else: - if enc == "default": - return decode(val) - else: - return decode(val, encoding=enc) + return decode(val, encoding=enc) def get_commands(*, env=None): @@ -218,9 +218,7 @@ def get_real_command(cmd): if os.path.splitext(cmd)[1] == ".py": cmd = cmd[:-3] # PATHEXT is necessary to check on Windows (force lowercase) - pathext = list( - map(lambda x: x.lower(), os.environ["PATHEXT"].split(os.pathsep)) - ) + pathext = [x.lower() for x in os.environ["PATHEXT"].split(os.pathsep)] if ".py" not in pathext: # we assume that PATHEXT contains always '.py' os.environ["PATHEXT"] = ".py;" + os.environ["PATHEXT"] @@ -985,9 +983,7 @@ def tempname(length, lowercase=False): if not lowercase: chars += string.ascii_uppercase random_part = "".join(random.choice(chars) for _ in range(length)) - randomname = "tmp_" + random_part - - return randomname + return "tmp_" + random_part def _compare_projection(dic): @@ -1170,9 +1166,8 @@ def compare_key_value_text_files( # We compare the sum of the entries if abs(sum(dict_a[key]) - sum(dict_b[key])) > precision: return False - else: - if dict_a[key] != dict_b[key]: - return False + elif dict_a[key] != dict_b[key]: + return False return True @@ -1286,8 +1281,8 @@ def region_env(region3d=False, flags=None, env=None, **kwargs): ) with open(windfile, "r") as fd: grass_region = "" - for line in fd.readlines(): - key, value = map(lambda x: x.strip(), line.split(":", 1)) + for line in fd: + key, value = (x.strip() for x in line.split(":", 1)) if kwargs and key not in {"proj", "zone"}: continue if ( @@ -1571,13 +1566,12 @@ def list_grouped( name, ] } + elif mapset in result: + result[mapset].append(name) else: - if mapset in result: - result[mapset].append(name) - else: - result[mapset] = [ - name, - ] + result[mapset] = [ + name, + ] return result diff --git a/python/grass/script/db.py b/python/grass/script/db.py index 421c57267d7..2725ff06ebe 100644 --- a/python/grass/script/db.py +++ b/python/grass/script/db.py @@ -191,7 +191,7 @@ def db_select(sql=None, filename=None, table=None, env=None, **args): fatal(_("Fetching data failed")) ofile = open(fname) - result = [tuple(x.rstrip(os.linesep).split(args["sep"])) for x in ofile.readlines()] + result = [tuple(x.rstrip(os.linesep).split(args["sep"])) for x in ofile] ofile.close() try_remove(fname) diff --git a/python/grass/script/task.py b/python/grass/script/task.py index 66f7667f5e4..7d635dc83bb 100644 --- a/python/grass/script/task.py +++ b/python/grass/script/task.py @@ -148,9 +148,8 @@ def get_param(self, value, element="name", raiseError=True): if isinstance(val, (list, tuple)): if value in val: return p - else: - if p[element] == value: - return p + elif p[element] == value: + return p if raiseError: raise ValueError( @@ -429,8 +428,7 @@ def _get_node_text(self, node, tag, default=""): """Get node text""" p = node.find(tag) if p is not None: - res = " ".join(p.text.split()) - return res + return " ".join(p.text.split()) return default @@ -448,15 +446,12 @@ def convert_xml_to_utf8(xml_text): m = re.match(pattern, xml_text) if m is None: return xml_text.encode("utf-8") if xml_text else None - # enc = m.groups()[0] # modify: change the encoding to "utf-8", for correct parsing xml_text_utf8 = xml_text.decode(enc.decode("ascii")).encode("utf-8") p = re.compile(b'encoding="' + enc + b'"', re.IGNORECASE) - xml_text_utf8 = p.sub(b'encoding="utf-8"', xml_text_utf8) - - return xml_text_utf8 + return p.sub(b'encoding="utf-8"', xml_text_utf8) def get_interface_description(cmd): @@ -509,13 +504,12 @@ def get_interface_description(cmd): ) desc = convert_xml_to_utf8(cmdout) - desc = desc.replace( + return desc.replace( b"grass-interface.dtd", os.path.join(os.getenv("GISBASE"), "gui", "xml", "grass-interface.dtd").encode( "utf-8" ), ) - return desc def parse_interface(name, parser=processTask, blackList=None): diff --git a/python/grass/script/tests/grass_script_core_location_test.py b/python/grass/script/tests/grass_script_core_location_test.py index fdffa340b83..b389d41ba8d 100644 --- a/python/grass/script/tests/grass_script_core_location_test.py +++ b/python/grass/script/tests/grass_script_core_location_test.py @@ -167,7 +167,7 @@ def set_and_test_description(tmp_path, text): gs.core._set_location_description(tmp_path, name, text) description_file = tmp_path / name / "PERMANENT" / "MYNAME" assert description_file.exists() - text = text if text else "" # None and empty should both yield empty. + text = text or "" # None and empty should both yield empty. assert description_file.read_text(encoding="utf-8").strip() == text diff --git a/python/grass/script/testsuite/test_utils.py b/python/grass/script/testsuite/test_utils.py index acdf7fe157e..db12041d66d 100644 --- a/python/grass/script/testsuite/test_utils.py +++ b/python/grass/script/testsuite/test_utils.py @@ -18,7 +18,7 @@ def setUp(self): os.environ[k] = v def tearDown(self): - for k, v in self.env.items(): + for k in self.env.keys(): oval = self.original_env[k] if oval == self.NOT_FOUND: os.environ.pop(k) diff --git a/python/grass/script/utils.py b/python/grass/script/utils.py index 57a3f3cd2de..13d049412a4 100644 --- a/python/grass/script/utils.py +++ b/python/grass/script/utils.py @@ -71,9 +71,9 @@ def separator(sep): return "," elif sep == "space": return " " - elif sep == "tab" or sep == "\\t": + elif sep in {"tab", "\\t"}: return "\t" - elif sep == "newline" or sep == "\\n": + elif sep in {"newline", "\\n"}: return "\n" return sep @@ -91,8 +91,7 @@ def diff_files(filename_a, filename_b): differ = difflib.Differ() fh_a = open(filename_a, "r") fh_b = open(filename_b, "r") - result = list(differ.compare(fh_a.readlines(), fh_b.readlines())) - return result + return list(differ.compare(fh_a.readlines(), fh_b.readlines())) def try_remove(path): diff --git a/python/grass/script/vector.py b/python/grass/script/vector.py index 4a57b5db07b..ca3caf18471 100644 --- a/python/grass/script/vector.py +++ b/python/grass/script/vector.py @@ -430,8 +430,7 @@ def vector_what( return data # lazy import - global json - global orderedDict + global json, orderedDict if json is None: import json if orderedDict is None: diff --git a/python/grass/semantic_label/reader.py b/python/grass/semantic_label/reader.py index bd19af69110..591006fe352 100644 --- a/python/grass/semantic_label/reader.py +++ b/python/grass/semantic_label/reader.py @@ -138,7 +138,7 @@ def print_info(self, shortcut=None, band=None, semantic_label=None, extended=Fal else: for iband in item["bands"]: self._print_label_extended(iband, item["bands"]) - else: + else: # noqa: PLR5501 # basic information only if band: self._print_label( @@ -181,7 +181,7 @@ def find_file(self, semantic_label): shortcut and config[root]["shortcut"].upper() == shortcut.upper() and band.upper() - in map(lambda x: x.upper(), config[root]["bands"].keys()) + in (x.upper() for x in config[root]["bands"].keys()) ): return filename diff --git a/python/grass/temporal/abstract_map_dataset.py b/python/grass/temporal/abstract_map_dataset.py index 89956189651..aa2472a9ee9 100644 --- a/python/grass/temporal/abstract_map_dataset.py +++ b/python/grass/temporal/abstract_map_dataset.py @@ -499,11 +499,9 @@ def set_absolute_time(self, start_time, end_time=None): % {"type": self.get_type(), "id": self.get_map_id()} ) return False - else: - # Do not create an interval in case start and end time are - # equal - if start_time == end_time: - end_time = None + # Do not create an interval in case start and end time are equal + elif start_time == end_time: + end_time = None self.base.set_ttype("absolute") self.absolute_time.set_start_time(start_time) @@ -619,11 +617,9 @@ def set_relative_time(self, start_time, end_time, unit): % {"type": self.get_type(), "id": self.get_id()} ) return False - else: - # Do not create an interval in case start and end time are - # equal - if start_time == end_time: - end_time = None + # Do not create an interval in case start and end time are equal + elif start_time == end_time: + end_time = None self.base.set_ttype("relative") @@ -1132,7 +1128,7 @@ def get_registered_stds(self, dbif=None, mapset=None): datasets = None if connection_state_changed: - dbif.close + dbif.close() return datasets @@ -1168,7 +1164,7 @@ def add_stds_to_register(self, stds_id, dbif=None, execute=True): # Check if the dataset is already present if stds_id in datasets: if connection_state_changed: - dbif.close + dbif.close() return "" datasets.append(stds_id) @@ -1183,7 +1179,7 @@ def add_stds_to_register(self, stds_id, dbif=None, execute=True): statement = self.stds_register.get_update_statement_mogrified(dbif=dbif) if connection_state_changed: - dbif.close + dbif.close() return statement @@ -1210,13 +1206,13 @@ def remove_stds_from_register(self, stds_id, dbif=None, execute=True): # Check if no datasets are present if datasets is None: if connection_state_changed: - dbif.close + dbif.close() return "" # Check if the dataset is already present if stds_id not in datasets: if connection_state_changed: - dbif.close + dbif.close() return "" datasets.remove(stds_id) @@ -1231,7 +1227,7 @@ def remove_stds_from_register(self, stds_id, dbif=None, execute=True): statement = self.stds_register.get_update_statement_mogrified(dbif=dbif) if connection_state_changed: - dbif.close + dbif.close() return statement diff --git a/python/grass/temporal/abstract_space_time_dataset.py b/python/grass/temporal/abstract_space_time_dataset.py index 68a8c5498e9..ab76ab4112c 100644 --- a/python/grass/temporal/abstract_space_time_dataset.py +++ b/python/grass/temporal/abstract_space_time_dataset.py @@ -98,10 +98,7 @@ def create_map_register_name(self): uuid_rand = str(uuid.uuid4()).replace("-", "") - table_name = ( - self.get_new_map_instance(None).get_type() + "_map_register_" + uuid_rand - ) - return table_name + return self.get_new_map_instance(None).get_type() + "_map_register_" + uuid_rand @abstractmethod def get_new_map_instance(self, ident=None): @@ -590,7 +587,7 @@ def check_temporal_topology(self, maps=None, dbif=None): map_time = self.get_map_time() - if map_time == "interval" or map_time == "mixed": + if map_time in {"interval", "mixed"}: if "equal" in relations and relations["equal"] > 0: return False if "during" in relations and relations["during"] > 0: @@ -966,9 +963,9 @@ def sample_by_dataset_sql(self, stds, method=None, spatial=False, dbif=None): use_during = True if name == "overlap": use_overlap = True - if name == "contain" or name == "contains": + if name in {"contain", "contains"}: use_contain = True - if name == "equal" or name == "equals": + if name in {"equal", "equals"}: use_equal = True if name == "follows": use_follows = True @@ -2154,7 +2151,7 @@ def snap_map_list(maps): maps[i].set_relative_time( start, start_next, maps[i].get_relative_time_unit() ) - else: + else: # noqa: PLR5501 if maps[i].is_time_absolute(): maps[i].set_absolute_time(start, end) elif maps[i].is_time_relative(): diff --git a/python/grass/temporal/aggregation.py b/python/grass/temporal/aggregation.py index 64b2c44d845..1ea60eaeea1 100644 --- a/python/grass/temporal/aggregation.py +++ b/python/grass/temporal/aggregation.py @@ -19,7 +19,7 @@ :author: Soeren Gebbert """ -import grass.script as gscript +import grass.script as gs from grass.exceptions import CalledModuleError from .core import get_current_mapset, get_tgis_message_interface, init_dbif @@ -145,7 +145,7 @@ def aggregate_raster_maps( # Check if new map is in the temporal database if new_map.is_in_db(dbif): - if gscript.overwrite() is True: + if gs.overwrite() is True: # Remove the existing temporal database entry new_map.delete(dbif) new_map = RasterDataset(map_id) @@ -167,7 +167,7 @@ def aggregate_raster_maps( ) # Create the r.series input file - filename = gscript.tempfile(True) + filename = gs.tempfile(True) file = open(filename, "w") for name in inputs: @@ -178,20 +178,20 @@ def aggregate_raster_maps( # Run r.series try: if len(inputs) > 1000: - gscript.run_command( + gs.run_command( "r.series", flags="z", file=filename, output=output, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), method=method, ) else: - gscript.run_command( + gs.run_command( "r.series", file=filename, output=output, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), method=method, ) @@ -205,7 +205,7 @@ def aggregate_raster_maps( # In case of a null map continue, do not register null maps if new_map.metadata.get_min() is None and new_map.metadata.get_max() is None: if not register_null: - gscript.run_command("g.remove", flags="f", type="raster", name=output) + gs.run_command("g.remove", flags="f", type="raster", name=output) return None return new_map @@ -364,7 +364,7 @@ def aggregate_by_topology( if len(aggregation_list) > 1: # Create the r.series input file - filename = gscript.tempfile(True) + filename = gs.tempfile(True) file = open(filename, "w") for name in aggregation_list: string = "%s\n" % (name) diff --git a/python/grass/temporal/base.py b/python/grass/temporal/base.py index a275fa1353f..f4175c77139 100644 --- a/python/grass/temporal/base.py +++ b/python/grass/temporal/base.py @@ -112,11 +112,10 @@ def serialize(self, type, table, where=None): sql += "?" else: sql += "%s" + elif self.dbmi_paramstyle == "qmark": + sql += " ,?" else: - if self.dbmi_paramstyle == "qmark": - sql += " ,?" - else: - sql += " ,%s" + sql += " ,%s" count += 1 args.append(self.D[key]) sql += ") " @@ -138,7 +137,7 @@ def serialize(self, type, table, where=None): else: sql += " %s " % key sql += "= %s " - else: + else: # noqa: PLR5501 if self.dbmi_paramstyle == "qmark": sql += " ,%s = ? " % key else: @@ -161,7 +160,7 @@ def serialize(self, type, table, where=None): else: sql += " %s " % key sql += "= %s " - else: + else: # noqa: PLR5501 if self.dbmi_paramstyle == "qmark": sql += " ,%s = ? " % key else: @@ -741,7 +740,7 @@ def set_ttype(self, ttype): :param ttype: The temporal type of the dataset "absolute or relative" """ - if ttype is None or (ttype != "absolute" and ttype != "relative"): + if ttype is None or (ttype not in {"absolute", "relative"}): self.D["temporal_type"] = "absolute" else: self.D["temporal_type"] = ttype diff --git a/python/grass/temporal/c_libraries_interface.py b/python/grass/temporal/c_libraries_interface.py index bd934c83b21..6b67dfb9869 100644 --- a/python/grass/temporal/c_libraries_interface.py +++ b/python/grass/temporal/c_libraries_interface.py @@ -80,8 +80,6 @@ def _read_map_full_info(lock, conn, data): info = _read_raster_full_info(name, mapset) elif maptype == RPCDefs.TYPE_VECTOR: info = _read_vector_full_info(name, mapset) - except: - raise finally: conn.send(info) @@ -295,8 +293,6 @@ def _get_database_name(lock, conn, data): dbstring = dbstring.replace(encode("$GISDBASE"), libgis.G_gisdbase()) dbstring = dbstring.replace(encode("$LOCATION_NAME"), libgis.G_location()) dbstring = dbstring.replace(encode("$MAPSET"), mapset) - except: - raise finally: conn.send(decode(dbstring)) @@ -353,8 +349,6 @@ def _available_mapsets(lock, conn, data): mapset_list.reverse() mapset_list.append(current_mapset) mapset_list.reverse() - except: - raise finally: conn.send(mapset_list) @@ -387,8 +381,6 @@ def _has_timestamp(lock, conn, data): elif maptype == RPCDefs.TYPE_RASTER3D: if libgis.G_has_raster3d_timestamp(name, mapset) == 1: check = True - except: - raise finally: conn.send(check) @@ -437,8 +429,6 @@ def _read_timestamp(lock, conn, data): check = libgis.G_read_raster3d_timestamp(name, mapset, byref(ts)) dates = _convert_timestamp_from_grass(ts) - except: - raise finally: conn.send((check, dates)) @@ -472,7 +462,9 @@ def _write_timestamp(lock, conn, data): check = libgis.G_scan_timestamp(byref(ts), timestring) if check != 1: - logging.error("Unable to convert the timestamp: " + timestring) + logging.error( + "Unable to convert the timestamp: {timestring}", timestring=timestring + ) return -2 if maptype == RPCDefs.TYPE_RASTER: @@ -481,8 +473,6 @@ def _write_timestamp(lock, conn, data): check = libgis.G_write_vector_timestamp(name, layer, byref(ts)) elif maptype == RPCDefs.TYPE_RASTER3D: check = libgis.G_write_raster3d_timestamp(name, byref(ts)) - except: - raise finally: conn.send(check) @@ -518,8 +508,6 @@ def _remove_timestamp(lock, conn, data): check = libgis.G_remove_vector_timestamp(name, layer, mapset) elif maptype == RPCDefs.TYPE_RASTER3D: check = libgis.G_remove_raster3d_timestamp(name, mapset) - except: - raise finally: conn.send(check) @@ -555,11 +543,10 @@ def _read_semantic_label(lock, conn, data): semantic_label = decode(ret) else: logging.error( - "Unable to read semantic label. Unsupported map type %s" % maptype + "Unable to read semantic label. Unsupported map type {maptype}", + maptype=maptype, ) return -1 - except: - raise finally: conn.send(semantic_label) @@ -592,11 +579,10 @@ def _write_semantic_label(lock, conn, data): libraster.Rast_write_semantic_label(name, semantic_label) else: logging.error( - "Unable to write semantic label. Unsupported map type %s" % maptype + "Unable to write semantic label. Unsupported map type {maptype}", + maptype=maptype, ) return -2 - except: - raise finally: conn.send(True) @@ -626,11 +612,10 @@ def _remove_semantic_label(lock, conn, data): check = libgis.G_remove_misc("cell_misc", "semantic_label", name) else: logging.error( - "Unable to remove semantic label. Unsupported map type %s" % maptype + "Unable to remove semantic label. Unsupported map type {maptype}", + maptype=maptype, ) return -2 - except: - raise finally: conn.send(check) @@ -663,8 +648,6 @@ def _map_exists(lock, conn, data): if mapset: check = True - except: - raise finally: conn.send(check) @@ -691,8 +674,6 @@ def _read_map_info(lock, conn, data): kvp = _read_vector_info(name, mapset) elif maptype == RPCDefs.TYPE_RASTER3D: kvp = _read_raster3d_info(name, mapset) - except: - raise finally: conn.send(kvp) @@ -1001,8 +982,6 @@ def _read_map_history(lock, conn, data): kvp = _read_vector_history(name, mapset) elif maptype == RPCDefs.TYPE_RASTER3D: kvp = _read_raster3d_history(name, mapset) - except: - raise finally: conn.send(kvp) @@ -1110,7 +1089,7 @@ def _read_vector_history(name, mapset): kvp["creation_time"] = decode(libvector.Vect_get_map_date(byref(Map))) kvp["creator"] = decode(libvector.Vect_get_person(byref(Map))) else: - None + kvp = None libvector.Vect_close(byref(Map)) return kvp diff --git a/python/grass/temporal/core.py b/python/grass/temporal/core.py index aad6fc4e2d4..0df95106e0f 100644 --- a/python/grass/temporal/core.py +++ b/python/grass/temporal/core.py @@ -33,7 +33,7 @@ # import traceback import os -import grass.script as gscript +import grass.script as gs from grass.pygrass import messages from grass.script.utils import decode @@ -62,7 +62,7 @@ def profile_function(func): """Profiling function provided by the temporal framework""" do_profiling = os.getenv("GRASS_TGIS_PROFILE") - if do_profiling == "True" or do_profiling == "1": + if do_profiling in {"True", "1"}: import cProfile import io import pstats @@ -454,8 +454,7 @@ def stop_subprocesses(): """Stop the messenger and C-interface subprocesses that are started by tgis.init() """ - global message_interface - global c_library_interface + global message_interface, c_library_interface if message_interface: message_interface.stop() if c_library_interface: @@ -473,8 +472,7 @@ def get_available_temporal_mapsets(): :returns: A dictionary, mapset names are keys, the tuple (driver, database) are the values """ - global c_library_interface - global message_interface + global c_library_interface, message_interface mapsets = c_library_interface.available_mapsets() @@ -562,24 +560,18 @@ def init(raise_fatal_error=False, skip_db_version_check=False): """ # We need to set the correct database backend and several global variables # from the GRASS mapset specific environment variables of g.gisenv and t.connect - global tgis_backend - global tgis_database - global tgis_database_string - global tgis_dbmi_paramstyle - global tgis_db_version - global raise_on_error - global enable_mapset_check - global enable_timestamp_write - global current_mapset - global current_location - global current_gisdbase + global tgis_backend, tgis_database, tgis_database_string # noqa: FURB154 + global tgis_dbmi_paramstyle, tgis_db_version # noqa: FURB154 + global raise_on_error # noqa: FURB154 + global enable_mapset_check, enable_timestamp_write # noqa: FURB154 + global current_mapset, current_location, current_gisdbase # noqa: FURB154 raise_on_error = raise_fatal_error # We must run t.connect at first to create the temporal database and to # get the environmental variables - gscript.run_command("t.connect", flags="c") - grassenv = gscript.gisenv() + gs.run_command("t.connect", flags="c") + grassenv = gs.gisenv() # Set the global variable for faster access current_mapset = grassenv["MAPSET"] @@ -595,7 +587,7 @@ def init(raise_fatal_error=False, skip_db_version_check=False): # Check if the script library raises on error, # if so we do the same - if gscript.get_raise_on_error() is True: + if gs.get_raise_on_error() is True: raise_on_error = True # Start the GRASS message interface server @@ -614,16 +606,16 @@ def init(raise_fatal_error=False, skip_db_version_check=False): # Set the mapset check and the timestamp write if "TGIS_DISABLE_MAPSET_CHECK" in grassenv: if ( - gscript.encode(grassenv["TGIS_DISABLE_MAPSET_CHECK"]) == "True" - or gscript.encode(grassenv["TGIS_DISABLE_MAPSET_CHECK"]) == "1" + gs.encode(grassenv["TGIS_DISABLE_MAPSET_CHECK"]) == "True" + or gs.encode(grassenv["TGIS_DISABLE_MAPSET_CHECK"]) == "1" ): enable_mapset_check = False msgr.warning("TGIS_DISABLE_MAPSET_CHECK is True") if "TGIS_DISABLE_TIMESTAMP_WRITE" in grassenv: if ( - gscript.encode(grassenv["TGIS_DISABLE_TIMESTAMP_WRITE"]) == "True" - or gscript.encode(grassenv["TGIS_DISABLE_TIMESTAMP_WRITE"]) == "1" + gs.encode(grassenv["TGIS_DISABLE_TIMESTAMP_WRITE"]) == "True" + or gs.encode(grassenv["TGIS_DISABLE_TIMESTAMP_WRITE"]) == "1" ): enable_timestamp_write = False msgr.warning("TGIS_DISABLE_TIMESTAMP_WRITE is True") @@ -662,7 +654,7 @@ def init(raise_fatal_error=False, skip_db_version_check=False): ) else: # Set the default sqlite3 connection in case nothing was defined - gscript.run_command("t.connect", flags="d") + gs.run_command("t.connect", flags="d") driver_string = ciface.get_driver_name() database_string = ciface.get_database_name() tgis_backend = driver_string @@ -846,10 +838,7 @@ def create_temporal_database(dbif): :param dbif: The database interface to be used """ - global tgis_backend - global tgis_version - global tgis_db_version - global tgis_database_string + global tgis_backend, tgis_version, tgis_db_version, tgis_database_string template_path = get_sql_template_path() msgr = get_tgis_message_interface() @@ -977,8 +966,7 @@ def upgrade_temporal_database(dbif): :param dbif: The database interface to be used """ - global tgis_database_string - global tgis_db_version + global tgis_database_string, tgis_db_version metadata = get_tgis_metadata(dbif) @@ -1279,7 +1267,7 @@ def __init__(self, backend=None, dbstring=None): self.dbmi = sqlite3 else: self.dbmi = psycopg2 - else: + else: # noqa: PLR5501 if decode(backend) == "sqlite": self.dbmi = sqlite3 else: @@ -1414,18 +1402,17 @@ def mogrify_sql_statement(self, content): if self.dbmi.__name__ == "psycopg2": if len(args) == 0: return sql + elif self.connected: + try: + return self.cursor.mogrify(sql, args) + except Exception as exc: + print(sql, args) + raise exc else: - if self.connected: - try: - return self.cursor.mogrify(sql, args) - except Exception as exc: - print(sql, args) - raise exc - else: - self.connect() - statement = self.cursor.mogrify(sql, args) - self.close() - return statement + self.connect() + statement = self.cursor.mogrify(sql, args) + self.close() + return statement elif self.dbmi.__name__ == "sqlite3": if len(args) == 0: diff --git a/python/grass/temporal/datetime_math.py b/python/grass/temporal/datetime_math.py index 9924284ed9b..3d4b2869854 100644 --- a/python/grass/temporal/datetime_math.py +++ b/python/grass/temporal/datetime_math.py @@ -242,7 +242,7 @@ def modify_datetime_by_string(mydate, increment, mult=1, sign=1): :return: The new datetime object or none in case of an error """ sign = int(sign) - if sign != 1 and sign != -1: + if sign not in {1, -1}: return None if increment: @@ -323,10 +323,7 @@ def modify_datetime( if residual_months == 0: residual_months = 1 - try: - dt1 = dt1.replace(year=year + years_to_add, month=residual_months) - except: - raise + dt1 = dt1.replace(year=year + years_to_add, month=residual_months) tdelta_months = dt1 - mydate elif months < 0: @@ -350,10 +347,7 @@ def modify_datetime( if residual_months <= 0: residual_months += 12 - try: - dt1 = dt1.replace(year=year - years_to_remove, month=residual_months) - except: - raise + dt1 = dt1.replace(year=year - years_to_remove, month=residual_months) tdelta_months = dt1 - mydate @@ -823,7 +817,7 @@ def check_datetime_string(time_string, use_dateutil=True): time_format = "%Y-%m-%dT%H:%M:%S.%f" else: time_format = "%Y-%m-%d %H:%M:%S.%f" - else: + else: # noqa: PLR5501 if "T" in time_string: time_format = "%Y-%m-%dT%H:%M:%S" else: diff --git a/python/grass/temporal/extract.py b/python/grass/temporal/extract.py index b96ce622540..94a4fd0f1c9 100644 --- a/python/grass/temporal/extract.py +++ b/python/grass/temporal/extract.py @@ -12,7 +12,7 @@ import sys from multiprocessing import Process -import grass.script as gscript +import grass.script as gs from grass.exceptions import CalledModuleError from .abstract_map_dataset import AbstractMapDataset @@ -84,7 +84,7 @@ def extract_dataset( sp = open_old_stds(input, type, dbif) # Check the new stds - new_sp = check_new_stds(output, type, dbif, gscript.overwrite()) + new_sp = check_new_stds(output, type, dbif, gs.overwrite()) if type == "vector": rows = sp.get_registered_maps("id,name,mapset,layer", where, "start_time", dbif) else: @@ -140,7 +140,7 @@ def extract_dataset( # Check if new map is in the temporal database if new_map.is_in_db(dbif): - if gscript.overwrite(): + if gs.overwrite(): # Remove the existing temporal database entry new_map.delete(dbif) new_map = sp.get_new_map_instance(map_id) @@ -224,7 +224,7 @@ def extract_dataset( description, semantic_type, dbif, - gscript.overwrite(), + gs.overwrite(), ) # collect empty maps to remove them @@ -251,7 +251,7 @@ def extract_dataset( # In case of a empty map continue, do not register empty # maps - if type == "raster" or type == "raster3d": + if type in {"raster", "raster3d"}: if ( new_map.metadata.get_min() is None and new_map.metadata.get_max() is None @@ -300,15 +300,15 @@ def extract_dataset( names += ",%s" % (map.get_name()) count += 1 if type == "raster": - gscript.run_command( + gs.run_command( "g.remove", flags="f", type="raster", name=names, quiet=True ) elif type == "raster3d": - gscript.run_command( + gs.run_command( "g.remove", flags="f", type="raster_3d", name=names, quiet=True ) elif type == "vector": - gscript.run_command( + gs.run_command( "g.remove", flags="f", type="vector", name=names, quiet=True ) @@ -321,8 +321,8 @@ def extract_dataset( def run_mapcalc2d(expr): """Helper function to run r.mapcalc in parallel""" try: - gscript.run_command( - "r.mapcalc", expression=expr, overwrite=gscript.overwrite(), quiet=True + gs.run_command( + "r.mapcalc", expression=expr, overwrite=gs.overwrite(), quiet=True ) except CalledModuleError: sys.exit(1) @@ -331,8 +331,8 @@ def run_mapcalc2d(expr): def run_mapcalc3d(expr): """Helper function to run r3.mapcalc in parallel""" try: - gscript.run_command( - "r3.mapcalc", expression=expr, overwrite=gscript.overwrite(), quiet=True + gs.run_command( + "r3.mapcalc", expression=expr, overwrite=gs.overwrite(), quiet=True ) except CalledModuleError: sys.exit(1) @@ -341,14 +341,14 @@ def run_mapcalc3d(expr): def run_vector_extraction(input, output, layer, type, where): """Helper function to run r.mapcalc in parallel""" try: - gscript.run_command( + gs.run_command( "v.extract", input=input, output=output, layer=layer, type=type, where=where, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), quiet=True, ) except CalledModuleError: diff --git a/python/grass/temporal/factory.py b/python/grass/temporal/factory.py index b4aec29f7fa..ba7f5e7d4f0 100644 --- a/python/grass/temporal/factory.py +++ b/python/grass/temporal/factory.py @@ -44,11 +44,11 @@ def dataset_factory(type, id): sp = SpaceTimeRaster3DDataset(id) elif type == "stvds": sp = SpaceTimeVectorDataset(id) - elif type == "rast" or type == "raster": + elif type in {"rast", "raster"}: sp = RasterDataset(id) - elif type == "raster_3d" or type == "rast3d" or type == "raster3d": + elif type in {"raster_3d", "rast3d", "raster3d"}: sp = Raster3DDataset(id) - elif type == "vect" or type == "vector": + elif type in {"vect", "vector"}: sp = VectorDataset(id) else: msgr = get_tgis_message_interface() diff --git a/python/grass/temporal/gui_support.py b/python/grass/temporal/gui_support.py index aa4bf44c008..41f22edc6b7 100644 --- a/python/grass/temporal/gui_support.py +++ b/python/grass/temporal/gui_support.py @@ -10,7 +10,7 @@ :authors: Soeren Gebbert """ -import grass.script as gscript +import grass.script as gs from .core import get_available_temporal_mapsets, init_dbif from .factory import dataset_factory @@ -47,15 +47,15 @@ def tlist_grouped(type, group_type=False, dbif=None): for type in types: try: tlist_result = tlist(type=type, dbif=dbif) - except gscript.ScriptError as e: - gscript.warning(e) + except gs.ScriptError as e: + gs.warning(e) continue for line in tlist_result: try: name, mapset = line.split("@") except ValueError: - gscript.warning(_("Invalid element '%s'") % line) + gs.warning(_("Invalid element '%s'") % line) continue if mapset not in result: diff --git a/python/grass/temporal/list_stds.py b/python/grass/temporal/list_stds.py index bb0823995da..9f6b6867766 100644 --- a/python/grass/temporal/list_stds.py +++ b/python/grass/temporal/list_stds.py @@ -438,12 +438,11 @@ def check_columns(column_names, output_format, element_type): output_format=output_format, element_type=element_type, ) + elif output_format == "line": + # For list of values, only one column is needed. + columns = ["id"] else: - if output_format == "line": - # For list of values, only one column is needed. - columns = ["id"] - else: - columns = ["name", "mapset", "start_time", "end_time"] + columns = ["name", "mapset", "start_time", "end_time"] if not order: order = "start_time" diff --git a/python/grass/temporal/mapcalc.py b/python/grass/temporal/mapcalc.py index 99f6d16670c..5f29cd32747 100644 --- a/python/grass/temporal/mapcalc.py +++ b/python/grass/temporal/mapcalc.py @@ -14,7 +14,7 @@ from datetime import datetime from multiprocessing import Process -import grass.script as gscript +import grass.script as gs from grass.exceptions import CalledModuleError from .core import ( @@ -127,7 +127,7 @@ def dataset_mapcalculator( sp = open_old_stds(input, type, dbif) input_list.append(copy.copy(sp)) - new_sp = check_new_stds(output, type, dbif, gscript.overwrite()) + new_sp = check_new_stds(output, type, dbif, gs.overwrite()) # Sample all inputs by the first input and create a sample matrix if spatial: @@ -241,7 +241,7 @@ def dataset_mapcalculator( # Create the r.mapcalc statement for the current time step map_name = "{base}_{suffix}".format( - base=base, suffix=gscript.get_num_suffix(count, num) + base=base, suffix=gs.get_num_suffix(count, num) ) # Remove spaces and new lines expr = expression.replace(" ", "") @@ -269,7 +269,7 @@ def dataset_mapcalculator( # Check if new map is in the temporal database if new_map.is_in_db(dbif): - if gscript.overwrite(): + if gs.overwrite(): # Remove the existing temporal database entry new_map.delete(dbif) new_map = first_input.get_new_map_instance(map_id) @@ -312,7 +312,7 @@ def dataset_mapcalculator( proc_list[proc_count].start() proc_count += 1 - if proc_count == nprocs or proc_count == num or count == num: + if proc_count in {nprocs, num} or count == num: proc_count = 0 exitcodes = 0 for proc in proc_list: @@ -344,7 +344,7 @@ def dataset_mapcalculator( description, semantic_type, dbif, - gscript.overwrite(), + gs.overwrite(), ) count = 0 @@ -394,11 +394,11 @@ def dataset_mapcalculator( names += ",%s" % (map.get_name()) count += 1 if type == "raster": - gscript.run_command( + gs.run_command( "g.remove", flags="f", type="raster", name=names, quiet=True ) elif type == "raster3d": - gscript.run_command( + gs.run_command( "g.remove", flags="f", type="raster_3d", name=names, quiet=True ) @@ -411,8 +411,8 @@ def dataset_mapcalculator( def _run_mapcalc2d(expr): """Helper function to run r.mapcalc in parallel""" try: - gscript.run_command( - "r.mapcalc", expression=expr, overwrite=gscript.overwrite(), quiet=True + gs.run_command( + "r.mapcalc", expression=expr, overwrite=gs.overwrite(), quiet=True ) except CalledModuleError: sys.exit(1) @@ -424,8 +424,8 @@ def _run_mapcalc2d(expr): def _run_mapcalc3d(expr): """Helper function to run r3.mapcalc in parallel""" try: - gscript.run_command( - "r3.mapcalc", expression=expr, overwrite=gscript.overwrite(), quiet=True + gs.run_command( + "r3.mapcalc", expression=expr, overwrite=gs.overwrite(), quiet=True ) except CalledModuleError: sys.exit(1) @@ -481,9 +481,7 @@ def _operator_parser(expr, first, current): expr = _parse_start_time_operator(expr, is_time_absolute, first, current) expr = _parse_end_time_operator(expr, is_time_absolute, first, current) expr = _parse_start_operators(expr, is_time_absolute, current) - expr = _parse_end_operators(expr, is_time_absolute, current) - - return expr + return _parse_end_operators(expr, is_time_absolute, current) ############################################################################### diff --git a/python/grass/temporal/open_stds.py b/python/grass/temporal/open_stds.py index 75d1c1eb075..f17288695e3 100644 --- a/python/grass/temporal/open_stds.py +++ b/python/grass/temporal/open_stds.py @@ -58,18 +58,13 @@ def open_old_stds(name, type, dbif=None): msgr.fatal("Invalid name of the space time dataset. Only one dot allowed.") id = name + "@" + mapset - if type == "strds" or type == "rast" or type == "raster": + if type in {"strds", "rast", "raster"}: sp = dataset_factory("strds", id) if semantic_label: sp.set_semantic_label(semantic_label) - elif ( - type == "str3ds" - or type == "raster3d" - or type == "rast3d" - or type == "raster_3d" - ): + elif type in {"str3ds", "raster3d", "rast3d", "raster_3d"}: sp = dataset_factory("str3ds", id) - elif type == "stvds" or type == "vect" or type == "vector": + elif type in {"stvds", "vect", "vector"}: sp = dataset_factory("stvds", id) else: msgr.fatal(_("Unknown type: %s") % (type)) @@ -123,21 +118,16 @@ def check_new_stds(name, type, dbif=None, overwrite=False): ) id = name - if type == "strds" or type == "rast" or type == "raster": + if type in {"strds", "rast", "raster"}: if name.find(".") > -1: # a dot is used as a separator for semantic label filtering msgr.fatal( _("Illegal dataset name <{}>. Character '.' not allowed.").format(name) ) sp = dataset_factory("strds", id) - elif ( - type == "str3ds" - or type == "raster3d" - or type == "rast3d " - or type == "raster_3d" - ): + elif type in {"str3ds", "raster3d", "rast3d ", "raster_3d"}: sp = dataset_factory("str3ds", id) - elif type == "stvds" or type == "vect" or type == "vector": + elif type in {"stvds", "vect", "vector"}: sp = dataset_factory("stvds", id) else: msgr.error(_("Unknown type: %s") % (type)) diff --git a/python/grass/temporal/spatial_extent.py b/python/grass/temporal/spatial_extent.py index 4f6ecb8280c..6c025fb7a40 100644 --- a/python/grass/temporal/spatial_extent.py +++ b/python/grass/temporal/spatial_extent.py @@ -183,11 +183,11 @@ def overlapping_2d(self, extent): # Adjust the east and west in case of LL projection if self.get_projection() == "LL": - while E < self.get_west(): + while self.get_west() > E: E += 360.0 W += 360.0 - while W > self.get_east(): + while self.get_east() < W: E -= 360.0 W -= 360.0 @@ -285,16 +285,16 @@ def intersect_2d(self, extent): nE = E nW = W - if W < eW: + if eW > W: nW = eW - if E > eE: + if eE < E: nE = eE - if N > eN: + if eN < N: nN = eN - if S < eS: + if eS > S: nS = eS - new = SpatialExtent( + return SpatialExtent( north=nN, south=nS, east=nE, @@ -303,7 +303,6 @@ def intersect_2d(self, extent): bottom=0, proj=self.get_projection(), ) - return new def intersect(self, extent): """Return the three dimensional intersection as spatial_extent @@ -396,9 +395,9 @@ def intersect(self, extent): nT = T nB = B - if B < eB: + if eB > B: nB = eB - if T > eT: + if eT < T: nT = eT new.set_top(nT) @@ -450,16 +449,16 @@ def disjoint_union_2d(self, extent): nE = E nW = W - if W > eW: + if eW < W: nW = eW - if E < eE: + if eE > E: nE = eE - if N < eN: + if eN > N: nN = eN - if S > eS: + if eS < S: nS = eS - new = SpatialExtent( + return SpatialExtent( north=nN, south=nS, east=nE, @@ -468,7 +467,6 @@ def disjoint_union_2d(self, extent): bottom=0, proj=self.get_projection(), ) - return new def union(self, extent): """Return the three dimensional union as spatial_extent @@ -584,9 +582,9 @@ def disjoint_union(self, extent): nT = T nB = B - if B > eB: + if eB < B: nB = eB - if T < eT: + if eT > T: nT = eT new.set_top(nT) @@ -638,13 +636,13 @@ def is_in_2d(self, extent): eE -= 360.0 eW -= 360.0 - if W <= eW: + if eW >= W: return False - if E >= eE: + if eE <= E: return False - if N >= eN: + if eN <= N: return False - if S <= eS: + if eS >= S: return False return True @@ -680,9 +678,9 @@ def is_in(self, extent): T = self.get_top() B = self.get_bottom() - if B <= eB: + if eB >= B: return False - if T >= eT: + if eT <= T: return False return True @@ -778,13 +776,13 @@ def equivalent_2d(self, extent): eE -= 360.0 eW -= 360.0 - if W != eW: + if eW != W: return False - if E != eE: + if eE != E: return False - if N != eN: + if eN != N: return False - if S != eS: + if eS != S: return False return True @@ -821,9 +819,9 @@ def equivalent(self, extent): T = self.get_top() B = self.get_bottom() - if B != eB: + if eB != B: return False - if T != eT: + if eT != T: return False return True @@ -894,28 +892,28 @@ def cover_2d(self, extent): eW -= 360.0 # Edges of extent located outside of self are not allowed - if E <= eW: + if eW >= E: return False - if W >= eE: + if eE <= W: return False - if N <= eS: + if eS >= N: return False - if S >= eN: + if eN <= S: return False # First we check that at least one edge of extent meets an edge of self - if W != eW and E != eE and N != eN and S != eS: + if eW != W and eE != E and eN != N and eS != S: return False # We check that at least one edge of extent is located in self edge_count = 0 - if W < eW and E > eW: + if eW > W and eW < E: edge_count += 1 - if E > eE and W < eE: + if eE < E and eE > W: edge_count += 1 - if N > eN and S < eN: + if eN < N and eN > S: edge_count += 1 - if S < eS and N > eS: + if eS > S and eS < N: edge_count += 1 if edge_count == 0: @@ -976,40 +974,40 @@ def cover(self, extent): eW -= 360.0 # Edges of extent located outside of self are not allowed - if E <= eW: + if eW >= E: return False - if W >= eE: + if eE <= W: return False - if N <= eS: + if eS >= N: return False - if S >= eN: + if eN <= S: return False - if T <= eB: + if eB >= T: return False - if B >= eT: + if eT <= B: return False # First we check that at least one edge of extent meets an edge of self - if W != eW and E != eE and N != eN and S != eS and B != eB and T != eT: + if eW != W and eE != E and eN != N and eS != S and eB != B and eT != T: return False # We check that at least one edge of extent is located in self edge_count = 0 - if W < eW and E > eW: + if eW > W and eW < E: edge_count += 1 - if E > eE and W < eE: + if eE < E and eE > W: edge_count += 1 - if N > eN and S < eN: + if eN < N and eN > S: edge_count += 1 - if S < eS and N > eS: + if eS > S and eS < N: edge_count += 1 - if N > eN and S < eN: + if eN < N and eN > S: edge_count += 1 - if S < eS and N > eS: + if eS > S and eS < N: edge_count += 1 - if T > eT and B < eT: + if eT < T and eT > B: edge_count += 1 - if B < eB and T > eB: + if eB > B and eB < T: edge_count += 1 if edge_count == 0: @@ -1097,11 +1095,11 @@ def overlap_2d(self, extent): # Adjust the east and west in case of LL projection if self.get_projection() == "LL": - while E < self.get_west(): + while self.get_west() > E: E += 360.0 W += 360.0 - while W > self.get_east(): + while self.get_east() < W: E -= 360.0 W -= 360.0 @@ -1159,11 +1157,11 @@ def overlap(self, extent): # Adjust the east and west in case of LL projection if self.get_projection() == "LL": - while E < self.get_west(): + while self.get_west() > E: E += 360.0 W += 360.0 - while W > self.get_east(): + while self.get_east() < W: E -= 360.0 W -= 360.0 @@ -1244,16 +1242,16 @@ def meet_2d(self, extent): edge = None edge_count = 0 - if E == eW: + if eW == E: edge = "E" edge_count += 1 - if W == eE: + if eE == W: edge = "W" edge_count += 1 - if N == eS: + if eS == N: edge = "N" edge_count += 1 - if S == eN: + if eN == S: edge = "S" edge_count += 1 @@ -1262,12 +1260,12 @@ def meet_2d(self, extent): return False # Check boundaries of the faces - if edge == "E" or edge == "W": - if N < eS or S > eN: + if edge in {"E", "W"}: + if eS > N or eN < S: return False - if edge == "N" or edge == "S": - if E < eW or W > eE: + if edge in {"N", "S"}: + if eW > E or eE < W: return False return True @@ -1308,22 +1306,22 @@ def meet(self, extent): edge = None edge_count = 0 - if E == eW: + if eW == E: edge = "E" edge_count += 1 - if W == eE: + if eE == W: edge = "W" edge_count += 1 - if N == eS: + if eS == N: edge = "N" edge_count += 1 - if S == eN: + if eN == S: edge = "S" edge_count += 1 - if T == eB: + if eB == T: edge = "T" edge_count += 1 - if B == eT: + if eT == B: edge = "B" edge_count += 1 @@ -1332,22 +1330,22 @@ def meet(self, extent): return False # Check boundaries of the faces - if edge == "E" or edge == "W": - if N < eS or S > eN: + if edge in {"E", "W"}: + if eS > N or eN < S: return False - if T < eB or B > eT: + if eB > T or eT < B: return False - if edge == "N" or edge == "S": - if E < eW or W > eE: + if edge in {"N", "S"}: + if eW > E or eE < W: return False - if T < eB or B > eT: + if eB > T or eT < B: return False - if edge == "T" or edge == "B": - if E < eW or W > eE: + if edge in {"T", "B"}: + if eW > E or eE < W: return False - if N < eS or S > eN: + if eS > N or eN < S: return False return True @@ -1806,7 +1804,7 @@ def set_projection(self, proj): """Set the projection of the spatial extent it should be XY or LL. As default the projection is XY """ - if proj is None or (proj != "XY" and proj != "LL"): + if proj is None or (proj not in {"XY", "LL"}): self.D["proj"] = "XY" else: self.D["proj"] = proj diff --git a/python/grass/temporal/spatio_temporal_relationships.py b/python/grass/temporal/spatio_temporal_relationships.py index 04fc4e58b8e..d22bc2bb0da 100644 --- a/python/grass/temporal/spatio_temporal_relationships.py +++ b/python/grass/temporal/spatio_temporal_relationships.py @@ -620,7 +620,7 @@ def __contains__(self, _map): def set_temoral_relationship(A, B, relation): - if relation == "equal" or relation == "equals": + if relation in {"equal", "equals"}: if A != B: if not B.get_equal() or (B.get_equal() and A not in B.get_equal()): B.append_equal(A) @@ -636,7 +636,7 @@ def set_temoral_relationship(A, B, relation): B.append_precedes(A) if not A.get_follows() or (A.get_follows() and B not in A.get_follows()): A.append_follows(B) - elif relation == "during" or relation == "starts" or relation == "finishes": + elif relation in {"during", "starts", "finishes"}: if not B.get_during() or (B.get_during() and A not in B.get_during()): B.append_during(A) if not A.get_contains() or (A.get_contains() and B not in A.get_contains()): @@ -651,7 +651,7 @@ def set_temoral_relationship(A, B, relation): B.append_finishes(A) if not A.get_finished() or (A.get_finished() and B not in A.get_finished()): A.append_finished(B) - elif relation == "contains" or relation == "started" or relation == "finished": + elif relation in {"contains", "started", "finished"}: if not B.get_contains() or (B.get_contains() and A not in B.get_contains()): B.append_contains(A) if not A.get_during() or (A.get_during() and B not in A.get_during()): diff --git a/python/grass/temporal/stds_export.py b/python/grass/temporal/stds_export.py index 0e2c7f7e216..f2fdd7ca9bf 100644 --- a/python/grass/temporal/stds_export.py +++ b/python/grass/temporal/stds_export.py @@ -30,7 +30,7 @@ import tarfile import tempfile -import grass.script as gscript +import grass.script as gs from grass.exceptions import CalledModuleError from .open_stds import open_old_stds @@ -82,7 +82,7 @@ def _export_raster_maps_as_gdal( gdal_type = "UInt32" else: gdal_type = "Int32" - gscript.run_command( + gs.run_command( "r.out.gdal", flags="c", input=name, @@ -93,7 +93,7 @@ def _export_raster_maps_as_gdal( **kwargs, ) elif type_: - gscript.run_command( + gs.run_command( "r.out.gdal", flags="cf", input=name, @@ -103,7 +103,7 @@ def _export_raster_maps_as_gdal( **kwargs, ) else: - gscript.run_command( + gs.run_command( "r.out.gdal", flags="c", input=name, @@ -114,7 +114,7 @@ def _export_raster_maps_as_gdal( elif format_ == "AAIGrid": # Export the raster map with r.out.gdal as Arc/Info ASCII Grid out_name = name + ".asc" - gscript.run_command( + gs.run_command( "r.out.gdal", flags="c", input=name, @@ -126,18 +126,18 @@ def _export_raster_maps_as_gdal( except CalledModuleError: shutil.rmtree(new_cwd) tar.close() - gscript.fatal(_("Unable to export raster map <%s>" % name)) + gs.fatal(_("Unable to export raster map <%s>" % name)) tar.add(out_name) # Export the color rules out_name = name + ".color" try: - gscript.run_command("r.colors.out", map=name, rules=out_name) + gs.run_command("r.colors.out", map=name, rules=out_name) except CalledModuleError: shutil.rmtree(new_cwd) tar.close() - gscript.fatal( + gs.fatal( _( "Unable to export color rules for raster " "map <%s> r.out.gdal" % name @@ -163,11 +163,11 @@ def _export_raster_maps(rows, tar, list_file, new_cwd, fs): list_file.write(string) # Export the raster map with r.pack try: - gscript.run_command("r.pack", input=name, flags="c") + gs.run_command("r.pack", input=name, flags="c") except CalledModuleError: shutil.rmtree(new_cwd) tar.close() - gscript.fatal(_("Unable to export raster map <%s> with r.pack" % name)) + gs.fatal(_("Unable to export raster map <%s> with r.pack" % name)) tar.add(name + ".pack") @@ -190,7 +190,7 @@ def _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs): list_file.write(string) # Export the vector map with v.out.ogr try: - gscript.run_command( + gs.run_command( "v.out.ogr", input=name, output=(name + ".xml"), @@ -200,9 +200,7 @@ def _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs): except CalledModuleError: shutil.rmtree(new_cwd) tar.close() - gscript.fatal( - _("Unable to export vector map <%s> as GML with v.out.ogr" % name) - ) + gs.fatal(_("Unable to export vector map <%s> as GML with v.out.ogr" % name)) tar.add(name + ".xml") tar.add(name + ".xsd") @@ -226,7 +224,7 @@ def _export_vector_maps_as_gpkg(rows, tar, list_file, new_cwd, fs): list_file.write(string) # Export the vector map with v.out.ogr try: - gscript.run_command( + gs.run_command( "v.out.ogr", input=name, output=(name + ".gpkg"), @@ -236,7 +234,7 @@ def _export_vector_maps_as_gpkg(rows, tar, list_file, new_cwd, fs): except CalledModuleError: shutil.rmtree(new_cwd) tar.close() - gscript.fatal( + gs.fatal( _("Unable to export vector map <%s> as GPKG with v.out.ogr" % name) ) @@ -266,11 +264,11 @@ def _export_vector_maps(rows, tar, list_file, new_cwd, fs): list_file.write(string) # Export the vector map with v.pack try: - gscript.run_command("v.pack", input=name, flags="c") + gs.run_command("v.pack", input=name, flags="c") except CalledModuleError: shutil.rmtree(new_cwd) tar.close() - gscript.fatal(_("Unable to export vector map <%s> with v.pack" % name)) + gs.fatal(_("Unable to export vector map <%s> with v.pack" % name)) tar.add(name + ".pack") @@ -292,11 +290,11 @@ def _export_raster3d_maps(rows, tar, list_file, new_cwd, fs): list_file.write(string) # Export the raster 3d map with r3.pack try: - gscript.run_command("r3.pack", input=name, flags="c") + gs.run_command("r3.pack", input=name, flags="c") except CalledModuleError: shutil.rmtree(new_cwd) tar.close() - gscript.fatal(_("Unable to export raster map <%s> with r3.pack" % name)) + gs.fatal(_("Unable to export raster map <%s> with r3.pack" % name)) tar.add(name + ".pack") @@ -383,7 +381,7 @@ def export_stds( if rows: if type_ == "strds": - if format_ == "GTiff" or format_ == "AAIGrid": + if format_ in {"GTiff", "AAIGrid"}: _export_raster_maps_as_gdal( rows, tar, list_file, new_cwd, fs, format_, datatype, **kwargs ) @@ -402,7 +400,7 @@ def export_stds( list_file.close() # Write projection and metadata - proj = gscript.read_command("g.proj", flags="j") + proj = gs.read_command("g.proj", flags="j") proj_file = open(proj_file_name, "w") proj_file.write(proj) @@ -432,7 +430,7 @@ def export_stds( init_file.write(string) init_file.close() - metadata = gscript.read_command("t.info", type=type_, input=sp.get_id()) + metadata = gs.read_command("t.info", type=type_, input=sp.get_id()) metadata_file = open(metadata_file_name, "w") metadata_file.write(metadata) metadata_file.close() diff --git a/python/grass/temporal/stds_import.py b/python/grass/temporal/stds_import.py index 98a41518c1f..e8684d9ecb4 100644 --- a/python/grass/temporal/stds_import.py +++ b/python/grass/temporal/stds_import.py @@ -33,7 +33,7 @@ import os.path import tarfile -import grass.script as gscript +import grass.script as gs from grass.exceptions import CalledModuleError from .core import get_current_mapset, get_tgis_message_interface @@ -71,25 +71,25 @@ def _import_raster_maps_from_gdal( try: if link: - gscript.run_command( + gs.run_command( "r.external", input=filename, output=name, flags=impflags, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), ) else: - gscript.run_command( + gs.run_command( "r.in.gdal", input=filename, output=name, memory=memory, flags=impflags, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), ) except CalledModuleError: - gscript.fatal( + gs.fatal( _("Unable to import/link raster map <%s> from file %s.") % (name, filename) ) @@ -98,17 +98,15 @@ def _import_raster_maps_from_gdal( filename = row["filename"] + ".color" if os.path.isfile(filename): try: - gscript.run_command( - "r.colors", map=name, rules=filename, overwrite=gscript.overwrite() + gs.run_command( + "r.colors", map=name, rules=filename, overwrite=gs.overwrite() ) except CalledModuleError: - gscript.fatal( - _("Unable to set the color rules for raster map <%s>.") % name - ) + gs.fatal(_("Unable to set the color rules for raster map <%s>.") % name) # Set the computational region from the last map imported if set_current_region is True: - gscript.run_command("g.region", raster=name) + gs.run_command("g.region", raster=name) ############################################################################ @@ -122,23 +120,23 @@ def _import_raster_maps(maplist, set_current_region=False): name = row["name"] filename = row["filename"] + ".pack" try: - gscript.run_command( + gs.run_command( "r.unpack", input=filename, output=name, flags=impflags, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), verbose=True, ) except CalledModuleError: - gscript.fatal( + gs.fatal( _("Unable to unpack raster map <%s> from file %s.") % (name, filename) ) # Set the computational region from the last map imported if set_current_region is True: - gscript.run_command("g.region", raster=name) + gs.run_command("g.region", raster=name) ############################################################################ @@ -153,16 +151,16 @@ def _import_vector_maps_from_gml(maplist, overr, exp, location, link): filename = row["filename"] + ".xml" try: - gscript.run_command( + gs.run_command( "v.in.ogr", input=filename, output=name, flags=impflags, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), ) except CalledModuleError: - gscript.fatal( + gs.fatal( _("Unable to import vector map <%s> from file %s.") % (name, filename) ) @@ -182,17 +180,17 @@ def _import_vector_maps(maplist): continue filename = row["filename"] + ".pack" try: - gscript.run_command( + gs.run_command( "v.unpack", input=filename, output=name, flags=impflags, - overwrite=gscript.overwrite(), + overwrite=gs.overwrite(), verbose=True, ) except CalledModuleError: - gscript.fatal( + gs.fatal( _("Unable to unpack vector map <%s> from file %s.") % (name, filename) ) @@ -241,14 +239,14 @@ def import_stds( :param memory: Cache size for raster rows, used in r.in.gdal """ - old_state = gscript.raise_on_error - gscript.set_raise_on_error(True) + old_state = gs.raise_on_error + gs.set_raise_on_error(True) # Check if input file and extraction directory exits if not os.path.exists(input): - gscript.fatal(_("Space time raster dataset archive <%s> not found") % input) + gs.fatal(_("Space time raster dataset archive <%s> not found") % input) if not create and not os.path.exists(directory): - gscript.fatal(_("Extraction directory <%s> not found") % directory) + gs.fatal(_("Extraction directory <%s> not found") % directory) tar = tarfile.open(name=input, mode="r") @@ -265,11 +263,11 @@ def import_stds( member_basenames = [os.path.basename(name) for name in members] if init_file_name not in member_basenames: - gscript.fatal(_("Unable to find init file <%s>") % init_file_name) + gs.fatal(_("Unable to find init file <%s>") % init_file_name) if list_file_name not in member_basenames: - gscript.fatal(_("Unable to find list file <%s>") % list_file_name) + gs.fatal(_("Unable to find list file <%s>") % list_file_name) if proj_file_name not in member_basenames: - gscript.fatal(_("Unable to find projection file <%s>") % proj_file_name) + gs.fatal(_("Unable to find projection file <%s>") % proj_file_name) msgr.message(_("Extracting data...")) # Extraction filters were added in Python 3.12, @@ -282,7 +280,7 @@ def import_stds( tar.extractall(path=directory, filter="data") else: # Remove this when no longer needed - gscript.warning(_("Extracting may be unsafe; consider updating Python")) + gs.warning(_("Extracting may be unsafe; consider updating Python")) tar.extractall(path=directory) tar.close() @@ -296,7 +294,7 @@ def import_stds( # Check projection information if not location: - temp_name = gscript.tempfile() + temp_name = gs.tempfile() temp_file = open(temp_name, "w") proj_name = os.path.abspath(proj_file_name) @@ -315,33 +313,31 @@ def import_stds( proj_file.write(proj_content) proj_file.close() - p = gscript.start_command("g.proj", flags="j", stdout=temp_file) + p = gs.start_command("g.proj", flags="j", stdout=temp_file) p.communicate() temp_file.close() - if not gscript.compare_key_value_text_files(temp_name, proj_name_tmp, sep="="): + if not gs.compare_key_value_text_files(temp_name, proj_name_tmp, sep="="): if overr: - gscript.warning( - _("Projection information does not match. Proceeding...") - ) + gs.warning(_("Projection information does not match. Proceeding...")) else: - diff = "".join(gscript.diff_files(temp_name, proj_name)) - gscript.warning( + diff = "".join(gs.diff_files(temp_name, proj_name)) + gs.warning( _( "Difference between PROJ_INFO file of " "imported map and of current location:" "\n{diff}" ).format(diff=diff) ) - gscript.fatal(_("Projection information does not match. Aborting.")) + gs.fatal(_("Projection information does not match. Aborting.")) # Create a new location based on the projection information and switch # into it - old_env = gscript.gisenv() + old_env = gs.gisenv() if location: try: proj4_string = open(proj_file_name, "r").read() - gscript.create_location( + gs.create_location( dbase=old_env["GISDBASE"], location=location, proj4=proj4_string ) # Just create a new location and return @@ -349,25 +345,25 @@ def import_stds( os.chdir(old_cwd) return except Exception as e: - gscript.fatal( + gs.fatal( _("Unable to create location %(l)s. Reason: %(e)s") % {"l": location, "e": str(e)} ) # Switch to the new created location try: - gscript.run_command( + gs.run_command( "g.mapset", mapset="PERMANENT", project=location, dbase=old_env["GISDBASE"], ) except CalledModuleError: - gscript.fatal(_("Unable to switch to location %s") % location) + gs.fatal(_("Unable to switch to location %s") % location) # create default database connection try: - gscript.run_command("t.connect", flags="d") + gs.run_command("t.connect", flags="d") except CalledModuleError: - gscript.fatal( + gs.fatal( _("Unable to create default temporal database in new location %s") % location ) @@ -406,7 +402,7 @@ def import_stds( if base: mapname = "%s_%s" % ( base, - gscript.get_num_suffix(line_count + 1, max_count), + gs.get_num_suffix(line_count + 1, max_count), ) mapid = "%s@%s" % (mapname, mapset) else: @@ -451,13 +447,13 @@ def import_stds( or "semantic_type" not in init or "number_of_maps" not in init ): - gscript.fatal( + gs.fatal( _("Key words %(t)s, %(s)s or %(n)s not found in init file.") % {"t": "temporal_type", "s": "semantic_type", "n": "number_of_maps"} ) if line_count != int(init["number_of_maps"]): - gscript.fatal(_("Number of maps mismatch in init and list file.")) + gs.fatal(_("Number of maps mismatch in init and list file.")) format_ = "GTiff" type_ = "strds" @@ -468,14 +464,14 @@ def import_stds( format_ = init["format"] if stds_type != type_: - gscript.fatal(_("The archive file is of wrong space time dataset type")) + gs.fatal(_("The archive file is of wrong space time dataset type")) # Check the existence of the files if format_ == "GTiff": for row in maplist: filename = row["filename"] + ".tif" if not os.path.exists(filename): - gscript.fatal( + gs.fatal( _("Unable to find GeoTIFF raster file <%s> in archive.") % filename ) @@ -483,7 +479,7 @@ def import_stds( for row in maplist: filename = row["filename"] + ".asc" if not os.path.exists(filename): - gscript.fatal( + gs.fatal( _("Unable to find AAIGrid raster file <%s> in archive.") % filename ) @@ -491,7 +487,7 @@ def import_stds( for row in maplist: filename = row["filename"] + ".xml" if not os.path.exists(filename): - gscript.fatal( + gs.fatal( _("Unable to find GML vector file <%s> in archive.") % filename ) elif format_ == "pack": @@ -501,18 +497,18 @@ def import_stds( else: filename = row["filename"] + ".pack" if not os.path.exists(filename): - gscript.fatal( + gs.fatal( _("Unable to find GRASS package file <%s> in archive.") % filename ) else: - gscript.fatal(_("Unsupported input format")) + gs.fatal(_("Unsupported input format")) # Check the space time dataset id = output + "@" + mapset sp = dataset_factory(type_, id) - if sp.is_in_db() and gscript.overwrite() is False: - gscript.fatal( + if sp.is_in_db() and gs.overwrite() is False: + gs.fatal( _( "Space time %(t)s dataset <%(sp)s> is already in" " the database. Use the overwrite flag." @@ -522,7 +518,7 @@ def import_stds( # Import the maps if type_ == "strds": - if format_ == "GTiff" or format_ == "AAIGrid": + if format_ in {"GTiff", "AAIGrid"}: _import_raster_maps_from_gdal( maplist, overr, @@ -542,8 +538,8 @@ def import_stds( _import_vector_maps(maplist) # Create the space time dataset - if sp.is_in_db() and gscript.overwrite() is True: - gscript.info( + if sp.is_in_db() and gs.overwrite() is True: + gs.info( _( "Overwrite space time %(sp)s dataset " "<%(id)s> and unregister all maps." @@ -558,13 +554,13 @@ def import_stds( relative_time_unit = None if temporal_type == "relative": if "relative_time_unit" not in init: - gscript.fatal( + gs.fatal( _("Key word %s not found in init file.") % ("relative_time_unit") ) relative_time_unit = init["relative_time_unit"] sp.set_relative_time_unit(relative_time_unit) - gscript.verbose( + gs.verbose( _("Create space time %s dataset.") % sp.get_new_map_instance(None).get_type() ) @@ -597,13 +593,13 @@ def import_stds( if location: # Switch to the old location try: - gscript.run_command( + gs.run_command( "g.mapset", mapset=old_env["MAPSET"], project=old_env["LOCATION_NAME"], gisdbase=old_env["GISDBASE"], ) except CalledModuleError: - gscript.warning(_("Switching to original location failed")) + gs.warning(_("Switching to original location failed")) - gscript.set_raise_on_error(old_state) + gs.set_raise_on_error(old_state) diff --git a/python/grass/temporal/temporal_algebra.py b/python/grass/temporal/temporal_algebra.py index 0d6d200ff29..c2546ec0d9e 100644 --- a/python/grass/temporal/temporal_algebra.py +++ b/python/grass/temporal/temporal_algebra.py @@ -870,7 +870,7 @@ def setup_common_granularity(self, expression, stdstype="strds", lexer=None): :return: True if successful, False otherwise """ - l = lexer + lx = lexer # Split the expression to ignore the left part expressions = expression.split("=")[1:] expression = " ".join(expressions) @@ -886,17 +886,17 @@ def setup_common_granularity(self, expression, stdstype="strds", lexer=None): return False # detect all STDS - if l is None: - l = TemporalAlgebraLexer() - l.build() - l.lexer.input(expression) + if lx is None: + lx = TemporalAlgebraLexer() + lx.build() + lx.lexer.input(expression) name_list = [] tokens = [] count = 0 while True: - tok = l.lexer.token() + tok = lx.lexer.token() if not tok: break @@ -1179,8 +1179,7 @@ def set_temporal_extent_list(self, maplist, topolist=["EQUAL"], temporal="l"): # resultlist.append(map_new) # Get sorted map objects as values from result dictionary. resultlist = resultdict.values() - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def remove_maps(self): """Removes empty or intermediate maps of different type.""" @@ -1641,9 +1640,7 @@ def build_spatio_temporal_topology_list( resultlist = resultdict.values() # Sort list of maps chronological. - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def assign_bool_value( self, map_i, temporal_topo_list=["EQUAL"], spatial_topo_list=[] @@ -1728,8 +1725,7 @@ def compare_bool_value( is True ): if count == 0: - condition_value_list.append(compop[0]) - condition_value_list.append("(") + condition_value_list.extend((compop[0], "(")) for boolean in relationmap.condition_value: if isinstance(boolean, bool): if count > 0: @@ -1872,8 +1868,7 @@ def perform_temporal_selection( # map_i.condition_value.append(False) # Sort list of maps chronological. - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def set_granularity(self, maplistA, maplistB, toperator="l", topolist=["EQUAL"]): """This function sets the temporal extends of a list of maps based on @@ -2007,13 +2002,11 @@ def set_granularity(self, maplistA, maplistB, toperator="l", topolist=["EQUAL"]) resultlist = resultdict.values() # Sort list of maps chronological. - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) # Get relations to maplistB per map in A. # Loop over all relations from list # temporal extent = map.temporal_intersection(map) # if temporal extend is None = delete map. - - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def get_temporal_func_dict(self, map): """This function creates a dictionary containing temporal functions for a @@ -2197,18 +2190,15 @@ def eval_map_list(self, maplist, thenlist, topolist=["EQUAL"]): """ # Get topology of then statement map list in relation to the other maplist # and assign boolean values of the maplist to the thenlist. - containlist = self.perform_temporal_selection( - thenlist, maplist, assign_val=True, topolist=topolist - ) # Inverse selection of maps from thenlist and assigning False values. # excludelist = self.perform_temporal_selection(thenlist, maplist, # assign_val = True, # inverse = True, # topolist = topolist) # Combining the selection and inverse selection list. - resultlist = containlist # + excludelist - - return resultlist + return self.perform_temporal_selection( + thenlist, maplist, assign_val=True, topolist=topolist + ) def build_condition_list(self, tvarexpr, thenlist, topolist=["EQUAL"]): """This function evaluates temporal variable expressions of a conditional @@ -2250,7 +2240,7 @@ def build_condition_list(self, tvarexpr, thenlist, topolist=["EQUAL"]): # Use method eval_global_var to evaluate expression. resultlist = self.eval_global_var(tvarexpr, thenlist) # Check if a given list is a list of maps. - elif all([issubclass(type(ele), AbstractMapDataset) for ele in tvarexpr]): + elif all(issubclass(type(ele), AbstractMapDataset) for ele in tvarexpr): # Use method eval_map_list to evaluate map_list in comparison to thenlist. resultlist = self.eval_map_list(tvarexpr, thenlist, topolist) elif len(tvarexpr) % 2 != 0: @@ -2260,12 +2250,12 @@ def build_condition_list(self, tvarexpr, thenlist, topolist=["EQUAL"]): expr = tvarexpr[iter] operator = tvarexpr[iter + 1] relexpr = tvarexpr[iter + 2] - if all([issubclass(type(ele), list) for ele in [expr, relexpr]]): + if all(issubclass(type(ele), list) for ele in [expr, relexpr]): resultlist = self.build_spatio_temporal_topology_list(expr, relexpr) # Loop through the list, search for map lists or global variables. for expr in tvarexpr: if isinstance(expr, list): - if all([issubclass(type(ele), AbstractMapDataset) for ele in expr]): + if all(issubclass(type(ele), AbstractMapDataset) for ele in expr): # Use method eval_map_list to evaluate map_list resultlist = self.eval_map_list(expr, thenlist, topolist) else: @@ -2275,7 +2265,7 @@ def build_condition_list(self, tvarexpr, thenlist, topolist=["EQUAL"]): elif isinstance(expr, GlobalTemporalVar): # Use according functions for different global variable types. if expr.get_type() == "operator": - if all(["condition_value" in dir(map_i) for map_i in thenlist]): + if all("condition_value" in dir(map_i) for map_i in thenlist): # Add operator string to the condition list. [ map_i.condition_value.extend(expr.get_type_value()) @@ -2286,9 +2276,7 @@ def build_condition_list(self, tvarexpr, thenlist, topolist=["EQUAL"]): resultlist = self.eval_global_var(expr, thenlist) # Sort resulting list of maps chronological. - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def eval_condition_list(self, maplist, inverse=False): """This function evaluates conditional values of a map list. @@ -2337,9 +2325,7 @@ def recurse_compare(conditionlist): conditionlist[ele_index - 2] = result recurse_compare(conditionlist) - resultlist = conditionlist - - return resultlist + return conditionlist resultlist = [] inverselist = [] @@ -2550,10 +2536,9 @@ def p_statement_assign(self, t): "Error map %s exist in temporal database. " "Use overwrite flag." % map_i.get_map_id() ) - else: + elif self.dry_run is False: # Insert map into temporal database. - if self.dry_run is False: - map_i.insert(dbif) + map_i.insert(dbif) # Register map in result space time dataset. if self.dry_run is False: @@ -3255,11 +3240,10 @@ def p_expr_condition_elif_relation(self, t): resultlist = self.check_stds(resultlist, clear=True) # Return resulting map list. t[0] = resultlist + elif t[5]: + t[0] = str(t[7]) else: - if t[5]: - t[0] = str(t[7]) - else: - t[0] = str(t[9]) + t[0] = str(t[9]) if self.debug: if t[5]: diff --git a/python/grass/temporal/temporal_extent.py b/python/grass/temporal/temporal_extent.py index b3ce5714c3b..fd9c63db2fa 100644 --- a/python/grass/temporal/temporal_extent.py +++ b/python/grass/temporal/temporal_extent.py @@ -176,7 +176,7 @@ def intersect(self, extent): """ relation = self.temporal_relation(extent) - if relation == "after" or relation == "before": + if relation in {"after", "before"}: return None if self.D["end_time"] is None: @@ -423,7 +423,7 @@ def union(self, extent): relation = self.temporal_relation(extent) - if relation == "after" or relation == "before": + if relation in {"after", "before"}: return None return self.disjoint_union(extent) diff --git a/python/grass/temporal/temporal_granularity.py b/python/grass/temporal/temporal_granularity.py index ffe84646e5b..d66f6c57ffb 100644 --- a/python/grass/temporal/temporal_granularity.py +++ b/python/grass/temporal/temporal_granularity.py @@ -83,7 +83,6 @@ def check_granularity_string(granularity, temporal_type): False """ - temporal_type if granularity is None: return False @@ -1001,14 +1000,19 @@ def compute_common_absolute_time_granularity_simple(gran_list): seconds.append(days[0] * 60 * 60 * 24) if has_months: months.sort() - seconds.append(months[0] * 60 * 60 * 24 * 28) - seconds.append(months[0] * 60 * 60 * 24 * 29) - seconds.append(months[0] * 60 * 60 * 24 * 30) - seconds.append(months[0] * 60 * 60 * 24 * 31) + seconds.extend( + ( + months[0] * 60 * 60 * 24 * 28, + months[0] * 60 * 60 * 24 * 29, + months[0] * 60 * 60 * 24 * 30, + months[0] * 60 * 60 * 24 * 31, + ) + ) if has_years: years.sort() - seconds.append(years[0] * 60 * 60 * 24 * 365) - seconds.append(years[0] * 60 * 60 * 24 * 366) + seconds.extend( + (years[0] * 60 * 60 * 24 * 365, years[0] * 60 * 60 * 24 * 366) + ) num = gcd_list(seconds) gran = "second" @@ -1025,14 +1029,17 @@ def compute_common_absolute_time_granularity_simple(gran_list): minutes.append(days[0] * 60 * 24) if has_months: months.sort() - minutes.append(months[0] * 60 * 24 * 28) - minutes.append(months[0] * 60 * 24 * 29) - minutes.append(months[0] * 60 * 24 * 30) - minutes.append(months[0] * 60 * 24 * 31) + minutes.extend( + ( + months[0] * 60 * 24 * 28, + months[0] * 60 * 24 * 29, + months[0] * 60 * 24 * 30, + months[0] * 60 * 24 * 31, + ) + ) if has_years: years.sort() - minutes.append(years[0] * 60 * 24 * 365) - minutes.append(years[0] * 60 * 24 * 366) + minutes.extend((years[0] * 60 * 24 * 365, years[0] * 60 * 24 * 366)) num = gcd_list(minutes) gran = "minute" if num > 1: @@ -1045,14 +1052,17 @@ def compute_common_absolute_time_granularity_simple(gran_list): hours.append(days[0] * 24) if has_months: months.sort() - hours.append(months[0] * 24 * 28) - hours.append(months[0] * 24 * 29) - hours.append(months[0] * 24 * 30) - hours.append(months[0] * 24 * 31) + hours.extend( + ( + months[0] * 24 * 28, + months[0] * 24 * 29, + months[0] * 24 * 30, + months[0] * 24 * 31, + ) + ) if has_years: years.sort() - hours.append(years[0] * 24 * 365) - hours.append(years[0] * 24 * 366) + hours.extend((years[0] * 24 * 365, years[0] * 24 * 366)) num = gcd_list(hours) gran = "hour" if num > 1: @@ -1062,14 +1072,12 @@ def compute_common_absolute_time_granularity_simple(gran_list): if has_days: if has_months: months.sort() - days.append(months[0] * 28) - days.append(months[0] * 29) - days.append(months[0] * 30) - days.append(months[0] * 31) + days.extend( + (months[0] * 28, months[0] * 29, months[0] * 30, months[0] * 31) + ) if has_years: years.sort() - days.append(years[0] * 365) - days.append(years[0] * 366) + days.extend((years[0] * 365, years[0] * 366)) num = gcd_list(days) gran = "day" if num > 1: @@ -1229,11 +1237,11 @@ def _return(output, tounit, shell): """Function to return the output""" if shell: return output + + if output == 1: + return f"{output} {tounit}" else: - if output == 1: - return f"{output} {tounit}" - else: - return f"{output} {tounit}s" + return f"{output} {tounit}s" # TODO check the leap second if check_granularity_string(from_gran, "absolute"): diff --git a/python/grass/temporal/temporal_operator.py b/python/grass/temporal/temporal_operator.py index bbecd6720a9..572e1559611 100644 --- a/python/grass/temporal/temporal_operator.py +++ b/python/grass/temporal/temporal_operator.py @@ -241,19 +241,19 @@ def temporal_symbol(self, t): # Check for reserved words if t.value in TemporalOperatorLexer.relations.keys(): t.type = TemporalOperatorLexer.relations.get(t.value) - elif t.value == "l" or t.value == "left": + elif t.value in {"l", "left"}: t.value = "l" t.type = "LEFTREF" - elif t.value == "r" or t.value == "right": + elif t.value in {"r", "right"}: t.value = "r" t.type = "RIGHTREF" - elif t.value == "u" or t.value == "union": + elif t.value in {"u", "union"}: t.value = "u" t.type = "UNION" - elif t.value == "d" or t.value == "disjoint": + elif t.value in {"d", "disjoint"}: t.value = "d" t.type = "DISJOINT" - elif t.value == "i" or t.value == "intersect": + elif t.value in {"i", "intersect"}: t.value = "i" t.type = "INTERSECT" else: diff --git a/python/grass/temporal/temporal_raster3d_algebra.py b/python/grass/temporal/temporal_raster3d_algebra.py index 56b3ac82751..cd26f8cb220 100644 --- a/python/grass/temporal/temporal_raster3d_algebra.py +++ b/python/grass/temporal/temporal_raster3d_algebra.py @@ -54,16 +54,16 @@ def __init__( def parse(self, expression, basename=None, overwrite=False): # Check for space time dataset type definitions from temporal algebra - l = TemporalRasterAlgebraLexer() - l.build() - l.lexer.input(expression) + lx = TemporalRasterAlgebraLexer() + lx.build() + lx.lexer.input(expression) while True: - tok = l.lexer.token() + tok = lx.lexer.token() if not tok: break - if tok.type == "STVDS" or tok.type == "STRDS" or tok.type == "STR3DS": + if tok.type in {"STVDS", "STRDS", "STR3DS"}: raise SyntaxError("Syntax error near '%s'" % (tok.type)) self.lexer = TemporalRasterAlgebraLexer() diff --git a/python/grass/temporal/temporal_raster_algebra.py b/python/grass/temporal/temporal_raster_algebra.py index 76e1a08af66..1785183cc50 100644 --- a/python/grass/temporal/temporal_raster_algebra.py +++ b/python/grass/temporal/temporal_raster_algebra.py @@ -100,16 +100,16 @@ def __init__( def parse(self, expression, basename=None, overwrite=False): # Check for space time dataset type definitions from temporal algebra - l = TemporalRasterAlgebraLexer() - l.build() - l.lexer.input(expression) + lx = TemporalRasterAlgebraLexer() + lx.build() + lx.lexer.input(expression) while True: - tok = l.lexer.token() + tok = lx.lexer.token() if not tok: break - if tok.type == "STVDS" or tok.type == "STRDS" or tok.type == "STR3DS": + if tok.type in {"STVDS", "STRDS", "STR3DS"}: raise SyntaxError("Syntax error near '%s'" % (tok.type)) self.lexer = TemporalRasterAlgebraLexer() diff --git a/python/grass/temporal/temporal_raster_base_algebra.py b/python/grass/temporal/temporal_raster_base_algebra.py index 4207e251b38..02e28e0e435 100644 --- a/python/grass/temporal/temporal_raster_base_algebra.py +++ b/python/grass/temporal/temporal_raster_base_algebra.py @@ -354,9 +354,7 @@ def build_spatio_temporal_topology_list( resultlist = resultdict.values() # Sort list of maps chronological. - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def build_command_string(self, map_i, relmap, operator=None, cmd_type=None): """This function build the r.mapcalc command string for conditionals, @@ -464,8 +462,7 @@ def compare_cmd_value( if topo.upper() in temporal_relations.keys(): relationmaplist = temporal_relations[topo.upper()] if count == 0 and "cmd_list" in dir(map_i): - cmd_value_list.append(compop) - cmd_value_list.append("(") + cmd_value_list.extend((compop, "(")) for relationmap in relationmaplist: if ( self._check_spatial_topology_relation( @@ -637,9 +634,7 @@ def set_temporal_extent_list( # resultlist.append(map_new) # Get sorted map objects as values from result dictionary. resultlist = resultdict.values() - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def build_condition_cmd_list( self, @@ -740,14 +735,13 @@ def build_condition_cmd_list( conditiontopolist = self.build_spatio_temporal_topology_list( iflist, conclusionlist, topolist=condition_topolist ) - resultlist = self.set_temporal_extent_list( + return self.set_temporal_extent_list( conditiontopolist, topolist=condition_topolist, temporal="r", cmd_bool=True, cmd_type="condition", ) - return resultlist def p_statement_assign(self, t): # This function executes the processing of raster/raster3d algebra @@ -934,10 +928,9 @@ def p_statement_assign(self, t): "Error raster map %s exist in temporal database. " "Use overwrite flag." % map_i.get_map_id() ) - else: + elif self.dry_run is False: # Insert map into temporal database. - if self.dry_run is False: - map_i.insert(dbif) + map_i.insert(dbif) # Register map in result space time dataset. if self.dry_run is False: success = resultstds.register_map(map_i, dbif) diff --git a/python/grass/temporal/temporal_vector_algebra.py b/python/grass/temporal/temporal_vector_algebra.py index 5bdf51455d9..d8e8474f26e 100644 --- a/python/grass/temporal/temporal_vector_algebra.py +++ b/python/grass/temporal/temporal_vector_algebra.py @@ -153,16 +153,16 @@ def __init__(self, pid=None, run=False, debug=True, spatial=False): def parse(self, expression, basename=None, overwrite=False): # Check for space time dataset type definitions from temporal algebra - l = TemporalVectorAlgebraLexer() - l.build() - l.lexer.input(expression) + lx = TemporalVectorAlgebraLexer() + lx.build() + lx.lexer.input(expression) while True: - tok = l.lexer.token() + tok = lx.lexer.token() if not tok: break - if tok.type == "STVDS" or tok.type == "STRDS" or tok.type == "STR3DS": + if tok.type in {"STVDS", "STRDS", "STR3DS"}: raise SyntaxError("Syntax error near '%s'" % (tok.type)) self.lexer = TemporalVectorAlgebraLexer() @@ -291,9 +291,7 @@ def build_spatio_temporal_topology_list( resultlist = resultdict.values() # Sort list of maps chronological. - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def overlay_cmd_value(self, map_i, tbrelations, function, topolist=["EQUAL"]): """Function to evaluate two map lists by given overlay operator. @@ -411,8 +409,7 @@ def set_temporal_extent_list(self, maplist, topolist=["EQUAL"], temporal="l"): # resultlist.append(map_new) # Get sorted map objects as values from result dictionary. resultlist = resultdict.values() - resultlist = sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) - return resultlist + return sorted(resultlist, key=AbstractDatasetComparisonKeyStartTime) def p_statement_assign(self, t): # The expression should always return a list of maps. diff --git a/python/grass/temporal/testsuite/test_register_function.py b/python/grass/temporal/testsuite/test_register_function.py index b1fb779684b..a58ec7d739a 100644 --- a/python/grass/temporal/testsuite/test_register_function.py +++ b/python/grass/temporal/testsuite/test_register_function.py @@ -12,7 +12,7 @@ import datetime import os -import grass.script as gscript +import grass.script as gs import grass.temporal as tgis from grass.gunittest.case import TestCase from grass.gunittest.main import test @@ -980,11 +980,11 @@ def tearDown(self): name="register_map_1,register_map_2", quiet=True, ) - grassenv = gscript.gisenv() + grassenv = gs.gisenv() mapset_path = os.path.join( grassenv["GISDBASE"], grassenv["LOCATION_NAME"], self.newmapset ) - gscript.try_rmdir(mapset_path) + gs.try_rmdir(mapset_path) def test_mapset_access_1(self): """Test the registration of maps from a different mapset.""" diff --git a/python/grass/temporal/testsuite/unittests_temporal_algebra_grs.py b/python/grass/temporal/testsuite/unittests_temporal_algebra_grs.py index a4f5b7f1f78..7e0db57a8ce 100644 --- a/python/grass/temporal/testsuite/unittests_temporal_algebra_grs.py +++ b/python/grass/temporal/testsuite/unittests_temporal_algebra_grs.py @@ -10,7 +10,6 @@ import datetime import os -import grass.script import grass.temporal as tgis from grass.gunittest.case import TestCase from grass.gunittest.main import test diff --git a/python/grass/temporal/testsuite/unittests_temporal_algebra_mixed_stds.py b/python/grass/temporal/testsuite/unittests_temporal_algebra_mixed_stds.py index b821a617df9..cf0e9c82bb7 100644 --- a/python/grass/temporal/testsuite/unittests_temporal_algebra_mixed_stds.py +++ b/python/grass/temporal/testsuite/unittests_temporal_algebra_mixed_stds.py @@ -10,7 +10,6 @@ import datetime import os -import grass.script import grass.temporal as tgis from grass.gunittest.case import TestCase from grass.gunittest.main import test diff --git a/python/grass/temporal/testsuite/unittests_temporal_conditionals.py b/python/grass/temporal/testsuite/unittests_temporal_conditionals.py index 0921b8eb063..ff0703aec1d 100644 --- a/python/grass/temporal/testsuite/unittests_temporal_conditionals.py +++ b/python/grass/temporal/testsuite/unittests_temporal_conditionals.py @@ -10,7 +10,6 @@ import datetime import os -import grass.script import grass.temporal as tgis from grass.gunittest.case import TestCase from grass.gunittest.main import test diff --git a/python/grass/temporal/testsuite/unittests_temporal_raster3d_algebra.py b/python/grass/temporal/testsuite/unittests_temporal_raster3d_algebra.py index 285da1955be..f2d8a215bdb 100644 --- a/python/grass/temporal/testsuite/unittests_temporal_raster3d_algebra.py +++ b/python/grass/temporal/testsuite/unittests_temporal_raster3d_algebra.py @@ -9,7 +9,7 @@ import datetime -import grass.script +import grass.script as gs import grass.temporal as tgis from grass.gunittest.case import TestCase from grass.gunittest.main import test @@ -21,7 +21,7 @@ def setUpClass(cls): """Initiate the temporal GIS and set the region""" tgis.init(True) # Raise on error instead of exit(1) cls.use_temp_region() - ret = grass.script.run_command( + ret = gs.run_command( "g.region", n=80.0, s=0.0, e=120.0, w=0.0, t=100.0, b=0.0, res=10.0 ) diff --git a/python/grass/temporal/univar_statistics.py b/python/grass/temporal/univar_statistics.py index ddf55345b34..9bf29f74eba 100755 --- a/python/grass/temporal/univar_statistics.py +++ b/python/grass/temporal/univar_statistics.py @@ -440,7 +440,7 @@ def print_vector_dataset_univar_statistics( else: string += fs + fs + fs - if type == "point" or type == "centroid": + if type in {"point", "centroid"}: if "mean" in stats: string += ( fs diff --git a/python/libgrass_interface_generator/CMakeLists.txt b/python/libgrass_interface_generator/CMakeLists.txt index 7c2a429f080..129320cf1ff 100644 --- a/python/libgrass_interface_generator/CMakeLists.txt +++ b/python/libgrass_interface_generator/CMakeLists.txt @@ -18,7 +18,7 @@ set(MODULES rowio temporal) -if(WITH_OPENGL) +if(TARGET grass_ogsf) list(APPEND MODULES ogsf nviz) endif() diff --git a/raster/CMakeLists.txt b/raster/CMakeLists.txt index 5e36e052ab2..534e4133b1d 100644 --- a/raster/CMakeLists.txt +++ b/raster/CMakeLists.txt @@ -161,6 +161,7 @@ build_program_in_subdir( grass_vector grass_bitmap grass_dig2 + GDAL LIBM) build_program_in_subdir(r.category DEPENDS grass_gis grass_raster) @@ -188,10 +189,11 @@ build_program_in_subdir( grass_dbmibase grass_dbmiclient grass_dbmidriver + GDAL LIBM) build_program_in_subdir(r.cost DEPENDS grass_gis grass_raster grass_segment - grass_vector LIBM) + grass_vector GDAL LIBM) build_program_in_subdir(r.covar DEPENDS grass_gis grass_raster LIBM) @@ -226,6 +228,7 @@ build_program_in_subdir( grass_segment grass_vector grass_bitmap + GDAL LIBM) build_program_in_subdir(r.geomorphon DEPENDS grass_gis grass_raster grass_gmath LIBM) @@ -238,7 +241,7 @@ build_program_in_subdir(r.gwflow DEPENDS grass_gis grass_raster grass_gpde build_program_in_subdir(r.his DEPENDS grass_gis grass_raster grass_gproj) build_program_in_subdir(r.horizon DEPENDS grass_gis grass_raster grass_gproj - grass_parson LIBM) + grass_parson GDAL LIBM) build_program_in_subdir(r.in.ascii DEPENDS grass_gis grass_raster) @@ -270,6 +273,7 @@ build_program_in_subdir( grass_gmath grass_segment grass_gproj + GDAL LIBM PRIMARY_DEPENDS PDAL) @@ -288,7 +292,7 @@ build_program_in_subdir(r.info TEST_SOURCES "test_r_info.py" DEPENDS grass_gis L build_program_in_subdir(r.kappa DEPENDS grass_gis grass_raster LIBM) -build_program_in_subdir(r.latlong DEPENDS grass_gis grass_raster grass_gproj) +build_program_in_subdir(r.latlong DEPENDS grass_gis grass_raster grass_gproj GDAL) build_program_in_subdir(r.lake DEPENDS grass_gis grass_raster) @@ -374,7 +378,7 @@ build_program_in_subdir( build_program_in_subdir(r.patch DEPENDS grass_gis grass_raster OPTIONAL_DEPENDS OPENMP) -build_program_in_subdir(r.path DEPENDS grass_gis grass_raster grass_vector) +build_program_in_subdir(r.path DEPENDS grass_gis grass_raster grass_vector GDAL) build_program_in_subdir(r.profile DEPENDS grass_gis grass_raster grass_parson LIBM) @@ -384,6 +388,7 @@ build_program_in_subdir( grass_gis grass_raster grass_gproj + GDAL LIBM OPTIONAL_DEPENDS OPENMP) @@ -401,6 +406,7 @@ build_program_in_subdir( grass_dbmibase grass_dbmiclient grass_dbmidriver + GDAL LIBM) build_program_in_subdir(r.random.cells DEPENDS grass_gis grass_raster LIBM) @@ -411,7 +417,7 @@ build_program_in_subdir(r.reclass DEPENDS grass_gis grass_raster grass_manage) build_program_in_subdir(r.recode DEPENDS grass_gis grass_raster) -build_program_in_subdir(r.region DEPENDS grass_gis grass_raster grass_vector) +build_program_in_subdir(r.region DEPENDS grass_gis grass_raster grass_vector GDAL) build_program_in_subdir(r.regression.line DEPENDS grass_gis grass_raster LIBM) @@ -428,6 +434,7 @@ build_program_in_subdir( grass_vector grass_segment grass_lidar + GDAL LIBM) build_program_in_subdir(r.resamp.filter DEPENDS grass_gis grass_raster LIBM @@ -444,7 +451,9 @@ build_program_in_subdir( grass_gmath grass_interpfl grass_interpdata - grass_qtree) + grass_qtree + GDAL) + build_program_in_subdir(r.resamp.stats DEPENDS grass_gis grass_raster grass_stats LIBM) @@ -511,6 +520,7 @@ build_program_in_subdir( grass_dbmibase grass_dbmiclient grass_dbmidriver + GDAL LIBM) build_program_in_subdir( @@ -520,13 +530,14 @@ build_program_in_subdir( grass_gmath grass_raster grass_gproj + GDAL LIBM OPTIONAL_DEPENDS OPENMP) -build_program_in_subdir(r.sunhours DEPENDS grass_gis grass_raster grass_gproj LIBM) +build_program_in_subdir(r.sunhours DEPENDS grass_gis grass_raster grass_gproj GDAL LIBM) -build_program_in_subdir(r.sunmask DEPENDS grass_gis grass_raster grass_gproj LIBM) +build_program_in_subdir(r.sunmask DEPENDS grass_gis grass_raster grass_gproj GDAL LIBM) build_program_in_subdir(r.support DEPENDS grass_gis grass_raster) @@ -574,7 +585,8 @@ build_program_in_subdir( grass_vector grass_dbmibase grass_dbmiclient - grass_dbmidriver) + grass_dbmidriver + GDAL) build_program_in_subdir(r.topidx DEPENDS grass_gis grass_raster LIBM) @@ -596,15 +608,16 @@ build_program_in_subdir( grass_vector grass_dbmibase grass_dbmiclient - grass_dbmidriver) + grass_dbmidriver + GDAL) build_program_in_subdir(r.walk DEPENDS grass_gis grass_raster grass_segment - grass_vector LIBM) + grass_vector GDAL LIBM) build_program_in_subdir(r.water.outlet DEPENDS grass_gis grass_raster) build_program_in_subdir(r.what DEPENDS grass_gis grass_raster grass_vector - grass_parson) + grass_parson GDAL) build_program_in_subdir(r.what.color DEPENDS grass_gis grass_raster) diff --git a/raster/r.coin/print_coin.c b/raster/r.coin/print_coin.c index f2a291fa326..a74ab75044b 100644 --- a/raster/r.coin/print_coin.c +++ b/raster/r.coin/print_coin.c @@ -32,7 +32,7 @@ int print_coin(int Conformat, int out_cols, int tofile) double colarea_no_0, rowarea_no_0; double area; - int addflag; + int addflag = 0; char topformat[133], midformat[133], namformat[133]; char fillformat[133]; const char *mapone; diff --git a/raster/r.mapcalc/map3.c b/raster/r.mapcalc/map3.c index 374f6a76109..c9683148275 100644 --- a/raster/r.mapcalc/map3.c +++ b/raster/r.mapcalc/map3.c @@ -265,7 +265,7 @@ static void translate_from_cats(map *m, CELL *cell, DCELL *xcell, int ncols) { struct Categories *pcats; BTREE *btree; - int i, idx; + int i = 0, idx = 0; CELL cat, key; double vbuf[1 << SHIFT]; double *values; diff --git a/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py b/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py index 7212fc7e193..2dc85b411d8 100644 --- a/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py +++ b/raster/r.mfilter/benchmark/benchmark_r_mfilter_nprocs.py @@ -3,6 +3,8 @@ @author Aaron Saw Min Sern """ +from pathlib import Path + from grass.exceptions import CalledModuleError from grass.pygrass.modules import Module from grass.script import tempfile @@ -27,9 +29,8 @@ def benchmark(size, label, results): reference = "r_mfilter_reference_map" output = "benchmark_r_mfilter_nprocs" filter = tempfile() - with open(filter, "w") as w: - w.write( - """MATRIX 9 + Path(filter).write_text( + """MATRIX 9 1 1 1 1 1 1 1 1 1 1 2 1 2 1 2 1 2 1 1 1 3 1 3 1 3 1 1 @@ -41,7 +42,7 @@ def benchmark(size, label, results): 1 1 1 1 1 1 1 1 1 DIVISOR 81 TYPE P""" - ) + ) generate_map(rows=size, cols=size, fname=reference) module = Module( diff --git a/raster/r.neighbors/testsuite/test_r_neighbors.py b/raster/r.neighbors/testsuite/test_r_neighbors.py index b447eabe1d2..c333a3abdaa 100644 --- a/raster/r.neighbors/testsuite/test_r_neighbors.py +++ b/raster/r.neighbors/testsuite/test_r_neighbors.py @@ -1,3 +1,4 @@ +from pathlib import Path from grass.gunittest.case import TestCase from grass.gunittest.main import test from grass.script.raster import raster_info @@ -628,8 +629,9 @@ def test_weighting_file(self): self.to_remove.extend(outputs_threaded) weights = tempfile() - with open(weights, "w") as w: - w.write("0 1 1 1 0\n1 0 0 0 1\n1 0 0 0 1\n1 0 0 0 1\n0 1 1 1 0") + Path(weights).write_text( + "0 1 1 1 0\n1 0 0 0 1\n1 0 0 0 1\n1 0 0 0 1\n0 1 1 1 0" + ) self.assertModule( "r.neighbors", diff --git a/raster/r.object.geometry/main.c b/raster/r.object.geometry/main.c index 062a7aa1a83..f808c4b88e1 100644 --- a/raster/r.object.geometry/main.c +++ b/raster/r.object.geometry/main.c @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) } *obj_geos; double unit_area; int n_objects; - int planimetric, compute_areas; + int planimetric = 0, compute_areas = 0; struct Cell_head cellhd; G_gisinit(argv[0]); diff --git a/raster/r.out.mpeg/main.c b/raster/r.out.mpeg/main.c index a83004544b1..0ac3b631b80 100644 --- a/raster/r.out.mpeg/main.c +++ b/raster/r.out.mpeg/main.c @@ -235,7 +235,7 @@ static int load_files(void) register int i, rowoff, row, col, vxoff, vyoff, offset; int cnt, fd, size, tsiz, coff; int vnum; - int y_rows, y_cols; + int y_rows = 0, y_cols = 0; char *pr, *pg, *pb; unsigned char *tr, *tg, *tb, *tset; char *mpfilename, *name; diff --git a/raster/r.sim/CMakeLists.txt b/raster/r.sim/CMakeLists.txt index 60295c44446..904eecae8a0 100644 --- a/raster/r.sim/CMakeLists.txt +++ b/raster/r.sim/CMakeLists.txt @@ -8,6 +8,7 @@ build_library_in_subdir( grass_raster grass_vector grass_gmath + GDAL LIBM OPTIONAL_DEPENDS OPENMP @@ -21,6 +22,7 @@ build_program_in_subdir( grass_gis grass_gmath grass_sim + GDAL OPTIONAL_DEPENDS OPENMP INCLUDES @@ -32,6 +34,7 @@ build_program_in_subdir( grass_gis grass_gmath grass_sim + GDAL OPTIONAL_DEPENDS OPENMP INCLUDES diff --git a/raster/r.sim/simlib/random.c b/raster/r.sim/simlib/random.c index 4fff384f795..8646a93bf9f 100644 --- a/raster/r.sim/simlib/random.c +++ b/raster/r.sim/simlib/random.c @@ -25,7 +25,7 @@ double gasdev(void) double ret_val; /* Local variables */ - double r = 0., vv1, vv2, fac; + double r = 0.0, vv1 = 0.0, vv2 = 0.0, fac = 0.0; if (iset == 0) { while (r >= 1. || r == 0.) { @@ -47,7 +47,7 @@ double gasdev(void) void gasdev_for_paralel(double *x, double *y) { - double r = 0., vv1, vv2, fac; + double r = 0.0, vv1 = 0.0, vv2 = 0.0, fac = 0.0; while (r >= 1. || r == 0.) { vv1 = simwe_rand() * 2. - 1.; diff --git a/raster/r.solute.transport/example.py b/raster/r.solute.transport/example.py index aef8dfe0621..0371f681223 100755 --- a/raster/r.solute.transport/example.py +++ b/raster/r.solute.transport/example.py @@ -24,7 +24,6 @@ gs.run_command("r.mapcalc", expression="poros=0.17") gs.run_command("r.mapcalc", expression="syield=0.0001") gs.run_command("r.mapcalc", expression="null=0.0") -# gs.message(_("Compute a steady state groundwater flow")) gs.run_command( diff --git a/raster/r.solute.transport/seguin_verify.py b/raster/r.solute.transport/seguin_verify.py index fc1bdeba66f..745d254ad68 100755 --- a/raster/r.solute.transport/seguin_verify.py +++ b/raster/r.solute.transport/seguin_verify.py @@ -8,49 +8,47 @@ # year = "1996", # series = "Handbuch zur Erkundung des Untergrundes von Deponien und Altlasten" -import grass.script as grass +import grass.script as gs # Overwrite existing maps -grass.run_command("g.gisenv", set="OVERWRITE=1") +gs.run_command("g.gisenv", set="OVERWRITE=1") -grass.message(_("Set the region")) +gs.message(_("Set the region")) # The area is 2000m x 1000m with a cell size of 50m x 50m -grass.run_command("g.region", res=50, res3=50, t=25, b=0, n=1000, s=0, w=0, e=2000) +gs.run_command("g.region", res=50, res3=50, t=25, b=0, n=1000, s=0, w=0, e=2000) -grass.message(_("Create all the input maps needed for groundwater flow computation")) +gs.message(_("Create all the input maps needed for groundwater flow computation")) # Initial condition of the piezometric head, we have a huge gradient from 275m to 50m # over a distance of 2000m -grass.run_command("r.mapcalc", expression="phead_1=if(col() == 1 , 275, 50)") +gs.run_command("r.mapcalc", expression="phead_1=if(col() == 1 , 275, 50)") # Set the active cells and the dirichlet boundary condition, # the first and the last cells a dirichlet -grass.run_command( - "r.mapcalc", expression="status_1=if(col() == 1 || col() == 40 , 2, 1)" -) +gs.run_command("r.mapcalc", expression="status_1=if(col() == 1 || col() == 40 , 2, 1)") # We have a no wells -grass.run_command("r.mapcalc", expression="well_1=0") +gs.run_command("r.mapcalc", expression="well_1=0") # The hydraulic conductivity is 0.0001 m/s -grass.run_command("r.mapcalc", expression="hydcond_1=0.0001") +gs.run_command("r.mapcalc", expression="hydcond_1=0.0001") # The recharge, well we have no recharge at all -grass.run_command("r.mapcalc", expression="recharge_1=0") +gs.run_command("r.mapcalc", expression="recharge_1=0") # We have a confined aquifer with a height of 25m -grass.run_command("r.mapcalc", expression="top_conf_1=25") +gs.run_command("r.mapcalc", expression="top_conf_1=25") # Bottom of the aquifer starts at 0m -grass.run_command("r.mapcalc", expression="bottom_1=0") +gs.run_command("r.mapcalc", expression="bottom_1=0") # This porosity of sand aquifer is 0.17 in example 1.1 -grass.run_command("r.mapcalc", expression="poros_1=0.17") +gs.run_command("r.mapcalc", expression="poros_1=0.17") # The specific yield of a confined aquifer -grass.run_command("r.mapcalc", expression="syield_1=0.0001") -grass.run_command("r.mapcalc", expression="null_1=0.0") +gs.run_command("r.mapcalc", expression="syield_1=0.0001") +gs.run_command("r.mapcalc", expression="null_1=0.0") -grass.message( +gs.message( "First compute a steady state groundwater flow with a mean velocity" " of 5.88 m/d or 6.8*10^5m/s" ) # Compute the steady state groundwater flow -grass.run_command( +gs.run_command( "r.gwflow", solver="cg", top="top_conf_1", @@ -68,26 +66,22 @@ ) -grass.message(_("generate the transport data")) +gs.message(_("generate the transport data")) # The initial concentration is zero -grass.run_command( - "r.mapcalc", expression="c_1=if(col() == 10 && row() == 10 , 0.0, 0.0)" -) +gs.run_command("r.mapcalc", expression="c_1=if(col() == 10 && row() == 10 , 0.0, 0.0)") # One inner sources (result of chemical reaction) -grass.run_command( +gs.run_command( "r.mapcalc", expression="cs_1=if(col() == 10 && row() == 10 , 0.0013888, 0.0)" ) # No pollution by well -grass.run_command("r.mapcalc", expression="cin_1=0.0") +gs.run_command("r.mapcalc", expression="cin_1=0.0") # We have a transfer boundary condition -grass.run_command( - "r.mapcalc", expression="tstatus_1=if(col() == 1 || col() == 40 , 3, 1)" -) +gs.run_command("r.mapcalc", expression="tstatus_1=if(col() == 1 || col() == 40 , 3, 1)") # No diffusion coefficient known for the solution -grass.run_command("r.mapcalc", expression="diff_1=0.0") +gs.run_command("r.mapcalc", expression="diff_1=0.0") # Normal retardation -grass.run_command("r.mapcalc", expression="R_1=1.0") +gs.run_command("r.mapcalc", expression="R_1=1.0") # Longitudinal and transversal dispersivity length al = 100m, at = 10m AL = 100 @@ -95,7 +89,7 @@ # Compute the solute transport using the above defined dispersivity coefficients # for a timestep of 1000d -grass.run_command( +gs.run_command( "r.solute.transport", "c", error=0.000000000000001, @@ -124,14 +118,14 @@ ) # Get the maximum concentration -range = grass.parse_command("r.info", "r", map="stresult_conf_1") +range = gs.parse_command("r.info", "r", map="stresult_conf_1") # Normalize the result -grass.run_command( +gs.run_command( "r.mapcalc", expression="stresult_conf_1_norm = stresult_conf_1/" + str(range["max"]), ) # Create contour lines range from 0.7 to 0.1 in 0.1 steps -grass.run_command( +gs.run_command( "r.contour", input="stresult_conf_1_norm", output="stresult_conf_1_norm", @@ -144,11 +138,11 @@ # Used to compute a lower velocity, so the mean velocity is # about 1 m/d or 1.15*10^-5 m/s -grass.run_command("r.mapcalc", expression="poros_2=1") +gs.run_command("r.mapcalc", expression="poros_2=1") # Compute the solute transport using the above defined dispersivity coefficients for # a timestep of 1000d -grass.run_command( +gs.run_command( "r.solute.transport", "c", error=0.000000000000001, @@ -177,14 +171,14 @@ ) # Get the maximum concentration -range = grass.parse_command("r.info", "r", map="stresult_conf_2") +range = gs.parse_command("r.info", "r", map="stresult_conf_2") # Normalize the result -grass.run_command( +gs.run_command( "r.mapcalc", expression="stresult_conf_2_norm = stresult_conf_2/" + str(range["max"]), ) # Create contour lines range from 0.7 to 0.1 in 0.1 steps -grass.run_command( +gs.run_command( "r.contour", input="stresult_conf_2_norm", output="stresult_conf_2_norm", diff --git a/raster/r.solute.transport/seguin_verify_well.py b/raster/r.solute.transport/seguin_verify_well.py index 10ddc6a2dd5..85b82e53140 100755 --- a/raster/r.solute.transport/seguin_verify_well.py +++ b/raster/r.solute.transport/seguin_verify_well.py @@ -9,47 +9,45 @@ # series = "Handbuch zur Erkundung des Untergrundes von Deponien und Altlasten" # -import grass.script as grass +import grass.script as gs # Overwrite existing maps -grass.run_command("g.gisenv", set="OVERWRITE=1") +gs.run_command("g.gisenv", set="OVERWRITE=1") -grass.message(_("Set the region")) +gs.message(_("Set the region")) # The area is 2000m x 1000m with a cell size of 50m x 50m -grass.run_command("g.region", res=50, res3=50, t=25, b=0, n=1000, s=0, w=0, e=2000) +gs.run_command("g.region", res=50, res3=50, t=25, b=0, n=1000, s=0, w=0, e=2000) -grass.message(_("Create all the input maps needed for groundwater flow computation")) +gs.message(_("Create all the input maps needed for groundwater flow computation")) # Initial condition of the piezometric head, we have a huge gradient from 275m to 50m # over a distance of 2000m -grass.run_command("r.mapcalc", expression="phead_1=if(col() == 1 , 275, 50)") +gs.run_command("r.mapcalc", expression="phead_1=if(col() == 1 , 275, 50)") # Set the active cells and the dirichlet boundary condition -grass.run_command( - "r.mapcalc", expression="status_1=if(col() == 1 || col() == 40 , 2, 1)" -) +gs.run_command("r.mapcalc", expression="status_1=if(col() == 1 || col() == 40 , 2, 1)") # We have a single well with a small influent pumping rate -grass.run_command( +gs.run_command( "r.mapcalc", expression="well_1=if((row() == 10 && col() == 10), 0.000002818287, 0)" ) # The hydraulic conductivity -grass.run_command("r.mapcalc", expression="hydcond_1=0.0001") +gs.run_command("r.mapcalc", expression="hydcond_1=0.0001") # The recharge, well we have no recharge at all -grass.run_command("r.mapcalc", expression="recharge_1=0") +gs.run_command("r.mapcalc", expression="recharge_1=0") # We have a confined aquifer with a height of 25m -grass.run_command("r.mapcalc", expression="top_conf_1=25") +gs.run_command("r.mapcalc", expression="top_conf_1=25") # Bottom of the aquifer starts at 0m -grass.run_command("r.mapcalc", expression="bottom_1=0") +gs.run_command("r.mapcalc", expression="bottom_1=0") # This is the standard porosity of sand aquifer -grass.run_command("r.mapcalc", expression="poros_1=0.17") +gs.run_command("r.mapcalc", expression="poros_1=0.17") # The specific yield of a confined aquifer -grass.run_command("r.mapcalc", expression="syield_1=0.0001") -grass.run_command("r.mapcalc", expression="null_1=0.0") +gs.run_command("r.mapcalc", expression="syield_1=0.0001") +gs.run_command("r.mapcalc", expression="null_1=0.0") -grass.message("First compute a steady state groundwater flow") +gs.message("First compute a steady state groundwater flow") # Compute the steady state groundwater flow -grass.run_command( +gs.run_command( "r.gwflow", solver="cg", top="top_conf_1", @@ -66,27 +64,23 @@ type="confined", ) -grass.message(_("generate the transport data")) +gs.message(_("generate the transport data")) # The initial concentration is zero -grass.run_command( - "r.mapcalc", expression="c_1=if(col() == 10 && row() == 10 , 0.0, 0.0)" -) +gs.run_command("r.mapcalc", expression="c_1=if(col() == 10 && row() == 10 , 0.0, 0.0)") # No inner sources or sinks (result of chemical reaction) -grass.run_command("r.mapcalc", expression="cs_1=0.0") +gs.run_command("r.mapcalc", expression="cs_1=0.0") # The pollution is inserted by a well -grass.run_command( +gs.run_command( "r.mapcalc", expression="cin_1=if(col() == 10 && row() == 10 ," + str(0.2 / 86400) + ", 0.0)", ) # We have a transfer boundary condition -grass.run_command( - "r.mapcalc", expression="tstatus_1=if(col() == 1 || col() == 40 , 3, 1)" -) +gs.run_command("r.mapcalc", expression="tstatus_1=if(col() == 1 || col() == 40 , 3, 1)") # No diffusion coefficient known for the solution -grass.run_command("r.mapcalc", expression="diff_1=0.0") +gs.run_command("r.mapcalc", expression="diff_1=0.0") # Normal retardation -grass.run_command("r.mapcalc", expression="R_1=1.0") +gs.run_command("r.mapcalc", expression="R_1=1.0") # Longitudinal and transversal dispersivity length AL = 50 @@ -94,7 +88,7 @@ # Compute the solute transport using the above defined dispersivity coefficients # for a timestep of 250d -grass.run_command( +gs.run_command( "r.solute.transport", "c", error=0.000000000000001, @@ -121,14 +115,14 @@ ) # Get the maximum concentration -range = grass.parse_command("r.info", "r", map="stresult_conf_1") +range = gs.parse_command("r.info", "r", map="stresult_conf_1") # Normalize the result -grass.run_command( +gs.run_command( "r.mapcalc", expression="stresult_conf_1_norm = stresult_conf_1/" + str(range["max"]), ) # Create contour lines range from 0.7 to 0.1 in 0.1 steps -grass.run_command( +gs.run_command( "r.contour", input="stresult_conf_1_norm", output="stresult_conf_1_norm", @@ -143,7 +137,7 @@ # Compute the solute transport using the above defined dispersivity coefficients # for a timestep of 250d -grass.run_command( +gs.run_command( "r.solute.transport", "c", error=0.000000000000001, @@ -171,14 +165,14 @@ # Get the maximum concentration -range = grass.parse_command("r.info", "r", map="stresult_conf_2") +range = gs.parse_command("r.info", "r", map="stresult_conf_2") # Normalize the result -grass.run_command( +gs.run_command( "r.mapcalc", expression="stresult_conf_2_norm = stresult_conf_2/" + str(range["max"]), ) # Create contour lines range from 0.7 to 0.1 in 0.1 steps -grass.run_command( +gs.run_command( "r.contour", input="stresult_conf_2_norm", output="stresult_conf_2_norm", diff --git a/raster/r.spreadpath/path_finder.c b/raster/r.spreadpath/path_finder.c index 8b5cfe87a39..9cf98048d47 100644 --- a/raster/r.spreadpath/path_finder.c +++ b/raster/r.spreadpath/path_finder.c @@ -10,7 +10,7 @@ void path_finder(int row, int col, int backrow, int backcol) { - int data, new_backrow, new_backcol; + int data = 0, new_backrow = 0, new_backcol = 0; extern char *value; extern int nrows, ncols; extern SEGMENT in_row_seg, in_col_seg, out_seg; diff --git a/raster/r.statistics/o_kurt.c b/raster/r.statistics/o_kurt.c index b6383811dd4..0155ffa0893 100644 --- a/raster/r.statistics/o_kurt.c +++ b/raster/r.statistics/o_kurt.c @@ -17,7 +17,7 @@ int o_kurt(const char *basemap, const char *covermap, const char *outputmap, { struct Popen stats_child, reclass_child; FILE *stats, *reclass; - int first, i, count; + int first, i, count = 0; size_t mem; long basecat, covercat, catb, catc; double value, var, x; diff --git a/raster/r.statistics/o_sdev.c b/raster/r.statistics/o_sdev.c index 4a39cd76559..b49c134508f 100644 --- a/raster/r.statistics/o_sdev.c +++ b/raster/r.statistics/o_sdev.c @@ -17,7 +17,7 @@ int o_sdev(const char *basemap, const char *covermap, const char *outputmap, { struct Popen stats_child, reclass_child; FILE *stats, *reclass; - int first, i, count; + int first, i, count = 0; size_t mem; long basecat, covercat, catb, catc; double value, sdev, x; diff --git a/raster/r.statistics/o_skew.c b/raster/r.statistics/o_skew.c index e08c97e5951..09cca655d46 100644 --- a/raster/r.statistics/o_skew.c +++ b/raster/r.statistics/o_skew.c @@ -17,7 +17,7 @@ int o_skew(const char *basemap, const char *covermap, const char *outputmap, { struct Popen stats_child, reclass_child; FILE *stats, *reclass; - int first, i, count; + int first, i, count = 0; size_t mem; long basecat, covercat, catb, catc; double value, var, x; diff --git a/raster/r.statistics/o_var.c b/raster/r.statistics/o_var.c index 1e880d0026f..5f73ad10145 100644 --- a/raster/r.statistics/o_var.c +++ b/raster/r.statistics/o_var.c @@ -17,7 +17,7 @@ int o_var(const char *basemap, const char *covermap, const char *outputmap, { struct Popen stats_child, reclass_child; FILE *stats, *reclass; - int first, i, count; + int first, i, count = 0; size_t mem; long basecat, covercat, catb, catc; double value, vari, x; diff --git a/raster/r.stats.zonal/graphics_for_description.ipynb b/raster/r.stats.zonal/graphics_for_description.ipynb index 38b0f4c2a1a..b61d77d3c82 100644 --- a/raster/r.stats.zonal/graphics_for_description.ipynb +++ b/raster/r.stats.zonal/graphics_for_description.ipynb @@ -77,13 +77,6 @@ "!optipng -o7 {filename}\n", "Image(filename)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/raster/r.univar/CMakeLists.txt b/raster/r.univar/CMakeLists.txt index d6e323abad9..7db873ac479 100644 --- a/raster/r.univar/CMakeLists.txt +++ b/raster/r.univar/CMakeLists.txt @@ -9,6 +9,7 @@ build_program( DEPENDS grass_gis grass_raster + grass_parson LIBM OPTIONAL_DEPENDS OPENMP) @@ -22,6 +23,7 @@ build_program( grass_gis grass_raster grass_raster3d + grass_parson LIBM OPTIONAL_DEPENDS OPENMP) diff --git a/raster/r.univar/Makefile b/raster/r.univar/Makefile index f14d55967db..1513d3496a8 100644 --- a/raster/r.univar/Makefile +++ b/raster/r.univar/Makefile @@ -1,8 +1,8 @@ MODULE_TOPDIR = ../.. -LIBES2 = $(RASTERLIB) $(GISLIB) $(MATHLIB) $(OPENMP_LIBPATH) $(OPENMP_LIB) -LIBES3 = $(RASTER3DLIB) $(RASTERLIB) $(GISLIB) $(MATHLIB) $(OPENMP_LIBPATH) $(OPENMP_LIB) +LIBES2 = $(RASTERLIB) $(GISLIB) $(MATHLIB) $(OPENMP_LIBPATH) $(OPENMP_LIB) $(PARSONLIB) +LIBES3 = $(RASTER3DLIB) $(RASTERLIB) $(GISLIB) $(MATHLIB) $(OPENMP_LIBPATH) $(OPENMP_LIB) $(PARSONLIB) DEPENDENCIES = $(RASTER3DDEP) $(GISDEP) $(RASTERDEP) EXTRA_CFLAGS = $(OPENMP_CFLAGS) EXTRA_INC = $(OPENMP_INCPATH) diff --git a/raster/r.univar/globals.h b/raster/r.univar/globals.h index 38599361109..a2bbc184f4a 100644 --- a/raster/r.univar/globals.h +++ b/raster/r.univar/globals.h @@ -52,18 +52,20 @@ typedef struct { /* command line options are the same for raster and raster3d maps */ typedef struct { struct Option *inputfile, *zonefile, *percentile, *output_file, *separator, - *nprocs; + *nprocs, *format; struct Flag *shell_style, *extended, *table, *use_rast_region; } param_type; extern param_type param; extern zone_type zone_info; +enum OutputFormat { PLAIN, JSON }; + /* fn prototypes */ void heapsort_double(double *data, size_t n); void heapsort_float(float *data, size_t n); void heapsort_int(int *data, size_t n); -int print_stats(univar_stat *stats); +int print_stats(univar_stat *stats, enum OutputFormat format); int print_stats_table(univar_stat *stats); univar_stat *create_univar_stat_struct(int map_type, int n_perc); void free_univar_stat_struct(univar_stat *stats); diff --git a/raster/r.univar/r.univar.html b/raster/r.univar/r.univar.html index eaedaa0aae8..5220bc64a44 100644 --- a/raster/r.univar/r.univar.html +++ b/raster/r.univar/r.univar.html @@ -238,6 +238,44 @@

          Zonal statistics

          dataset) viewed through Libre/Open Office Calc. +

          JSON Output

          +
          +r.univar -e elevation percentile=98 format=json
          +
          +will output the results in JSON format: + +
          +[
          +    {
          +        "n": 2025000,
          +        "null_cells": 0,
          +        "cells": 2025000,
          +        "min": 55.578792572021484,
          +        "max": 156.32986450195312,
          +        "range": 100.75107192993164,
          +        "mean": 110.37544027560575,
          +        "mean_of_abs": 110.37544027560575,
          +        "stddev": 20.315323320598083,
          +        "variance": 412.7123616204363,
          +        "coeff_var": 18.40565552433679,
          +        "sum": 223510266.55810165,
          +        "first_quartile": 94.789985656738281,
          +        "median": 108.87990570068359,
          +        "third_quartile": 126.79196929931641,
          +         "percentiles": [
          +            {
          +                "percentile": 98,
          +                "value": 147.7265625
          +            },
          +            {
          +                "percentile": 9,
          +                "value": 83.494270324707031
          +            }
          +        ]
          +    }
          +]
          +
          +

          TODO

          To be implemented mode, skewness, kurtosis. diff --git a/raster/r.univar/r.univar_main.c b/raster/r.univar/r.univar_main.c index 3c070ca827d..84550a87347 100644 --- a/raster/r.univar/r.univar_main.c +++ b/raster/r.univar/r.univar_main.c @@ -110,6 +110,9 @@ void set_params(void) _("Table output format instead of standard output format"); param.table->guisection = _("Formatting"); + param.format = G_define_standard_option(G_OPT_F_FORMAT); + param.format->guisection = _("Print"); + param.use_rast_region = G_define_flag(); param.use_rast_region->key = 'r'; param.use_rast_region->description = @@ -140,6 +143,8 @@ int main(int argc, char *argv[]) const char *mapset, *name; int t; + enum OutputFormat format; + G_gisinit(argv[0]); module = G_define_module(); @@ -175,6 +180,13 @@ int main(int argc, char *argv[]) } } + if (strcmp(param.format->answer, "json") == 0) { + format = JSON; + } + else { + format = PLAIN; + } + /* set nprocs parameter */ int nprocs; sscanf(param.nprocs->answer, "%d", &nprocs); @@ -283,7 +295,7 @@ int main(int argc, char *argv[]) if (param.table->answer) print_stats_table(stats); else - print_stats(stats); + print_stats(stats, format); /* release memory */ free_univar_stat_struct(stats); diff --git a/raster/r.univar/r3.univar_main.c b/raster/r.univar/r3.univar_main.c index 5ad71240bbd..28fdb69acd5 100644 --- a/raster/r.univar/r3.univar_main.c +++ b/raster/r.univar/r3.univar_main.c @@ -66,6 +66,9 @@ void set_params(void) param.table->description = _("Table output format instead of standard output format"); + param.format = G_define_standard_option(G_OPT_F_FORMAT); + param.format->guisection = _("Print"); + return; } @@ -91,6 +94,8 @@ int main(int argc, char *argv[]) struct GModule *module; + enum OutputFormat format; + G_gisinit(argv[0]); module = G_define_module(); @@ -129,6 +134,13 @@ int main(int argc, char *argv[]) } } + if (strcmp(param.format->answer, "json") == 0) { + format = JSON; + } + else { + format = PLAIN; + } + /* table field separator */ zone_info.sep = G_option_to_separator(param.separator); @@ -318,7 +330,7 @@ int main(int argc, char *argv[]) if (param.table->answer) print_stats_table(stats); else - print_stats(stats); + print_stats(stats, format); /* release memory */ free_univar_stat_struct(stats); diff --git a/raster/r.univar/stats.c b/raster/r.univar/stats.c index efdcbe22f57..97367976103 100644 --- a/raster/r.univar/stats.c +++ b/raster/r.univar/stats.c @@ -11,6 +11,7 @@ * */ +#include #include "globals.h" /* *************************************************************** */ @@ -81,8 +82,20 @@ void free_univar_stat_struct(univar_stat *stats) /* *************************************************************** */ /* **** compute and print univar statistics to stdout ************ */ /* *************************************************************** */ -int print_stats(univar_stat *stats) +int print_stats(univar_stat *stats, enum OutputFormat format) { + JSON_Value *root_value, *zone_value; + JSON_Array *root_array; + JSON_Object *zone_object; + + if (format == JSON) { + root_value = json_value_init_array(); + if (root_value == NULL) { + G_fatal_error(_("Failed to initialize JSON array. Out of memory?")); + } + root_array = json_array(root_value); + } + int z, n_zones = zone_info.n_zones; if (n_zones == 0) @@ -117,7 +130,7 @@ int print_stats(univar_stat *stats) sprintf(sum_str, "%.15g", stats[z].sum); G_trim_decimal(sum_str); - if (!param.shell_style->answer) { + if (!param.shell_style->answer && format == PLAIN) { if (zone_info.n_zones) { int z_cat = z + zone_info.min; @@ -131,26 +144,61 @@ int print_stats(univar_stat *stats) fprintf(stdout, "Of the non-null cells:\n----------------------\n"); } - if (param.shell_style->answer) { + if (param.shell_style->answer || format == JSON) { + if (format == JSON) { + zone_value = json_value_init_object(); + zone_object = json_object(zone_value); + } if (zone_info.n_zones) { int z_cat = z + zone_info.min; - fprintf(stdout, "zone=%d;%s\n", z_cat, + switch (format) { + case PLAIN: + fprintf(stdout, "zone=%d;%s\n", z_cat, + Rast_get_c_cat(&z_cat, &(zone_info.cats))); + break; + case JSON: + json_object_set_number(zone_object, "zone_number", z_cat); + json_object_set_string( + zone_object, "zone_category", Rast_get_c_cat(&z_cat, &(zone_info.cats))); + break; + } + } + switch (format) { + case PLAIN: + fprintf(stdout, "n=%lu\n", stats[z].n); + fprintf(stdout, "null_cells=%lu\n", stats[z].size - stats[z].n); + fprintf(stdout, "cells=%lu\n", stats[z].size); + fprintf(stdout, "min=%.15g\n", stats[z].min); + fprintf(stdout, "max=%.15g\n", stats[z].max); + fprintf(stdout, "range=%.15g\n", stats[z].max - stats[z].min); + fprintf(stdout, "mean=%.15g\n", mean); + fprintf(stdout, "mean_of_abs=%.15g\n", + stats[z].sum_abs / stats[z].n); + fprintf(stdout, "stddev=%.15g\n", stdev); + fprintf(stdout, "variance=%.15g\n", variance); + fprintf(stdout, "coeff_var=%.15g\n", var_coef); + fprintf(stdout, "sum=%s\n", sum_str); + break; + case JSON: + json_object_set_number(zone_object, "n", stats[z].n); + json_object_set_number(zone_object, "null_cells", + stats[z].size - stats[z].n); + json_object_set_number(zone_object, "cells", stats[z].size); + json_object_set_number(zone_object, "min", stats[z].min); + json_object_set_number(zone_object, "max", stats[z].max); + json_object_set_number(zone_object, "range", + stats[z].max - stats[z].min); + json_object_set_number(zone_object, "mean", mean); + json_object_set_number(zone_object, "mean_of_abs", + stats[z].sum_abs / stats[z].n); + json_object_set_number(zone_object, "stddev", stdev); + json_object_set_number(zone_object, "variance", variance); + json_object_set_number(zone_object, "coeff_var", var_coef); + json_object_set_number(zone_object, "sum", stats[z].sum); + break; } - fprintf(stdout, "n=%lu\n", stats[z].n); - fprintf(stdout, "null_cells=%lu\n", stats[z].size - stats[z].n); - fprintf(stdout, "cells=%lu\n", stats[z].size); - fprintf(stdout, "min=%.15g\n", stats[z].min); - fprintf(stdout, "max=%.15g\n", stats[z].max); - fprintf(stdout, "range=%.15g\n", stats[z].max - stats[z].min); - fprintf(stdout, "mean=%.15g\n", mean); - fprintf(stdout, "mean_of_abs=%.15g\n", - stats[z].sum_abs / stats[z].n); - fprintf(stdout, "stddev=%.15g\n", stdev); - fprintf(stdout, "variance=%.15g\n", variance); - fprintf(stdout, "coeff_var=%.15g\n", var_coef); - fprintf(stdout, "sum=%s\n", sum_str); } else { fprintf(stdout, "n: %lu\n", stats[z].n); @@ -244,17 +292,57 @@ int print_stats(univar_stat *stats) } } - if (param.shell_style->answer) { - fprintf(stdout, "first_quartile=%g\n", quartile_25); - fprintf(stdout, "median=%g\n", median); - fprintf(stdout, "third_quartile=%g\n", quartile_75); + if (param.shell_style->answer || format == JSON) { + switch (format) { + case PLAIN: + fprintf(stdout, "first_quartile=%g\n", quartile_25); + fprintf(stdout, "median=%g\n", median); + fprintf(stdout, "third_quartile=%g\n", quartile_75); + break; + case JSON: + json_object_set_number(zone_object, "first_quartile", + quartile_25); + json_object_set_number(zone_object, "median", median); + json_object_set_number(zone_object, "third_quartile", + quartile_75); + break; + } + + JSON_Value *percentiles_array_value, *percentile_value; + JSON_Array *percentiles_array; + JSON_Object *percentile_object; + + if (format == JSON) { + percentiles_array_value = json_value_init_array(); + percentiles_array = json_array(percentiles_array_value); + } + for (i = 0; i < stats[z].n_perc; i++) { char buf[24]; - sprintf(buf, "%.15g", stats[z].perc[i]); + snprintf(buf, sizeof(buf), "%.15g", stats[z].perc[i]); G_strchg(buf, '.', '_'); - fprintf(stdout, "percentile_%s=%g\n", buf, - quartile_perc[i]); + switch (format) { + case PLAIN: + fprintf(stdout, "percentile_%s=%g\n", buf, + quartile_perc[i]); + break; + case JSON: + percentile_value = json_value_init_object(); + percentile_object = json_object(percentile_value); + json_object_set_number(percentile_object, "percentile", + stats[z].perc[i]); + json_object_set_number(percentile_object, "value", + quartile_perc[i]); + json_array_append_value(percentiles_array, + percentile_value); + break; + } + } + + if (format == JSON) { + json_object_set_value(zone_object, "percentiles", + percentiles_array_value); } } else { @@ -301,6 +389,19 @@ int print_stats(univar_stat *stats) * above with zone */ /* if (!(param.shell_style->answer)) G_message("\n"); */ + if (format == JSON) { + json_array_append_value(root_array, zone_value); + } + } + + if (format == JSON) { + char *serialized_string = json_serialize_to_string_pretty(root_value); + if (serialized_string == NULL) { + G_fatal_error(_("Failed to initialize pretty JSON string.")); + } + puts(serialized_string); + json_free_serialized_string(serialized_string); + json_value_free(root_value); } return 1; diff --git a/raster/r.univar/testsuite/test_r_univar.py b/raster/r.univar/testsuite/test_r_univar.py index c03aea5dcfa..de28f0753d5 100644 --- a/raster/r.univar/testsuite/test_r_univar.py +++ b/raster/r.univar/testsuite/test_r_univar.py @@ -3,8 +3,13 @@ @author Soeren Gebbert """ +import json +from itertools import zip_longest + from grass.gunittest.case import TestCase +from grass.gunittest.gmodules import SimpleModule + class TestRasterUnivar(TestCase): @classmethod @@ -562,11 +567,66 @@ def test_zone_with_gap_in_cats(self): sep="=", ) - -class TestAccumulateFails(TestCase): - def test_error_handling(self): - # No vector map, no strds, no coordinates - self.assertModuleFail("r.univar", flags="r", map="map_a", zones="map_b") + def test_json(self): + reference = [ + { + "zone_number": 1, + "zone_category": "", + "n": 3420, + "null_cells": 0, + "cells": 3420, + "min": 102, + "max": 309, + "range": 207, + "mean": 205.5, + "mean_of_abs": 205.5, + "stddev": 56.611983419296187, + "variance": 3204.9166666666665, + "coeff_var": 27.548410423015174, + "sum": 702810, + "first_quartile": 155, + "median": 205.5, + "percentiles": [{"percentile": 90, "value": 282}], + "third_quartile": 255, + }, + { + "zone_number": 2, + "zone_category": "", + "n": 12780, + "null_cells": 0, + "cells": 12780, + "min": 121, + "max": 380, + "range": 259, + "mean": 250.5, + "mean_of_abs": 250.5, + "stddev": 59.957623924457401, + "variance": 3594.9166666666665, + "coeff_var": 23.935179211360243, + "sum": 3201390, + "first_quartile": 200, + "median": 250.5, + "percentiles": [{"percentile": 90, "value": 330}], + "third_quartile": 300, + }, + ] + + module = SimpleModule( + "r.univar", + map=["map_a", "map_b"], + zones="zone_map", + flags="ge", + format="json", + ) + self.runModule(module) + output = json.loads(module.outputs.stdout) + for expected, received in zip_longest(reference, output): + self.assertCountEqual(list(expected.keys()), list(received.keys())) + for key in expected: + if isinstance(expected[key], float): + self.assertAlmostEqual(expected[key], received[key], places=6) + else: + self.assertEqual(expected[key], received[key]) if __name__ == "__main__": diff --git a/raster3d/r3.flow/CMakeLists.txt b/raster3d/r3.flow/CMakeLists.txt index 961d981b554..cc7d9258981 100644 --- a/raster3d/r3.flow/CMakeLists.txt +++ b/raster3d/r3.flow/CMakeLists.txt @@ -13,6 +13,7 @@ build_program( grass_raster grass_raster3d grass_vector + GDAL LIBM) set(test_r3flow_SRCS test_main.c flowline.c integrate.c interpolate.c @@ -31,4 +32,5 @@ build_program( grass_dbmiclient grass_dbmidriver grass_vector + GDAL LIBM) diff --git a/raster3d/r3.info/main.c b/raster3d/r3.info/main.c index 17b8b501f53..1a12cfcc126 100644 --- a/raster3d/r3.info/main.c +++ b/raster3d/r3.info/main.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { const char *mapset; char *line = NULL; - char tmp1[TMP_LENGTH], tmp2[TMP_LENGTH], tmp3[TMP_LENGTH]; + char tmp1[TMP_LENGTH] = "", tmp2[TMP_LENGTH] = "", tmp3[TMP_LENGTH] = ""; char timebuff[256]; int i; FILE *out; diff --git a/renovate.json5 b/renovate.json5 index f0d45a3e2eb..b5c0aeba9b8 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -19,5 +19,37 @@ // Renovate's pre-commit support is still opt-in ":enablePreCommit", - ] + + // weekly update of lock files (flake.lock) + ":maintainLockFilesWeekly", + "group:githubArtifactActions", + ], + + // enable Nix lock file update (flake.lock) + "nix": { + "enabled": true, + }, + + "packageRules": [ + { + "groupName": "ruff", + "matchPackageNames": [ + "astral-sh/ruff", + "astral-sh/ruff-pre-commit", + "ruff", + ], + }, + { + "groupName": "flake8", + "matchPackageNames": ["pycqa/flake8", "flake8"], + }, + { + "groupName": "black", + "matchPackageNames": [ + "psf/black-pre-commit-mirror", + "psf/black", + "black", + ], + }, + ], } diff --git a/scripts/d.frame/d.frame.py b/scripts/d.frame/d.frame.py index 2d75457bee0..e9b44b21650 100755 --- a/scripts/d.frame/d.frame.py +++ b/scripts/d.frame/d.frame.py @@ -96,7 +96,7 @@ def read_monitor_file(monitor, ftype="env"): fatal(_("Unable to get monitor info. %s"), e) lines = [] - for line in fd.readlines(): + for line in fd: lines.append(line) fd.close() @@ -311,22 +311,19 @@ def main(): fatal(_("Required parameter <%s> not set") % "at") # create new frame if not exists create_frame(monitor, options["frame"], options["at"]) - else: - if os.getenv("GRASS_OVERWRITE", "0") == "1": - warning( - _("Frame <%s> already exists and will be overwritten") - % options["frame"] + elif os.getenv("GRASS_OVERWRITE", "0") == "1": + warning( + _("Frame <%s> already exists and will be overwritten") % options["frame"] + ) + create_frame(monitor, options["frame"], options["at"], overwrite=True) + elif options["at"]: + warning( + _( + "Frame <%s> already found. An existing frame can be " + "overwritten by '%s' flag." ) - create_frame(monitor, options["frame"], options["at"], overwrite=True) - else: - if options["at"]: - warning( - _( - "Frame <%s> already found. An existing frame can be " - "overwritten by '%s' flag." - ) - % (options["frame"], "--overwrite") - ) + % (options["frame"], "--overwrite") + ) # select givenframe select_frame(monitor, options["frame"]) diff --git a/scripts/d.polar/d.polar.py b/scripts/d.polar/d.polar.py index ed26e0a1d42..4ef578d5676 100755 --- a/scripts/d.polar/d.polar.py +++ b/scripts/d.polar/d.polar.py @@ -510,7 +510,7 @@ def main(): occurrences = sorted([(math.radians(x), freq[x]) for x in freq]) # find the maximum value - maxradius = max([f for a, f in occurrences]) + maxradius = max(f for a, f in occurrences) # now do cos() sin() sine_cosine = [(math.cos(a) * f, math.sin(a) * f) for a, f in occurrences] diff --git a/scripts/d.rast.edit/d.rast.edit.py b/scripts/d.rast.edit/d.rast.edit.py index 61f6a63cedc..6519d10c7a1 100755 --- a/scripts/d.rast.edit/d.rast.edit.py +++ b/scripts/d.rast.edit/d.rast.edit.py @@ -77,7 +77,7 @@ import sys import math import atexit -import grass.script as grass +import grass.script as gs from grass.script.setup import set_gui_path @@ -91,7 +91,7 @@ if len(sys.argv) == 2: arg = sys.argv[1] if arg[0:2] == "--" or arg in {"help", "-help"}: - grass.parser() + gs.parser() # Either we didn't call g.parser, or it returned # At this point, there's nothing to be done except re-raise the exception raise @@ -114,7 +114,7 @@ def run(cmd, **kwargs): - grass.run_command(cmd, quiet=True, **kwargs) + gs.run_command(cmd, quiet=True, **kwargs) def wxGUI(): @@ -137,7 +137,7 @@ def __init__(self, app, parent): run("r.out.ppm", input=app.inmap, output=app.tempfile) self.image = wx.Bitmap(wx.Image(app.tempfile)) - grass.try_remove(app.tempfile) + gs.try_remove(app.tempfile) app.force_window() @@ -475,19 +475,19 @@ def __init__(self, options): wx.App.__init__(self) def initialize(self): - grass.use_temp_region() + gs.use_temp_region() run("g.region", raster=self.inmap) - reg = grass.region() + reg = gs.region() for k, f in wind_keys.values(): self.total[k] = (f)(reg[k]) self.cols = min(self.cols, self.total["cols"]) self.rows = min(self.rows, self.total["rows"]) - tempbase = grass.tempfile() - grass.try_remove(tempbase) + tempbase = gs.tempfile() + gs.try_remove(tempbase) self.tempfile = tempbase + ".ppm" self.tempmap = "tmp.d.rast.edit" @@ -498,7 +498,7 @@ def initialize(self): run("r.colors", map=self.outmap, rast=self.inmap) def cleanup(self): - grass.try_remove(self.tempfile) + gs.try_remove(self.tempfile) run("g.remove", flags="f", type="raster", name=self.tempmap) def finalize(self): @@ -506,28 +506,28 @@ def finalize(self): sys.exit(0) def save_map(self): - p = grass.feed_command( + p = gs.feed_command( "r.in.ascii", input="-", output=self.tempmap, quiet=True, overwrite=True ) outf = p.stdin - outf.write(grass.encode("north: %f\n" % self.wind["n"])) - outf.write(grass.encode("south: %f\n" % self.wind["s"])) - outf.write(grass.encode("east: %f\n" % self.wind["e"])) - outf.write(grass.encode("west: %f\n" % self.wind["w"])) - outf.write(grass.encode("rows: %d\n" % self.wind["rows"])) - outf.write(grass.encode("cols: %d\n" % self.wind["cols"])) - outf.write(grass.encode("null: *\n")) + outf.write(gs.encode("north: %f\n" % self.wind["n"])) + outf.write(gs.encode("south: %f\n" % self.wind["s"])) + outf.write(gs.encode("east: %f\n" % self.wind["e"])) + outf.write(gs.encode("west: %f\n" % self.wind["w"])) + outf.write(gs.encode("rows: %d\n" % self.wind["rows"])) + outf.write(gs.encode("cols: %d\n" % self.wind["cols"])) + outf.write(gs.encode("null: *\n")) for row in range(self.wind["rows"]): for col in range(self.wind["cols"]): if col > 0: - outf.write(grass.encode(" ")) + outf.write(gs.encode(" ")) val = self.values[row][col] if val and self.changed[row][col]: - outf.write(grass.encode("%s" % val)) + outf.write(gs.encode("%s" % val)) else: - outf.write(grass.encode("*")) - outf.write(grass.encode("\n")) + outf.write(gs.encode("*")) + outf.write(gs.encode("\n")) outf.close() p.wait() @@ -545,7 +545,7 @@ def save_map(self): def read_header(self, infile): wind = {} for i in range(6): - line = grass.decode(infile.readline()).rstrip("\r\n") + line = gs.decode(infile.readline()).rstrip("\r\n") f = line.split(":") key = f[0] val = f[1].strip() @@ -556,14 +556,14 @@ def read_header(self, infile): def read_data(self, infile): values = [] for row in range(self.wind["rows"]): - line = grass.decode(infile.readline()).rstrip("\r\n") + line = gs.decode(infile.readline()).rstrip("\r\n") values.append(line.split()) return values def load_map(self): run("g.region", **self.wind) - p = grass.pipe_command("r.out.ascii", input=self.inmap, quiet=True) + p = gs.pipe_command("r.out.ascii", input=self.inmap, quiet=True) self.wind = self.read_header(p.stdout) self.values = self.read_data(p.stdout) self.changed = [[False for c in row] for row in self.values] @@ -573,7 +573,7 @@ def load_map(self): run("r.out.ppm", input=self.inmap, output=self.tempfile) colorimg = wx.Image(self.tempfile) - grass.try_remove(self.tempfile) + gs.try_remove(self.tempfile) for row in range(self.wind["rows"]): for col in range(self.wind["cols"]): @@ -592,7 +592,7 @@ def load_aspect(self): if not self.aspect: return - p = grass.pipe_command("r.out.ascii", input=self.aspect, quiet=True) + p = gs.pipe_command("r.out.ascii", input=self.aspect, quiet=True) self.read_header(p.stdout) self.angles = self.read_data(p.stdout) p.wait() @@ -653,7 +653,7 @@ def force_color(self, val): run("g.remove", flags="f", type="raster", name=self.tempmap) tempimg = wx.Image(self.tempfile) - grass.try_remove(self.tempfile) + gs.try_remove(self.tempfile) rgb = tempimg.get(0, 0) color = "#%02x%02x%02x" % rgb @@ -721,7 +721,7 @@ def OnInit(self): if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() from gui_core.wrap import ClientDC, Menu, Panel diff --git a/scripts/d.rast.leg/d.rast.leg.py b/scripts/d.rast.leg/d.rast.leg.py index 855bf85e684..46c46928d9b 100755 --- a/scripts/d.rast.leg/d.rast.leg.py +++ b/scripts/d.rast.leg/d.rast.leg.py @@ -63,10 +63,10 @@ import sys import os -import grass.script as grass +import grass.script as gs -def make_frame(f, b, t, l, r): +def make_frame(f, b, t, l, r): # noqa: E741 (fl, fr, ft, fb) = f t /= 100.0 @@ -91,14 +91,14 @@ def main(): smooth = flags["s"] # for -n flag of d.legend - if not grass.find_file(map)["file"]: - grass.fatal(_("Raster map <%s> not found") % map) + if not gs.find_file(map)["file"]: + gs.fatal(_("Raster map <%s> not found") % map) # for rast= - if rast and not grass.find_file(rast)["file"]: - grass.fatal(_("Raster map <%s> not found") % rast) + if rast and not gs.find_file(rast)["file"]: + gs.fatal(_("Raster map <%s> not found") % rast) - s = grass.read_command("d.info", flags="f") + s = gs.read_command("d.info", flags="f") if not s: sys.exit(1) @@ -106,7 +106,7 @@ def main(): s = s.split(":")[1] f = tuple([float(x) for x in s.split()]) - grass.run_command("d.erase") + gs.run_command("d.erase") os.environ["GRASS_RENDER_FILE_READ"] = "TRUE" # draw title @@ -115,14 +115,12 @@ def main(): make_frame(f, 90, 100, 70, 100) # use map name without mapset suffix mapname = map.split("@")[0] - grass.run_command( - "d.text", color="black", size=5, at="5,97", align="cl", text=mapname - ) + gs.run_command("d.text", color="black", size=5, at="5,97", align="cl", text=mapname) # draw legend # set legend vertical position and size based on number of categories - cats = grass.read_command("r.describe", map=map, flags="1n") + cats = gs.read_command("r.describe", map=map, flags="1n") ncats = len(cats.strip().split("\n")) # Only need to adjust legend size if number of categories is between 1 and 10 @@ -139,7 +137,7 @@ def main(): else: lmap = map - kv = grass.raster_info(map=lmap) + kv = gs.raster_info(map=lmap) if kv["datatype"] == "CELL": leg_at = None else: @@ -161,13 +159,13 @@ def main(): # lflags += 'n' make_frame(f, 0, 90, 70, 100) - grass.run_command("d.legend", flags=lflags, raster=lmap, lines=nlines, at=leg_at) + gs.run_command("d.legend", flags=lflags, raster=lmap, lines=nlines, at=leg_at) # draw map make_frame(f, 0, 100, 0, 70) - grass.run_command("d.rast", map=map) + gs.run_command("d.rast", map=map) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() main() diff --git a/scripts/db.dropcolumn/db.dropcolumn.py b/scripts/db.dropcolumn/db.dropcolumn.py index a097ec3314f..24681b18b23 100755 --- a/scripts/db.dropcolumn/db.dropcolumn.py +++ b/scripts/db.dropcolumn/db.dropcolumn.py @@ -46,7 +46,7 @@ import string from grass.exceptions import CalledModuleError -import grass.script as gscript +import grass.script as gs def main(): @@ -57,10 +57,10 @@ def main(): force = flags["f"] # check if DB parameters are set, and if not set them. - gscript.run_command("db.connect", flags="c") + gs.run_command("db.connect", flags="c") if not database or not driver: - kv = gscript.db_connection() + kv = gs.db_connection() if not database: database = kv["database"] if not driver: @@ -68,10 +68,10 @@ def main(): # schema needed for PG? if force: - gscript.message(_("Forcing ...")) + gs.message(_("Forcing ...")) if column == "cat": - gscript.warning( + gs.warning( _( "Deleting <%s> column which may be needed to keep " "table connected to a vector map" @@ -80,22 +80,21 @@ def main(): ) cols = [ - f[0] - for f in gscript.db_describe(table, database=database, driver=driver)["cols"] + f[0] for f in gs.db_describe(table, database=database, driver=driver)["cols"] ] if column not in cols: - gscript.fatal(_("Column <%s> not found in table") % column) + gs.fatal(_("Column <%s> not found in table") % column) if not force: - gscript.message(_("Column <%s> would be deleted.") % column) - gscript.message("") - gscript.message( + gs.message(_("Column <%s> would be deleted.") % column) + gs.message("") + gs.message( _("You must use the force flag (-f) to actually remove it. Exiting.") ) return 0 if driver == "sqlite": - sqlite3_version = gscript.read_command( + sqlite3_version = gs.read_command( "db.select", sql="SELECT sqlite_version();", flags="c", @@ -111,7 +110,7 @@ def main(): # for older sqlite3 versions, use old way to remove column colnames = [] coltypes = [] - for f in gscript.db_describe(table)["cols"]: + for f in gs.db_describe(table)["cols"]: if f[0] != column: colnames.append(f[0]) coltypes.append("%s %s" % (f[0], f[1])) @@ -135,15 +134,15 @@ def main(): sql = "ALTER TABLE %s DROP COLUMN %s" % (table, column) try: - gscript.write_command( + gs.write_command( "db.execute", input="-", database=database, driver=driver, stdin=sql ) except CalledModuleError: - gscript.fatal(_("Cannot continue (problem deleting column)")) + gs.fatal(_("Cannot continue (problem deleting column)")) return 0 if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() sys.exit(main()) diff --git a/scripts/db.droptable/db.droptable.py b/scripts/db.droptable/db.droptable.py index 689185263fd..571638748cf 100755 --- a/scripts/db.droptable/db.droptable.py +++ b/scripts/db.droptable/db.droptable.py @@ -43,7 +43,7 @@ # %end import sys -import grass.script as grass +import grass.script as gs from grass.script.utils import encode @@ -53,9 +53,9 @@ def main(): if not options["driver"] or not options["database"]: # check if DB parameters are set, and if not set them. - grass.run_command("db.connect", flags="c", quiet=True) + gs.run_command("db.connect", flags="c", quiet=True) - kv = grass.db_connection() + kv = gs.db_connection() if options["database"]: database = options["database"] else: @@ -67,36 +67,36 @@ def main(): # schema needed for PG? if force: - grass.message(_("Forcing ...")) + gs.message(_("Forcing ...")) # check if table exists - if not grass.db_table_exist(table): - grass.warning(_("Table <%s> not found in database <%s>") % (table, database)) + if not gs.db_table_exist(table): + gs.warning(_("Table <%s> not found in database <%s>") % (table, database)) sys.exit(0) # check if table is used somewhere (connected to vector map) - used = grass.db.db_table_in_vector(table) + used = gs.db.db_table_in_vector(table) if used: - grass.warning( + gs.warning( _("Deleting table <%s> which is attached to following map(s):") % table ) for vect in used: - grass.warning("%s" % vect) + gs.warning("%s" % vect) if not force: - grass.message(_("The table <%s> would be deleted.") % table) - grass.message("") - grass.message(_("You must use the force flag to actually remove it. Exiting.")) + gs.message(_("The table <%s> would be deleted.") % table) + gs.message("") + gs.message(_("You must use the force flag to actually remove it. Exiting.")) sys.exit(0) - p = grass.feed_command("db.execute", input="-", database=database, driver=driver) + p = gs.feed_command("db.execute", input="-", database=database, driver=driver) p.stdin.write(encode("DROP TABLE " + table)) p.stdin.close() p.wait() if p.returncode != 0: - grass.fatal(_("Cannot continue (problem deleting table).")) + gs.fatal(_("Cannot continue (problem deleting table).")) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() main() diff --git a/scripts/db.in.ogr/db.in.ogr.py b/scripts/db.in.ogr/db.in.ogr.py index 32b3815e68a..a95919f4936 100755 --- a/scripts/db.in.ogr/db.in.ogr.py +++ b/scripts/db.in.ogr/db.in.ogr.py @@ -73,7 +73,7 @@ # %end import os -import grass.script as grass +import grass.script as gs from grass.script.utils import decode from grass.exceptions import CalledModuleError @@ -86,47 +86,47 @@ def main(): output = options["output"] key = options["key"] - mapset = grass.gisenv()["MAPSET"] + mapset = gs.gisenv()["MAPSET"] if db_table: input = db_table if not output: tmpname = input.replace(".", "_") - output = grass.basename(tmpname) + output = gs.basename(tmpname) # check if table exists try: nuldev = open(os.devnull, "w+") - s = grass.read_command("db.tables", flags="p", quiet=True, stderr=nuldev) + s = gs.read_command("db.tables", flags="p", quiet=True, stderr=nuldev) nuldev.close() except CalledModuleError: # check connection parameters, set if uninitialized - grass.read_command("db.connect", flags="c") - s = grass.read_command("db.tables", flags="p", quiet=True) + gs.read_command("db.connect", flags="c") + s = gs.read_command("db.tables", flags="p", quiet=True) for line in decode(s).splitlines(): if line == output: - if grass.overwrite(): - grass.warning( + if gs.overwrite(): + gs.warning( _("Table <%s> already exists and will be overwritten") % output ) - grass.write_command( + gs.write_command( "db.execute", input="-", stdin="DROP TABLE %s" % output ) break else: - grass.fatal(_("Table <%s> already exists") % output) + gs.fatal(_("Table <%s> already exists") % output) # treat DB as real vector map... - layer = db_table if db_table else None + layer = db_table or None vopts = {} if options["encoding"]: vopts["encoding"] = options["encoding"] try: - grass.run_command( + gs.run_command( "v.in.ogr", flags="o", input=input, @@ -139,12 +139,12 @@ def main(): ) except CalledModuleError: if db_table: - grass.fatal(_("Input table <%s> not found or not readable") % input) + gs.fatal(_("Input table <%s> not found or not readable") % input) else: - grass.fatal(_("Input DSN <%s> not found or not readable") % input) + gs.fatal(_("Input DSN <%s> not found or not readable") % input) # save db connection settings of the output - f = grass.vector_layer_db(output, "1") + f = gs.vector_layer_db(output, "1") table = f["table"] database = f["database"] @@ -152,13 +152,13 @@ def main(): # rename ID col if requested from cat to new name if key: - grass.write_command( + gs.write_command( "db.execute", quiet=True, input="-", stdin="ALTER TABLE %s ADD COLUMN %s integer" % (output, key), ) - grass.write_command( + gs.write_command( "db.execute", quiet=True, input="-", @@ -166,17 +166,17 @@ def main(): ) # ... and immediately drop the empty geometry - vectfile = grass.find_file(output, element="vector", mapset=mapset)["file"] + vectfile = gs.find_file(output, element="vector", mapset=mapset)["file"] if not vectfile: - grass.fatal(_("Something went wrong. Should not happen")) + gs.fatal(_("Something went wrong. Should not happen")) else: # remove the vector part - grass.run_command("v.db.connect", quiet=True, map=output, layer="1", flags="d") - grass.run_command("g.remove", flags="f", quiet=True, type="vector", name=output) + gs.run_command("v.db.connect", quiet=True, map=output, layer="1", flags="d") + gs.run_command("g.remove", flags="f", quiet=True, type="vector", name=output) # get rid of superfluous auto-added cat column (and cat_ if present) nuldev = open(os.devnull, "w+") - grass.run_command( + gs.run_command( "db.dropcolumn", quiet=True, flags="f", @@ -189,10 +189,10 @@ def main(): ) nuldev.close() - records = grass.db_describe(table, database=database, driver=driver)["nrows"] - grass.message(_("Imported table <%s> with %d rows") % (output, records)) + records = gs.db_describe(table, database=database, driver=driver)["nrows"] + gs.message(_("Imported table <%s> with %d rows") % (output, records)) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() main() diff --git a/scripts/db.univar/db.univar.py b/scripts/db.univar/db.univar.py index 1ffc81d8c3e..f941be42140 100755 --- a/scripts/db.univar/db.univar.py +++ b/scripts/db.univar/db.univar.py @@ -68,23 +68,23 @@ import json import math -import grass.script as gscript +import grass.script as gs def cleanup(): for ext in ["", ".sort"]: - gscript.try_remove(tmp + ext) + gs.try_remove(tmp + ext) def sortfile(infile, outfile): inf = open(infile, "r") outf = open(outfile, "w") - if gscript.find_program("sort", "--help"): - gscript.run_command("sort", flags="n", stdin=inf, stdout=outf) + if gs.find_program("sort", "--help"): + gs.run_command("sort", flags="n", stdin=inf, stdout=outf) else: # FIXME: we need a large-file sorting function - gscript.warning(_("'sort' not found: sorting in memory")) + gs.warning(_("'sort' not found: sorting in memory")) lines = inf.readlines() for i in range(len(lines)): lines[i] = float(lines[i].rstrip("\r\n")) @@ -103,7 +103,7 @@ def main(): # as well as pushing the limit of how long the function can be. # pylint: disable=too-many-branches global tmp - tmp = gscript.tempfile() + tmp = gs.tempfile() extend = flags["e"] shellstyle = flags["g"] @@ -125,25 +125,23 @@ def main(): elif shellstyle: # This can be a message or warning in future versions. # In version 9, -g may be removed. - gscript.verbose(_("The format option is used and -g flag ignored")) + gs.verbose(_("The format option is used and -g flag ignored")) - desc_table = gscript.db_describe(table, database=database, driver=driver) + desc_table = gs.db_describe(table, database=database, driver=driver) if not desc_table: - gscript.fatal(_("Unable to describe table <%s>") % table) + gs.fatal(_("Unable to describe table <%s>") % table) found = False for cname, ctype, cwidth in desc_table["cols"]: if cname == column: found = True if ctype not in {"INTEGER", "DOUBLE PRECISION"}: - gscript.fatal(_("Column <%s> is not numeric") % cname) + gs.fatal(_("Column <%s> is not numeric") % cname) if not found: - gscript.fatal(_("Column <%s> not found in table <%s>") % (column, table)) + gs.fatal(_("Column <%s> not found in table <%s>") % (column, table)) if output_format == "plain": - gscript.verbose( - _("Calculation for column <%s> of table <%s>...") % (column, table) - ) - gscript.message(_("Reading column values...")) + gs.verbose(_("Calculation for column <%s> of table <%s>...") % (column, table)) + gs.message(_("Reading column values...")) sql = "SELECT %s FROM %s" % (column, table) if where: @@ -156,7 +154,7 @@ def main(): driver = None tmpf = open(tmp, "w") - gscript.run_command( + gs.run_command( "db.select", flags="c", table=table, @@ -171,12 +169,12 @@ def main(): tmpf = open(tmp) if tmpf.read(1) == "": if output_format in {"plain", "shell"}: - gscript.fatal(_("Table <%s> contains no data.") % table) + gs.fatal(_("Table <%s> contains no data.") % table) tmpf.close() # calculate statistics if output_format == "plain": - gscript.verbose(_("Calculating statistics...")) + gs.verbose(_("Calculating statistics...")) N = 0 sum = 0.0 @@ -201,7 +199,7 @@ def main(): if N <= 0: if output_format in {"plain", "shell"}: - gscript.fatal(_("No non-null values found")) + gs.fatal(_("No non-null values found")) else: # We produce valid JSON with a value for n even when the query returned # no rows or when all values are nulls. @@ -313,23 +311,23 @@ def main(): pval[i] = 0 inf = open(tmp + ".sort") - l = 1 + line_number = 1 for line in inf: line = line.rstrip("\r\n") if len(line) == 0: continue - if l == q25pos: + if line_number == q25pos: q25 = float(line) - if l == q50apos: + if line_number == q50apos: q50a = float(line) - if l == q50bpos: + if line_number == q50bpos: q50b = float(line) - if l == q75pos: + if line_number == q75pos: q75 = float(line) for i in range(len(ppos)): - if l == ppos[i]: + if line_number == ppos[i]: pval[i] = float(line) - l += 1 + line_number += 1 q50 = (q50a + q50b) / 2 @@ -379,6 +377,6 @@ def main(): if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() atexit.register(cleanup) main() diff --git a/scripts/g.extension.all/g.extension.all.py b/scripts/g.extension.all/g.extension.all.py index 14a928ff9a1..8535dc06502 100644 --- a/scripts/g.extension.all/g.extension.all.py +++ b/scripts/g.extension.all/g.extension.all.py @@ -46,7 +46,7 @@ from urllib import request as urlrequest from urllib.error import HTTPError, URLError -import grass.script as gscript +import grass.script as gs from grass.exceptions import CalledModuleError HEADERS = { @@ -58,7 +58,7 @@ def get_extensions(): addon_base = os.getenv("GRASS_ADDON_BASE") if not addon_base: - gscript.fatal(_("%s not defined") % "GRASS_ADDON_BASE") + gs.fatal(_("%s not defined") % "GRASS_ADDON_BASE") fXML = os.path.join(addon_base, "modules.xml") if not os.path.exists(fXML): return [] @@ -68,13 +68,13 @@ def get_extensions(): try: tree = etree.fromstring(fo.read()) except Exception as e: - gscript.error(_("Unable to parse metadata file: %s") % e) + gs.error(_("Unable to parse metadata file: %s") % e) fo.close() return [] fo.close() - libgis_rev = gscript.version()["libgis_revision"] + libgis_rev = gs.version()["libgis_revision"] ret = [] for tnode in tree.findall("task"): gnode = tnode.find("libgis") @@ -107,7 +107,7 @@ def download_modules_xml_file(url, response_format, *args, **kwargs): if not response.code == 200: index = HTTP_STATUS_CODES.index(response.code) desc = HTTP_STATUS_CODES[index].description - gscript.fatal( + gs.fatal( _( "Download file from <{url}>, " "return status code {code}, " @@ -119,7 +119,7 @@ def download_modules_xml_file(url, response_format, *args, **kwargs): ), ) if response_format not in response.getheader("Content-Type"): - gscript.fatal( + gs.fatal( _( "Wrong file format downloaded. " "Check url <{url}>. Allowed file format is " @@ -133,7 +133,7 @@ def download_modules_xml_file(url, response_format, *args, **kwargs): except HTTPError as err: if err.code == 404: - gscript.fatal( + gs.fatal( _( "The download of the modules.xml file " "from the server was not successful. " @@ -147,7 +147,7 @@ def download_modules_xml_file(url, response_format, *args, **kwargs): response_format=response_format, ) except URLError: - gscript.fatal( + gs.fatal( _( "Download file from <{url}>, " "failed. Check internet connection.".format( @@ -176,7 +176,7 @@ def find_addon_name(addons): if grass_version != "unknown": major, minor, patch = grass_version.split(".") else: - gscript.fatal(_("Unable to get GRASS GIS version.")) + gs.fatal(_("Unable to get GRASS GIS version.")) url = "https://grass.osgeo.org/addons/grass{major}/modules.xml".format( major=major, ) @@ -196,7 +196,7 @@ def find_addon_name(addons): found = True break if not found: - gscript.warning( + gs.warning( _( "The <{}> addon cannot be reinstalled. " "Addon wasn't found among the official " @@ -209,36 +209,34 @@ def find_addon_name(addons): def main(): remove = options["operation"] == "remove" if remove or flags["f"]: - extensions = gscript.read_command( - "g.extension", quiet=True, flags="a" - ).splitlines() + extensions = gs.read_command("g.extension", quiet=True, flags="a").splitlines() else: extensions = get_extensions() if not extensions: if remove: - gscript.info(_("No extension found. Nothing to remove.")) + gs.info(_("No extension found. Nothing to remove.")) else: - gscript.info( + gs.info( _("Nothing to rebuild. Rebuilding process can be forced with -f flag.") ) return 0 if remove and not flags["f"]: - gscript.message(_("List of extensions to be removed:")) + gs.message(_("List of extensions to be removed:")) print(os.linesep.join(extensions)) - gscript.message( + gs.message( _("You must use the force flag (-f) to actually remove them. Exiting.") ) return 0 for ext in find_addon_name(addons=extensions): - gscript.message("-" * 60) + gs.message("-" * 60) if remove: - gscript.message(_("Removing extension <%s>...") % ext) + gs.message(_("Removing extension <%s>...") % ext) else: - gscript.message(_("Reinstalling extension <%s>...") % ext) - gscript.message("-" * 60) + gs.message(_("Reinstalling extension <%s>...") % ext) + gs.message("-" * 60) if remove: operation = "remove" operation_flags = "f" @@ -246,15 +244,15 @@ def main(): operation = "add" operation_flags = "" try: - gscript.run_command( + gs.run_command( "g.extension", flags=operation_flags, extension=ext, operation=operation ) except CalledModuleError: - gscript.error(_("Unable to process extension:%s") % ext) + gs.error(_("Unable to process extension:%s") % ext) return 0 if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() sys.exit(main()) diff --git a/scripts/g.extension/g.extension.py b/scripts/g.extension/g.extension.py index 3f2f5b6c7ee..fb399db9d06 100644 --- a/scripts/g.extension/g.extension.py +++ b/scripts/g.extension/g.extension.py @@ -489,8 +489,7 @@ def urlretrieve(url, filename, *args, **kwargs): """ request = urlrequest.Request(url, headers=HEADERS) response = urlrequest.urlopen(request, *args, **kwargs) - with open(filename, "wb") as f: - f.write(response.read()) + Path(filename).write_bytes(response.read()) def urlopen(url, *args, **kwargs): @@ -572,8 +571,7 @@ def get_default_branch(full_url): def etree_fromfile(filename): """Create XML element tree from a given file name""" - with open(filename, "r") as file_: - return etree.fromstring(file_.read()) + return etree.fromstring(Path(filename).read_text()) def etree_fromurl(url): @@ -667,11 +665,10 @@ def list_installed_extensions(toolboxes=False): gs.message(_("List of installed extensions (modules):")) sys.stdout.write("\n".join(elist)) sys.stdout.write("\n") + elif toolboxes: + gs.info(_("No extension (toolbox) installed")) else: - if toolboxes: - gs.info(_("No extension (toolbox) installed")) - else: - gs.info(_("No extension (module) installed")) + gs.info(_("No extension (module) installed")) def get_installed_toolboxes(force=False): @@ -722,11 +719,13 @@ def get_installed_modules(force=False): for tnode in tree.findall("task"): if flags["g"]: desc, keyw = get_optional_params(tnode) - ret.append("name={0}".format(tnode.get("name").strip())) - ret.append("description={0}".format(desc)) - ret.append("keywords={0}".format(keyw)) - ret.append( - "executables={0}".format(",".join(get_module_executables(tnode))) + ret.extend( + ( + "name={0}".format(tnode.get("name").strip()), + "description={0}".format(desc), + "keywords={0}".format(keyw), + "executables={0}".format(",".join(get_module_executables(tnode))), + ) ) else: ret.append(tnode.get("name").strip()) @@ -756,9 +755,8 @@ def list_available_extensions(url): print("%s (%s)" % (toolbox_data["name"], toolbox_code)) if flags["c"] or flags["g"]: list_available_modules(url, toolbox_data["modules"]) - else: - if toolbox_data["modules"]: - print(os.linesep.join(["* " + x for x in toolbox_data["modules"]])) + elif toolbox_data["modules"]: + print(os.linesep.join(["* " + x for x in toolbox_data["modules"]])) else: gs.message(_("List of available extensions (modules):")) # TODO: extensions with several modules + lib @@ -1292,8 +1290,7 @@ def install_toolbox_xml(url, name): write_xml_modules(xml_file) # read XML file - with open(xml_file, "r") as xml: - tree = etree.fromstring(xml.read()) + tree = etree.fromstring(Path(xml_file).read_text()) # update tree tnode = None @@ -1796,16 +1793,14 @@ def is_binary_string(bytes): continue # ignore binary files # read content of text file - with open(filename, "rb") as fd: - data = fd.read() + data = Path(filename).read_bytes() # we don't expect there would be CRLF file by # purpose if we want to allow CRLF files we would # have to whitelite .py etc newdata = data.replace(b"\r\n", b"\n") if newdata != data: - with open(filename, "wb") as newfile: - newfile.write(newdata) + Path(filename).write_bytes(newdata) def extract_zip(name, directory, tmpdir): @@ -1898,7 +1893,7 @@ def download_source_code( ) ) download_source_code_svn(url, name, outdev, directory) - elif source in {"remote_zip"}: + elif source == "remote_zip": gs.message( _("Fetching <{name}> from <{url}> (be patient)...").format( name=name, url=url @@ -1998,7 +1993,7 @@ def install_extension_std_platforms(name, source, url, branch): if filename == "Makefile": # get the module name: PGM = with open(os.path.join(r, "Makefile")) as fp: - for line in fp.readlines(): + for line in fp: if re.match(r"PGM.*.=|PGM=", line): try: modulename = line.split("=")[1].strip() @@ -2076,7 +2071,7 @@ def install_extension_std_platforms(name, source, url, branch): if not os.path.exists(os.path.join(gisbase, "include", "Make", "Module.make")): gs.fatal(_("Please install GRASS development package")) - if 0 != gs.call(make_cmd, stdout=outdev): + if gs.call(make_cmd, stdout=outdev) != 0: gs.fatal(_("Compilation failed, sorry. Please check above error messages.")) if flags["i"]: @@ -2195,23 +2190,22 @@ def remove_extension(force=False): for ename in edict: if ename in eremoved: gs.message(_("Extension <%s> successfully uninstalled.") % ename) - else: - if flags["t"]: - gs.warning( - _( - "Toolbox <%s> not removed. " - "Re-run '%s' with '-f' flag to force removal" - ) - % (options["extension"], "g.extension") + elif flags["t"]: + gs.warning( + _( + "Toolbox <%s> not removed. " + "Re-run '%s' with '-f' flag to force removal" ) - else: - gs.warning( - _( - "Extension <%s> not removed. " - "Re-run '%s' with '-f' flag to force removal" - ) - % (options["extension"], "g.extension") + % (options["extension"], "g.extension") + ) + else: + gs.warning( + _( + "Extension <%s> not removed. " + "Re-run '%s' with '-f' flag to force removal" ) + % (options["extension"], "g.extension") + ) # remove existing extension(s) (reading XML file) @@ -2593,15 +2587,14 @@ def resolve_known_host_service(url, name, branch): if "branch" in match["url_end"]: suffix = match["url_end"].format( name=name, - branch=branch if branch else get_default_branch(url), + branch=branch or get_default_branch(url), ) else: suffix = match["url_end"].format(name=name) url = "{prefix}{base}{suffix}".format( prefix=actual_start, base=url.rstrip("/"), suffix=suffix ) - gs.verbose - (_("Will use the following URL for download: {0}").format(url)) + gs.verbose(_("Will use the following URL for download: {0}").format(url)) return "remote_zip", url else: return None, None diff --git a/scripts/g.extension/testsuite/test_addons_download.py b/scripts/g.extension/testsuite/test_addons_download.py index e5077f9894e..c4618306d12 100644 --- a/scripts/g.extension/testsuite/test_addons_download.py +++ b/scripts/g.extension/testsuite/test_addons_download.py @@ -159,7 +159,7 @@ def test_github_install_official_multimodule(self): for file in files: self.assertFileExists(file) - if file.suffix != ".html" and file.suffix != ".py": + if file.suffix not in {".html", ".py"}: self.assertModule(str(file), help=True) def test_github_install_official_non_exists_module(self): @@ -203,8 +203,7 @@ def test_github_official_module_man_page_src_code_links_exists(self): ) html_man_page = self.install_prefix / "docs" / "html" / "db.join.html" self.assertFileExists(str(html_man_page)) - with open(html_man_page) as f: - content = f.read() + content = Path(html_man_page).read_text() for link_name in [f"{extension} source code", "history"]: url = re.search(rf"{link_name}", content).group(1) self.assertTrue(url) diff --git a/scripts/i.colors.enhance/i.colors.enhance.py b/scripts/i.colors.enhance/i.colors.enhance.py index c64406a51e2..68444007bd6 100755 --- a/scripts/i.colors.enhance/i.colors.enhance.py +++ b/scripts/i.colors.enhance/i.colors.enhance.py @@ -70,7 +70,7 @@ import sys import multiprocessing as mp -import grass.script as gscript +import grass.script as gs def get_percentile(map, percentiles): @@ -79,7 +79,7 @@ def get_percentile(map, percentiles): val2 = percentiles[1] values = "%s,%s" % (val1, val2) - s = gscript.read_command("r.quantile", input=map, percentiles=values, quiet=True) + s = gs.read_command("r.quantile", input=map, percentiles=values, quiet=True) val_str1 = s.splitlines()[0].split(":")[2] val_str2 = s.splitlines()[1].split(":")[2] @@ -97,7 +97,7 @@ def get_percentile_mp(map, percentiles, conn): output_pipe, input_pipe = conn input_pipe.close() result = get_percentile(map, percentiles) - gscript.debug("child (%s) (%.1f, %.1f)" % (map, result[0], result[1])) + gs.debug("child (%s) (%.1f, %.1f)" % (map, result[0], result[1])) output_pipe.send(result) output_pipe.close() @@ -106,7 +106,7 @@ def set_colors(map, v0, v1): rules = "".join( ["0% black\n", "%f black\n" % v0, "%f white\n" % v1, "100% white\n"] ) - gscript.write_command("r.colors", map=map, rules="-", stdin=rules, quiet=True) + gs.write_command("r.colors", map=map, rules="-", stdin=rules, quiet=True) def main(): @@ -124,29 +124,29 @@ def main(): check = True for m in [red, green, blue]: - ex = gscript.find_file(m) + ex = gs.find_file(m) if ex["name"] == "": check = False - gscript.warning("Raster map <{}> not found ".format(m)) + gs.warning("Raster map <{}> not found ".format(m)) if not check: - gscript.fatal("At least one of the input raster map was not found") + gs.fatal("At least one of the input raster map was not found") # 90 or 98? MAX value controls brightness # think of percent (0-100), must be positive or 0 # must be more than "2" ? if full: for i in [red, green, blue]: - gscript.run_command("r.colors", map=i, color="grey", quiet=True) + gs.run_command("r.colors", map=i, color="grey", quiet=True) sys.exit(0) if reset: for i in [red, green, blue]: - gscript.run_command("r.colors", map=i, color="grey255", quiet=True) + gs.run_command("r.colors", map=i, color="grey255", quiet=True) sys.exit(0) if not preserve: if do_mp: - gscript.message(_("Processing...")) + gs.message(_("Processing...")) # set up jobs and launch them proc = {} conn = {} @@ -161,22 +161,22 @@ def main(): ), ) proc[i].start() - gscript.percent(1, 2, 1) + gs.percent(1, 2, 1) # collect results and wait for jobs to finish for i in [red, green, blue]: output_pipe, input_pipe = conn[i] (v0, v1) = input_pipe.recv() - gscript.debug("parent (%s) (%.1f, %.1f)" % (i, v0, v1)) + gs.debug("parent (%s) (%.1f, %.1f)" % (i, v0, v1)) input_pipe.close() proc[i].join() set_colors(i, v0, v1) - gscript.percent(1, 1, 1) + gs.percent(1, 1, 1) else: for i in [red, green, blue]: - gscript.message(_("Processing...")) + gs.message(_("Processing...")) (v0, v1) = get_percentile(i, ["2", brightness]) - gscript.debug("<%s>: min=%f max=%f" % (i, v0, v1)) + gs.debug("<%s>: min=%f max=%f" % (i, v0, v1)) set_colors(i, v0, v1) else: @@ -184,7 +184,7 @@ def main(): all_min = 999999 if do_mp: - gscript.message(_("Processing...")) + gs.message(_("Processing...")) # set up jobs and launch jobs proc = {} conn = {} @@ -199,37 +199,37 @@ def main(): ), ) proc[i].start() - gscript.percent(1, 2, 1) + gs.percent(1, 2, 1) # collect results and wait for jobs to finish for i in [red, green, blue]: output_pipe, input_pipe = conn[i] (v0, v1) = input_pipe.recv() - gscript.debug("parent (%s) (%.1f, %.1f)" % (i, v0, v1)) + gs.debug("parent (%s) (%.1f, %.1f)" % (i, v0, v1)) input_pipe.close() proc[i].join() all_min = min(all_min, v0) all_max = max(all_max, v1) - gscript.percent(1, 1, 1) + gs.percent(1, 1, 1) else: for i in [red, green, blue]: - gscript.message(_("Processing...")) + gs.message(_("Processing...")) (v0, v1) = get_percentile(i, ["2", brightness]) - gscript.debug("<%s>: min=%f max=%f" % (i, v0, v1)) + gs.debug("<%s>: min=%f max=%f" % (i, v0, v1)) all_min = min(all_min, v0) all_max = max(all_max, v1) - gscript.debug("all_min=%f all_max=%f" % (all_min, all_max)) + gs.debug("all_min=%f all_max=%f" % (all_min, all_max)) for i in [red, green, blue]: set_colors(i, all_min, all_max) # write cmd history: - mapset = gscript.gisenv()["MAPSET"] + mapset = gs.gisenv()["MAPSET"] for i in [red, green, blue]: - if gscript.find_file(i)["mapset"] == mapset: - gscript.raster_history(i) + if gs.find_file(i)["mapset"] == mapset: + gs.raster_history(i) if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() main() diff --git a/scripts/i.image.mosaic/i.image.mosaic.py b/scripts/i.image.mosaic/i.image.mosaic.py index a11edc14146..df194c49c8f 100755 --- a/scripts/i.image.mosaic/i.image.mosaic.py +++ b/scripts/i.image.mosaic/i.image.mosaic.py @@ -34,23 +34,23 @@ # %option G_OPT_R_OUTPUT # %end -import grass.script as gscript +import grass.script as gs def copy_colors(fh, map, offset): - p = gscript.pipe_command("r.colors.out", map=map) + p = gs.pipe_command("r.colors.out", map=map) for line in p.stdout: - f = gscript.decode(line).rstrip("\r\n").split(" ") + f = gs.decode(line).rstrip("\r\n").split(" ") if offset: if f[0] in {"nv", "default"}: continue f[0] = str(float(f[0]) + offset) - fh.write(gscript.encode(" ".join(f) + "\n")) + fh.write(gs.encode(" ".join(f) + "\n")) p.wait() def get_limit(map): - return gscript.raster_info(map)["max"] + return gs.raster_info(map)["max"] def make_expression(i, count): @@ -67,7 +67,7 @@ def main(): count = len(images) msg = _("Do not forget to set region properly to cover all images.") - gscript.warning(msg) + gs.warning(msg) offset = 0 offsets = [] @@ -78,24 +78,24 @@ def main(): parms["offset%d" % (n + 1)] = offset offset += get_limit(img) + 1 - gscript.message(_("Mosaicing %d images...") % count) + gs.message(_("Mosaicing %d images...") % count) - gscript.mapcalc("$output = " + make_expression(1, count), output=output, **parms) + gs.mapcalc("$output = " + make_expression(1, count), output=output, **parms) # modify the color table: - p = gscript.feed_command("r.colors", map=output, rules="-") + p = gs.feed_command("r.colors", map=output, rules="-") for img, offset in zip(images, offsets): print(img, offset) copy_colors(p.stdin, img, offset) p.stdin.close() p.wait() - gscript.message(_("Done. Raster map <%s> created.") % output) + gs.message(_("Done. Raster map <%s> created.") % output) # write cmd history: - gscript.raster_history(output) + gs.raster_history(output) if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() main() diff --git a/scripts/i.in.spotvgt/i.in.spotvgt.py b/scripts/i.in.spotvgt/i.in.spotvgt.py index 61be75f8d49..cd744d4c252 100755 --- a/scripts/i.in.spotvgt/i.in.spotvgt.py +++ b/scripts/i.in.spotvgt/i.in.spotvgt.py @@ -50,7 +50,7 @@ import os import atexit import string -import grass.script as gscript +import grass.script as gs from grass.exceptions import CalledModuleError @@ -112,8 +112,8 @@ def create_VRT_file(projfile, vrtfile, infile): def cleanup(): # clean up the mess - gscript.try_remove(vrtfile) - gscript.try_remove(tmpfile) + gs.try_remove(vrtfile) + gs.try_remove(tmpfile) def main(): @@ -124,37 +124,37 @@ def main(): also = flags["a"] # check for gdalinfo (just to check if installation is complete) - if not gscript.find_program("gdalinfo", "--help"): - gscript.fatal( + if not gs.find_program("gdalinfo", "--help"): + gs.fatal( _("'gdalinfo' not found, install GDAL tools first (http://www.gdal.org)") ) pid = str(os.getpid()) - tmpfile = gscript.tempfile() + tmpfile = gs.tempfile() # let's go spotdir = os.path.dirname(infile) - spotname = gscript.basename(infile, "hdf") + spotname = gs.basename(infile, "hdf") if rast: name = rast else: name = spotname - if not gscript.overwrite() and gscript.find_file(name)["file"]: - gscript.fatal(_("<%s> already exists. Aborting.") % name) + if not gs.overwrite() and gs.find_file(name)["file"]: + gs.fatal(_("<%s> already exists. Aborting.") % name) # still a ZIP file? (is this portable?? see the r.in.srtm script for # ideas) if infile.lower().endswith(".zip"): - gscript.fatal(_("Please extract %s before import.") % infile) + gs.fatal(_("Please extract %s before import.") % infile) try: - p = gscript.Popen(["file", "-ib", infile], stdout=gscript.PIPE) + p = gs.Popen(["file", "-ib", infile], stdout=gs.PIPE) s = p.communicate()[0] if s == "application/x-zip": - gscript.fatal(_("Please extract %s before import.") % infile) + gs.fatal(_("Please extract %s before import.") % infile) except Exception: pass @@ -164,17 +164,17 @@ def main(): vrtfile = tmpfile + ".vrt" # first process the NDVI: - gscript.try_remove(vrtfile) + gs.try_remove(vrtfile) create_VRT_file(projfile, vrtfile, infile) # let's import the NDVI map... - gscript.message(_("Importing SPOT VGT NDVI map...")) + gs.message(_("Importing SPOT VGT NDVI map...")) try: - gscript.run_command("r.in.gdal", input=vrtfile, output=name) + gs.run_command("r.in.gdal", input=vrtfile, output=name) except CalledModuleError: - gscript.fatal(_("An error occurred. Stop.")) + gs.fatal(_("An error occurred. Stop.")) - gscript.message(_("Imported SPOT VEGETATION NDVI map <%s>.") % name) + gs.message(_("Imported SPOT VEGETATION NDVI map <%s>.") % name) ################# # http://www.vgt.vito.be/faq/FAQS/faq19.html @@ -187,21 +187,21 @@ def main(): # clone current region # switch to a temporary region - gscript.use_temp_region() + gs.use_temp_region() - gscript.run_command("g.region", raster=name, quiet=True) + gs.run_command("g.region", raster=name, quiet=True) - gscript.message(_("Remapping digital numbers to NDVI...")) + gs.message(_("Remapping digital numbers to NDVI...")) tmpname = "%s_%s" % (name, pid) - gscript.mapcalc("$tmpname = 0.004 * $name - 0.1", tmpname=tmpname, name=name) - gscript.run_command("g.remove", type="raster", name=name, quiet=True, flags="f") - gscript.run_command("g.rename", raster=(tmpname, name), quiet=True) + gs.mapcalc("$tmpname = 0.004 * $name - 0.1", tmpname=tmpname, name=name) + gs.run_command("g.remove", type="raster", name=name, quiet=True, flags="f") + gs.run_command("g.rename", raster=(tmpname, name), quiet=True) # write cmd history: - gscript.raster_history(name) + gs.raster_history(name) # apply color table: - gscript.run_command("r.colors", map=name, color="ndvi", quiet=True) + gs.run_command("r.colors", map=name, color="ndvi", quiet=True) ########################## # second, optionally process the SM quality map: @@ -232,8 +232,8 @@ def main(): # A good map threshold: >= 248 if also: - gscript.message(_("Importing SPOT VGT NDVI quality map...")) - gscript.try_remove(vrtfile) + gs.message(_("Importing SPOT VGT NDVI quality map...")) + gs.try_remove(vrtfile) qname = spotname.replace("NDV", "SM") qfile = os.path.join(spotdir, qname) create_VRT_file(projfile, vrtfile, qfile) @@ -241,9 +241,9 @@ def main(): # let's import the SM quality map... smfile = name + ".sm" try: - gscript.run_command("r.in.gdal", input=vrtfile, output=smfile) + gs.run_command("r.in.gdal", input=vrtfile, output=smfile) except CalledModuleError: - gscript.fatal(_("An error occurred. Stop.")) + gs.fatal(_("An error occurred. Stop.")) # some of the possible values: rules = [ @@ -262,38 +262,38 @@ def main(): "252 green", ] ] - gscript.write_command("r.colors", map=smfile, rules="-", stdin=rules) + gs.write_command("r.colors", map=smfile, rules="-", stdin=rules) - gscript.message(_("Imported SPOT VEGETATION SM quality map <%s>.") % smfile) - gscript.message( + gs.message(_("Imported SPOT VEGETATION SM quality map <%s>.") % smfile) + gs.message( _( "Note: A snow map can be extracted by category " "252 (d.rast %s cat=252)" ) % smfile ) - gscript.message("") - gscript.message(_("Filtering NDVI map by Status Map quality layer...")) + gs.message("") + gs.message(_("Filtering NDVI map by Status Map quality layer...")) filtfile = "%s_filt" % name - gscript.mapcalc( + gs.mapcalc( "$filtfile = if($smfile % 4 == 3 || " "($smfile / 16) % 16 == 0, null(), $name)", filtfile=filtfile, smfile=smfile, name=name, ) - gscript.run_command("r.colors", map=filtfile, color="ndvi", quiet=True) - gscript.message(_("Filtered SPOT VEGETATION NDVI map <%s>.") % filtfile) + gs.run_command("r.colors", map=filtfile, color="ndvi", quiet=True) + gs.message(_("Filtered SPOT VEGETATION NDVI map <%s>.") % filtfile) # write cmd history: - gscript.raster_history(smfile) - gscript.raster_history(filtfile) + gs.raster_history(smfile) + gs.raster_history(filtfile) - gscript.message(_("Done.")) + gs.message(_("Done.")) if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() atexit.register(cleanup) main() diff --git a/scripts/i.pansharpen/i.pansharpen.py b/scripts/i.pansharpen/i.pansharpen.py index d0b06e53727..ff0146d7708 100755 --- a/scripts/i.pansharpen/i.pansharpen.py +++ b/scripts/i.pansharpen/i.pansharpen.py @@ -101,12 +101,12 @@ except ImportError: hasNumPy = False -import grass.script as grass +import grass.script as gs def main(): if not hasNumPy: - grass.fatal(_("Required dependency NumPy not found. Exiting.")) + gs.fatal(_("Required dependency NumPy not found. Exiting.")) sharpen = options["method"] # sharpening algorithm ms1_orig = options["blue"] # blue channel @@ -122,17 +122,17 @@ def main(): # Checking bit depth bits = float(bits) if bits < 2 or bits > 30: - grass.warning(_("Bit depth is outside acceptable range")) + gs.warning(_("Bit depth is outside acceptable range")) return - outb = grass.core.find_file("%s_blue" % out) - outg = grass.core.find_file("%s_green" % out) - outr = grass.core.find_file("%s_red" % out) + outb = gs.core.find_file("%s_blue" % out) + outg = gs.core.find_file("%s_green" % out) + outr = gs.core.find_file("%s_red" % out) if ( outb["name"] != "" or outg["name"] != "" or outr["name"] != "" - ) and not grass.overwrite(): - grass.warning( + ) and not gs.overwrite(): + gs.warning( _( "Maps with selected output prefix names already exist." " Delete them or use overwrite flag" @@ -150,28 +150,28 @@ def main(): if not rescale: if bits == 8: - grass.message(_("Using 8bit image channels")) + gs.message(_("Using 8bit image channels")) if sproc: # serial processing - grass.run_command( + gs.run_command( "g.copy", raster="%s,%s" % (ms1_orig, ms1), quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "g.copy", raster="%s,%s" % (ms2_orig, ms2), quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "g.copy", raster="%s,%s" % (ms3_orig, ms3), quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "g.copy", raster="%s,%s" % (pan_orig, pan), quiet=True, @@ -179,25 +179,25 @@ def main(): ) else: # parallel processing - pb = grass.start_command( + pb = gs.start_command( "g.copy", raster="%s,%s" % (ms1_orig, ms1), quiet=True, overwrite=True, ) - pg = grass.start_command( + pg = gs.start_command( "g.copy", raster="%s,%s" % (ms2_orig, ms2), quiet=True, overwrite=True, ) - pr = grass.start_command( + pr = gs.start_command( "g.copy", raster="%s,%s" % (ms3_orig, ms3), quiet=True, overwrite=True, ) - pp = grass.start_command( + pp = gs.start_command( "g.copy", raster="%s,%s" % (pan_orig, pan), quiet=True, @@ -210,11 +210,11 @@ def main(): pp.wait() else: - grass.message(_("Converting image channels to 8bit for processing")) + gs.message(_("Converting image channels to 8bit for processing")) maxval = pow(2, bits) - 1 if sproc: # serial processing - grass.run_command( + gs.run_command( "r.rescale", input=ms1_orig, from_="0,%f" % maxval, @@ -223,7 +223,7 @@ def main(): quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "r.rescale", input=ms2_orig, from_="0,%f" % maxval, @@ -232,7 +232,7 @@ def main(): quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "r.rescale", input=ms3_orig, from_="0,%f" % maxval, @@ -241,7 +241,7 @@ def main(): quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "r.rescale", input=pan_orig, from_="0,%f" % maxval, @@ -253,7 +253,7 @@ def main(): else: # parallel processing - pb = grass.start_command( + pb = gs.start_command( "r.rescale", input=ms1_orig, from_="0,%f" % maxval, @@ -262,7 +262,7 @@ def main(): quiet=True, overwrite=True, ) - pg = grass.start_command( + pg = gs.start_command( "r.rescale", input=ms2_orig, from_="0,%f" % maxval, @@ -271,7 +271,7 @@ def main(): quiet=True, overwrite=True, ) - pr = grass.start_command( + pr = gs.start_command( "r.rescale", input=ms3_orig, from_="0,%f" % maxval, @@ -280,7 +280,7 @@ def main(): quiet=True, overwrite=True, ) - pp = grass.start_command( + pp = gs.start_command( "r.rescale", input=pan_orig, from_="0,%f" % maxval, @@ -296,21 +296,21 @@ def main(): pp.wait() else: - grass.message(_("Rescaling image channels to 8bit for processing")) + gs.message(_("Rescaling image channels to 8bit for processing")) - min_ms1 = int(grass.raster_info(ms1_orig)["min"]) - max_ms1 = int(grass.raster_info(ms1_orig)["max"]) - min_ms2 = int(grass.raster_info(ms2_orig)["min"]) - max_ms2 = int(grass.raster_info(ms2_orig)["max"]) - min_ms3 = int(grass.raster_info(ms3_orig)["min"]) - max_ms3 = int(grass.raster_info(ms3_orig)["max"]) - min_pan = int(grass.raster_info(pan_orig)["min"]) - max_pan = int(grass.raster_info(pan_orig)["max"]) + min_ms1 = int(gs.raster_info(ms1_orig)["min"]) + max_ms1 = int(gs.raster_info(ms1_orig)["max"]) + min_ms2 = int(gs.raster_info(ms2_orig)["min"]) + max_ms2 = int(gs.raster_info(ms2_orig)["max"]) + min_ms3 = int(gs.raster_info(ms3_orig)["min"]) + max_ms3 = int(gs.raster_info(ms3_orig)["max"]) + min_pan = int(gs.raster_info(pan_orig)["min"]) + max_pan = int(gs.raster_info(pan_orig)["max"]) maxval = pow(2, bits) - 1 if sproc: # serial processing - grass.run_command( + gs.run_command( "r.rescale", input=ms1_orig, from_="%f,%f" % (min_ms1, max_ms1), @@ -319,7 +319,7 @@ def main(): quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "r.rescale", input=ms2_orig, from_="%f,%f" % (min_ms2, max_ms2), @@ -328,7 +328,7 @@ def main(): quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "r.rescale", input=ms3_orig, from_="%f,%f" % (min_ms3, max_ms3), @@ -337,7 +337,7 @@ def main(): quiet=True, overwrite=True, ) - grass.run_command( + gs.run_command( "r.rescale", input=pan_orig, from_="%f,%f" % (min_pan, max_pan), @@ -349,7 +349,7 @@ def main(): else: # parallel processing - pb = grass.start_command( + pb = gs.start_command( "r.rescale", input=ms1_orig, from_="%f,%f" % (min_ms1, max_ms1), @@ -358,7 +358,7 @@ def main(): quiet=True, overwrite=True, ) - pg = grass.start_command( + pg = gs.start_command( "r.rescale", input=ms2_orig, from_="%f,%f" % (min_ms2, max_ms2), @@ -367,7 +367,7 @@ def main(): quiet=True, overwrite=True, ) - pr = grass.start_command( + pr = gs.start_command( "r.rescale", input=ms3_orig, from_="%f,%f" % (min_ms3, max_ms3), @@ -376,7 +376,7 @@ def main(): quiet=True, overwrite=True, ) - pp = grass.start_command( + pp = gs.start_command( "r.rescale", input=pan_orig, from_="%f,%f" % (min_pan, max_pan), @@ -392,17 +392,17 @@ def main(): pp.wait() # get PAN resolution: - kv = grass.raster_info(map=pan) + kv = gs.raster_info(map=pan) nsres = kv["nsres"] ewres = kv["ewres"] panres = (nsres + ewres) / 2 # clone current region - grass.use_temp_region() - grass.run_command("g.region", res=panres, align=pan) + gs.use_temp_region() + gs.run_command("g.region", res=panres, align=pan) # Select sharpening method - grass.message(_("Performing pan sharpening with hi res pan image: %f" % panres)) + gs.message(_("Performing pan sharpening with hi res pan image: %f" % panres)) if sharpen == "brovey": brovey(pan, ms1, ms2, ms3, out, pid, sproc) elif sharpen == "ihs": @@ -411,51 +411,51 @@ def main(): pca(pan, ms1, ms2, ms3, out, pid, sproc) # Could add other sharpening algorithms here, e.g. wavelet transformation - grass.message(_("Assigning grey equalized color tables to output images...")) + gs.message(_("Assigning grey equalized color tables to output images...")) # equalized grey scales give best contrast - grass.message(_("setting pan-sharpened channels to equalized grey scale")) + gs.message(_("setting pan-sharpened channels to equalized grey scale")) for ch in ["red", "green", "blue"]: - grass.run_command( + gs.run_command( "r.colors", quiet=True, map="%s_%s" % (out, ch), flags="e", color="grey" ) # Landsat too blue-ish because panchromatic band less sensitive to blue # light, so output blue channed can be modified if bladjust: - grass.message(_("Adjusting blue channel color table...")) + gs.message(_("Adjusting blue channel color table...")) blue_colors = ["0 0 0 0\n5% 0 0 0\n67% 255 255 255\n100% 255 255 255"] # these previous colors are way too blue for landsat # blue_colors = ['0 0 0 0\n10% 0 0 0\n20% 200 200 200\n40% 230 230 230\n67% # 255 255 255\n100% 255 255 255'] - bc = grass.feed_command("r.colors", quiet=True, map="%s_blue" % out, rules="-") - bc.stdin.write(grass.encode("\n".join(blue_colors))) + bc = gs.feed_command("r.colors", quiet=True, map="%s_blue" % out, rules="-") + bc.stdin.write(gs.encode("\n".join(blue_colors))) bc.stdin.close() # output notice - grass.verbose(_("The following pan-sharpened output maps have been generated:")) + gs.verbose(_("The following pan-sharpened output maps have been generated:")) for ch in ["red", "green", "blue"]: - grass.verbose(_("%s_%s") % (out, ch)) + gs.verbose(_("%s_%s") % (out, ch)) - grass.verbose(_("To visualize output, run: g.region -p raster=%s_red" % out)) - grass.verbose(_("d.rgb r=%s_red g=%s_green b=%s_blue" % (out, out, out))) - grass.verbose( + gs.verbose(_("To visualize output, run: g.region -p raster=%s_red" % out)) + gs.verbose(_("d.rgb r=%s_red g=%s_green b=%s_blue" % (out, out, out))) + gs.verbose( _("If desired, combine channels into a single RGB map with 'r.composite'.") ) - grass.verbose(_("Channel colors can be rebalanced using i.colors.enhance.")) + gs.verbose(_("Channel colors can be rebalanced using i.colors.enhance.")) # write cmd history: for ch in ["red", "green", "blue"]: - grass.raster_history("%s_%s" % (out, ch)) + gs.raster_history("%s_%s" % (out, ch)) # create a group with the three outputs - # grass.run_command('i.group', group=out, + # gs.run_command('i.group', group=out, # input="{n}_red,{n}_blue,{n}_green".format(n=out)) # Cleanup - grass.message(_("cleaning up temp files")) + gs.message(_("cleaning up temp files")) try: - grass.run_command( + gs.run_command( "g.remove", flags="f", type="raster", pattern="tmp%s*" % pid, quiet=True ) except: @@ -463,10 +463,10 @@ def main(): def brovey(pan, ms1, ms2, ms3, out, pid, sproc): - grass.verbose(_("Using Brovey algorithm")) + gs.verbose(_("Using Brovey algorithm")) # pan/intensity histogram matching using linear regression - grass.message(_("Pan channel/intensity histogram matching using linear regression")) + gs.message(_("Pan channel/intensity histogram matching using linear regression")) outname = "tmp%s_pan1" % pid panmatch1 = matchhist(pan, ms1, outname) @@ -481,7 +481,7 @@ def brovey(pan, ms1, ms2, ms3, out, pid, sproc): outb = "%s_blue" % out # calculate brovey transformation - grass.message(_("Calculating Brovey transformation...")) + gs.message(_("Calculating Brovey transformation...")) if sproc: # serial processing @@ -489,7 +489,7 @@ def brovey(pan, ms1, ms2, ms3, out, pid, sproc): "$outr" = 1 * round("$ms3" * "$panmatch3" / k) "$outg" = 1 * round("$ms2" * "$panmatch2" / k) "$outb" = 1 * round("$ms1" * "$panmatch1" / k)""" - grass.mapcalc( + gs.mapcalc( e, outr=outr, outg=outg, @@ -504,17 +504,17 @@ def brovey(pan, ms1, ms2, ms3, out, pid, sproc): ) else: # parallel processing - pb = grass.mapcalc_start( + pb = gs.mapcalc_start( "%s_blue = 1 * round((%s * %s) / (%s + %s + %s))" % (out, ms1, panmatch1, ms1, ms2, ms3), overwrite=True, ) - pg = grass.mapcalc_start( + pg = gs.mapcalc_start( "%s_green = 1 * round((%s * %s) / (%s + %s + %s))" % (out, ms2, panmatch2, ms1, ms2, ms3), overwrite=True, ) - pr = grass.mapcalc_start( + pr = gs.mapcalc_start( "%s_red = 1 * round((%s * %s) / (%s + %s + %s))" % (out, ms3, panmatch3, ms1, ms2, ms3), overwrite=True, @@ -528,7 +528,7 @@ def brovey(pan, ms1, ms2, ms3, out, pid, sproc): # Cleanup try: - grass.run_command( + gs.run_command( "g.remove", flags="f", quiet=True, @@ -540,10 +540,10 @@ def brovey(pan, ms1, ms2, ms3, out, pid, sproc): def ihs(pan, ms1, ms2, ms3, out, pid, sproc): - grass.verbose(_("Using IHS<->RGB algorithm")) + gs.verbose(_("Using IHS<->RGB algorithm")) # transform RGB channels into IHS color space - grass.message(_("Transforming to IHS color space...")) - grass.run_command( + gs.message(_("Transforming to IHS color space...")) + gs.run_command( "i.rgb.his", overwrite=True, red=ms3, @@ -560,8 +560,8 @@ def ihs(pan, ms1, ms2, ms3, out, pid, sproc): panmatch = matchhist(pan, target, outname) # substitute pan for intensity channel and transform back to RGB color space - grass.message(_("Transforming back to RGB color space and sharpening...")) - grass.run_command( + gs.message(_("Transforming back to RGB color space and sharpening...")) + gs.run_command( "i.his.rgb", overwrite=True, hue="tmp%s_hue" % pid, @@ -574,19 +574,17 @@ def ihs(pan, ms1, ms2, ms3, out, pid, sproc): # Cleanup try: - grass.run_command( - "g.remove", flags="f", quiet=True, type="raster", name=panmatch - ) + gs.run_command("g.remove", flags="f", quiet=True, type="raster", name=panmatch) except: pass def pca(pan, ms1, ms2, ms3, out, pid, sproc): - grass.verbose(_("Using PCA/inverse PCA algorithm")) - grass.message(_("Creating PCA images and calculating eigenvectors...")) + gs.verbose(_("Using PCA/inverse PCA algorithm")) + gs.message(_("Creating PCA images and calculating eigenvectors...")) # initial PCA with RGB channels - pca_out = grass.read_command( + pca_out = gs.read_command( "i.pca", quiet=True, rescale="0,0", @@ -594,7 +592,7 @@ def pca(pan, ms1, ms2, ms3, out, pid, sproc): output="tmp%s.pca" % pid, ) if len(pca_out) < 1: - grass.fatal(_("Input has no data. Check region settings.")) + gs.fatal(_("Input has no data. Check region settings.")) b1evect = [] b2evect = [] @@ -627,17 +625,17 @@ def pca(pan, ms1, ms2, ms3, out, pid, sproc): outname = "tmp%s_pan3" % pid panmatch3 = matchhist(pan, ms3, outname) - grass.message(_("Performing inverse PCA ...")) + gs.message(_("Performing inverse PCA ...")) # Get mean value of each channel - stats1 = grass.parse_command( - "r.univar", map=ms1, flags="g", parse=(grass.parse_key_val, {"sep": "="}) + stats1 = gs.parse_command( + "r.univar", map=ms1, flags="g", parse=(gs.parse_key_val, {"sep": "="}) ) - stats2 = grass.parse_command( - "r.univar", map=ms2, flags="g", parse=(grass.parse_key_val, {"sep": "="}) + stats2 = gs.parse_command( + "r.univar", map=ms2, flags="g", parse=(gs.parse_key_val, {"sep": "="}) ) - stats3 = grass.parse_command( - "r.univar", map=ms3, flags="g", parse=(grass.parse_key_val, {"sep": "="}) + stats3 = gs.parse_command( + "r.univar", map=ms3, flags="g", parse=(gs.parse_key_val, {"sep": "="}) ) b1mean = float(stats1["mean"]) @@ -656,7 +654,7 @@ def pca(pan, ms1, ms2, ms3, out, pid, sproc): cmd = "\n".join([cmd1, cmd2, cmd3]) - grass.mapcalc( + gs.mapcalc( cmd, outb=outb, outg=outg, @@ -682,19 +680,19 @@ def pca(pan, ms1, ms2, ms3, out, pid, sproc): ) else: # parallel processing - pb = grass.mapcalc_start( + pb = gs.mapcalc_start( "%s_blue = 1 * round((%s * %f) + (%s * %f) + (%s * %f) + %f)" % (out, panmatch1, b1evect1, pca2, b1evect2, pca3, b1evect3, b1mean), overwrite=True, ) - pg = grass.mapcalc_start( + pg = gs.mapcalc_start( "%s_green = 1 * round((%s * %f) + (%s * %f) + (%s * %f) + %f)" % (out, panmatch2, b2evect1, pca2, b2evect2, pca3, b2evect3, b2mean), overwrite=True, ) - pr = grass.mapcalc_start( + pr = gs.mapcalc_start( "%s_red = 1 * round((%s * %f) + (%s * %f) + (%s * %f) + %f)" % (out, panmatch3, b3evect1, pca2, b3evect2, pca3, b3evect3, b3mean), overwrite=True, @@ -707,7 +705,7 @@ def pca(pan, ms1, ms2, ms3, out, pid, sproc): pass # Cleanup - grass.run_command( + gs.run_command( "g.remove", flags="f", quiet=True, @@ -718,7 +716,7 @@ def pca(pan, ms1, ms2, ms3, out, pid, sproc): def matchhist(original, target, matched): # pan/intensity histogram matching using numpy arrays - grass.message(_("Histogram matching...")) + gs.message(_("Histogram matching...")) # input images original = original.split("@")[0] @@ -730,8 +728,8 @@ def matchhist(original, target, matched): for img in images: # calculate number of cells for each grey value for for each image - stats_out = grass.pipe_command("r.stats", flags="cin", input=img, sep=":") - stats = grass.decode(stats_out.communicate()[0]).split("\n")[:-1] + stats_out = gs.pipe_command("r.stats", flags="cin", input=img, sep=":") + stats = gs.decode(stats_out.communicate()[0]).split("\n")[:-1] stats_dict = dict(s.split(":", 1) for s in stats) total_cells = 0 # total non-null cells for j in stats_dict: @@ -740,7 +738,7 @@ def matchhist(original, target, matched): total_cells += stats_dict[j] if total_cells < 1: - grass.fatal(_("Input has no data. Check region settings.")) + gs.fatal(_("Input has no data. Check region settings.")) # Make a 2x256 structured array for each image with a # cumulative distribution function (CDF) for each grey value. @@ -767,7 +765,7 @@ def matchhist(original, target, matched): arrays[img][n] = (n, cdf) # open file for reclass rules - outfile = open(grass.tempfile(), "w") + outfile = open(gs.tempfile(), "w") for i in arrays[original]: # for each grey value and corresponding cdf value in original, find the @@ -794,23 +792,21 @@ def matchhist(original, target, matched): outfile.close() # create reclass of target from reclass rules file - result = grass.core.find_file(matched, element="cell") + result = gs.core.find_file(matched, element="cell") if result["fullname"]: - grass.run_command( - "g.remove", flags="f", quiet=True, type="raster", name=matched - ) - grass.run_command("r.reclass", input=original, out=matched, rules=outfile.name) + gs.run_command("g.remove", flags="f", quiet=True, type="raster", name=matched) + gs.run_command("r.reclass", input=original, out=matched, rules=outfile.name) else: - grass.run_command("r.reclass", input=original, out=matched, rules=outfile.name) + gs.run_command("r.reclass", input=original, out=matched, rules=outfile.name) # Cleanup # remove the rules file - grass.try_remove(outfile.name) + gs.try_remove(outfile.name) # return reclass of target with histogram that matches original return matched if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() main() diff --git a/scripts/i.spectral/i.spectral.py b/scripts/i.spectral/i.spectral.py index a54cd92e07e..9ac8cd09bf3 100755 --- a/scripts/i.spectral/i.spectral.py +++ b/scripts/i.spectral/i.spectral.py @@ -211,7 +211,7 @@ def draw_linegraph(what): ) ) with open(gcore.parse_command("d.mon", flags="g", quiet=True)["env"]) as f: - for line in f.readlines(): + for line in f: if "GRASS_RENDER_FILE=" in line: gcore.info( _( diff --git a/scripts/i.tasscap/i.tasscap.py b/scripts/i.tasscap/i.tasscap.py index c6fb6c3711b..4c68c234c73 100755 --- a/scripts/i.tasscap/i.tasscap.py +++ b/scripts/i.tasscap/i.tasscap.py @@ -82,7 +82,7 @@ # % options: landsat4_tm,landsat5_tm,landsat7_etm,landsat8_oli,modis,sentinel2,worldview2 # %end -import grass.script as grass +import grass.script as gs # weights for 6 Landsat bands: TM4, TM5, TM7, OLI @@ -236,7 +236,7 @@ def calc1bands6(out, bands, k1, k2, k3, k4, k5, k6, k0=0): "$out = $k1 * $in1band + $k2 * $in2band + $k3 * $in3band + " "$k4 * $in4band + $k5 * $in5band + $k6 * $in6band + $k0" ) - grass.mapcalc( + gs.mapcalc( equation, out=out, k1=k1, k2=k2, k3=k3, k4=k4, k5=k5, k6=k6, k0=k0, **bands ) @@ -250,7 +250,7 @@ def calc1bands7(out, bands, k1, k2, k3, k4, k5, k6, k7): "$k4 * $in4band + $k5 * $in5band + $k6 * $in6band + $k7 * " "$in7band" ) - grass.mapcalc( + gs.mapcalc( equation, out=out, k1=k1, k2=k2, k3=k3, k4=k4, k5=k5, k6=k6, k7=k7, **bands ) @@ -264,7 +264,7 @@ def calc1bands8(out, bands, k1, k2, k3, k4, k5, k6, k7, k8): "$k4 * $in4band + $k5 * $in5band + $k6 * $in6band + $k7 * " "$in7band + $k8 * $in8band" ) - grass.mapcalc( + gs.mapcalc( equation, out=out, k1=k1, @@ -289,7 +289,7 @@ def calc1bands13(out, bands, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, "$in7band + $k8 * $in8band + $k9 * $in9band + $k10 * $in10band + " "$k11 * $in11band + $k12 * $in12band + $k13 * $in13band" ) - grass.mapcalc( + gs.mapcalc( equation, out=out, k1=k1, @@ -314,7 +314,7 @@ def calcN(outpre, bands, satel): Calculating Tasseled Cap components """ i = satellites.index(satel) - grass.message(_("Satellite %s...") % satel) + gs.message(_("Satellite %s...") % satel) for j, p in enumerate(parms[i]): out = "%s.%d" % (outpre, j + 1) @@ -322,22 +322,22 @@ def calcN(outpre, bands, satel): name = " (%s)" % names[j] message = "Calculating {ordinal} TC component {outprefix}{outname} ..." message = message.format(ordinal=ord, outprefix=out, outname=name) - grass.message(_(message)) + gs.message(_(message)) bands_num = used_bands[i] # use combination function suitable for used number of bands eval("calc1bands%d(out, bands, *p)" % bands_num) - grass.run_command("r.colors", map=out, color="grey", quiet=True) + gs.run_command("r.colors", map=out, color="grey", quiet=True) def main(): - options, flags = grass.parser() + options, flags = gs.parser() satellite = options["sensor"] output_basename = options["output"] inputs = options["input"].split(",") num_of_bands = used_bands[satellites.index(satellite)] if len(inputs) != num_of_bands: - grass.fatal( + gs.fatal( _("The number of input raster maps (bands) should be %s") % num_of_bands ) @@ -345,7 +345,7 @@ def main(): for i, band in enumerate(inputs): band_num = i + 1 bands["in" + str(band_num) + "band"] = band - grass.debug(bands, 1) + gs.debug(bands, 1) # core tasseled cap components computation calcN(output_basename, bands, satellite) @@ -354,13 +354,13 @@ def main(): num_comp = len(parms[satellites.index(satellite)]) for i in range(0, num_comp): comp = names[i] - grass.run_command( + gs.run_command( "r.support", map="%s.%d" % (output_basename, i + 1), description="Tasseled Cap %d: %s" % (i + 1, comp), ) - grass.message(_("Tasseled Cap components calculated")) + gs.message(_("Tasseled Cap components calculated")) if __name__ == "__main__": diff --git a/scripts/m.proj/m.proj.py b/scripts/m.proj/m.proj.py index 6c5c2c0eed7..4540b3dcd0a 100755 --- a/scripts/m.proj/m.proj.py +++ b/scripts/m.proj/m.proj.py @@ -216,16 +216,15 @@ def main(): fd.write("%s%s%s\n" % (x, ifs, y)) fd.close() inf = open(tmpfile) + elif input == "-": + infile = None + inf = sys.stdin else: - if input == "-": - infile = None - inf = sys.stdin - else: - infile = input - if not os.path.exists(infile): - gcore.fatal(_("Unable to read input data")) - inf = open(infile) - gcore.debug("input file=[%s]" % infile) + infile = input + if not os.path.exists(infile): + gcore.fatal(_("Unable to read input data")) + inf = open(infile) + gcore.debug("input file=[%s]" % infile) # set up output file if not output: diff --git a/scripts/r.blend/r.blend.py b/scripts/r.blend/r.blend.py index 66a7ac63cfb..4bda8be6d49 100755 --- a/scripts/r.blend/r.blend.py +++ b/scripts/r.blend/r.blend.py @@ -45,7 +45,7 @@ import os import string -import grass.script as gscript +import grass.script as gs def main(): @@ -54,13 +54,13 @@ def main(): output = options["output"] percent = options["percent"] - mapset = gscript.gisenv()["MAPSET"] + mapset = gs.gisenv()["MAPSET"] - if not gscript.overwrite(): + if not gs.overwrite(): for ch in ["r", "g", "b"]: map = "%s.%s" % (output, ch) - if gscript.find_file(map, element="cell", mapset=mapset)["file"]: - gscript.fatal(_("Raster map <%s> already exists.") % map) + if gs.find_file(map, element="cell", mapset=mapset)["file"]: + gs.fatal(_("Raster map <%s> already exists.") % map) percent = float(percent) perc_inv = 100.0 - percent @@ -68,7 +68,7 @@ def main(): frac1 = percent / 100.0 frac2 = perc_inv / 100.0 - gscript.message(_("Calculating the three component maps...")) + gs.message(_("Calculating the three component maps...")) template = string.Template( "$$output.$ch = " @@ -80,31 +80,29 @@ def main(): cmd = [template.substitute(ch=ch) for ch in ["r", "g", "b"]] cmd = ";".join(cmd) - gscript.mapcalc( - cmd, output=output, first=first, second=second, frac1=frac1, frac2=frac2 - ) + gs.mapcalc(cmd, output=output, first=first, second=second, frac1=frac1, frac2=frac2) for ch in ["r", "g", "b"]: map = "%s.%s" % (output, ch) - gscript.run_command("r.colors", map=map, color="grey255") - gscript.run_command( + gs.run_command("r.colors", map=map, color="grey255") + gs.run_command( "r.support", map=map, history="", title="Color blend of %s and %s" % (first, second), description="generated by r.blend", ) - gscript.run_command("r.support", map=map, history="r.blend %s channel." % ch) - gscript.run_command( + gs.run_command("r.support", map=map, history="r.blend %s channel." % ch) + gs.run_command( "r.support", map=map, history=" %d%% of %s, %d%% of %s" % (percent, first, perc_inv, second), ) - gscript.run_command("r.support", map=map, history="") - gscript.run_command("r.support", map=map, history=os.environ["CMDLINE"]) + gs.run_command("r.support", map=map, history="") + gs.run_command("r.support", map=map, history=os.environ["CMDLINE"]) if flags["c"]: - gscript.run_command( + gs.run_command( "r.composite", r="%s.r" % output, g="%s.g" % output, @@ -112,25 +110,25 @@ def main(): output=output, ) - gscript.run_command( + gs.run_command( "r.support", map=output, history="", title="Color blend of %s and %s" % (first, second), description="generated by r.blend", ) - gscript.run_command( + gs.run_command( "r.support", map=output, history=" %d%% of %s, %d%% of %s" % (percent, first, perc_inv, second), ) - gscript.run_command("r.support", map=output, history="") - gscript.run_command("r.support", map=output, history=os.environ["CMDLINE"]) + gs.run_command("r.support", map=output, history="") + gs.run_command("r.support", map=output, history=os.environ["CMDLINE"]) else: - gscript.message(_("Done. Use the following command to visualize the result:")) - gscript.message(_("d.rgb r=%s.r g=%s.g b=%s.b") % (output, output, output)) + gs.message(_("Done. Use the following command to visualize the result:")) + gs.message(_("d.rgb r=%s.r g=%s.g b=%s.b") % (output, output, output)) if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() main() diff --git a/scripts/r.buffer.lowmem/r.buffer.lowmem.py b/scripts/r.buffer.lowmem/r.buffer.lowmem.py index 01e44973e91..2916ad95e7d 100755 --- a/scripts/r.buffer.lowmem/r.buffer.lowmem.py +++ b/scripts/r.buffer.lowmem/r.buffer.lowmem.py @@ -43,7 +43,7 @@ import os import atexit -import grass.script as grass +import grass.script as gs from grass.script.utils import encode @@ -59,12 +59,10 @@ def cleanup(): - if grass.find_file(temp_src)["file"]: - grass.run_command( - "g.remove", quiet=True, flags="fb", type="raster", name=temp_src - ) - if grass.find_file(temp_dist)["file"]: - grass.run_command( + if gs.find_file(temp_src)["file"]: + gs.run_command("g.remove", quiet=True, flags="fb", type="raster", name=temp_src) + if gs.find_file(temp_dist)["file"]: + gs.run_command( "g.remove", quiet=True, flags="fb", type="raster", name=temp_dist ) @@ -83,8 +81,8 @@ def main(): temp_src = "r.buffer.tmp.%s.src" % tmp # check if input file exists - if not grass.find_file(input)["file"]: - grass.fatal(_("Raster map <%s> not found") % input) + if not gs.find_file(input)["file"]: + gs.fatal(_("Raster map <%s> not found") % input) scale = scales[units] @@ -92,14 +90,14 @@ def main(): distances1 = [scale * float(d) for d in distances] distances2 = [d * d for d in distances1] - s = grass.read_command("g.proj", flags="j") - kv = grass.parse_key_val(s) + s = gs.read_command("g.proj", flags="j") + kv = gs.parse_key_val(s) if kv["+proj"] == "longlat": metric = "geodesic" else: metric = "squared" - grass.run_command( + gs.run_command( "r.grow.distance", input=input, metric=metric, distance=temp_dist, flags="m" ) @@ -108,8 +106,8 @@ def main(): else: exp = "$temp_src = if(isnull($input),null(),1)" - grass.message(_("Extracting buffers (1/2)...")) - grass.mapcalc(exp, temp_src=temp_src, input=input) + gs.message(_("Extracting buffers (1/2)...")) + gs.mapcalc(exp, temp_src=temp_src, input=input) exp = "$output = if(!isnull($input),$input,%s)" if metric == "squared": @@ -120,10 +118,10 @@ def main(): exp %= "if($dist <= %f,%d,%%s)" % (dist2, n + 2) exp %= "null()" - grass.message(_("Extracting buffers (2/2)...")) - grass.mapcalc(exp, output=output, input=temp_src, dist=temp_dist) + gs.message(_("Extracting buffers (2/2)...")) + gs.mapcalc(exp, output=output, input=temp_src, dist=temp_dist) - p = grass.feed_command("r.category", map=output, separator=":", rules="-") + p = gs.feed_command("r.category", map=output, separator=":", rules="-") msg = "1:distances calculated from these locations\n" p.stdin.write(encode(msg)) d0 = "0" @@ -134,13 +132,13 @@ def main(): p.stdin.close() p.wait() - grass.run_command("r.colors", map=output, color="rainbow") + gs.run_command("r.colors", map=output, color="rainbow") # write cmd history: - grass.raster_history(output) + gs.raster_history(output) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() atexit.register(cleanup) main() diff --git a/scripts/r.colors.stddev/r.colors.stddev.py b/scripts/r.colors.stddev/r.colors.stddev.py index e8d4321939f..d8db41e427d 100755 --- a/scripts/r.colors.stddev/r.colors.stddev.py +++ b/scripts/r.colors.stddev/r.colors.stddev.py @@ -33,7 +33,7 @@ import os import atexit -import grass.script as gscript +import grass.script as gs from grass.script.utils import decode @@ -43,9 +43,7 @@ def z(n): def cleanup(): if tmpmap: - gscript.run_command( - "g.remove", flags="f", type="raster", name=tmpmap, quiet=True - ) + gs.run_command("g.remove", flags="f", type="raster", name=tmpmap, quiet=True) def main(): @@ -57,8 +55,8 @@ def main(): bands = flags["b"] if not zero: - s = gscript.read_command("r.univar", flags="g", map=map) - kv = gscript.parse_key_val(decode(s)) + s = gs.read_command("r.univar", flags="g", map=map) + kv = gs.parse_key_val(decode(s)) global mean, stddev mean = float(kv["mean"]) stddev = float(kv["stddev"]) @@ -103,17 +101,17 @@ def main(): ) else: tmpmap = "r_col_stdev_abs_%d" % os.getpid() - gscript.mapcalc("$tmp = abs($map)", tmp=tmpmap, map=map) + gs.mapcalc("$tmp = abs($map)", tmp=tmpmap, map=map) # data centered on 0 (e.g. map of deviations) - info = gscript.raster_info(tmpmap) + info = gs.raster_info(tmpmap) maxv = info["max"] # current r.univar truncates percentage to the base integer - s = gscript.read_command( + s = gs.read_command( "r.univar", flags="eg", map=map, percentile=[95.45, 68.2689, 99.7300] ) - kv = gscript.parse_key_val(decode(s)) + kv = gs.parse_key_val(decode(s)) stddev1 = float(kv["percentile_68_2689"]) stddev2 = float(kv["percentile_95_45"]) @@ -154,10 +152,10 @@ def main(): ] ) - gscript.write_command("r.colors", map=map, rules="-", stdin=rules) + gs.write_command("r.colors", map=map, rules="-", stdin=rules) if __name__ == "__main__": - options, flags = gscript.parser() + options, flags = gs.parser() atexit.register(cleanup) main() diff --git a/scripts/r.fillnulls/r.fillnulls.py b/scripts/r.fillnulls/r.fillnulls.py index b09ea17889d..2627bca9ffe 100755 --- a/scripts/r.fillnulls/r.fillnulls.py +++ b/scripts/r.fillnulls/r.fillnulls.py @@ -105,7 +105,7 @@ import atexit import subprocess -import grass.script as grass +import grass.script as gs from grass.exceptions import CalledModuleError tmp_rmaps = [] @@ -119,16 +119,16 @@ def cleanup(): # delete internal mask and any TMP files: if len(tmp_vmaps) > 0: - grass.run_command( + gs.run_command( "g.remove", quiet=True, flags="fb", type="vector", name=tmp_vmaps ) if len(tmp_rmaps) > 0: - grass.run_command( + gs.run_command( "g.remove", quiet=True, flags="fb", type="raster", name=tmp_rmaps ) if usermask and mapset: - if grass.find_file(usermask, mapset=mapset)["file"]: - grass.run_command( + if gs.find_file(usermask, mapset=mapset)["file"]: + gs.run_command( "g.rename", quiet=True, raster=(usermask, "MASK"), overwrite=True ) @@ -147,7 +147,7 @@ def main(): lambda_ = float(options["lambda"]) memory = options["memory"] quiet = True # FIXME - mapset = grass.gisenv()["MAPSET"] + mapset = gs.gisenv()["MAPSET"] unique = str(os.getpid()) # Shouldn't we use temp name? prefix = "r_fillnulls_%s_" % unique failed_list = ( @@ -155,19 +155,19 @@ def main(): ) # a list of failed holes. Caused by issues with v.surf.rst. Connected with #1813 # check if input file exists - if not grass.find_file(input)["file"]: - grass.fatal(_("Raster map <%s> not found") % input) + if not gs.find_file(input)["file"]: + gs.fatal(_("Raster map <%s> not found") % input) # save original region - reg_org = grass.region() + reg_org = gs.region() # check if a MASK is already present # and remove it to not interfere with NULL lookup part # as we don't fill MASKed parts! - if grass.find_file("MASK", mapset=mapset)["file"]: + if gs.find_file("MASK", mapset=mapset)["file"]: usermask = "usermask_mask." + unique - grass.message(_("A user raster mask (MASK) is present. Saving it...")) - grass.run_command("g.rename", quiet=quiet, raster=("MASK", usermask)) + gs.message(_("A user raster mask (MASK) is present. Saving it...")) + gs.run_command("g.rename", quiet=quiet, raster=("MASK", usermask)) # check if method is rst to use v.surf.rst if method == "rst": @@ -175,19 +175,19 @@ def main(): # interpolate from these surrounding 3 pixel edge filling = prefix + "filled" - grass.use_temp_region() - grass.run_command("g.region", align=input, quiet=quiet) - region = grass.region() + gs.use_temp_region() + gs.run_command("g.region", align=input, quiet=quiet) + region = gs.region() ns_res = region["nsres"] ew_res = region["ewres"] - grass.message(_("Using RST interpolation...")) - grass.message(_("Locating and isolating NULL areas...")) + gs.message(_("Using RST interpolation...")) + gs.message(_("Locating and isolating NULL areas...")) # creating binary (0/1) map if usermask: - grass.message(_("Skipping masked raster parts")) - grass.mapcalc( + gs.message(_("Skipping masked raster parts")) + gs.mapcalc( ( '$tmp1 = if(isnull("$input") && !($mask == 0 || isnull($mask)),1,' "null())" @@ -197,7 +197,7 @@ def main(): mask=usermask, ) else: - grass.mapcalc( + gs.mapcalc( '$tmp1 = if(isnull("$input"),1,null())', tmp1=prefix + "nulls", input=input, @@ -207,18 +207,18 @@ def main(): # restoring user's mask, if present # to ignore MASKed original values if usermask: - grass.message(_("Restoring user mask (MASK)...")) + gs.message(_("Restoring user mask (MASK)...")) try: - grass.run_command("g.rename", quiet=quiet, raster=(usermask, "MASK")) + gs.run_command("g.rename", quiet=quiet, raster=(usermask, "MASK")) except CalledModuleError: - grass.warning(_("Failed to restore user MASK!")) + gs.warning(_("Failed to restore user MASK!")) usermask = None # grow identified holes by X pixels - grass.message(_("Growing NULL areas")) + gs.message(_("Growing NULL areas")) tmp_rmaps.append(prefix + "grown") try: - grass.run_command( + gs.run_command( "r.grow", input=prefix + "nulls", radius=edge + 0.01, @@ -228,7 +228,7 @@ def main(): quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary map, restoring " "user mask if needed:" @@ -237,17 +237,17 @@ def main(): # assign unique IDs to each hole or hole system (holes closer than edge # distance) - grass.message(_("Assigning IDs to NULL areas")) + gs.message(_("Assigning IDs to NULL areas")) tmp_rmaps.append(prefix + "clumped") try: - grass.run_command( + gs.run_command( "r.clump", input=prefix + "grown", output=prefix + "clumped", quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary map, restoring " "user mask if needed:" @@ -255,7 +255,7 @@ def main(): ) # get a list of unique hole cat's - grass.mapcalc( + gs.mapcalc( "$out = if(isnull($inp), null(), $clumped)", out=prefix + "holes", inp=prefix + "nulls", @@ -265,7 +265,7 @@ def main(): # use new IDs to identify holes try: - grass.run_command( + gs.run_command( "r.to.vect", flags="v", input=prefix + "holes", @@ -274,7 +274,7 @@ def main(): quiet=quiet, ) except: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring " "user mask if needed:" @@ -283,8 +283,8 @@ def main(): tmp_vmaps.append(prefix + "holes") # get a list of unique hole cat's - cats_file_name = grass.tempfile(False) - grass.run_command( + cats_file_name = gs.tempfile(False) + gs.run_command( "v.db.select", flags="c", map=prefix + "holes", @@ -301,10 +301,10 @@ def main(): if len(cat_list) < 1: # no holes found in current region - grass.run_command( + gs.run_command( "g.copy", raster="%s,%sfilled" % (input, prefix), overwrite=True ) - grass.warning( + gs.warning( _( "Input map <%s> has no holes. Copying to output without " "modification." @@ -313,17 +313,17 @@ def main(): ) # GTC Hole is NULL area in a raster map - grass.message(_("Processing %d map holes") % len(cat_list)) + gs.message(_("Processing %d map holes") % len(cat_list)) first = True hole_n = 1 for cat in cat_list: holename = prefix + "hole_" + cat # GTC Hole is a NULL area in a raster map - grass.message(_("Filling hole %s of %s") % (hole_n, len(cat_list))) + gs.message(_("Filling hole %s of %s") % (hole_n, len(cat_list))) hole_n = hole_n + 1 # cut out only CAT hole for processing try: - grass.run_command( + gs.run_command( "v.extract", input=prefix + "holes", output=holename + "_pol", @@ -331,7 +331,7 @@ def main(): quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring " "user mask if needed:" @@ -342,7 +342,7 @@ def main(): # zoom to specific hole with a buffer of two cells around the hole to # remove rest of data try: - grass.run_command( + gs.run_command( "g.region", vector=holename + "_pol", align=input, @@ -353,7 +353,7 @@ def main(): quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring " "user mask if needed:" @@ -362,7 +362,7 @@ def main(): # remove temporary map to not overfill disk try: - grass.run_command( + gs.run_command( "g.remove", flags="fb", type="vector", @@ -370,7 +370,7 @@ def main(): quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring " "user mask if needed:" @@ -379,7 +379,7 @@ def main(): tmp_vmaps.remove(holename + "_pol") # copy only data around hole - grass.mapcalc( + gs.mapcalc( "$out = if($inp == $catn, $inp, null())", out=holename, inp=prefix + "holes", @@ -394,7 +394,7 @@ def main(): # grow hole border to get it's edge area tmp_rmaps.append(holename + "_grown") try: - grass.run_command( + gs.run_command( "r.grow", input=holename, radius=edge + 0.01, @@ -403,7 +403,7 @@ def main(): quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary map, restoring " "user mask if needed:" @@ -411,7 +411,7 @@ def main(): ) # no idea why r.grow old=-1 doesn't replace existing values with NULL - grass.mapcalc( + gs.mapcalc( '$out = if($inp == -1, null(), "$dem")', out=holename + "_edges", inp=holename + "_grown", @@ -422,7 +422,7 @@ def main(): # convert to points for interpolation tmp_vmaps.append(holename) try: - grass.run_command( + gs.run_command( "r.to.vect", input=holename + "_edges", output=holename, @@ -431,7 +431,7 @@ def main(): quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring " "user mask if needed:" @@ -439,11 +439,11 @@ def main(): ) # count number of points to control segmax parameter for interpolation: - pointsnumber = grass.vector_info_topo(map=holename)["points"] - grass.verbose(_("Interpolating %d points") % pointsnumber) + pointsnumber = gs.vector_info_topo(map=holename)["points"] + gs.verbose(_("Interpolating %d points") % pointsnumber) if pointsnumber < 2: - grass.verbose(_("No points to interpolate")) + gs.verbose(_("No points to interpolate")) failed_list.append(holename) continue @@ -458,7 +458,7 @@ def main(): # launch v.surf.rst tmp_rmaps.append(holename + "_dem") try: - grass.run_command( + gs.run_command( "v.surf.rst", quiet=quiet, input=holename, @@ -470,11 +470,11 @@ def main(): ) except CalledModuleError: # GTC Hole is NULL area in a raster map - grass.fatal(_("Failed to fill hole %s") % cat) + gs.fatal(_("Failed to fill hole %s") % cat) # v.surf.rst sometimes fails with exit code 0 # related bug #1813 - if not grass.find_file(holename + "_dem")["file"]: + if not gs.find_file(holename + "_dem")["file"]: try: tmp_rmaps.remove(holename) tmp_rmaps.remove(holename + "_grown") @@ -483,7 +483,7 @@ def main(): tmp_vmaps.remove(holename) except: pass - grass.warning( + gs.warning( _( "Filling has failed silently. Leaving temporary maps " "with prefix <%s> for debugging." @@ -497,10 +497,10 @@ def main(): # original DEM if first: tmp_rmaps.append(filling) - grass.run_command( + gs.run_command( "g.region", align=input, raster=holename + "_dem", quiet=quiet ) - grass.mapcalc( + gs.mapcalc( "$out = if(isnull($inp), null(), $dem)", out=filling, inp=holename, @@ -509,13 +509,13 @@ def main(): first = False else: tmp_rmaps.append(filling + "_tmp") - grass.run_command( + gs.run_command( "g.region", align=input, raster=(filling, holename + "_dem"), quiet=quiet, ) - grass.mapcalc( + gs.mapcalc( "$out = if(isnull($inp), if(isnull($fill), null(), $fill), $dem)", out=filling + "_tmp", inp=holename, @@ -523,14 +523,14 @@ def main(): fill=filling, ) try: - grass.run_command( + gs.run_command( "g.rename", raster=(filling + "_tmp", filling), overwrite=True, quiet=quiet, ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring user " "mask if needed:" @@ -548,7 +548,7 @@ def main(): except: pass try: - grass.run_command( + gs.run_command( "g.remove", quiet=quiet, flags="fb", @@ -561,7 +561,7 @@ def main(): ), ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring " "user mask if needed:" @@ -572,11 +572,11 @@ def main(): except: pass try: - grass.run_command( + gs.run_command( "g.remove", quiet=quiet, flags="fb", type="vector", name=holename ) except CalledModuleError: - grass.fatal( + gs.fatal( _( "abandoned. Removing temporary maps, restoring user mask if " "needed:" @@ -585,13 +585,13 @@ def main(): # check if method is different from rst to use r.resamp.bspline if method != "rst": - grass.message(_("Using %s bspline interpolation") % method) + gs.message(_("Using %s bspline interpolation") % method) # clone current region - grass.use_temp_region() - grass.run_command("g.region", align=input) + gs.use_temp_region() + gs.run_command("g.region", align=input) - reg = grass.region() + reg = gs.region() # launch r.resamp.bspline tmp_rmaps.append(prefix + "filled") # If there are no NULL cells, r.resamp.bslpine call @@ -601,7 +601,7 @@ def main(): new_env["LC_ALL"] = "C" if usermask: try: - p = grass.core.start_command( + p = gs.core.start_command( "r.resamp.bspline", input=input, mask=usermask, @@ -615,13 +615,13 @@ def main(): stderr=subprocess.PIPE, env=new_env, ) - stderr = grass.decode(p.communicate()[1]) + stderr = gs.decode(p.communicate()[1]) if "No NULL cells found" in stderr: - grass.run_command( + gs.run_command( "g.copy", raster="%s,%sfilled" % (input, prefix), overwrite=True ) p.returncode = 0 - grass.warning( + gs.warning( _( "Input map <%s> has no holes. Copying to output without " "modification." @@ -629,13 +629,13 @@ def main(): % (input,) ) except CalledModuleError: - grass.fatal( + gs.fatal( _("Failure during bspline interpolation. Error message: %s") % stderr ) else: try: - p = grass.core.start_command( + p = gs.core.start_command( "r.resamp.bspline", input=input, output=prefix + "filled", @@ -648,13 +648,13 @@ def main(): stderr=subprocess.PIPE, env=new_env, ) - stderr = grass.decode(p.communicate()[1]) + stderr = gs.decode(p.communicate()[1]) if "No NULL cells found" in stderr: - grass.run_command( + gs.run_command( "g.copy", raster="%s,%sfilled" % (input, prefix), overwrite=True ) p.returncode = 0 - grass.warning( + gs.warning( _( "Input map <%s> has no holes. Copying to output without " "modification." @@ -662,22 +662,22 @@ def main(): % (input,) ) except CalledModuleError: - grass.fatal( + gs.fatal( _("Failure during bspline interpolation. Error message: %s") % stderr ) # restoring user's mask, if present: if usermask: - grass.message(_("Restoring user mask (MASK)...")) + gs.message(_("Restoring user mask (MASK)...")) try: - grass.run_command("g.rename", quiet=quiet, raster=(usermask, "MASK")) + gs.run_command("g.rename", quiet=quiet, raster=(usermask, "MASK")) except CalledModuleError: - grass.warning(_("Failed to restore user MASK!")) + gs.warning(_("Failed to restore user MASK!")) usermask = None # set region to original extents, align to input - grass.run_command( + gs.run_command( "g.region", n=reg_org["n"], s=reg_org["s"], @@ -687,22 +687,22 @@ def main(): ) # patch orig and fill map - grass.message(_("Patching fill data into NULL areas...")) + gs.message(_("Patching fill data into NULL areas...")) # we can use --o here as g.parser already checks on startup - grass.run_command( + gs.run_command( "r.patch", input=(input, prefix + "filled"), output=output, overwrite=True ) # restore the real region - grass.del_temp_region() + gs.del_temp_region() - grass.message(_("Filled raster map is: %s") % output) + gs.message(_("Filled raster map is: %s") % output) # write cmd history: - grass.raster_history(output) + gs.raster_history(output) if len(failed_list) > 0: - grass.warning( + gs.warning( _( "Following holes where not filled. Temporary maps with are left " "in place to allow examination of unfilled holes" @@ -711,12 +711,12 @@ def main(): outlist = failed_list[0] for hole in failed_list[1:]: outlist = ", " + outlist - grass.message(outlist) + gs.message(outlist) - grass.message(_("Done.")) + gs.message(_("Done.")) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() atexit.register(cleanup) main() diff --git a/scripts/r.grow/r.grow.py b/scripts/r.grow/r.grow.py index 72601d78ddb..86fdfd9ebc3 100755 --- a/scripts/r.grow/r.grow.py +++ b/scripts/r.grow/r.grow.py @@ -64,7 +64,7 @@ import atexit import math -import grass.script as grass +import grass.script as gs from grass.exceptions import CalledModuleError @@ -72,7 +72,7 @@ def cleanup(): for map in [temp_dist, temp_val]: if map: - grass.run_command("g.remove", flags="fb", quiet=True, type="rast", name=map) + gs.run_command("g.remove", flags="fb", quiet=True, type="rast", name=map) def main(): @@ -104,7 +104,7 @@ def main(): old = '"%s"' % input if not mapunits: - kv = grass.region() + kv = gs.region() scale = math.sqrt(float(kv["nsres"]) * float(kv["ewres"])) radius *= scale @@ -113,22 +113,22 @@ def main(): radius = radius * radius # check if input file exists - if not grass.find_file(input)["file"]: - grass.fatal(_("Raster map <%s> not found") % input) + if not gs.find_file(input)["file"]: + gs.fatal(_("Raster map <%s> not found") % input) # Workaround for r.mapcalc bug #3475 # Mapcalc will fail if output is a fully qualified map name out_name = options["output"].split("@") if len(out_name) == 2: - if out_name[1] != grass.gisenv()["MAPSET"]: - grass.fatal(_("Output can be written only to the current mapset")) + if out_name[1] != gs.gisenv()["MAPSET"]: + gs.fatal(_("Output can be written only to the current mapset")) output = out_name[0] else: output = out_name[0] if not shrink: try: - grass.run_command( + gs.run_command( "r.grow.distance", input=input, metric=metric, @@ -136,9 +136,9 @@ def main(): value=temp_val, ) except CalledModuleError: - grass.fatal(_("Growing failed. Removing temporary maps.")) + gs.fatal(_("Growing failed. Removing temporary maps.")) - grass.mapcalc( + gs.mapcalc( '$output = if(!isnull("$input"),$old,if($dist < $radius,$new,null()))', output=output, input=input, @@ -150,7 +150,7 @@ def main(): else: # shrink try: - grass.run_command( + gs.run_command( "r.grow.distance", input=input, metric=metric, @@ -159,9 +159,9 @@ def main(): flags="n", ) except CalledModuleError: - grass.fatal(_("Shrinking failed. Removing temporary maps.")) + gs.fatal(_("Shrinking failed. Removing temporary maps.")) - grass.mapcalc( + gs.mapcalc( "$output = if(isnull($dist), $old, if($dist < $radius,null(),$old))", output=output, radius=radius, @@ -169,13 +169,13 @@ def main(): dist=temp_dist, ) - grass.run_command("r.colors", map=output, raster=input) + gs.run_command("r.colors", map=output, raster=input) # write cmd history: - grass.raster_history(output) + gs.raster_history(output) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() atexit.register(cleanup) main() diff --git a/scripts/r.import/r.import.py b/scripts/r.import/r.import.py index 195b7c79c31..a3f952c037b 100644 --- a/scripts/r.import/r.import.py +++ b/scripts/r.import/r.import.py @@ -118,7 +118,7 @@ import atexit import math -import grass.script as grass +import grass.script as gs from grass.exceptions import CalledModuleError @@ -132,16 +132,16 @@ def cleanup(): # remove temp location if TMPLOC: - grass.try_rmdir(os.path.join(GISDBASE, TMPLOC)) + gs.try_rmdir(os.path.join(GISDBASE, TMPLOC)) if SRCGISRC: - grass.try_remove(SRCGISRC) + gs.try_remove(SRCGISRC) if ( TMP_REG_NAME - and grass.find_file( - name=TMP_REG_NAME, element="vector", mapset=grass.gisenv()["MAPSET"] + and gs.find_file( + name=TMP_REG_NAME, element="vector", mapset=gs.gisenv()["MAPSET"] )["fullname"] ): - grass.run_command( + gs.run_command( "g.remove", type="vector", name=TMP_REG_NAME, flags="f", quiet=True ) @@ -150,7 +150,7 @@ def is_projection_matching(GDALdatasource): """Returns True if current location projection matches dataset projection, otherwise False""" try: - grass.run_command("r.in.gdal", input=GDALdatasource, flags="j", quiet=True) + gs.run_command("r.in.gdal", input=GDALdatasource, flags="j", quiet=True) return True except CalledModuleError: return False @@ -170,14 +170,14 @@ def main(): output = "rimport_tmp" # will be removed with the entire tmp location if options["resolution_value"]: if tgtres != "value": - grass.fatal( + gs.fatal( _("To set custom resolution value, select 'value' in resolution option") ) tgtres_value = float(options["resolution_value"]) if tgtres_value <= 0: - grass.fatal(_("Resolution value can't be smaller than 0")) + gs.fatal(_("Resolution value can't be smaller than 0")) elif tgtres == "value": - grass.fatal( + gs.fatal( _( "Please provide the resolution for the imported dataset or change to " "'estimated' resolution" @@ -201,21 +201,21 @@ def main(): if bands: parameters["band"] = bands try: - grass.run_command("r.in.gdal", **parameters) - grass.verbose( + gs.run_command("r.in.gdal", **parameters) + gs.verbose( _("Input <%s> successfully imported without reprojection") % GDALdatasource ) return 0 except CalledModuleError: - grass.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource) + gs.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource) - grassenv = grass.gisenv() + grassenv = gs.gisenv() tgtloc = grassenv["LOCATION_NAME"] # make sure target is not xy - if grass.parse_command("g.proj", flags="g")["name"] == "xy_location_unprojected": - grass.fatal( + if gs.parse_command("g.proj", flags="g")["name"] == "xy_location_unprojected": + gs.fatal( _("Coordinate reference system not available for current project <%s>") % tgtloc ) @@ -223,16 +223,16 @@ def main(): tgtmapset = grassenv["MAPSET"] GISDBASE = grassenv["GISDBASE"] - TMPLOC = grass.append_node_pid("tmp_r_import_location") - TMP_REG_NAME = grass.append_node_pid("tmp_r_import_region") + TMPLOC = gs.append_node_pid("tmp_r_import_location") + TMP_REG_NAME = gs.append_node_pid("tmp_r_import_region") - SRCGISRC, src_env = grass.create_environment(GISDBASE, TMPLOC, "PERMANENT") + SRCGISRC, src_env = gs.create_environment(GISDBASE, TMPLOC, "PERMANENT") # create temp location from input without import - grass.verbose(_("Creating temporary project for <%s>...") % GDALdatasource) + gs.verbose(_("Creating temporary project for <%s>...") % GDALdatasource) # creating a new location with r.in.gdal requires a sanitized env env = os.environ.copy() - env = grass.sanitize_mapset_environment(env) + env = gs.sanitize_mapset_environment(env) parameters = { "input": GDALdatasource, "output": output, @@ -245,34 +245,32 @@ def main(): if bands: parameters["band"] = bands try: - grass.run_command("r.in.gdal", env=env, **parameters) + gs.run_command("r.in.gdal", env=env, **parameters) except CalledModuleError: - grass.fatal(_("Unable to read GDAL dataset <%s>") % GDALdatasource) + gs.fatal(_("Unable to read GDAL dataset <%s>") % GDALdatasource) # prepare to set region in temp location if "r" in region_flag: tgtregion = TMP_REG_NAME - grass.run_command("v.in.region", output=tgtregion, flags="d") + gs.run_command("v.in.region", output=tgtregion, flags="d") # switch to temp location # print projection at verbose level - grass.verbose( - grass.read_command("g.proj", flags="p", env=src_env).rstrip(os.linesep) - ) + gs.verbose(gs.read_command("g.proj", flags="p", env=src_env).rstrip(os.linesep)) # make sure input is not xy if ( - grass.parse_command("g.proj", flags="g", env=src_env)["name"] + gs.parse_command("g.proj", flags="g", env=src_env)["name"] == "xy_location_unprojected" ): - grass.fatal( + gs.fatal( _("Coordinate reference system not available for input <%s>") % GDALdatasource ) # import into temp location - grass.verbose(_("Importing <%s> to temporary project...") % GDALdatasource) + gs.verbose(_("Importing <%s> to temporary project...") % GDALdatasource) parameters = { "input": GDALdatasource, "output": output, @@ -282,7 +280,7 @@ def main(): if bands: parameters["band"] = bands if "r" in region_flag: - grass.run_command( + gs.run_command( "v.proj", project=tgtloc, mapset=tgtmapset, @@ -290,14 +288,14 @@ def main(): output=tgtregion, env=src_env, ) - grass.run_command("g.region", vector=tgtregion, env=src_env) + gs.run_command("g.region", vector=tgtregion, env=src_env) parameters["flags"] = parameters["flags"] + region_flag try: - grass.run_command("r.in.gdal", env=src_env, **parameters) + gs.run_command("r.in.gdal", env=src_env, **parameters) except CalledModuleError: - grass.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource) + gs.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource) - outfiles = grass.list_grouped("raster", env=src_env)["PERMANENT"] + outfiles = gs.list_grouped("raster", env=src_env)["PERMANENT"] # is output a group? group = False @@ -306,17 +304,17 @@ def main(): group = True path = os.path.join(GISDBASE, TMPLOC, "group", output, "POINTS") if os.path.exists(path): - grass.fatal(_("Input contains GCPs, rectification is required")) + gs.fatal(_("Input contains GCPs, rectification is required")) if "r" in region_flag: - grass.run_command( + gs.run_command( "g.remove", type="vector", flags="f", name=tgtregion, env=src_env ) # switch to target location - grass.run_command("g.remove", type="vector", flags="f", name=tgtregion) + gs.run_command("g.remove", type="vector", flags="f", name=tgtregion) - region = grass.region() + region = gs.region() rflags = None if flags["n"]: @@ -334,7 +332,7 @@ def main(): if options["extent"] == "input": # r.proj -g try: - tgtextents = grass.read_command( + tgtextents = gs.read_command( "r.proj", project=TMPLOC, mapset="PERMANENT", @@ -344,37 +342,37 @@ def main(): quiet=True, ) except CalledModuleError: - grass.fatal(_("Unable to get reprojected map extent")) + gs.fatal(_("Unable to get reprojected map extent")) try: - srcregion = grass.parse_key_val(tgtextents, val_type=float, vsep=" ") + srcregion = gs.parse_key_val(tgtextents, val_type=float, vsep=" ") n = srcregion["n"] s = srcregion["s"] e = srcregion["e"] w = srcregion["w"] except ValueError: # import into latlong, expect 53:39:06.894826N - srcregion = grass.parse_key_val(tgtextents, vsep=" ") - n = grass.float_or_dms(srcregion["n"][:-1]) * ( + srcregion = gs.parse_key_val(tgtextents, vsep=" ") + n = gs.float_or_dms(srcregion["n"][:-1]) * ( -1 if srcregion["n"][-1] == "S" else 1 ) - s = grass.float_or_dms(srcregion["s"][:-1]) * ( + s = gs.float_or_dms(srcregion["s"][:-1]) * ( -1 if srcregion["s"][-1] == "S" else 1 ) - e = grass.float_or_dms(srcregion["e"][:-1]) * ( + e = gs.float_or_dms(srcregion["e"][:-1]) * ( -1 if srcregion["e"][-1] == "W" else 1 ) - w = grass.float_or_dms(srcregion["w"][:-1]) * ( + w = gs.float_or_dms(srcregion["w"][:-1]) * ( -1 if srcregion["w"][-1] == "W" else 1 ) - env["GRASS_REGION"] = grass.region_env(n=n, s=s, e=e, w=w) + env["GRASS_REGION"] = gs.region_env(n=n, s=s, e=e, w=w) # v.in.region in tgt - grass.run_command("v.in.region", output=vreg, quiet=True, env=env) + gs.run_command("v.in.region", output=vreg, quiet=True, env=env) # reproject to src # switch to temp location try: - grass.run_command( + gs.run_command( "v.proj", input=vreg, output=vreg, @@ -384,29 +382,29 @@ def main(): env=src_env, ) # test if v.proj created a valid area - if grass.vector_info_topo(vreg, env=src_env)["areas"] != 1: - grass.fatal(_("Please check the 'extent' parameter")) + if gs.vector_info_topo(vreg, env=src_env)["areas"] != 1: + gs.fatal(_("Please check the 'extent' parameter")) except CalledModuleError: - grass.fatal(_("Unable to reproject to source project")) + gs.fatal(_("Unable to reproject to source project")) # set region from region vector - grass.run_command("g.region", raster=outfile, env=src_env) - grass.run_command("g.region", vector=vreg, env=src_env) + gs.run_command("g.region", raster=outfile, env=src_env) + gs.run_command("g.region", vector=vreg, env=src_env) # align to first band - grass.run_command("g.region", align=outfile, env=src_env) + gs.run_command("g.region", align=outfile, env=src_env) # get number of cells - cells = grass.region(env=src_env)["cells"] + cells = gs.region(env=src_env)["cells"] estres = math.sqrt((n - s) * (e - w) / cells) # remove from source location for multi bands import - grass.run_command( + gs.run_command( "g.remove", type="vector", name=vreg, flags="f", quiet=True, env=src_env ) # switch to target location - grass.run_command("g.remove", type="vector", name=vreg, flags="f", quiet=True) + gs.run_command("g.remove", type="vector", name=vreg, flags="f", quiet=True) - grass.message( + gs.message( _("Estimated target resolution for input band <{out}>: {res}").format( out=outfile, res=estres ) @@ -417,23 +415,23 @@ def main(): env = os.environ.copy() if options["extent"] == "input": - env["GRASS_REGION"] = grass.region_env(n=n, s=s, e=e, w=w) + env["GRASS_REGION"] = gs.region_env(n=n, s=s, e=e, w=w) res = None if tgtres == "estimated": res = estres elif tgtres == "value": res = tgtres_value - grass.message( + gs.message( _("Using given resolution for input band <{out}>: {res}").format( out=outfile, res=res ) ) # align to requested resolution - env["GRASS_REGION"] = grass.region_env(res=res, flags="a", env=env) + env["GRASS_REGION"] = gs.region_env(res=res, flags="a", env=env) else: - curr_reg = grass.region() - grass.message( + curr_reg = gs.region() + gs.message( _( "Using current region resolution for input band " "<{out}>: nsres={ns}, ewres={ew}" @@ -441,9 +439,9 @@ def main(): ) # r.proj - grass.message(_("Reprojecting <%s>...") % outfile) + gs.message(_("Reprojecting <%s>...") % outfile) try: - grass.run_command( + gs.run_command( "r.proj", project=TMPLOC, mapset="PERMANENT", @@ -456,16 +454,16 @@ def main(): env=env, ) except CalledModuleError: - grass.fatal(_("Unable to to reproject raster <%s>") % outfile) + gs.fatal(_("Unable to to reproject raster <%s>") % outfile) - if grass.raster_info(outfile)["min"] is None: - grass.fatal(_("The reprojected raster <%s> is empty") % outfile) + if gs.raster_info(outfile)["min"] is None: + gs.fatal(_("The reprojected raster <%s> is empty") % outfile) if flags["e"]: return 0 if group: - grass.run_command("i.group", group=output, input=",".join(outfiles)) + gs.run_command("i.group", group=output, input=",".join(outfiles)) # TODO: write metadata with r.support @@ -473,6 +471,6 @@ def main(): if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() atexit.register(cleanup) sys.exit(main()) diff --git a/scripts/r.in.aster/r.in.aster.py b/scripts/r.in.aster/r.in.aster.py index 41f6f14810f..24722293dde 100755 --- a/scripts/r.in.aster/r.in.aster.py +++ b/scripts/r.in.aster/r.in.aster.py @@ -52,7 +52,7 @@ # %end import os -import grass.script as grass +import grass.script as gs bands = { "L1A": { @@ -115,18 +115,18 @@ def main(): band = options["band"] # check whether gdalwarp is in path and executable - if not grass.find_program("gdalwarp", "--help"): - grass.fatal(_("gdalwarp is not in the path and executable")) + if not gs.find_program("gdalwarp", "--help"): + gs.fatal(_("gdalwarp is not in the path and executable")) # create temporary file to hold gdalwarp output before importing to GRASS - tempfile = grass.read_command("g.tempfile", pid=os.getpid()).strip() + ".tif" + tempfile = gs.read_command("g.tempfile", pid=os.getpid()).strip() + ".tif" # get projection information for current GRASS location - proj = grass.read_command("g.proj", flags="jf").strip() + proj = gs.read_command("g.proj", flags="jf").strip() # currently only runs in projected location if "XY location" in proj: - grass.fatal( + gs.fatal( _("This module needs to be run in a projected location (found: %s)") % proj ) @@ -165,40 +165,40 @@ def main(): srcfile = "HDF4_EOS:EOS_SWATH:%s:%s" % (input, dataset) import_aster(proj, srcfile, tempfile, output, band) else: - grass.fatal(_("band %s is not an available Terra/ASTER band") % band) + gs.fatal(_("band %s is not an available Terra/ASTER band") % band) elif proctype == "DEM": srcfile = input import_aster(proj, srcfile, tempfile, output, "DEM") # cleanup - grass.message(_("Cleaning up ...")) - grass.try_remove(tempfile) - grass.message(_("Done.")) + gs.message(_("Cleaning up ...")) + gs.try_remove(tempfile) + gs.message(_("Done.")) def import_aster(proj, srcfile, tempfile, output, band): # run gdalwarp with selected options (must be in $PATH) # to translate aster image to geotiff - grass.message(_("Georeferencing aster image ...")) - grass.debug("gdalwarp -t_srs %s %s %s" % (proj, srcfile, tempfile)) + gs.message(_("Georeferencing aster image ...")) + gs.debug("gdalwarp -t_srs %s %s %s" % (proj, srcfile, tempfile)) # We assume gdal is build natively for the platform GRASS is running on. # see #3258 cmd = ["gdalwarp", "-t_srs", proj, srcfile, tempfile] - p = grass.call(cmd) + p = gs.call(cmd) if p != 0: # check to see if gdalwarp executed properly return # import geotiff to GRASS - grass.message(_("Importing into GRASS ...")) + gs.message(_("Importing into GRASS ...")) outfile = "%s.%s" % (output, band) - grass.run_command("r.in.gdal", input=tempfile, output=outfile) + gs.run_command("r.in.gdal", input=tempfile, output=outfile) # write cmd history - grass.raster_history(outfile) + gs.raster_history(outfile) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() main() diff --git a/scripts/r.in.srtm/r.in.srtm.py b/scripts/r.in.srtm/r.in.srtm.py index 271ed7ad6ec..1e4c585ac02 100755 --- a/scripts/r.in.srtm/r.in.srtm.py +++ b/scripts/r.in.srtm/r.in.srtm.py @@ -74,7 +74,7 @@ import os import shutil import atexit -import grass.script as grass +import grass.script as gs import zipfile as zfile @@ -148,9 +148,9 @@ def cleanup(): if not in_temp: return for ext in [".bil", ".hdr", ".prj", ".hgt.zip"]: - grass.try_remove(tile + ext) + gs.try_remove(tile + ext) os.chdir("..") - grass.try_rmdir(tmpdir) + gs.try_rmdir(tmpdir) def main(): @@ -166,10 +166,10 @@ def main(): one = flags["1"] # are we in LatLong location? - s = grass.read_command("g.proj", flags="j") - kv = grass.parse_key_val(s) + s = gs.read_command("g.proj", flags="j") + kv = gs.parse_key_val(s) if "+proj" not in kv.keys() or kv["+proj"] != "longlat": - grass.fatal(_("This module only operates in LatLong locations")) + gs.fatal(_("This module only operates in LatLong locations")) # use these from now on: infile = input @@ -194,18 +194,18 @@ def main(): if os.path.isfile(zipfile): # really a ZIP file? if not zfile.is_zipfile(zipfile): - grass.fatal(_("'%s' does not appear to be a valid zip file.") % zipfile) + gs.fatal(_("'%s' does not appear to be a valid zip file.") % zipfile) is_zip = True elif os.path.isfile(hgtfile): # try and see if it's already unzipped is_zip = False else: - grass.fatal(_("File '%s' or '%s' not found") % (zipfile, hgtfile)) + gs.fatal(_("File '%s' or '%s' not found") % (zipfile, hgtfile)) # make a temporary directory - tmpdir = grass.tempfile() - grass.try_remove(tmpdir) + tmpdir = gs.tempfile() + gs.try_remove(tmpdir) os.mkdir(tmpdir) if is_zip: shutil.copyfile( @@ -226,14 +226,14 @@ def main(): if is_zip: # unzip & rename data file: - grass.message(_("Extracting '%s'...") % infile) + gs.message(_("Extracting '%s'...") % infile) try: zf = zfile.ZipFile(zipfile) zf.extractall() except: - grass.fatal(_("Unable to unzip file.")) + gs.fatal(_("Unable to unzip file.")) - grass.message(_("Converting input file to BIL...")) + gs.message(_("Converting input file to BIL...")) os.rename(hgtfile, bilfile) north = tile[0] @@ -257,10 +257,10 @@ def main(): if not one: tmpl = tmpl3sec elif swbd: - grass.message(_("Attempting to import 1-arcsec SWBD data")) + gs.message(_("Attempting to import 1-arcsec SWBD data")) tmpl = swbd1sec else: - grass.message(_("Attempting to import 1-arcsec data")) + gs.message(_("Attempting to import 1-arcsec data")) tmpl = tmpl1sec header = tmpl % (ulxmap, ulymap) @@ -276,24 +276,24 @@ def main(): outf.close() try: - grass.run_command("r.in.gdal", input=bilfile, out=tileout) + gs.run_command("r.in.gdal", input=bilfile, out=tileout) except: - grass.fatal(_("Unable to import data")) + gs.fatal(_("Unable to import data")) # nice color table if not swbd: - grass.run_command("r.colors", map=tileout, color="srtm") + gs.run_command("r.colors", map=tileout, color="srtm") # write cmd history: - grass.raster_history(tileout) + gs.raster_history(tileout) - grass.message(_("Done: generated map ") + tileout) - grass.message( + gs.message(_("Done: generated map ") + tileout) + gs.message( _("(Note: Holes in the data can be closed with 'r.fillnulls' using splines)") ) if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() atexit.register(cleanup) main() diff --git a/scripts/r.in.wms/r.in.wms.py b/scripts/r.in.wms/r.in.wms.py index cc571dbd878..71780d55842 100755 --- a/scripts/r.in.wms/r.in.wms.py +++ b/scripts/r.in.wms/r.in.wms.py @@ -207,7 +207,7 @@ import os import sys -import grass.script as grass +import grass.script as gs from grass.script.utils import decode @@ -219,16 +219,16 @@ def GetRegionParams(opt_region): if len(reg_spl) > 1: reg_mapset = reg_spl[1] - if not grass.find_file(name=reg_spl[0], element="windows", mapset=reg_mapset)[ + if not gs.find_file(name=reg_spl[0], element="windows", mapset=reg_mapset)[ "name" ]: - grass.fatal(_("Region <%s> not found") % opt_region) + gs.fatal(_("Region <%s> not found") % opt_region) if opt_region: - s = grass.read_command("g.region", quiet=True, flags="ug", region=opt_region) - region_params = grass.parse_key_val(decode(s), val_type=float) + s = gs.read_command("g.region", quiet=True, flags="ug", region=opt_region) + region_params = gs.parse_key_val(decode(s), val_type=float) else: - region_params = grass.region() + region_params = gs.region() return region_params @@ -237,12 +237,12 @@ def main(): sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), "etc", "r.in.wms")) if "GRASS" in options["driver"]: - grass.debug("Using GRASS driver") + gs.debug("Using GRASS driver") from wms_drv import WMSDrv wms = WMSDrv() elif "GDAL" in options["driver"]: - grass.debug("Using GDAL WMS driver") + gs.debug("Using GDAL WMS driver") from wms_gdal_drv import WMSGdalDrv if options["gdal_createopt"]: @@ -262,7 +262,7 @@ def main(): if options["proxy"]: wms.setProxy(options["proxy"]) if "GRASS" in options["driver"]: - grass.warning( + gs.warning( _( "The proxy will be ignored by the chosen GRASS driver. It is " "only used with the GDAL driver." @@ -272,9 +272,9 @@ def main(): options["region"] = GetRegionParams(options["region"]) fetched_map = wms.GetMap(options, flags) - grass.message(_("Importing raster map into GRASS...")) + gs.message(_("Importing raster map into GRASS...")) if not fetched_map: - grass.warning( + gs.warning( _("Nothing to import.\nNo data has been downloaded from wms server.") ) return @@ -285,5 +285,5 @@ def main(): if __name__ == "__main__": - options, flags = grass.parser() + options, flags = gs.parser() sys.exit(main()) diff --git a/scripts/r.in.wms/wms_base.py b/scripts/r.in.wms/wms_base.py index b27abc74f97..a14e15dc786 100644 --- a/scripts/r.in.wms/wms_base.py +++ b/scripts/r.in.wms/wms_base.py @@ -19,11 +19,12 @@ import os from http.client import HTTPException from math import ceil +from pathlib import Path from urllib.request import Request, urlopen from urllib.error import HTTPError -import grass.script as grass +import grass.script as gs from grass.exceptions import CalledModuleError @@ -43,10 +44,10 @@ def __del__(self): # removed before, implemented just in case of unexpected # stop of module for temp_file in self.temp_files_to_cleanup: - grass.try_remove(temp_file) + gs.try_remove(temp_file) def _debug(self, fn, msg): - grass.debug("%s.%s: %s" % (self.__class__.__name__, fn, msg)) + gs.debug("%s.%s: %s" % (self.__class__.__name__, fn, msg)) def _initializeParameters(self, options, flags): self._debug("_initialize_parameters", "started") @@ -76,7 +77,7 @@ def _initializeParameters(self, options, flags): if (self.params["password"] and self.params["username"] == "") or ( self.params["password"] == "" and self.params["username"] ): - grass.fatal( + gs.fatal( _( "Please insert both %s and %s parameters or none of them." % ("password", "username") @@ -90,7 +91,7 @@ def _initializeParameters(self, options, flags): and "format" not in driver_props["ignored_params"] ): if not flags["o"] and "WMS" in self.params["driver"]: - grass.warning(_("JPEG format does not support transparency")) + gs.warning(_("JPEG format does not support transparency")) self.params["format"] = drv_info.GetFormat(options["format"]) if not self.params["format"]: @@ -99,7 +100,7 @@ def _initializeParameters(self, options, flags): # TODO: get srs from Tile Service file in OnEarth_GRASS driver self.params["srs"] = int(options["srs"]) if self.params["srs"] <= 0 and "srs" not in driver_props["ignored_params"]: - grass.fatal(_("Invalid EPSG code %d") % self.params["srs"]) + gs.fatal(_("Invalid EPSG code %d") % self.params["srs"]) self.params["wms_version"] = options["wms_version"] if ( @@ -107,7 +108,7 @@ def _initializeParameters(self, options, flags): and self.params["wms_version"] == "1.1.1" ): self.params["wms_version"] = "1.3.0" - grass.warning( + gs.warning( _( "WMS version <1.3.0> will be used, because version <1.1.1> does " "not support <%s>projection" @@ -121,16 +122,16 @@ def _initializeParameters(self, options, flags): self.params["proj_name"] = "SRS" # read projection info - self.proj_location = grass.read_command("g.proj", flags="jf").rstrip("\n") + self.proj_location = gs.read_command("g.proj", flags="jf").rstrip("\n") self.proj_location = self._modifyProj(self.proj_location) self.source_epsg = str(GetEpsg(self.params["srs"])) self.target_epsg = None - target_crs = grass.parse_command("g.proj", flags="g", delimiter="=") + target_crs = gs.parse_command("g.proj", flags="g", delimiter="=") if "epsg" in target_crs.keys(): self.target_epsg = target_crs["epsg"] if self.source_epsg != self.target_epsg: - grass.warning( + gs.warning( _( "SRS differences: WMS source EPSG %s != location EPSG %s (use " "srs=%s to adjust)" @@ -138,7 +139,7 @@ def _initializeParameters(self, options, flags): % (self.source_epsg, self.target_epsg, self.target_epsg) ) - self.proj_srs = grass.read_command( + self.proj_srs = gs.read_command( "g.proj", flags="jf", epsg=str(GetEpsg(self.params["srs"])) ) self.proj_srs = self.proj_srs.rstrip("\n") @@ -146,18 +147,18 @@ def _initializeParameters(self, options, flags): self.proj_srs = self._modifyProj(self.proj_srs) if not self.proj_srs or not self.proj_location: - grass.fatal(_("Unable to get projection info")) + gs.fatal(_("Unable to get projection info")) self.region = options["region"] min_tile_size = 100 maxcols = int(options["maxcols"]) if maxcols <= min_tile_size: - grass.fatal(_("Maxcols must be greater than 100")) + gs.fatal(_("Maxcols must be greater than 100")) maxrows = int(options["maxrows"]) if maxrows <= min_tile_size: - grass.fatal(_("Maxrows must be greater than 100")) + gs.fatal(_("Maxrows must be greater than 100")) # setting optimal tile size according to maxcols and maxrows constraint # and region cols and rows @@ -197,7 +198,7 @@ def _checkIgnoeredParams(self, options, flags, driver_props): not_relevant_params.append("<" + i_param + ">") if len(not_relevant_params) > 0: - grass.warning( + gs.warning( _( "These parameter are ignored: %s\n\ %s driver does not support the parameters." @@ -211,7 +212,7 @@ def _checkIgnoeredParams(self, options, flags, driver_props): not_relevant_flags.append("<" + i_flag + ">") if len(not_relevant_flags) > 0: - grass.warning( + gs.warning( _( "These flags are ignored: %s\n\ %s driver does not support the flags." @@ -255,7 +256,7 @@ def _fetchCapabilities(self, options): if options["urlparams"]: cap_url += "&" + options["urlparams"] - grass.debug("Fetching capabilities file.\n%s" % cap_url) + gs.debug("Fetching capabilities file.\n%s" % cap_url) try: cap = self._fetchDataFromServer( @@ -263,7 +264,7 @@ def _fetchCapabilities(self, options): ) except (OSError, HTTPException) as e: if isinstance(e, HTTPError) and e.code == 401: - grass.fatal( + gs.fatal( _("Authorization failed to <%s> when fetching capabilities") % options["url"] ) @@ -277,10 +278,10 @@ def _fetchCapabilities(self, options): else: msg += "{0}".format(e) - grass.fatal(msg) + gs.fatal(msg) - grass.debug("Fetching capabilities OK") - return grass.decode(cap.read()) + gs.debug("Fetching capabilities OK") + return gs.decode(cap.read()) def _fetchDataFromServer(self, url, username=None, password=None): """!Fetch data from server""" @@ -294,7 +295,7 @@ def _fetchDataFromServer(self, url, username=None, password=None): try: return urlopen(request) except ValueError as error: - grass.fatal("%s" % error) + gs.fatal("%s" % error) def GetCapabilities(self, options): """!Get capabilities from WMS server""" @@ -304,13 +305,10 @@ def GetCapabilities(self, options): # save to file if capfile_output: try: - with open(capfile_output, "w") as temp: - temp.write(cap) + Path(capfile_output).write_text(cap) return except OSError as error: - grass.fatal( - _("Unable to open file '%s'.\n%s\n" % (capfile_output, error)) - ) + gs.fatal(_("Unable to open file '%s'.\n%s\n" % (capfile_output, error))) # print to output print(cap) @@ -352,11 +350,11 @@ def _computeBbox(self): ) ) except OSError: - grass.fatal(_("Unable to write data into tempfile")) + gs.fatal(_("Unable to write data into tempfile")) finally: temp_region_opened.close() try: - points = grass.read_command( + points = gs.read_command( "m.proj", flags="d", proj_out=self.proj_srs, @@ -367,20 +365,20 @@ def _computeBbox(self): except CalledModuleError: points = None finally: - grass.try_remove(temp_region) + gs.try_remove(temp_region) if not points: - grass.fatal(_("Unable to determine region, %s failed") % "m.proj") + gs.fatal(_("Unable to determine region, %s failed") % "m.proj") points = points.splitlines() if len(points) != 4: - grass.fatal(_("Region definition: 4 points required")) + gs.fatal(_("Region definition: 4 points required")) for point in points: try: point = list(map(float, point.split("|"))) except ValueError: - grass.fatal(_("Reprojection of region using m.proj failed.")) + gs.fatal(_("Reprojection of region using m.proj failed.")) if not bbox["maxy"]: bbox["maxy"] = point[1] bbox["miny"] = point[1] @@ -420,8 +418,8 @@ def _reprojectMap(self): if do_reproject and self.proj_srs == self.proj_location: do_reproject = False if do_reproject: - grass.message(_("Reprojecting raster...")) - self.temp_warpmap = grass.tempfile() + ".tif" + gs.message(_("Reprojecting raster...")) + self.temp_warpmap = gs.tempfile() + ".tif" if int(os.getenv("GRASS_VERBOSE", "2")) <= 2: nuldev = open(os.devnull, "w+") @@ -438,7 +436,7 @@ def _reprojectMap(self): # RGB rasters - alpha layer is added for cropping edges of projected raster try: if self.temp_map_bands_num == 3: - ps = grass.Popen( + ps = gs.Popen( [ "gdalwarp", "-s_srs", @@ -455,7 +453,7 @@ def _reprojectMap(self): ) # RGBA rasters else: - ps = grass.Popen( + ps = gs.Popen( [ "gdalwarp", "-s_srs", @@ -471,7 +469,7 @@ def _reprojectMap(self): ) ps.wait() except OSError as e: - grass.fatal( + gs.fatal( "%s \nThis can be caused by missing %s utility. " % (e, "gdalwarp") ) @@ -479,8 +477,8 @@ def _reprojectMap(self): nuldev.close() if ps.returncode != 0: - grass.fatal(_("%s failed") % "gdalwarp") - grass.try_remove(self.temp_map) + gs.fatal(_("%s failed") % "gdalwarp") + gs.try_remove(self.temp_map) # raster projection is same as projection of location else: self.temp_warpmap = self.temp_map @@ -494,9 +492,9 @@ def _tempfile(self): @return string path to temp_file """ - temp_file = grass.tempfile() + temp_file = gs.tempfile() if temp_file is None: - grass.fatal(_("Unable to create temporary files")) + gs.fatal(_("Unable to create temporary files")) # list of created tempfiles for destructor self.temp_files_to_cleanup.append(temp_file) @@ -520,11 +518,11 @@ def __init__(self, opt_output, cleanup_bands): maps = [] for suffix in (".red", ".green", ".blue", ".alpha", self.original_mask_suffix): rast = self.opt_output + suffix - if grass.find_file(rast, element="cell", mapset=".")["file"]: + if gs.find_file(rast, element="cell", mapset=".")["file"]: maps.append(rast) if len(maps) != 0: - grass.fatal( + gs.fatal( _( "Please change output name, or change names of these rasters: %s, " "module needs to create this temporary maps during execution." @@ -537,34 +535,34 @@ def __del__(self): if self.cleanup_mask: # clear temporary mask, which was set by module try: - grass.run_command("r.mask", quiet=True, flags="r") + gs.run_command("r.mask", quiet=True, flags="r") except CalledModuleError: - grass.fatal(_("%s failed") % "r.mask") + gs.fatal(_("%s failed") % "r.mask") # restore original mask, if exists - if grass.find_file( + if gs.find_file( self.opt_output + self.original_mask_suffix, element="cell", mapset="." )["name"]: try: mask_copy = self.opt_output + self.original_mask_suffix - grass.run_command("g.copy", quiet=True, raster=mask_copy + ",MASK") + gs.run_command("g.copy", quiet=True, raster=mask_copy + ",MASK") except CalledModuleError: - grass.fatal(_("%s failed") % "g.copy") + gs.fatal(_("%s failed") % "g.copy") # remove temporary created rasters maps = [] rast = self.opt_output + ".alpha" - if grass.find_file(rast, element="cell", mapset=".")["file"]: + if gs.find_file(rast, element="cell", mapset=".")["file"]: maps.append(rast) if self.cleanup_bands: for suffix in (".red", ".green", ".blue", self.original_mask_suffix): rast = self.opt_output + suffix - if grass.find_file(rast, element="cell", mapset=".")["file"]: + if gs.find_file(rast, element="cell", mapset=".")["file"]: maps.append(rast) if maps: - grass.run_command( + gs.run_command( "g.remove", quiet=True, flags="fb", type="raster", name=",".join(maps) ) @@ -572,7 +570,7 @@ def __del__(self): if "GRASS_REGION" in os.environ.keys(): os.environ.pop("GRASS_REGION") - maplist = grass.read_command( + maplist = gs.read_command( "g.list", type="raster", pattern="%s*" % (self.opt_output), @@ -581,21 +579,21 @@ def __del__(self): ).rstrip("\n") if len(maplist) == 0: - grass.fatal(_("WMS import failed, nothing imported")) + gs.fatal(_("WMS import failed, nothing imported")) else: for raster in maplist.split(","): - grass.raster_history(raster, overwrite=True) - grass.run_command( + gs.raster_history(raster, overwrite=True) + gs.run_command( "r.support", map=raster, description="generated by r.in.wms" ) - grass.message(_("<%s> created.") % raster) + gs.message(_("<%s> created.") % raster) def ImportMapIntoGRASS(self, raster): """!Import raster into GRASS.""" # importing temp_map into GRASS try: # do not use -o flag ! - grass.run_command( + gs.run_command( "r.in.gdal", flags="o", quiet=True, @@ -604,38 +602,34 @@ def ImportMapIntoGRASS(self, raster): output=self.opt_output, ) except CalledModuleError: - grass.fatal(_("%s failed") % "r.in.gdal") + gs.fatal(_("%s failed") % "r.in.gdal") # information for destructor to cleanup temp_layers, created # with r.in.gdal # setting region for full extend of imported raster - if grass.find_file(self.opt_output + ".red", element="cell", mapset=".")[ - "file" - ]: + if gs.find_file(self.opt_output + ".red", element="cell", mapset=".")["file"]: region_map = self.opt_output + ".red" else: region_map = self.opt_output - os.environ["GRASS_REGION"] = grass.region_env(rast=region_map) + os.environ["GRASS_REGION"] = gs.region_env(rast=region_map) # mask created from alpha layer, which describes real extend # of warped layer (may not be a rectangle), also mask contains # transparent parts of raster - if grass.find_file(self.opt_output + ".alpha", element="cell", mapset=".")[ - "name" - ]: + if gs.find_file(self.opt_output + ".alpha", element="cell", mapset=".")["name"]: # saving current mask (if exists) into temp raster - if grass.find_file("MASK", element="cell", mapset=".")["name"]: + if gs.find_file("MASK", element="cell", mapset=".")["name"]: try: mask_copy = self.opt_output + self.original_mask_suffix - grass.run_command("g.copy", quiet=True, raster="MASK," + mask_copy) + gs.run_command("g.copy", quiet=True, raster="MASK," + mask_copy) except CalledModuleError: - grass.fatal(_("%s failed") % "g.copy") + gs.fatal(_("%s failed") % "g.copy") # info for destructor self.cleanup_mask = True try: - grass.run_command( + gs.run_command( "r.mask", quiet=True, overwrite=True, @@ -644,24 +638,24 @@ def ImportMapIntoGRASS(self, raster): raster=self.opt_output + ".alpha", ) except CalledModuleError: - grass.fatal(_("%s failed") % "r.mask") + gs.fatal(_("%s failed") % "r.mask") if not self.cleanup_bands: # use the MASK to set NULL values for suffix in (".red", ".green", ".blue"): rast = self.opt_output + suffix - if grass.find_file(rast, element="cell", mapset=".")["file"]: - grass.run_command( + if gs.find_file(rast, element="cell", mapset=".")["file"]: + gs.run_command( "g.rename", rast="%s,%s" % (rast, rast + "_null"), quiet=True, ) - grass.run_command( + gs.run_command( "r.mapcalc", expression="%s = %s" % (rast, rast + "_null"), quiet=True, ) - grass.run_command( + gs.run_command( "g.remove", type="raster", name="%s" % (rast + "_null"), @@ -671,13 +665,11 @@ def ImportMapIntoGRASS(self, raster): # TODO one band + alpha band? if ( - grass.find_file(self.opt_output + ".red", element="cell", mapset=".")[ - "file" - ] + gs.find_file(self.opt_output + ".red", element="cell", mapset=".")["file"] and self.cleanup_bands ): try: - grass.run_command( + gs.run_command( "r.composite", quiet=True, overwrite=True, @@ -687,7 +679,7 @@ def ImportMapIntoGRASS(self, raster): output=self.opt_output, ) except CalledModuleError: - grass.fatal(_("%s failed") % "r.composite") + gs.fatal(_("%s failed") % "r.composite") class WMSDriversInfo: diff --git a/scripts/r.in.wms/wms_cap_parsers.py b/scripts/r.in.wms/wms_cap_parsers.py index a053942ee77..5435fe29591 100644 --- a/scripts/r.in.wms/wms_cap_parsers.py +++ b/scripts/r.in.wms/wms_cap_parsers.py @@ -22,7 +22,7 @@ from xml.etree.ElementTree import ParseError import xml.etree.ElementTree as etree -import grass.script as grass +import grass.script as gs class BaseCapabilitiesTree(etree.ElementTree): @@ -99,7 +99,7 @@ def __init__(self, cap_file, force_version=None): BaseCapabilitiesTree.__init__(self, cap_file) self.xml_ns = WMSXMLNsHandler(self) - grass.debug("Checking WMS capabilities tree.", 4) + gs.debug("Checking WMS capabilities tree.", 4) if "version" not in self.getroot().attrib: raise ParseError( @@ -125,7 +125,7 @@ def __init__(self, cap_file, force_version=None): self._checkFormats(capability) self._checkLayerTree(root_layer) - grass.debug("Check of WMS capabilities tree was finished.", 4) + gs.debug("Check of WMS capabilities tree was finished.", 4) def _checkFormats(self, capability): """!Check if format element is defined.""" @@ -140,9 +140,9 @@ def _checkLayerTree(self, parent_layer, first=True): layers = parent_layer.findall(self.xml_ns.Ns("Layer")) - for l in layers: - self._initLayer(l, parent_layer) - self._checkLayerTree(l, False) + for layer in layers: + self._initLayer(layer, parent_layer) + self._checkLayerTree(layer, False) def _initLayer(self, layer, parent_layer): """Inherit elements from parent layer @@ -189,7 +189,7 @@ def _initLayer(self, layer, parent_layer): for s in styles: s_name = s.find(self.xml_ns.Ns("Name")) if s_name is None or not s_name.text: - grass.debug("Removed invalid