diff --git a/.github/workflows/apt.txt b/.github/workflows/apt.txt index 09c1898afc7..8d7d60e1336 100644 --- a/.github/workflows/apt.txt +++ b/.github/workflows/apt.txt @@ -22,7 +22,6 @@ python3-numpy python3-pil python3-ply python3-pyvirtualdisplay -python3-six python3-termcolor sqlite3 zlib1g-dev diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ac0cd234c6f..a9239549898 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -5,16 +5,11 @@ name: Docker # # Summary # -# job docker-branch-os-matrix: -# * creates tags latest-alpine, latest-debian and latest-ubuntu for main branch -# * creates tags stable-alpine, stable-debian and stable-ubuntu for releasebranch_8_2 -# * creates tags -alpine, -debian and -ubuntu for all triggered branches -# -# job docker-main-latest: -# * creates tag latest for main branch -# -# job docker-release-os-matrix: +# job docker-os-matrix: # * creates tags -alpine, -debian and -ubuntu for each release +# * creates tags -alpine, -debian and -ubuntu for all triggered branches +# * creates tags current-alpine, current-debian and current-ubuntu for releasebranch_8_3 +# * creates tag latest for last stable release with ubuntu os on: push: @@ -22,26 +17,25 @@ on: - main - releasebranch_* - '!releasebranch_7_*' - tags: ['*.*.*'] + # tags: ['*.*.*'] paths-ignore: [doc/**] release: types: [published] -env: - # Additionally mentioned in docker-sha-release-latest - # as use of variable fails there - DOCKERHUB_REPOSITORY: osgeo/grass-gis - jobs: - # Only run for push to configured branches, do not run for releases. - # Take care of different os. For main branch, created tags are: - # latest-alpine, latest-debian, latest-ubuntu - # For releasebranch_8_2, created tags are: - # stable-alpine, stable-debian, stable-ubuntu - docker-branch-os-matrix: - name: build and push ${{ matrix.os }} for branch - if: startsWith(github.ref, 'refs/heads/') && github.repository_owner == 'OSGeo' + # Run for push to configured branches and all published releases. + # Take care of different os. + # For main branch, created tags are: + # main-alpine, main-debian, main-ubuntu + # For releasebranch_8_3, created tags are: + # current-alpine, current-debian, current-ubuntu, + # releasebranch_8_3-alpine, releasebranch_8_3-debian, releasebranch_8_3-ubuntu + # For a release, e.g. 8.3.0, created tags are: + # 8.3.0-alpine, 8.3.0-debian, 8.3.0-ubuntu and latest (with ubuntu) + docker-os-matrix: + name: build and push ${{ matrix.os }} for ${{ github.ref }} + if: github.repository_owner == 'OSGeo' runs-on: ubuntu-latest strategy: @@ -58,125 +52,19 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 - - id: meta - name: Create tag name - run: | - if [ "$GITHUB_REF" == "refs/heads/main" ] - then - TAG_PREFIX=latest - elif [ "$GITHUB_REF" == "refs/heads/releasebranch_8_2" ] - then - TAG_PREFIX=stable - else - # use branch name as TAG_PREFIX - TAG_PREFIX=`echo $GITHUB_REF|cut -d '/' -f3` - fi - tag="${DOCKERHUB_REPOSITORY}:${TAG_PREFIX}-${{ matrix.os }}" - echo "tags=$tag" >> $GITHUB_OUTPUT - - name: Log - run: | - echo ${{ steps.meta.outputs.tags }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push - id: docker_build - uses: docker/build-push-action@v4 - with: - push: true - pull: true - context: . - tags: ${{ steps.meta.outputs.tags }} - file: docker/${{ matrix.os }}/Dockerfile - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} - - - # Only run for push to main branch - # Take care of tag latest - # This job needs to build the configured image (ubuntu) - # again for main branch to create latest tag. - docker-main-latest: - name: build and push latest for main branch - if: github.ref == 'refs/heads/main' && github.repository_owner == 'OSGeo' - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: meta - name: Create tag name - run: | - tag=${DOCKERHUB_REPOSITORY}:latest - echo "tags=$tag" >> $GITHUB_OUTPUT - - name: Log - run: echo ${{ steps.meta.outputs.tags }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push - id: docker_build - uses: docker/build-push-action@v4 - with: - push: true - pull: true - context: . - tags: ${{ steps.meta.outputs.tags }} - file: docker/ubuntu/Dockerfile - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} - - - # run for releases, take care of release tags - docker-release-os-matrix: - name: build and push release for ${{ matrix.os }} - if: startsWith(github.ref, 'refs/tags/') && github.repository_owner == 'OSGeo' - runs-on: ubuntu-latest - strategy: - matrix: - os: - - alpine - - debian - - ubuntu - fail-fast: false - - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Create image and tag name + - name: Docker meta id: meta uses: docker/metadata-action@v4 with: - # images: ${DOCKERHUB_REPOSITORY} images: osgeo/grass-gis tags: | type=ref,event=tag + type=ref,event=branch + type=raw,value=current,enable=${{ github.ref == format('refs/heads/{0}', 'releasebranch_8_3') }} + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/8.3') && matrix.os == 'ubuntu' }},suffix= flavor: | latest=false - - id: meta2 - name: Update tag name - run: | - tag="${{ steps.meta.outputs.tags }}-${{ matrix.os }}" - echo "tags=$tag" >> $GITHUB_OUTPUT - - name: Log - run: | - echo ${{ steps.meta2.outputs.tags }} + suffix=-${{ matrix.os }} - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx @@ -193,7 +81,7 @@ jobs: push: true pull: true context: . - tags: ${{ steps.meta2.outputs.tags }} + tags: ${{ steps.meta.outputs.tags }} file: docker/${{ matrix.os }}/Dockerfile - name: Image digest run: echo ${{ steps.docker_build.outputs.digest }} diff --git a/.github/workflows/osgeo4w.yml b/.github/workflows/osgeo4w.yml index 5ad3a3fa76e..fbbd06caf8c 100644 --- a/.github/workflows/osgeo4w.yml +++ b/.github/workflows/osgeo4w.yml @@ -43,7 +43,7 @@ jobs: mingw-w64-x86_64-gcc mingw-w64-x86_64-ccache mingw-w64-x86_64-zlib mingw-w64-x86_64-libiconv mingw-w64-x86_64-bzip2 mingw-w64-x86_64-gettext mingw-w64-x86_64-libsystre mingw-w64-x86_64-libtre-git mingw-w64-x86_64-libwinpthread-git mingw-w64-x86_64-libpng - mingw-w64-x86_64-pcre mingw-w64-x86_64-python3-six + mingw-w64-x86_64-pcre - name: Install OSGeo4W run: | @@ -57,7 +57,7 @@ jobs: pdal-devel,netcdf-devel,cairo-devel,fftw,freetype-devel,gdal-ecw,\ gdal-mrsid,liblas-devel,libxdr,libpq-devel,pdcurses,\ python3-matplotlib,python3-numpy,python3-ply,python3-pywin32,\ - python3-six,python3-wxpython,regex-devel,zstd-devel" + python3-wxpython,regex-devel,zstd-devel" - name: Compile GRASS GIS run: D:\msys64\usr\bin\bash.exe -l (''+(Get-Location)+'\.github\workflows\build_osgeo4w.sh') (Get-Location) diff --git a/.pylintrc b/.pylintrc index 51746f92942..b260c0fd401 100644 --- a/.pylintrc +++ b/.pylintrc @@ -350,7 +350,7 @@ init-import=no # List of qualified module names which can have objects that can redefine # builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io +redefining-builtins-modules=past.builtins,future.builtins,builtins,io [SIMILARITIES] diff --git a/.travis/linux.install.sh b/.travis/linux.install.sh index d7f97e3ae72..d695ab12992 100755 --- a/.travis/linux.install.sh +++ b/.travis/linux.install.sh @@ -35,7 +35,6 @@ sudo apt-get install --no-install-recommends \ python3-pil \ python3-pip \ python3-ply \ - python3-six \ python-wxgtk3.0 \ unixodbc-dev \ libnetcdf-dev \ diff --git a/CITATION.cff b/CITATION.cff index 340a17784c6..99f1e68573c 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,18 +1,19 @@ cff-version: 1.2.0 -message: If you use this software, please cite it using the metadata from this file. - title: GRASS GIS +message: If you use this software, please cite it using the metadata from this file. version: 8.4.0 abstract: GRASS GIS (Geographic Resources Analysis Support System) is a free and open source Geographic Information System (GIS) software used for geospatial data management and analysis, image processing, graphics and maps production, spatial modeling, and visualization. - +type: software authors: - - name: GRASS Development Team + - family-names: GRASS Development Team email: grass-dev@lists.osgeo.org affiliation: Open Source Geospatial Foundation (OSGeo) - - name: Martin Landa + - given-names: Martin + family-names: Landa affiliation: Czech Technical University in Prague orcid: https://orcid.org/0000-0001-6869-3542 - - name: Markus Neteler + - given-names: Markus + family-names: Neteler affiliation: mundialis GmbH & Co. KG orcid: https://orcid.org/0000-0003-1916-1966 - given-names: Markus @@ -20,10 +21,12 @@ authors: email: metz@mundialis.de affiliation: mundialis GmbH & Co. KG orcid: https://orcid.org/0000-0002-4038-8754 - - name: Anna Petrášová + - given-names: Anna + family-names: Petrášová affiliation: North Carolina State University orcid: https://orcid.org/0000-0002-5120-5538 - - name: Vaclav Petráš + - given-names: Vaclav + family-names: Petráš affiliation: North Carolina State University orcid: https://orcid.org/0000-0001-5566-9236 - given-names: Glynn @@ -104,9 +107,8 @@ authors: - given-names: Hamish family-names: Bowman email: hamish_b@yahoo.com - repository-code: https://github.com/OSGeo/grass -license: GNU General Public License v2 or later +license: GPL-2.0-or-later doi: 10.5281/zenodo.4621728 keywords: - GIS @@ -117,7 +119,3 @@ keywords: - open source - free software - GNU GPL v2 - -citation: - - text: GRASS Development Team. (2023). Geographic Resources Analysis Support System (GRASS GIS) Software, Version 8.4.0. Open Source Geospatial Foundation. https://grass.osgeo.org - doi: 10.5281/zenodo.4621728 diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index b9fd04e7456..1908c827efb 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -82,10 +82,6 @@ Note: also the respective development packages (commonly named `xxx-dev` or [https://cran.r-project.org](https://cran.r-project.org) - **FreeType2** (for TrueType font support and `d.text.freetype`) [https://freetype.org/](https://freetype.org/) -- **Ctypes** (for ctypes interface) - Ctypes can be added as a third-party module in Python 2.3 and - 2.4 - [https://pypi.org/project/ctypes/1.0.2/](https://pypi.org/project/ctypes/1.0.2/) - [https://docs.python.org/library/ctypes.html](https://docs.python.org/library/ctypes.html) - **wxPython >= 2.8.10.1** (for wxGUI) [https://www.wxpython.org](https://www.wxpython.org) - **NumPy >= 1.0.4** (for various wxGUI components and pyGRASS) @@ -107,10 +103,6 @@ Note: also the respective development packages (commonly named `xxx-dev` or [https://matplotlib.org/](https://matplotlib.org/) - **python-termcolor** (recommended for `g.search.modules`) [https://pypi.org/project/termcolor/](https://pypi.org/project/termcolor/) -- **six** (`python-six`, needed for Python API and for cross-version Python - compatibility) - [https://pypi.python.org/pypi/six](https://pypi.python.org/pypi/six) - [https://github.com/benjaminp/six](https://github.com/benjaminp/six) - **FFMPEG or alternative** (for wxGUI Animation tool - `g.gui.module`), specifically ffmpeg tool [https://ffmpeg.org](https://ffmpeg.org) diff --git a/Vagrantfile b/Vagrantfile index e3e2f5d8fe3..2ece6c417c4 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -71,7 +71,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| "python3-numpy", "python3-ply", "python3-pil", - "python3-six", "libnetcdf-dev", "netcdf-bin", "libblas-dev", diff --git a/doc/development/rfc/version_numbering.md b/doc/development/rfc/version_numbering.md index 9f516652de2..7829b0eb513 100644 --- a/doc/development/rfc/version_numbering.md +++ b/doc/development/rfc/version_numbering.md @@ -2,7 +2,7 @@ Author: Vaclav Petras -Status: Draft +Status: Adopted (5 June 2023) ## Summary diff --git a/doc/python/raster_example_ctypes.py b/doc/python/raster_example_ctypes.py index f45b075ba38..f62ce4a9492 100644 --- a/doc/python/raster_example_ctypes.py +++ b/doc/python/raster_example_ctypes.py @@ -29,7 +29,7 @@ if len(sys.argv) == 2: input = sys.argv[1] else: - input = raw_input("Name of raster map? ") + input = input("Name of raster map? ") # initialize GRASS library G_gisinit("") diff --git a/doc/python/vector_example_ctypes.py b/doc/python/vector_example_ctypes.py index b0748e64733..9f8a90d6459 100644 --- a/doc/python/vector_example_ctypes.py +++ b/doc/python/vector_example_ctypes.py @@ -17,7 +17,7 @@ if len(sys.argv) == 2: input = sys.argv[1] else: - input = raw_input("Name of vector map? ") + input = input("Name of vector map? ") # initialize GRASS library G_gisinit("") diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile index e56e6b3aa76..2ec9a0a09e1 100644 --- a/docker/alpine/Dockerfile +++ b/docker/alpine/Dockerfile @@ -56,7 +56,6 @@ ENV GRASS_RUN_PACKAGES="\ openblas \ py3-numpy \ py3-pillow \ - py3-six \ pdal \ pdal-dev \ postgresql15-client \ diff --git a/gui/wxpython/.pylintrc b/gui/wxpython/.pylintrc index bfb8db8a492..6268e8467a7 100644 --- a/gui/wxpython/.pylintrc +++ b/gui/wxpython/.pylintrc @@ -379,7 +379,7 @@ init-import=no # List of qualified module names which can have objects that can redefine # builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io +redefining-builtins-modules=past.builtins,future.builtins,builtins,io [SIMILARITIES] diff --git a/gui/wxpython/animation/dialogs.py b/gui/wxpython/animation/dialogs.py index 74821e678c2..eebf2d61203 100644 --- a/gui/wxpython/animation/dialogs.py +++ b/gui/wxpython/animation/dialogs.py @@ -20,8 +20,6 @@ @author Anna Petrasova """ -from __future__ import print_function - import os import wx import copy diff --git a/gui/wxpython/animation/frame.py b/gui/wxpython/animation/frame.py index 2c64700418a..1f46e827c1b 100644 --- a/gui/wxpython/animation/frame.py +++ b/gui/wxpython/animation/frame.py @@ -20,7 +20,6 @@ import os import wx import wx.aui -import six import grass.script as gcore import grass.temporal as tgis @@ -143,7 +142,7 @@ def _addPanes(self): .DestroyOnClose(True) .Layer(0), ) - for name, slider in six.iteritems(self.animationSliders): + for name, slider in self.animationSliders.items(): self._mgr.AddPane( slider, wx.aui.AuiPaneInfo() diff --git a/gui/wxpython/animation/nviztask.py b/gui/wxpython/animation/nviztask.py index 927d59ec47c..fb3dfe501a1 100644 --- a/gui/wxpython/animation/nviztask.py +++ b/gui/wxpython/animation/nviztask.py @@ -14,12 +14,7 @@ @author Anna Petrasova """ -from __future__ import print_function - -try: - import xml.etree.ElementTree as etree -except ImportError: - import elementtree.ElementTree as etree # Python <= 2.4 +import xml.etree.ElementTree as etree from core.workspace import ProcessWorkspaceFile from core.gcmd import RunCommand, GException diff --git a/gui/wxpython/animation/temporal_manager.py b/gui/wxpython/animation/temporal_manager.py index 1765ff05f70..b3e081a497f 100644 --- a/gui/wxpython/animation/temporal_manager.py +++ b/gui/wxpython/animation/temporal_manager.py @@ -17,8 +17,6 @@ @author Anna Kratochvilova """ -from __future__ import print_function - import datetime import grass.script as grass diff --git a/gui/wxpython/animation/utils.py b/gui/wxpython/animation/utils.py index 3b6493952a1..b6c0d27abac 100644 --- a/gui/wxpython/animation/utils.py +++ b/gui/wxpython/animation/utils.py @@ -20,7 +20,6 @@ import os import wx import hashlib -import six from multiprocessing import cpu_count try: @@ -99,7 +98,7 @@ def validateMapNames(names, etype): raise GException(_("Map <%s> not found.") % name) else: found = False - for mapset, mapNames in six.iteritems(mapDict): + for mapset, mapNames in mapDict.items(): if name in mapNames: found = True newNames.append(name + "@" + mapset) diff --git a/gui/wxpython/core/gcmd.py b/gui/wxpython/core/gcmd.py index b85874dc242..ebb3694d80a 100644 --- a/gui/wxpython/core/gcmd.py +++ b/gui/wxpython/core/gcmd.py @@ -25,8 +25,6 @@ @author Martin Landa """ -from __future__ import print_function - import os import sys import time @@ -53,9 +51,6 @@ from grass.script import core as grass from grass.script.utils import decode, encode -if sys.version_info.major == 2: - bytes = str - def DecodeString(string): """Decode string using system encoding diff --git a/gui/wxpython/core/gconsole.py b/gui/wxpython/core/gconsole.py index e25137c3556..a056368efde 100644 --- a/gui/wxpython/core/gconsole.py +++ b/gui/wxpython/core/gconsole.py @@ -409,13 +409,9 @@ def Redirect(self): except AttributeError: enc = locale.getdefaultlocale()[1] if enc: - if sys.version_info.major == 2: - sys.stdout = codecs.getwriter(enc)(sys.__stdout__) - sys.stderr = codecs.getwriter(enc)(sys.__stderr__) - else: - # https://stackoverflow.com/questions/4374455/how-to-set-sys-stdout-encoding-in-python-3 - sys.stdout = codecs.getwriter(enc)(sys.__stdout__.detach()) - sys.stderr = codecs.getwriter(enc)(sys.__stderr__.detach()) + # https://stackoverflow.com/questions/4374455/how-to-set-sys-stdout-encoding-in-python-3 + sys.stdout = codecs.getwriter(enc)(sys.__stdout__.detach()) + sys.stderr = codecs.getwriter(enc)(sys.__stderr__.detach()) else: sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ diff --git a/gui/wxpython/core/gthread.py b/gui/wxpython/core/gthread.py index bd6bd1a0f3e..7bd8929c553 100644 --- a/gui/wxpython/core/gthread.py +++ b/gui/wxpython/core/gthread.py @@ -22,10 +22,7 @@ import sys -if sys.version_info.major == 2: - import Queue -else: - import queue as Queue +import queue as Queue from core.gconsole import EVT_CMD_DONE, wxCmdDone diff --git a/gui/wxpython/core/menutree.py b/gui/wxpython/core/menutree.py index 4670e793269..7e4abe9d902 100644 --- a/gui/wxpython/core/menutree.py +++ b/gui/wxpython/core/menutree.py @@ -33,16 +33,10 @@ @author Anna Petrasova """ -from __future__ import print_function - import os import sys import copy - -try: - import xml.etree.ElementTree as etree -except ImportError: - import elementtree.ElementTree as etree # Python <= 2.4 +import xml.etree.ElementTree as etree import wx diff --git a/gui/wxpython/core/settings.py b/gui/wxpython/core/settings.py index e4c961607fb..6117a6f7352 100644 --- a/gui/wxpython/core/settings.py +++ b/gui/wxpython/core/settings.py @@ -19,8 +19,6 @@ @author Luca Delucchi (language choice) """ -from __future__ import print_function - import os import sys import copy diff --git a/gui/wxpython/core/toolboxes.py b/gui/wxpython/core/toolboxes.py index 196cb4bfc20..cdf1079eba0 100644 --- a/gui/wxpython/core/toolboxes.py +++ b/gui/wxpython/core/toolboxes.py @@ -12,31 +12,18 @@ @author Anna Petrasova """ -from __future__ import print_function - import os import sys import copy import xml.etree.ElementTree as etree from xml.parsers import expat -# Get the XML parsing exceptions to catch. The behavior chnaged with Python 2.7 -# and ElementTree 1.3. -if hasattr(etree, "ParseError"): - ETREE_EXCEPTIONS = (etree.ParseError, expat.ExpatError) -else: - ETREE_EXCEPTIONS = expat.ExpatError - -if sys.version_info[0:2] > (2, 6): - has_xpath = True -else: - has_xpath = False - import grass.script.task as gtask import grass.script.core as gcore from grass.script.utils import try_remove, decode from grass.exceptions import ScriptError, CalledModuleError +ETREE_EXCEPTIONS = (etree.ParseError, expat.ExpatError) # duplicating code from core/globalvar.py # if this will become part of grass Python library or module, this should be @@ -430,18 +417,7 @@ def _expandToolboxes(node, toolboxes): items = n.find("./items") idx = list(items).index(subtoolbox) - if has_xpath: - toolbox = toolboxes.find( - './/toolbox[@name="%s"]' % subtoolbox.get("name") - ) - else: - toolbox = None - potentialToolboxes = toolboxes.findall(".//toolbox") - sName = subtoolbox.get("name") - for pToolbox in potentialToolboxes: - if pToolbox.get("name") == sName: - toolbox = pToolbox - break + toolbox = toolboxes.find('.//toolbox[@name="%s"]' % subtoolbox.get("name")) if toolbox is None: # not in file continue @@ -576,15 +552,7 @@ def _expandItems(node, items, itemTag): """ for moduleItem in node.findall(".//" + itemTag): itemName = moduleItem.get("name") - if has_xpath: - moduleNode = items.find('.//%s[@name="%s"]' % (itemTag, itemName)) - else: - moduleNode = None - potentialModuleNodes = items.findall(".//%s" % itemTag) - for mNode in potentialModuleNodes: - if mNode.get("name") == itemName: - moduleNode = mNode - break + moduleNode = items.find('.//%s[@name="%s"]' % (itemTag, itemName)) if moduleNode is None: # module not available in dist continue diff --git a/gui/wxpython/core/treemodel.py b/gui/wxpython/core/treemodel.py index 380db91e3a8..cd444330d57 100644 --- a/gui/wxpython/core/treemodel.py +++ b/gui/wxpython/core/treemodel.py @@ -15,7 +15,6 @@ @author Anna Petrasova """ -import six import copy from grass.script.utils import naturally_sort @@ -219,7 +218,7 @@ def children(self): def nprint(self, text, indent=0): text.append(indent * " " + self.label) if self.data: - for key, value in six.iteritems(self.data): + for key, value in self.data.items(): text.append( "%(indent)s* %(key)s : %(value)s" % {"indent": (indent + 2) * " ", "key": key, "value": value} diff --git a/gui/wxpython/core/units.py b/gui/wxpython/core/units.py index a14569126fc..f2640710239 100644 --- a/gui/wxpython/core/units.py +++ b/gui/wxpython/core/units.py @@ -21,7 +21,6 @@ @author Martin Landa """ -import six import math if __name__ == "__main__": @@ -80,7 +79,7 @@ def GetUnitsIndex(self, type, key): :return: index """ - for k, u in six.iteritems(self._units[type]): + for k, u in self._units[type].items(): if u["key"] == key: return k return 0 diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py index 3f9bdd640c8..1aec2ddf032 100644 --- a/gui/wxpython/core/utils.py +++ b/gui/wxpython/core/utils.py @@ -20,7 +20,6 @@ import re import inspect import operator -import six from grass.script import core as grass from grass.script import task as gtask @@ -878,7 +877,7 @@ def StoreEnvVariable(key, value=None, envFile=None): else: expCmd = "export" - for key, value in six.iteritems(environ): + for key, value in environ.items(): fd.write("%s %s=%s\n" % (expCmd, key, value)) # write also skipped lines diff --git a/gui/wxpython/core/workspace.py b/gui/wxpython/core/workspace.py index 38b8555f02f..1612575832d 100644 --- a/gui/wxpython/core/workspace.py +++ b/gui/wxpython/core/workspace.py @@ -17,14 +17,9 @@ """ import os +from io import StringIO import wx -import six - -try: - from StringIO import StringIO -except ImportError: - from io import StringIO from core.utils import normalize_whitespace from core.settings import UserSettings @@ -1101,7 +1096,7 @@ def __writeLayer(self, mapTree, item): # layer properties self.file.write('%s\n' % (" " * self.indent, cmd[0])) self.indent += 4 - for key, val in six.iteritems(cmd[1]): + for key, val in cmd[1].items(): if key == "flags": for f in val: self.file.write( @@ -1130,7 +1125,7 @@ def __writeLayer(self, mapTree, item): self.file.write("%s\n" % (" " * self.indent)) if "geomAttr" in vdigit: self.indent += 4 - for type, val in six.iteritems(vdigit["geomAttr"]): + for type, val in vdigit["geomAttr"].items(): units = "" if val["units"] != "mu": units = ' units="%s"' % val["units"] @@ -1166,13 +1161,13 @@ def __writeNvizSurface(self, data): self.indent += 4 self.file.write("%s\n" % (" " * self.indent)) self.indent += 4 - for attrb in six.iterkeys(data): + for attrb in data.keys(): if len(data[attrb]) < 1: # skip empty attributes continue if attrb == "object": continue - for name in six.iterkeys(data[attrb]): + for name in data[attrb].keys(): # surface attribute if attrb == "attribute": if data[attrb][name]["map"] is None: @@ -1194,7 +1189,7 @@ def __writeNvizSurface(self, data): if attrb == "draw": self.file.write("%s<%s" % (" " * self.indent, attrb)) if "mode" in data[attrb]: - for tag, value in six.iteritems(data[attrb]["mode"]["desc"]): + for tag, value in data[attrb]["mode"]["desc"].items(): self.file.write(' %s="%s"' % (tag, value)) self.file.write(">\n") # @@ -1252,14 +1247,14 @@ def __writeNvizVolume(self, data): self.indent += 4 self.file.write("%s\n" % (" " * self.indent)) self.indent += 4 - for attrb in six.iterkeys(data): + for attrb in data.keys(): if len(data[attrb]) < 1: # skip empty attributes continue if attrb == "object": continue if attrb == "attribute": - for name in six.iterkeys(data[attrb]): + for name in data[attrb].keys(): # surface attribute if data[attrb][name]["map"] is None: continue @@ -1343,10 +1338,10 @@ def __writeNvizVolume(self, data): if attrb == "isosurface": for isosurface in data[attrb]: self.file.write("%s<%s>\n" % (" " * self.indent, attrb)) - for name in six.iterkeys(isosurface): + for name in isosurface.keys(): self.indent += 4 self.file.write("%s<%s>\n" % (" " * self.indent, name)) - for att in six.iterkeys(isosurface[name]): + for att in isosurface[name].keys(): if isosurface[name][att] is True: val = "1" elif isosurface[name][att] is False: @@ -1370,10 +1365,10 @@ def __writeNvizVolume(self, data): if attrb == "slice": for slice_ in data[attrb]: self.file.write("%s<%s>\n" % (" " * self.indent, attrb)) - for name in six.iterkeys(slice_): + for name in slice_.keys(): self.indent += 4 self.file.write("%s<%s>\n" % (" " * self.indent, name)) - for att in six.iterkeys(slice_[name]): + for att in slice_[name].keys(): if att in ("map", "update"): continue val = slice_[name][att] @@ -1401,7 +1396,7 @@ def __writeNvizVector(self, data): :param data: Nviz layer properties """ self.indent += 4 - for attrb in six.iterkeys(data): + for attrb in data.keys(): if len(data[attrb]) < 1: # skip empty attributes continue @@ -1421,7 +1416,7 @@ def __writeNvizVector(self, data): '%s\n' % (" " * self.indent, attrb, marker) ) self.indent += 4 - for name in six.iterkeys(data[attrb]): + for name in data[attrb].keys(): if name in ("object", "marker"): continue if name == "mode": @@ -1450,14 +1445,14 @@ def __writeNvizVector(self, data): self.file.write("%s\n" % ((" " * self.indent, name))) elif name == "thematic": self.file.write("%s<%s " % (" " * self.indent, name)) - for key in six.iterkeys(data[attrb][name]): + for key in data[attrb][name].keys(): if key.startswith("use"): self.file.write( '%s="%s" ' % (key, int(data[attrb][name][key])) ) self.file.write(">\n") self.indent += 4 - for key, value in six.iteritems(data[attrb][name]): + for key, value in data[attrb][name].items(): if key.startswith("use"): continue if value is None: diff --git a/gui/wxpython/dbmgr/base.py b/gui/wxpython/dbmgr/base.py index 2528ccb2f5a..0016d5f4cb1 100644 --- a/gui/wxpython/dbmgr/base.py +++ b/gui/wxpython/dbmgr/base.py @@ -29,7 +29,6 @@ @author Refactoring by Stepan Turek (GSoC 2012, mentor: Martin Landa) """ -import sys import os import locale import tempfile @@ -76,9 +75,6 @@ ) from core.utils import cmp -if sys.version_info.major >= 3: - unicode = str - class Log: """The log output SQL is redirected to the status bar of the @@ -689,7 +685,7 @@ def Sorter(self, key1, key2): item1 = self.itemDataMap[key1][self._col] item2 = self.itemDataMap[key2][self._col] - if isinstance(item1, str) or isinstance(item2, unicode): + if isinstance(item1, str) or isinstance(item2, str): cmpVal = locale.strcoll(GetUnicodeValue(item1), GetUnicodeValue(item2)) else: cmpVal = cmp(item1, item2) diff --git a/gui/wxpython/dbmgr/dialogs.py b/gui/wxpython/dbmgr/dialogs.py index d8d2da3ad66..5778c8a0fcd 100644 --- a/gui/wxpython/dbmgr/dialogs.py +++ b/gui/wxpython/dbmgr/dialogs.py @@ -17,8 +17,6 @@ @author Refactoring by Stepan Turek (GSoC 2012, mentor: Martin Landa) """ -import six - import wx import wx.lib.scrolledpanel as scrolled @@ -537,7 +535,7 @@ def UpdateDialog(self, map=None, query=None, cats=None, fid=-1, action=None): ctype = columns[name]["ctype"] if columns[name]["values"][idx] is not None: - if not isinstance(columns[name]["ctype"], six.string_types): + if not isinstance(columns[name]["ctype"], str): value = str(columns[name]["values"][idx]) else: value = columns[name]["values"][idx] @@ -598,7 +596,7 @@ def SetColumnValue(self, layer, column, value): table = self.mapDBInfo.GetTable(layer) columns = self.mapDBInfo.GetTableDesc(table) - for key, col in six.iteritems(columns): + for key, col in columns.items(): if key == column: col["values"] = [ col["ctype"](value), diff --git a/gui/wxpython/dbmgr/sqlbuilder.py b/gui/wxpython/dbmgr/sqlbuilder.py index d475031de2b..7aef2f3c311 100644 --- a/gui/wxpython/dbmgr/sqlbuilder.py +++ b/gui/wxpython/dbmgr/sqlbuilder.py @@ -24,11 +24,8 @@ @author Refactoring, SQLBUilderUpdate by Stepan Turek (GSoC 2012, mentor: Martin Landa) """ -from __future__ import print_function - import os import sys -import six from core import globalvar import wx @@ -186,7 +183,7 @@ def _doLayout(self, modeChoices, showDbInfo=False): } self.btn_logicpanel = wx.Panel(parent=self.panel, id=wx.ID_ANY) - for key, value in six.iteritems(self.btn_logic): + for key, value in self.btn_logic.items(): btn = Button(parent=self.btn_logicpanel, id=wx.ID_ANY, label=value[0]) self.btn_logic[key].append(btn.GetId()) @@ -344,7 +341,7 @@ def _doLayout(self, modeChoices, showDbInfo=False): self.btn_unique.Bind(wx.EVT_BUTTON, self.OnUniqueValues) self.btn_uniquesample.Bind(wx.EVT_BUTTON, self.OnSampleValues) - for key, value in six.iteritems(self.btn_logic): + for key, value in self.btn_logic.items(): self.FindWindowById(value[1]).Bind(wx.EVT_BUTTON, self.OnAddMark) self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose) @@ -455,7 +452,7 @@ def OnAddMark(self, event): elif self.btn_arithmeticpanel and self.btn_arithmeticpanel.IsShown(): btns = self.btn_arithmetic - for key, value in six.iteritems(btns): + for key, value in btns.items(): if event.GetId() == value[1]: mark = value[0] break @@ -695,7 +692,7 @@ def _doLayout(self, modeChoices): self.btn_arithmeticpanel = wx.Panel(parent=self.panel, id=wx.ID_ANY) - for key, value in six.iteritems(self.btn_arithmetic): + for key, value in self.btn_arithmetic.items(): btn = Button(parent=self.btn_arithmeticpanel, id=wx.ID_ANY, label=value[0]) self.btn_arithmetic[key].append(btn.GetId()) @@ -748,7 +745,7 @@ def _doLayout(self, modeChoices): self.hsizer.Insert(2, self.funcpanel, proportion=1, flag=wx.EXPAND) self.list_func.Bind(wx.EVT_LISTBOX, self.OnAddFunc) - for key, value in six.iteritems(self.btn_arithmetic): + for key, value in self.btn_arithmetic.items(): self.FindWindowById(value[1]).Bind(wx.EVT_BUTTON, self.OnAddMark) self.mode.SetSelection(0) self.OnMode(None) diff --git a/gui/wxpython/dbmgr/vinfo.py b/gui/wxpython/dbmgr/vinfo.py index 61b7350dae1..c6a4850e7e1 100644 --- a/gui/wxpython/dbmgr/vinfo.py +++ b/gui/wxpython/dbmgr/vinfo.py @@ -15,8 +15,6 @@ """ import os -import sys -import six import wx @@ -26,37 +24,21 @@ from core.settings import UserSettings import grass.script as grass -if sys.version_info.major >= 3: - unicode = str - def GetUnicodeValue(value): - """Get unicode value +def GetUnicodeValue(value): + """Get unicode value - :param value: value to be recoded + :param value: value to be recoded - :return: unicode value - """ - if isinstance(value, unicode): - return value - if isinstance(value, bytes): - enc = GetDbEncoding() - return str(value, enc, errors="replace") - else: - return str(value) - -else: - - def GetUnicodeValue(value): - """Get unicode value - - :param value: value to be recoded - - :return: unicode value - """ - if isinstance(value, unicode): - return value + :return: unicode value + """ + if isinstance(value, str): + return value + if isinstance(value, bytes): enc = GetDbEncoding() - return unicode(str(value), enc, errors="replace") + return str(value, enc, errors="replace") + else: + return str(value) def GetDbEncoding(): @@ -111,7 +93,7 @@ def GetColumns(self, table): except KeyError: return [] - for name, desc in six.iteritems(self.tables[table]): + for name, desc in self.tables[table].items(): names[desc["index"]] = name return names @@ -151,7 +133,7 @@ def SelectByPoint(self, queryCoords, qdist): continue table = record["Table"] - for key, value in six.iteritems(record["Attributes"]): + for key, value in record["Attributes"].items(): if len(value) < 1: value = None else: @@ -161,7 +143,7 @@ def SelectByPoint(self, queryCoords, qdist): value = GetUnicodeValue(value) self.tables[table][key]["values"].append(value) - for key, value in six.iteritems(record): + for key, value in record.items(): if key == "Attributes": continue if key in ret: diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py index 2cd202f15bb..2fa18cc0eff 100644 --- a/gui/wxpython/gcp/manager.py +++ b/gui/wxpython/gcp/manager.py @@ -27,12 +27,9 @@ @author Support for GraphicsSet added by Stepan Turek (2012) """ -from __future__ import print_function - import os import sys import shutil -import six from copy import copy import wx @@ -1412,7 +1409,7 @@ def SetSettings(self): } wpx = UserSettings.Get(group="gcpman", key="symbol", subkey="width") - for k, v in six.iteritems(colours): + for k, v in colours.items(): col = UserSettings.Get(group="gcpman", key="symbol", subkey=k) self.pointsToDrawSrc.GetPen(v).SetColour( wx.Colour(col[0], col[1], col[2], 255) diff --git a/gui/wxpython/gmodeler/dialogs.py b/gui/wxpython/gmodeler/dialogs.py index a7b230ddbc7..8879bb8224e 100644 --- a/gui/wxpython/gmodeler/dialogs.py +++ b/gui/wxpython/gmodeler/dialogs.py @@ -24,7 +24,6 @@ """ import os -import six import wx import wx.lib.mixins.listctrl as listmix @@ -806,7 +805,7 @@ def Populate(self, data): """Populate the list""" self.itemDataMap = dict() i = 0 - for name, values in six.iteritems(data): + for name, values in data.items(): self.itemDataMap[i] = [ name, values["type"], @@ -818,7 +817,7 @@ def Populate(self, data): self.itemCount = len(self.itemDataMap.keys()) self.DeleteAllItems() i = 0 - for name, vtype, value, desc in six.itervalues(self.itemDataMap): + for name, vtype, value, desc in self.itemDataMap.values(): index = self.InsertItem(i, name) self.SetItem(index, 0, name) self.SetItem(index, 1, vtype) @@ -833,7 +832,7 @@ def Append(self, name, vtype, value, desc): :return: None on success :return: error string """ - for iname, ivtype, ivalue, idesc in six.itervalues(self.itemDataMap): + for iname, ivtype, ivalue, idesc in self.itemDataMap.values(): if iname == name: return ( _( @@ -1004,7 +1003,7 @@ def Populate(self, data): self.DeleteAllItems() i = 0 if len(self.columns) == 2: - for name, desc in six.itervalues(self.itemDataMap): + for name, desc in self.itemDataMap.values(): index = self.InsertItem(i, str(i)) self.SetItem(index, 0, name) self.SetItem(index, 1, desc) @@ -1013,7 +1012,7 @@ def Populate(self, data): self.CheckItem(index, True) i += 1 else: - for name, inloop, param, desc in six.itervalues(self.itemDataMap): + for name, inloop, param, desc in self.itemDataMap.values(): index = self.InsertItem(i, str(i)) self.SetItem(index, 0, name) self.SetItem(index, 1, inloop) diff --git a/gui/wxpython/gmodeler/frame.py b/gui/wxpython/gmodeler/frame.py index 8ce9a716e82..ce0bd1a82b9 100644 --- a/gui/wxpython/gmodeler/frame.py +++ b/gui/wxpython/gmodeler/frame.py @@ -26,7 +26,6 @@ import stat import tempfile import random -import six import wx from wx.lib import ogl @@ -406,7 +405,7 @@ def OnModelProperties(self, event): dlg.Init(properties) if dlg.ShowModal() == wx.ID_OK: self.ModelChanged() - for key, value in six.iteritems(dlg.GetValues()): + for key, value in dlg.GetValues().items(): properties[key] = value for action in self.model.GetItems(objType=ModelAction): action.GetTask().set_flag("overwrite", properties["overwrite"]) @@ -1887,7 +1886,7 @@ def OnAdd(self, event): def UpdateModelVariables(self): """Update model variables""" variables = dict() - for values in six.itervalues(self.list.GetData()): + for values in self.list.GetData().values(): name = values[0] variables[name] = {"type": str(values[1])} if values[2]: diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 05f0f4ecbfc..7c43b9a66e7 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -34,12 +34,8 @@ import re import mimetypes import time -import six -try: - import xml.etree.ElementTree as etree -except ImportError: - import elementtree.ElementTree as etree # Python <= 2.4 +import xml.etree.ElementTree as etree import xml.sax.saxutils as saxutils @@ -131,7 +127,7 @@ def GetNumItems(self, actionOnly=False): def ReorderItems(self, idxList): items = list() - for oldIdx, newIdx in six.iteritems(idxList): + for oldIdx, newIdx in idxList.items(): item = self.items.pop(oldIdx) items.append(item) self.items.insert(newIdx, item) @@ -678,7 +674,7 @@ def Run(self, log, onDone, parent=None): return err = list() - for key, item in six.iteritems(params): + for key, item in params.items(): for p in item["params"]: if p.get("value", "") == "": err.append((key, p.get("name", ""), p.get("description", ""))) @@ -762,7 +758,7 @@ def Run(self, log, onDone, parent=None): # discard values if params: - for item in six.itervalues(params): + for item in params.values(): for p in item["params"]: p["value"] = "" @@ -828,7 +824,7 @@ def Parameterize(self): if self.variables: params = list() result["variables"] = {"flags": list(), "params": params, "idx": idx} - for name, values in six.iteritems(self.variables): + for name, values in self.variables.items(): gtype = values.get("type", "string") if gtype in ("raster", "vector", "mapset", "file", "region", "dir"): gisprompt = True @@ -2318,7 +2314,7 @@ def _variables(self): return self.fd.write("%s\n" % (" " * self.indent)) self.indent += 4 - for name, values in six.iteritems(self.variables): + for name, values in self.variables.items(): self.fd.write( '%s\n' % (" " * self.indent, name, values["type"]) @@ -2374,7 +2370,7 @@ def _action(self, action): self.indent += 4 if not action.IsEnabled(): self.fd.write("%s\n" % (" " * self.indent)) - for key, val in six.iteritems(action.GetParams()): + for key, val in action.GetParams().items(): if key == "flags": for f in val: if f.get("value", False) or f.get("parameterized", False): @@ -3431,7 +3427,7 @@ def _layout(self): def _createPages(self): """Create for each parameterized module its own page""" nameOrdered = [""] * len(self.params.keys()) - for name, params in six.iteritems(self.params): + for name, params in self.params.items(): nameOrdered[params["idx"]] = name for name in nameOrdered: params = self.params[name] diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py index 84188d6e26c..88d31c2b4ab 100644 --- a/gui/wxpython/gui_core/dialogs.py +++ b/gui/wxpython/gui_core/dialogs.py @@ -30,7 +30,6 @@ import os import re -import six import wx @@ -1121,7 +1120,7 @@ def GetLayers(self): """Get layers""" if self.edit_subg: layers = [] - for maps, sel in six.iteritems(self.subgmaps): + for maps, sel in self.subgmaps.items(): if sel: layers.append(maps) else: @@ -1166,7 +1165,7 @@ def FilterSubgroup(self): self.subgListBox.Set(maps) for i, m in enumerate(maps): - if m in six.iterkeys(self.subgmaps) and self.subgmaps[m]: + if m in self.subgmaps.keys() and self.subgmaps[m]: self.subgListBox.Check(i) self._checkSubGSellAll() diff --git a/gui/wxpython/gui_core/forms.py b/gui/wxpython/gui_core/forms.py index 86b8143bcd9..b8ddbf163aa 100644 --- a/gui/wxpython/gui_core/forms.py +++ b/gui/wxpython/gui_core/forms.py @@ -46,21 +46,12 @@ @author Stepan Turek (CoordinatesSelect) """ -from __future__ import print_function - import sys import textwrap import os import copy import locale -import six - -if sys.version_info.major == 2: - import Queue -else: - import queue as Queue - - unicode = str +import queue as Queue import codecs @@ -72,10 +63,7 @@ import wx.lib.filebrowsebutton as filebrowse from wx.lib.newevent import NewEvent -try: - import xml.etree.ElementTree as etree -except ImportError: - import elementtree.ElementTree as etree # Python <= 2.4 +import xml.etree.ElementTree as etree # needed when started from command line and for testing if __name__ == "__main__": @@ -1195,7 +1183,7 @@ def __init__(self, parent, giface, task, id=wx.ID_ANY, frame=None, *args, **kwar if len(p.get("values", [])) > 0: valuelist = list(map(str, p.get("values", []))) - valuelist_desc = list(map(unicode, p.get("values_desc", []))) + valuelist_desc = list(map(str, p.get("values_desc", []))) required_text = "*" if p.get("required", False) else "" if ( p.get("multiple", False) @@ -2715,7 +2703,7 @@ def OnVectorFormat(self, event): self.OnUpdateSelection(event) def OnUpdateDialog(self, event): - for fn, kwargs in six.iteritems(event.data): + for fn, kwargs in event.data.items(): fn(**kwargs) self.parent.updateValuesHook() diff --git a/gui/wxpython/gui_core/ghelp.py b/gui/wxpython/gui_core/ghelp.py index 76f85fb433f..230bf6959de 100644 --- a/gui/wxpython/gui_core/ghelp.py +++ b/gui/wxpython/gui_core/ghelp.py @@ -23,7 +23,6 @@ import re import textwrap import sys -import six import wx from wx.html import HtmlWindow @@ -622,7 +621,7 @@ def _langPanel(self, lang, js): # else: # panel.Collapse(True) pageSizer = wx.BoxSizer(wx.VERTICAL) - for k, v in six.iteritems(js): + for k, v in js.items(): if k != "total" and k != "name": box = self._langBox(win, k, v) pageSizer.Add(box, proportion=1, flag=wx.EXPAND | wx.ALL, border=3) diff --git a/gui/wxpython/gui_core/gselect.py b/gui/wxpython/gui_core/gselect.py index fe5cc2c756b..10670395c55 100644 --- a/gui/wxpython/gui_core/gselect.py +++ b/gui/wxpython/gui_core/gselect.py @@ -41,12 +41,9 @@ @author Matej Krejci (VectorCategorySelect) """ -from __future__ import print_function - import os import sys import glob -import six import ctypes import wx @@ -538,7 +535,7 @@ def _getElementList(self, element, mapsets=None, elements=None, exclude=False): # add extra items first if self.extraItems: - for group, items in six.iteritems(self.extraItems): + for group, items in self.extraItems.items(): node = self.AddItem(group, node=True) self.seltree.SetItemTextColour(node, wx.Colour(50, 50, 200)) for item in items: @@ -1167,16 +1164,16 @@ def InsertColumns( columnchoices = dbInfo.GetTableDesc(table) keyColumn = dbInfo.GetKeyColumn(layer) self.columns = len(columnchoices.keys()) * [""] - for key, val in six.iteritems(columnchoices): + for key, val in columnchoices.items(): self.columns[val["index"]] = key if excludeKey: # exclude key column self.columns.remove(keyColumn) if excludeCols: # exclude key column - for key in six.iterkeys(columnchoices): + for key in columnchoices.keys(): if key in excludeCols: self.columns.remove(key) if type: # only selected column types - for key, value in six.iteritems(columnchoices): + for key, value in columnchoices.item(): if value["type"] not in type: try: self.columns.remove(key) @@ -1728,7 +1725,7 @@ def _postInit(self, sourceType, data): dsn = v break optList = list() - for k, v in six.iteritems(data): + for k, v in data.items(): if k in ("format", "conninfo", "topology"): continue optList.append("%s=%s" % (k, v)) diff --git a/gui/wxpython/gui_core/mapdisp.py b/gui/wxpython/gui_core/mapdisp.py index fb4f1d7e6cf..c890be3b598 100644 --- a/gui/wxpython/gui_core/mapdisp.py +++ b/gui/wxpython/gui_core/mapdisp.py @@ -21,7 +21,6 @@ """ import sys -import six import wx @@ -387,7 +386,7 @@ def StatusbarReposition(self): def StatusbarEnableLongHelp(self, enable=True): """Enable/disable toolbars long help""" - for toolbar in six.itervalues(self.toolbars): + for toolbar in self.toolbars.values(): if toolbar: toolbar.EnableLongHelp(enable) diff --git a/gui/wxpython/gui_core/pyedit.py b/gui/wxpython/gui_core/pyedit.py index 6bec11ee9b9..024f131ce6a 100644 --- a/gui/wxpython/gui_core/pyedit.py +++ b/gui/wxpython/gui_core/pyedit.py @@ -14,10 +14,7 @@ import os import stat -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO import time import wx diff --git a/gui/wxpython/gui_core/query.py b/gui/wxpython/gui_core/query.py index ec9145dc483..638a64fa948 100644 --- a/gui/wxpython/gui_core/query.py +++ b/gui/wxpython/gui_core/query.py @@ -14,7 +14,6 @@ @author Anna Kratochvilova """ import wx -import six from gui_core.treeview import TreeListView from gui_core.wrap import Button, StaticText, Menu, NewId @@ -203,12 +202,12 @@ def QueryTreeBuilder(data, column): """ def addNode(parent, data, model): - for k, v in six.iteritems(data): + for k, v in data.items(): if isinstance(v, dict): node = model.AppendNode(parent=parent, data={"label": k}) addNode(parent=node, data=v, model=model) else: - if not isinstance(v, six.string_types): + if not isinstance(v, str): v = str(v) node = model.AppendNode(parent=parent, data={"label": k, column: v}) diff --git a/gui/wxpython/gui_core/treeview.py b/gui/wxpython/gui_core/treeview.py index 4319fa44808..cbb6e4b4dcc 100644 --- a/gui/wxpython/gui_core/treeview.py +++ b/gui/wxpython/gui_core/treeview.py @@ -14,8 +14,6 @@ @author Anna Petrasova """ -from __future__ import print_function - import wx from wx.lib.mixins.treemixin import VirtualTree, ExpansionState from core.globalvar import hasAgw, wxPythonPhoenix diff --git a/gui/wxpython/gui_core/widgets.py b/gui/wxpython/gui_core/widgets.py index be5bd28e5f0..1b9ce6451c1 100644 --- a/gui/wxpython/gui_core/widgets.py +++ b/gui/wxpython/gui_core/widgets.py @@ -53,7 +53,6 @@ import sys import string import re -import six from bisect import bisect from datetime import datetime from core.globalvar import wxPythonPhoenix @@ -1506,7 +1505,7 @@ def _writeSettings(self): try: fd = open(self.settingsFile, "w") fd.write("format_version=2.0\n") - for key, values in six.iteritems(self._settings): + for key, values in self._settings.items(): first = True for v in values: # escaping characters diff --git a/gui/wxpython/iclass/frame.py b/gui/wxpython/iclass/frame.py index 756cc032102..2dd76d2bf25 100644 --- a/gui/wxpython/iclass/frame.py +++ b/gui/wxpython/iclass/frame.py @@ -19,7 +19,6 @@ """ import os -import six import copy import tempfile @@ -1597,7 +1596,7 @@ def _changeOpacity(self, layer, opacity): def GetAlias(self, name): """Returns alias for layer""" - name = [k for k, v in six.iteritems(self.layerName) if v == name] + name = [k for k, v in self.layerName.items() if v == name] if name: return name[0] return None diff --git a/gui/wxpython/iclass/statistics.py b/gui/wxpython/iclass/statistics.py index 9ffa5eeb044..c083912988c 100644 --- a/gui/wxpython/iclass/statistics.py +++ b/gui/wxpython/iclass/statistics.py @@ -18,7 +18,6 @@ """ import os -import six from ctypes import * import grass.script as grass @@ -173,7 +172,7 @@ def SetBandStatistics(self, cStatistics): self.bands.append(band) def SetStatistics(self, stats): - for st, val in six.iteritems(stats): + for st, val in stats.items(): setattr(self, st, val) self.statisticsSet.emit(stats=stats) diff --git a/gui/wxpython/iclass/toolbars.py b/gui/wxpython/iclass/toolbars.py index 88ee299feee..6ba1db44ae5 100644 --- a/gui/wxpython/iclass/toolbars.py +++ b/gui/wxpython/iclass/toolbars.py @@ -18,8 +18,6 @@ @author Anna Kratochvilova """ -from __future__ import print_function - import wx from gui_core.toolbars import BaseToolbar, BaseIcons diff --git a/gui/wxpython/icons/icon.py b/gui/wxpython/icons/icon.py index ce3b48bd60e..c87e5af5e24 100644 --- a/gui/wxpython/icons/icon.py +++ b/gui/wxpython/icons/icon.py @@ -18,7 +18,6 @@ import os import sys import copy -import six import wx @@ -45,11 +44,8 @@ if iconPath and not os.path.exists(iconPath): raise OSError - for key, img in six.iteritems(iconSet): - if key not in iconSet or iconSet[key] is None: # add key - iconSet[key] = img - - iconSet[key] = os.path.join(iconPath, iconSet[key]) + for key, img in iconSet.items(): + iconSet[key] = os.path.join(iconPath, img) except Exception as e: sys.exit(_("Unable to load icon theme. Reason: %s. Quitting wxGUI...") % e) diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py index c7cdd37f783..d71d131886a 100644 --- a/gui/wxpython/image2target/ii2t_manager.py +++ b/gui/wxpython/image2target/ii2t_manager.py @@ -32,11 +32,9 @@ # TODO: i.ortho.transform looks for REF_POINTS/CONTROL_POINTS and not POINTS # TODO: CHECK CONTROL_POINTS format and create it for i.ortho.transform to use. -from __future__ import print_function import os import sys -import six import shutil from copy import copy @@ -109,7 +107,7 @@ def getSmallDnArrowImage(): return img -class GCPWizard(object): +class GCPWizard: """ Start wizard here and finish wizard here """ @@ -1384,7 +1382,7 @@ def SetSettings(self): } wpx = UserSettings.Get(group="gcpman", key="symbol", subkey="width") - for k, v in six.iteritems(colours): + for k, v in colours.items(): col = UserSettings.Get(group="gcpman", key="symbol", subkey=k) self.pointsToDrawSrc.GetPen(v).SetColour( wx.Colour(col[0], col[1], col[2], 255) diff --git a/gui/wxpython/iscatt/controllers.py b/gui/wxpython/iscatt/controllers.py index 8d04fd75fec..d3602d9124f 100644 --- a/gui/wxpython/iscatt/controllers.py +++ b/gui/wxpython/iscatt/controllers.py @@ -21,7 +21,6 @@ """ from copy import deepcopy import wx -import six from core.gcmd import GError, GMessage, RunCommand, GWarning @@ -409,7 +408,7 @@ def PlotClosed(self, scatt_id): def SetPlotsMode(self, mode): self.plot_mode = mode - for scatt in six.itervalues(self.plots): + for scatt in self.plots.values(): if scatt["scatt"]: scatt["scatt"].SetMode(mode) @@ -417,7 +416,7 @@ def SetPlotsMode(self, mode): def ActivateSelectionPolygonMode(self, activate): self.pol_sel_mode[0] = activate - for scatt in six.itervalues(self.plots): + for scatt in self.plots.values(): if not scatt["scatt"]: continue scatt["scatt"].SetSelectionPolygonMode(activate) @@ -429,7 +428,7 @@ def ActivateSelectionPolygonMode(self, activate): def ProcessSelectionPolygons(self, process_mode): scatts_polygons = {} - for scatt_id, scatt in six.iteritems(self.plots): + for scatt_id, scatt in self.plots.items(): if not scatt["scatt"]: continue coords = scatt["scatt"].GetCoords() @@ -463,7 +462,7 @@ def ProcessSelectionPolygons(self, process_mode): if not sel_cat_id: return - for scatt in six.itervalues(self.plots): + for scatt in self.plots.values(): if scatt["scatt"]: scatt["scatt"].SetEmpty() @@ -592,7 +591,7 @@ def _renderscattplts(self, scatt_ids, cats, cats_attrs): else: ellipses_dt = {} - for c in six.iterkeys(scatt_dt): + for c in scatt_dt.keys(): try: self.cat_ids.remove(c) scatt_dt[c]["render"] = True @@ -739,7 +738,7 @@ def SetCategoryAttrs(self, cat_id, attrs_dict): render = False update_cat_rast = [] - for k, v in six.iteritems(attrs_dict): + for k, v in attrs_dict.items(): if not render and k in ["color", "opacity", "show", "nstd"]: render = True if k in ["color", "name"]: @@ -1014,7 +1013,7 @@ def UpdateCategoryRaster(self, cat_id, attrs, render=True): cats_attrs["name"] def RenderCatRast(self, cat_id): - if cat_id not in six.iterkeys(self.added_cats_rasts): + if cat_id not in self.added_cats_rasts.keys(): cat_rast = self.scatt_mgr.core.GetCatRast(cat_id) cat_name = self.cats_mgr.GetCategoryAttrs(cat_id)["name"] diff --git a/gui/wxpython/iscatt/core_c.py b/gui/wxpython/iscatt/core_c.py index 45e028c65f0..96fcb90cb5c 100644 --- a/gui/wxpython/iscatt/core_c.py +++ b/gui/wxpython/iscatt/core_c.py @@ -12,7 +12,6 @@ """ import sys -import six import numpy as np from multiprocessing import Process, Queue @@ -107,13 +106,13 @@ def ComputeScatts( def _memmapToFileNames(data): - for k, v in six.iteritems(data): + for k, v in data.items(): if "np_vals" in v: data[k]["np_vals"] = v["np_vals"].filename() def _fileNamesToMemmap(data): - for k, v in six.iteritems(data): + for k, v in data.items(): if "np_vals" in v: data[k]["np_vals"] = np.memmap(filename=v["np_vals"]) @@ -195,7 +194,7 @@ def _regionToCellHead(region): "ewres": "ew_res", } - for k, v in six.iteritems(region): + for k, v in region.items(): if k in ["rows", "cols", "cells", "zone"]: # zone added in r65224 v = int(v) else: @@ -228,11 +227,11 @@ def _getComputationStruct(cats, cats_rasts, cats_type, n_bands): refs = [] cats_rasts_core = [] - for cat_id, scatt_ids in six.iteritems(cats): + for cat_id, scatt_ids in cats.items(): cat_c_id = I_sc_add_cat(pointer(sccats)) cats_rasts_core.append(cats_rasts[cat_id]) - for scatt_id, dt in six.iteritems(scatt_ids): + for scatt_id, dt in scatt_ids.items(): # if key is missing condition is always True (full scatter plor is # computed) vals = dt["np_vals"] diff --git a/gui/wxpython/iscatt/dialogs.py b/gui/wxpython/iscatt/dialogs.py index c64b5dad4ab..20787867f04 100644 --- a/gui/wxpython/iscatt/dialogs.py +++ b/gui/wxpython/iscatt/dialogs.py @@ -18,8 +18,6 @@ @author Stepan Turek (mentor: Martin Landa) """ -import six - import wx from gui_core.gselect import Select import wx.lib.colourselect as csel @@ -378,7 +376,7 @@ def __init__( "sel_area": ["selection", _("Selected area color:")], } - for settKey, sett in six.iteritems(self.colorsSetts): + for settKey, sett in self.colorsSetts.items(): settsLabels[settKey] = StaticText(parent=self, id=wx.ID_ANY, label=sett[1]) col = UserSettings.Get(group="scatt", key=sett[0], subkey=settKey) self.settings[settKey] = csel.ColourSelect( @@ -390,7 +388,7 @@ def __init__( "sel_area_opacty": ["selection", _("Selected area opacity:")], } - for settKey, sett in six.iteritems(self.sizeSetts): + for settKey, sett in self.sizeSetts.items(): settsLabels[settKey] = StaticText(parent=self, id=wx.ID_ANY, label=sett[1]) self.settings[settKey] = SpinCtrl(parent=self, id=wx.ID_ANY, min=0, max=100) size = int(UserSettings.Get(group="scatt", key=sett[0], subkey=settKey)) @@ -497,14 +495,14 @@ def OnSave(self, event): def UpdateSettings(self): chanaged_setts = [] - for settKey, sett in six.iteritems(self.colorsSetts): + for settKey, sett in self.colorsSetts.items(): col = tuple(self.settings[settKey].GetColour()) col_s = UserSettings.Get(group="scatt", key=sett[0], subkey=settKey) if col_s != col: UserSettings.Set(group="scatt", key=sett[0], subkey=settKey, value=col) chanaged_setts.append([settKey, sett[0]]) - for settKey, sett in six.iteritems(self.sizeSetts): + for settKey, sett in self.sizeSetts.items(): val = self.settings[settKey].GetValue() val_s = UserSettings.Get(group="scatt", key=sett[0], subkey=settKey) diff --git a/gui/wxpython/iscatt/frame.py b/gui/wxpython/iscatt/frame.py index 0a4ce90f5a3..44d555aa18c 100644 --- a/gui/wxpython/iscatt/frame.py +++ b/gui/wxpython/iscatt/frame.py @@ -18,10 +18,8 @@ @author Stepan Turek (mentor: Martin Landa) """ -from __future__ import print_function import os -import six import wx import wx.lib.scrolledpanel as scrolled @@ -244,7 +242,7 @@ def __init__(self, parent, scatt_mgr, id=wx.ID_ANY): self.scatt_mgr.cursorPlotMove.connect(self.CursorPlotMove) def SetBusy(self, busy): - for scatt in six.itervalues(self.scatts): + for scatt in self.scatts.values(): scatt.UpdateCur(busy) def CursorPlotMove(self, x, y, scatt_id): diff --git a/gui/wxpython/iscatt/iscatt_core.py b/gui/wxpython/iscatt/iscatt_core.py index b1820875116..e0fe7bad182 100644 --- a/gui/wxpython/iscatt/iscatt_core.py +++ b/gui/wxpython/iscatt/iscatt_core.py @@ -18,7 +18,6 @@ @author Stepan Turek (mentor: Martin Landa) """ import os -import six import numpy as np @@ -104,7 +103,7 @@ def SetEditCatData(self, cat_id, scatt_id, bbox, value): arr = self.scatt_conds_dt.GetValuesArr(cat_id, scatt_id) - for k, v in six.iteritems(bbox): + for k, v in bbox.items(): bbox[k] = self._validExtend(v) arr[bbox["btm_y"] : bbox["up_y"], bbox["btm_x"] : bbox["up_x"]] = value @@ -148,7 +147,7 @@ def UpdateCategoryWithPolygons(self, cat_id, scatts_pols, value): if cat_id not in self.scatts_dt.GetCategories(): raise GException(_("Select category for editing.")) - for scatt_id, coords in six.iteritems(scatts_pols): + for scatt_id, coords in scatts_pols.items(): if self.scatt_conds_dt.AddScattPlot(cat_id, scatt_id) < 0: return False @@ -445,7 +444,7 @@ def DeleteCategory(self, cat_id): if cat_id not in self.cats.keys(): return False - for scatt in six.itervalues(self.cats[cat_id]): + for scatt in self.cats[cat_id].values(): grass.try_remove(scatt["np_vals"]) del scatt["np_vals"] @@ -513,7 +512,7 @@ def GetValuesArr(self, cat_id, scatt_id): def GetData(self, requested_dt): cats = {} - for cat_id, scatt_ids in six.iteritems(requested_dt): + for cat_id, scatt_ids in requested_dt.items(): if cat_id not in cats: cats[cat_id] = {} for scatt_id in scatt_ids: @@ -528,7 +527,7 @@ def GetData(self, requested_dt): return cats def SetData(self, cats): - for cat_id, scatt_ids in six.iteritems(cats): + for cat_id, scatt_ids in cats.items(): for scatt_id in scatt_ids: # if key is missing condition is always True (full scatter plor # is computed) @@ -539,7 +538,7 @@ def SetData(self, cats): def GetScatt(self, scatt_id, cats_ids=None): scatts = {} - for cat_id in six.iterkeys(self.cats): + for cat_id in self.cats.keys(): if cats_ids and cat_id not in cats_ids: continue if scatt_id not in self.cats[cat_id]: @@ -603,7 +602,7 @@ def AddScattPlot(self, scatt_id): return False self.scatts_ids.append(scatt_id) - for cat_id in six.iterkeys(self.cats): + for cat_id in self.cats.keys(): ScattPlotsCondsData.AddScattPlot(self, cat_id, scatt_id) self.cats[cat_id][scatt_id]["ellipse"] = None @@ -615,7 +614,7 @@ def DeleteScatterPlot(self, scatt_id): self.scatts_ids.remove(scatt_id) - for cat_id in six.iterkeys(self.cats): + for cat_id in self.cats.keys(): ScattPlotsCondsData.DeleteScattPlot(self, cat_id, scatt_id) return True @@ -625,7 +624,7 @@ def GetEllipses(self, scatt_id, styles): return False scatts = {} - for cat_id in six.iterkeys(self.cats): + for cat_id in self.cats.keys(): if cat_id == 0: continue nstd = styles[cat_id]["nstd"] @@ -694,9 +693,9 @@ def eigsorted(cov): def CleanUp(self): ScattPlotsCondsData.CleanUp(self) - for tmp in six.itervalues(self.cats_rasts_conds): + for tmp in self.cats_rasts_conds.values(): grass.try_remove(tmp) - for tmp in six.itervalues(self.cats_rasts): + for tmp in self.cats_rasts.values(): RunCommand("g.remove", flags="f", type="raster", name=tmp, getErrorMsg=True) self.cats_rasts = {} @@ -714,7 +713,7 @@ def GetCatsRastsConds(self): max_cat_id = max(self.cats_rasts_conds.keys()) cats_rasts_conds = [""] * (max_cat_id + 1) - for i_cat_id, i_rast in six.iteritems(self.cats_rasts_conds): + for i_cat_id, i_rast in self.cats_rasts_conds.items(): cats_rasts_conds[i_cat_id] = i_rast return cats_rasts_conds @@ -723,7 +722,7 @@ def GetCatsRasts(self): max_cat_id = max(self.cats_rasts.keys()) cats_rasts = [""] * (max_cat_id + 1) - for i_cat_id, i_rast in six.iteritems(self.cats_rasts): + for i_cat_id, i_rast in self.cats_rasts.items(): cats_rasts[i_cat_id] = i_rast return cats_rasts diff --git a/gui/wxpython/iscatt/plots.py b/gui/wxpython/iscatt/plots.py index 80b0a2b2388..c3e9ac6dc02 100644 --- a/gui/wxpython/iscatt/plots.py +++ b/gui/wxpython/iscatt/plots.py @@ -16,7 +16,6 @@ @author Stepan Turek (mentor: Martin Landa) """ import wx -import six import numpy as np from math import ceil from multiprocessing import Process, Queue @@ -542,14 +541,14 @@ def MergeImg(cats_order, scatts, styles, rend_dt, output_queue): def _rendDtMemmapsToFiles(rend_dt): - for k, v in six.iteritems(rend_dt): + for k, v in rend_dt.items(): if "dt" in v: rend_dt[k]["sh"] = v["dt"].shape rend_dt[k]["dt"] = v["dt"].filename def _rendDtFilesToMemmaps(rend_dt): - for k, v in six.iteritems(rend_dt): + for k, v in rend_dt.items(): if "dt" in v: rend_dt[k]["dt"] = np.memmap(filename=v["dt"], shape=v["sh"]) del rend_dt[k]["sh"] diff --git a/gui/wxpython/lmgr/giface.py b/gui/wxpython/lmgr/giface.py index 79a48e8abc6..a9a5b8e53cb 100644 --- a/gui/wxpython/lmgr/giface.py +++ b/gui/wxpython/lmgr/giface.py @@ -15,8 +15,6 @@ @author Vaclav Petras """ -from __future__ import print_function - from grass.pydispatch.signal import Signal from core.giface import Notification from core.utils import GetLayerNameFromCmd diff --git a/gui/wxpython/lmgr/pyshell.py b/gui/wxpython/lmgr/pyshell.py index 9df338edd8b..06fe51729df 100644 --- a/gui/wxpython/lmgr/pyshell.py +++ b/gui/wxpython/lmgr/pyshell.py @@ -18,8 +18,6 @@ @author Martin Landa """ -from __future__ import print_function - import io from contextlib import redirect_stdout import sys diff --git a/gui/wxpython/location_wizard/wizard.py b/gui/wxpython/location_wizard/wizard.py index 7f1546dd1c2..c25e09b5ab6 100644 --- a/gui/wxpython/location_wizard/wizard.py +++ b/gui/wxpython/location_wizard/wizard.py @@ -35,7 +35,6 @@ """ import os import locale -import six import functools import wx @@ -905,7 +904,7 @@ def OnPageChange(self, event=None): """Go to next page""" if event.GetDirection(): self.p4projparams = "" - for id, param in six.iteritems(self.pparam): + for id, param in self.pparam.items(): if param["type"] == "bool": if param["value"] is False: continue @@ -1761,7 +1760,7 @@ def OnBrowseCodes(self, event, search=None): return data = list() - for code, val in six.iteritems(self.epsgCodeDict): + for code, val in self.epsgCodeDict.items(): if code is not None: data.append((code, val[0], val[1])) @@ -2037,7 +2036,7 @@ def OnBrowseCodes(self, event, search=None): return data = list() - for code, val in six.iteritems(self.epsgCodeDict): + for code, val in self.epsgCodeDict.items(): if code is not None: data.append((code, val[0], val[1])) diff --git a/gui/wxpython/mapdisp/main.py b/gui/wxpython/mapdisp/main.py index 13c1f9ed5da..eddcaaae5cf 100644 --- a/gui/wxpython/mapdisp/main.py +++ b/gui/wxpython/mapdisp/main.py @@ -27,11 +27,8 @@ @author Anna Kratochvilova (MapPanelBase) """ -from __future__ import print_function - import os import sys -import six import time import shutil import fileinput @@ -597,7 +594,7 @@ def OnExit(self): if self.timer.IsRunning: self.timer.Stop() # terminate thread - for f in six.itervalues(monFile): + for f in monFile.values(): try_remove(f) return True diff --git a/gui/wxpython/mapwin/base.py b/gui/wxpython/mapwin/base.py index fa9bae64e5b..98bcd78cedf 100644 --- a/gui/wxpython/mapwin/base.py +++ b/gui/wxpython/mapwin/base.py @@ -20,7 +20,6 @@ """ import wx -import six from core.settings import UserSettings from core.gcmd import GError @@ -208,7 +207,7 @@ def InitBinding(self): """Binds helper functions, which calls all handlers registered to events with the events """ - for ev, handlers in six.iteritems(self.handlersContainer): + for ev, handlers in self.handlersContainer.items(): self.Bind(ev, self.EventTypeHandler(handlers)) def EventTypeHandler(self, evHandlers): @@ -281,7 +280,7 @@ def OnMouseAction(self, event): """ self.mouseHandlerRegistered.emit() # inserts handler into list - for containerEv, handlers in six.iteritems(self.handlersContainer): + for containerEv, handlers in self.handlersContainer.items(): if event == containerEv: handlers.append(handler) @@ -302,7 +301,7 @@ def UnregisterAllHandlers(self): Before each handler is unregistered it is called with string value "unregistered" of event parameter. """ - for containerEv, handlers in six.iteritems(self.handlersContainer): + for containerEv, handlers in self.handlersContainer.items(): for handler in handlers: try: handler("unregistered") @@ -335,7 +334,7 @@ def UnregisterMouseEventHandler(self, event, handler): :return: False if event cannot be unbind """ # removes handler from list - for containerEv, handlers in six.iteritems(self.handlersContainer): + for containerEv, handlers in self.handlersContainer.items(): if event != containerEv: continue try: diff --git a/gui/wxpython/mapwin/buffered.py b/gui/wxpython/mapwin/buffered.py index 2c70b4a9b0b..761ae7a9de1 100644 --- a/gui/wxpython/mapwin/buffered.py +++ b/gui/wxpython/mapwin/buffered.py @@ -21,8 +21,6 @@ @author Vaclav Petras (refactoring) """ -from __future__ import print_function - import os import time import math diff --git a/gui/wxpython/modules/colorrules.py b/gui/wxpython/modules/colorrules.py index 5bdfb41bdb8..96606fb0653 100644 --- a/gui/wxpython/modules/colorrules.py +++ b/gui/wxpython/modules/colorrules.py @@ -26,7 +26,6 @@ import shutil import copy import tempfile -import six import wx import wx.lib.colourselect as csel @@ -679,7 +678,7 @@ def OnSaveRulesFile(self, event): return rulestxt = "" - for rule in six.itervalues(self.rulesPanel.ruleslines): + for rule in self.rulesPanel.ruleslines.values(): if "value" not in rule: continue rulestxt += rule["value"] + " " + rule["color"] + "\n" @@ -783,7 +782,7 @@ def CreateColorTable(self, tmp=False): """ rulestxt = "" - for rule in six.itervalues(self.rulesPanel.ruleslines): + for rule in self.rulesPanel.ruleslines.values(): if "value" not in rule: # skip empty rules continue @@ -1830,7 +1829,7 @@ def UpdateColorColumn(self, tmp): """ rulestxt = "" - for rule in six.itervalues(self.rulesPanel.ruleslines): + for rule in self.rulesPanel.ruleslines.values(): if "value" not in rule: # skip empty rules break diff --git a/gui/wxpython/nviz/mapwindow.py b/gui/wxpython/nviz/mapwindow.py index 22a94e5e298..2ad734747f6 100644 --- a/gui/wxpython/nviz/mapwindow.py +++ b/gui/wxpython/nviz/mapwindow.py @@ -20,7 +20,6 @@ import os import sys -import six import time import copy import math @@ -478,7 +477,7 @@ def _onUpdateOverlays(self): and then to textures so that they can be rendered by OpenGL. Updates self.imagelist""" # update images (legend and text) - for oid, overlay in six.iteritems(self.overlays): + for oid, overlay in self.overlays.items(): if not overlay.IsShown() or overlay.name in ("barscale", "northarrow"): continue if oid not in [t.GetId() for t in self.imagelist]: # new diff --git a/gui/wxpython/nviz/tools.py b/gui/wxpython/nviz/tools.py index 3daf9ebeeec..01e4bce1f96 100644 --- a/gui/wxpython/nviz/tools.py +++ b/gui/wxpython/nviz/tools.py @@ -22,7 +22,6 @@ import os import sys import copy -import six import wx import wx.lib.colourselect as csel @@ -2818,7 +2817,7 @@ def OnConstantSelection(self, event): return name = _("constant#") + str(layerIdx + 1) data = self.mapWindow.constants[layerIdx] - for attr, value in six.iteritems(data["constant"]): + for attr, value in data["constant"].items(): if attr == "color": value = self._getColorFromString(value) if attr in ("color", "value", "resolution", "transp"): @@ -2877,7 +2876,7 @@ def OnScroll(self, event, win, data): if not winName: return data[winName] = self.FindWindowById(event.GetId()).GetValue() - for w in six.itervalues(win[winName]): + for w in win[winName].values(): self.FindWindowById(w).SetValue(data[winName]) event.Skip() @@ -3212,9 +3211,9 @@ def _createCompass(self, panel, sizer, type): sizer.Add(w, pos=(1, 0), flag=wx.ALIGN_CENTER) def __GetWindowName(self, data, id): - for name in six.iterkeys(data): + for name in data.keys(): if isinstance(data[name], type({})): - for win in six.itervalues(data[name]): + for win in data[name].values(): if win == id: return name else: @@ -3227,7 +3226,7 @@ def UpdateSettings(self): """Update view from settings values stored in self.mapWindow.view dictionary""" for control in ("height", "persp", "twist", "z-exag"): - for win in six.itervalues(self.win["view"][control]): + for win in self.win["view"][control].values(): try: if control == "height": value = int(self.mapWindow.iview[control]["value"]) @@ -3268,7 +3267,7 @@ def OnLightChange(self, event): value = self.FindWindowById(event.GetId()).GetValue() self.mapWindow.light["position"]["z"] = value - for win in six.itervalues(self.win["light"][winName]): + for win in self.win["light"][winName].values(): self.FindWindowById(win).SetValue(value) self.PostLightEvent() @@ -3387,7 +3386,7 @@ def OnViewChange(self, event): view[winName]["value"] = convert(value) - for win in six.itervalues(self.win["view"][winName]): + for win in self.win["view"][winName].values(): self.FindWindowById(win).SetValue(value) self.mapWindow.iview["dir"]["use"] = False @@ -3449,7 +3448,7 @@ def OnResetView(self, event): def OnResetSurfacePosition(self, event): """Reset position of surface""" - for win in six.itervalues(self.win["surface"]["position"]): + for win in self.win["surface"]["position"].values(): if win == self.win["surface"]["position"]["axis"]: self.FindWindowById(win).SetSelection(2) # Z elif win == self.win["surface"]["position"]["reset"]: @@ -3586,13 +3585,13 @@ def OnMapObjUse(self, event): def EnablePage(self, name, enabled=True): """Enable/disable all widgets on page""" - for key, item in six.iteritems(self.win[name]): + for key, item in self.win[name].items(): if key in ("map", "surface", "new", "planes"): continue if isinstance(item, dict): - for skey, sitem in six.iteritems(self.win[name][key]): + for skey, sitem in self.win[name][key].items(): if isinstance(sitem, dict): - for ssitem in six.itervalues(self.win[name][key][skey]): + for ssitem in self.win[name][key][skey].values(): if not isinstance(ssitem, bool) and isinstance(ssitem, int): self.FindWindowById(ssitem).Enable(enabled) else: @@ -3902,7 +3901,7 @@ def OnSurfacePosition(self, event): slider = self.FindWindowById(self.win["surface"][winName]["slider"]) self.AdjustSliderRange(slider=slider, value=value) - for win in six.itervalues(self.win["surface"]["position"]): + for win in self.win["surface"]["position"].values(): if win in ( self.win["surface"]["position"]["axis"], self.win["surface"]["position"]["reset"], @@ -4124,7 +4123,7 @@ def OnVectorHeight(self, event): slider = self.FindWindowById(self.win["vector"][vtype]["height"]["slider"]) self.AdjustSliderRange(slider=slider, value=value) - for win in six.itervalues(self.win["vector"][vtype]["height"]): + for win in self.win["vector"][vtype]["height"].values(): self.FindWindowById(win).SetValue(value) data = self.GetLayerData("vector") @@ -4750,7 +4749,7 @@ def OnVolumePosition(self, event): slider = self.FindWindowById(self.win["volume"][winName]["slider"]) self.AdjustSliderRange(slider=slider, value=value) - for win in six.itervalues(self.win["volume"]["position"]): + for win in self.win["volume"]["position"].values(): if win in ( self.win["volume"]["position"]["axis"], self.win["volume"]["position"]["reset"], @@ -4818,7 +4817,7 @@ def OnVolumePositionText(self, event): def OnResetVolumePosition(self, event): """Reset position of volume""" - for win in six.itervalues(self.win["volume"]["position"]): + for win in self.win["volume"]["position"].values(): if win == self.win["volume"]["position"]["axis"]: self.FindWindowById(win).SetSelection(2) # Z elif win == self.win["volume"]["position"]["reset"]: @@ -5366,7 +5365,7 @@ def UpdateSurfacePage(self, layer, data, updateName=True): # # draw # - for control, drawData in six.iteritems(data["draw"]): + for control, drawData in data["draw"].items(): if control == "all": # skip 'all' property continue if control == "resolution": @@ -5575,7 +5574,7 @@ def UpdateVolumePage(self, layer, data, updateName=True): self.FindWindowById(self.win["volume"]["map"]).SetValue(layer.name) # draw - for control, idata in six.iteritems(data["draw"]): + for control, idata in data["draw"].items(): if control == "all": # skip 'all' property continue diff --git a/gui/wxpython/nviz/wxnviz.py b/gui/wxpython/nviz/wxnviz.py index 86696d211fe..b8b3cbd29c0 100644 --- a/gui/wxpython/nviz/wxnviz.py +++ b/gui/wxpython/nviz/wxnviz.py @@ -22,8 +22,6 @@ @author Anna Kratochvilova (Google SoC 2011) """ -from __future__ import print_function - import sys import locale import struct @@ -77,8 +75,7 @@ def print_error(msg, type): """Redirect stderr""" global log if log: - if sys.version_info.major >= 3: - msg = DecodeString(msg.data) + msg = DecodeString(msg.data) log.write(msg) else: print(msg) diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py index 64ff550054d..fb79bb979d0 100644 --- a/gui/wxpython/photo2image/ip2i_manager.py +++ b/gui/wxpython/photo2image/ip2i_manager.py @@ -25,11 +25,8 @@ @author Yann modified: graphical replacement of i.photo.2image (was in v6 using Vask lib) """ -from __future__ import print_function - import os import sys -import six import shutil from copy import copy @@ -760,7 +757,7 @@ def SetSettings(self): } wpx = UserSettings.Get(group="gcpman", key="symbol", subkey="width") - for k, v in six.iteritems(colours): + for k, v in colours.items(): col = UserSettings.Get(group="gcpman", key="symbol", subkey=k) self.pointsToDrawSrc.GetPen(v).SetColour( wx.Colour(col[0], col[1], col[2], 255) diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py index 80863778f2a..9263a159de6 100644 --- a/gui/wxpython/psmap/frame.py +++ b/gui/wxpython/psmap/frame.py @@ -18,10 +18,7 @@ import os import sys -if sys.version_info.major == 2: - import Queue -else: - import queue as Queue +import queue as Queue from math import sin, cos, pi, sqrt import wx diff --git a/gui/wxpython/psmap/instructions.py b/gui/wxpython/psmap/instructions.py index 10cdac25338..507754ab711 100644 --- a/gui/wxpython/psmap/instructions.py +++ b/gui/wxpython/psmap/instructions.py @@ -34,7 +34,6 @@ import os import string -import six from math import ceil from time import strftime, localtime from io import open @@ -825,7 +824,7 @@ def Read(self, instruction, text, **kwargs): # e.g. paper a3 try: instr["Format"] = pformat - for key, value in six.iteritems(availableFormats[pformat]): + for key, value in availableFormats[pformat].items(): instr[key] = float(value) break except KeyError: diff --git a/gui/wxpython/startup/locdownload.py b/gui/wxpython/startup/locdownload.py index cd3c3f376b7..56f6bc1d212 100644 --- a/gui/wxpython/startup/locdownload.py +++ b/gui/wxpython/startup/locdownload.py @@ -16,8 +16,6 @@ @author Vaclav Petras """ -from __future__ import print_function - import os import sys import shutil diff --git a/gui/wxpython/timeline/frame.py b/gui/wxpython/timeline/frame.py index 35c88adfb08..b594ee1cfbc 100644 --- a/gui/wxpython/timeline/frame.py +++ b/gui/wxpython/timeline/frame.py @@ -16,7 +16,6 @@ @author Anna Kratochvilova """ -import six from math import ceil from itertools import cycle import numpy as np @@ -493,9 +492,9 @@ def _checkDatasets(self, datasets): allDatasets = [ [ [(map, mapset, etype) for map in maps] - for etype, maps in six.iteritems(etypesDict) + for etype, maps in etypesDict.items() ] - for mapset, etypesDict in six.iteritems(tDict) + for mapset, etypesDict in tDict.items() ] # flatten this list if allDatasets: @@ -641,7 +640,7 @@ def InfoFormat(timeData, datasetName, mapIndex): return "\n".join(text) -class DataCursor(object): +class DataCursor: """A simple data cursor widget that displays the x,y location of a matplotlib artist when it is selected. @@ -678,8 +677,8 @@ def __init__( artists = [artists] self.artists = artists - self.axes = tuple(set(art.axes for art in self.artists)) - self.figures = tuple(set(ax.figure for ax in self.axes)) + self.axes = tuple({art.axes for art in self.artists}) + self.figures = tuple({ax.figure for ax in self.axes}) self.annotations = {} for ax in self.axes: diff --git a/gui/wxpython/tools/build_modules_xml.py b/gui/wxpython/tools/build_modules_xml.py index 11d8ca691c9..8022b816435 100644 --- a/gui/wxpython/tools/build_modules_xml.py +++ b/gui/wxpython/tools/build_modules_xml.py @@ -12,8 +12,6 @@ @author Anna Petrasova """ -from __future__ import print_function - import sys import grass.script.core as gcore diff --git a/gui/wxpython/tools/update_menudata.py b/gui/wxpython/tools/update_menudata.py index fce40eaf9c0..17a0332cc27 100644 --- a/gui/wxpython/tools/update_menudata.py +++ b/gui/wxpython/tools/update_menudata.py @@ -19,16 +19,11 @@ @author Martin Landa """ -from __future__ import print_function - import os import sys import tempfile -try: - import xml.etree.ElementTree as etree -except ImportError: - import elementtree.ElementTree as etree # Python <= 2.4 +import xml.etree.ElementTree as etree from grass.script import core as grass from grass.script import task as gtask diff --git a/gui/wxpython/tplot/frame.py b/gui/wxpython/tplot/frame.py index da3271acf66..0b36b3704fb 100755 --- a/gui/wxpython/tplot/frame.py +++ b/gui/wxpython/tplot/frame.py @@ -19,7 +19,6 @@ @author start stvds support Matej Krejci """ import os -import six from itertools import cycle import numpy as np @@ -840,7 +839,7 @@ def drawR(self): self.yticksPos.append(1) # TODO xdata = [] ydata = [] - for keys, values in six.iteritems(self.timeDataR[name]): + for keys, values in self.timeDataR[name].items(): if keys in [ "temporalType", "granularity", @@ -896,7 +895,7 @@ def drawVCats(self): xdata = [] ydata = [] xcsv = [] - for keys, values in six.iteritems(self.timeDataV[name_cat[0]][name_cat[1]]): + for keys, values in self.timeDataV[name_cat[0]][name_cat[1]].items(): if keys in [ "temporalType", "granularity", @@ -956,7 +955,7 @@ def drawV(self): xdata = [] ydata = [] xcsv = [] - for keys, values in six.iteritems(self.timeDataV[name]): + for keys, values in self.timeDataV[name].items(): if keys in [ "temporalType", "granularity", @@ -1149,9 +1148,9 @@ def _checkDatasets(self, datasets, typ): allDatasets = [ [ [(map, mapset, etype) for map in maps] - for etype, maps in six.iteritems(etypesDict) + for etype, maps in etypesDict.items() ] - for mapset, etypesDict in six.iteritems(tDict) + for mapset, etypesDict in tDict.items() ] # flatten this list if allDatasets: @@ -1346,7 +1345,7 @@ def AddDataset(self, yranges, xranges, datasetName): def GetInformation(self, x): values = {} - for key, value in six.iteritems(self.data): + for key, value in self.data.items(): if value[x]: values[key] = [self.convert(x), value[x]] @@ -1359,7 +1358,7 @@ def GetInformation(self, x): def InfoFormat(timeData, values): """Formats information about dataset""" text = [] - for key, val in six.iteritems(values): + for key, val in values.items(): etype = timeData[key]["temporalDataType"] if etype == "strds": text.append(_("Space time raster dataset: %s") % key) @@ -1375,7 +1374,7 @@ def InfoFormat(timeData, values): return "\n".join(text) -class DataCursor(object): +class DataCursor: """A simple data cursor widget that displays the x,y location of a matplotlib artist when it is selected. diff --git a/gui/wxpython/vdigit/dialogs.py b/gui/wxpython/vdigit/dialogs.py index b563514d240..395f92a4102 100644 --- a/gui/wxpython/vdigit/dialogs.py +++ b/gui/wxpython/vdigit/dialogs.py @@ -19,7 +19,6 @@ """ import copy -import six import wx import wx.lib.mixins.listctrl as listmix @@ -425,7 +424,7 @@ def ApplyChanges(self, fid): newfid = -1 # add/delete new category - for action, catsCurr in six.iteritems(check): + for action, catsCurr in check.items(): for layer in catsCurr[0].keys(): catList = [] for cat in catsCurr[0][layer]: diff --git a/gui/wxpython/vdigit/mapwindow.py b/gui/wxpython/vdigit/mapwindow.py index cd5c388c17e..650fe65261a 100644 --- a/gui/wxpython/vdigit/mapwindow.py +++ b/gui/wxpython/vdigit/mapwindow.py @@ -16,7 +16,6 @@ import wx import tempfile -import six from grass.pydispatch.signal import Signal @@ -397,9 +396,9 @@ def _geomAttrbUpdate(self, fids): dbInfo = gselect.VectorDBInfo(vectorName) sqlfile = tempfile.NamedTemporaryFile(mode="w") for fid in fids: - for layer, cats in six.iteritems(self.digit.GetLineCats(fid)): + for layer, cats in self.digit.GetLineCats(fid).items(): table = dbInfo.GetTable(layer) - for attrb, item in six.iteritems(vdigit["geomAttr"]): + for attrb, item in vdigit["geomAttr"].items(): val = -1 if attrb == "length": val = self.digit.GetLineLength(fid) diff --git a/gui/wxpython/vdigit/preferences.py b/gui/wxpython/vdigit/preferences.py index 693ad1bdd73..b9eb12f38a3 100644 --- a/gui/wxpython/vdigit/preferences.py +++ b/gui/wxpython/vdigit/preferences.py @@ -15,7 +15,6 @@ """ import textwrap -import six import wx import wx.lib.colourselect as csel @@ -752,7 +751,7 @@ def OnGeomAttrb(self, event): checked = event.IsChecked() id = event.GetId() key = None - for attrb, val in six.iteritems(self.geomAttrb): + for attrb, val in self.geomAttrb.items(): if val["check"] == id: key = attrb break @@ -903,7 +902,7 @@ def UpdateSettings(self): """ self._giface.workspaceChanged.emit() # symbology - for key, (enabled, color) in six.iteritems(self.symbology): + for key, (enabled, color) in self.symbology.items(): if enabled: UserSettings.Set( group="vdigit", @@ -993,7 +992,7 @@ def UpdateSettings(self): item = tree.FindItemByData("maplayer", mapLayer) else: item = None - for key, val in six.iteritems(self.geomAttrb): + for key, val in self.geomAttrb.items(): checked = self.FindWindowById(val["check"]).IsChecked() column = self.FindWindowById(val["column"]).GetValue() unitsIdx = self.FindWindowById(val["units"]).GetSelection() diff --git a/gui/wxpython/vdigit/wxdigit.py b/gui/wxpython/vdigit/wxdigit.py index 0b029af5e97..71d3dc9bef8 100644 --- a/gui/wxpython/vdigit/wxdigit.py +++ b/gui/wxpython/vdigit/wxdigit.py @@ -26,9 +26,7 @@ @author Martin Landa """ -from __future__ import print_function -import six import grass.script.core as grass from grass.pydispatch.signal import Signal @@ -1811,7 +1809,7 @@ def InitCats(self): ) # set default values - for field, cat in six.iteritems(self.cats): + for field, cat in self.cats.items(): if cat is None: self.cats[field] = 0 # first category 1 Debug.msg( diff --git a/gui/wxpython/vdigit/wxdisplay.py b/gui/wxpython/vdigit/wxdisplay.py index 47f0d70ec97..c3a2b9c85c9 100644 --- a/gui/wxpython/vdigit/wxdisplay.py +++ b/gui/wxpython/vdigit/wxdisplay.py @@ -17,10 +17,8 @@ @author Martin Landa """ -from __future__ import print_function import locale -import six import os import sys @@ -51,8 +49,7 @@ def print_error(msg, type): """Redirect stderr""" global log if log: - if sys.version_info.major >= 3: - msg = DecodeString(msg.data) + msg = DecodeString(msg.data) log.write(msg + os.linesep) else: print(msg) @@ -1189,7 +1186,7 @@ def _getCatString(self, line): catsDict[layer].append(cats.cat[i]) catsStr = "" - for l, c in six.iteritems(catsDict): + for l, c in catsDict.items(): catsStr = "%d: (%s)" % (l, ",".join(map(str, c))) return catsStr diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py index ad4d41f21fa..2d6ed76e44a 100644 --- a/gui/wxpython/vnet/dialogs.py +++ b/gui/wxpython/vnet/dialogs.py @@ -25,12 +25,7 @@ """ import os -import sys import math -import six - -if sys.version_info.major >= 3: - unicode = str from grass.script import core as grass @@ -769,11 +764,11 @@ def OnVectSel(self, event): self.inputData["arc_layer"].SetSelection(0) self.inputData["node_layer"].SetSelection(0) elif itemsLen >= 1: - if unicode("1") in items: - iItem = items.index(unicode("1")) + if "1" in items: + iItem = items.index("1") self.inputData["arc_layer"].SetSelection(iItem) - if unicode("2") in items: - iItem = items.index(unicode("2")) + if "2" in items: + iItem = items.index("2") self.inputData["node_layer"].SetSelection(iItem) self.addToTreeBtn.Enable() @@ -832,7 +827,7 @@ def OnNLayerSel(self, event): def _setInputData(self): params = {} - for k, v in six.iteritems(self.inputData): + for k, v in self.inputData.items(): params[k] = v.GetValue() flags = {} self.vnet_mgr.SetParams(params, flags) @@ -1008,7 +1003,7 @@ def OnAnalysisChanged(self, event): used_cols = [] attrCols = an_props["cmdParams"]["cols"] - for col in six.iterkeys(attrCols): + for col in attrCols.keys(): if "inputField" in attrCols[col]: colInptF = attrCols[col]["inputField"] else: @@ -1188,7 +1183,7 @@ def PointsChanged(self, method, kwargs): def SetData(self, key, data): idx = self._findIndex(key) - for k, v in six.iteritems(data): + for k, v in data.items(): if k == "use": if v and not self.IsItemChecked(idx): self.CheckItem(idx, True) @@ -1294,7 +1289,7 @@ def __init__( "selected": ["point_colors", _("Color for selected point:")], } - for settKey, sett in six.iteritems(self.colorsSetts): + for settKey, sett in self.colorsSetts.items(): settsLabels[settKey] = StaticText(parent=self, id=wx.ID_ANY, label=sett[1]) col = UserSettings.Get(group="vnet", key=sett[0], subkey=settKey) self.settings[settKey] = csel.ColourSelect( @@ -1309,7 +1304,7 @@ def __init__( "max_hist_steps": ["other", _("Maximum number of results in history:")], } - for settKey, sett in six.iteritems(self.sizeSetts): + for settKey, sett in self.sizeSetts.items(): settsLabels[settKey] = StaticText(parent=self, id=wx.ID_ANY, label=sett[1]) self.settings[settKey] = SpinCtrl(parent=self, id=wx.ID_ANY, min=1, max=50) size = int(UserSettings.Get(group="vnet", key=sett[0], subkey=settKey)) @@ -1463,11 +1458,11 @@ def UpdateSettings(self): value=self.settings["line_width"].GetValue(), ) - for settKey, sett in six.iteritems(self.colorsSetts): + for settKey, sett in self.colorsSetts.items(): col = tuple(self.settings[settKey].GetColour()) UserSettings.Set(group="vnet", key=sett[0], subkey=settKey, value=col) - for settKey, sett in six.iteritems(self.sizeSetts): + for settKey, sett in self.sizeSetts.items(): UserSettings.Set( group="vnet", key=sett[0], @@ -1573,7 +1568,7 @@ def __init__( ) bsizer.Add(selPanels[sel], proportion=0, flag=wx.EXPAND) - for k, v in six.iteritems(init_data): + for k, v in init_data.items(): if k in self.inputData: self.inputData[k].SetValue(v) @@ -1643,8 +1638,8 @@ def InputSel(self): elif itemsLen == 1: self.inputData["arc_layer"].SetSelection(0) elif itemsLen >= 1: - if unicode("1") in items: - iItem = items.index(unicode("1")) + if "1" in items: + iItem = items.index("1") self.inputData["arc_layer"].SetSelection(iItem) self.addToTreeBtn.Enable() if hasattr(self, "inpDbMgrData"): @@ -1652,7 +1647,7 @@ def InputSel(self): def GetData(self): params = {} - for param, sel in six.iteritems(self.inputData): + for param, sel in self.inputData.items(): params[param] = sel.GetValue() return params diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py index b541421aed9..ea5e329e319 100644 --- a/gui/wxpython/vnet/vnet_core.py +++ b/gui/wxpython/vnet/vnet_core.py @@ -20,7 +20,6 @@ """ import math -import six from grass.script.utils import try_remove from grass.script import core as grass from grass.script.task import cmdlist_to_tuple @@ -523,7 +522,7 @@ def _runTurnsAn(self, analysis, output, params, flags, catPts): cmdParams.append("output=" + output) cats = {} - for cat_name, pts_coor in six.iteritems(catPts): + for cat_name, pts_coor in catPts.items(): for coor in pts_coor: cat_num = str( GetNearestNodeCat( @@ -540,7 +539,7 @@ def _runTurnsAn(self, analysis, output, params, flags, catPts): else: cats[cat_name] = [cat_num] - for cat_name, cat_nums in six.iteritems(cats): + for cat_name, cat_nums in cats.items(): cmdParams.append(cat_name + "=" + ",".join(cat_nums)) self.tmpTurnAn = AddTmpMapAnalysisMsg("vnet_tunr_an_tmp", self.tmp_maps) @@ -701,7 +700,7 @@ def _runAn(self, analysis, output, params, flags, catPts): self._setCmdForSpecificAn(cmdParams) - for catName, catNum in six.iteritems(catsNums): + for catName, catNum in catsNums.items(): if catNum[0] == catNum[1]: cmdParams.append(catName + "=" + str(catNum[0])) else: @@ -758,9 +757,7 @@ def _setInputParams(self, analysis, params, flags): """ inParams = [] - for col, v in six.iteritems( - self.data.GetAnalysisProperties()["cmdParams"]["cols"] - ): + for col, v in self.data.GetAnalysisProperties()["cmdParams"]["cols"].items(): if "inputField" in v: colInptF = v["inputField"] else: @@ -807,7 +804,7 @@ def _getAsciiPts(self, catPts, maxCat, layerNum): pt_ascii = "" catNum = maxCat - for catName, pts in six.iteritems(catPts): + for catName, pts in catPts.items(): catsNums[catName] = [catNum + 1] for pt in pts: catNum += 1 @@ -891,7 +888,7 @@ def SaveHistStep(self): return # delete temporary maps in history steps which were deleted - for removedStep in six.itervalues(removedHistData): + for removedStep in removedHistData.values(): mapsNames = removedStep["tmp_data"]["maps"] for vectMapName in mapsNames: tmpMap = self.tmp_maps.GetTmpVectMap(vectMapName) @@ -937,7 +934,7 @@ def _updateHistStepData(self, histStepData): # update parameters params = {} histInputData = histStepData["an_params"] - for inpName, inp in six.iteritems(histInputData): + for inpName, inp in histInputData.items(): params[inpName] = str(inp) if inpName == "input": inpMap = inp @@ -989,7 +986,7 @@ def _saveAnInputToHist(self, analysis, params, flags): key="points", subkey=[ptName, "checked"], value=data["use"] ) - for param, value in six.iteritems(params): + for param, value in params.items(): if param == "input": inpMap = VectMap(self, value) self.history.Add( diff --git a/gui/wxpython/vnet/vnet_data.py b/gui/wxpython/vnet/vnet_data.py index 74841f4580c..175004db71e 100644 --- a/gui/wxpython/vnet/vnet_data.py +++ b/gui/wxpython/vnet/vnet_data.py @@ -24,7 +24,6 @@ """ import os import math -import six from copy import deepcopy from grass.script.utils import try_remove @@ -175,7 +174,7 @@ def InputsErrorMsgs( "turn_layer": _("turntable layer"), "turn_cat_layer": _("unique categories layer"), } - for layer, layerLabel in six.iteritems(vals): + for layer, layerLabel in vals.items(): if layer in ["turn_layer", "turn_cat_layer"] and not flags["t"]: continue if layer in inv_params: @@ -316,7 +315,7 @@ def SetPoints(self, pts_data): self.pointsChanged.emit(method="SetPoints", kwargs={"pts_data": pts_data}) def SetPointData(self, pt_id, data): - for col, v in six.iteritems(data): + for col, v in data.items(): if col == "use": continue @@ -387,7 +386,7 @@ def SetPointDrawSettings(self): textProp = self.pointsToDraw.GetPropertyVal("text") textProp["font"].SetPointSize(ptSize + 2) - for colKey, col in six.iteritems(colors): + for colKey, col in colors.items(): pen = self.pointsToDraw.GetPen(colKey) if pen: pen.SetColour(wx.Colour(col[0], col[1], col[2], 255)) @@ -422,7 +421,7 @@ def _updateTypeCol(self): def _ptDataToList(self, pt_data): pt_list_data = [None] * len(self.cols["name"]) - for k, val in six.iteritems(pt_data): + for k, val in pt_data.items(): pt_list_data[self.cols["name"].index(k)] = val return pt_list_data @@ -569,7 +568,7 @@ def GetColumns(self, only_relevant=True): i_red = 0 hidden_cols.sort() for idx in hidden_cols: - for dt in six.itervalues(cols_data): + for dt in cols_data.values(): dt.pop(idx - i_red) i_red += 1 @@ -600,7 +599,7 @@ def __init__(self, an_props): def SetParams(self, params, flags): changed_params = {} - for p, v in six.iteritems(params): + for p, v in params.items(): if p == "analysis" and v not in self.an_props.used_an: continue @@ -616,7 +615,7 @@ def SetParams(self, params, flags): changed_params[p] = v changed_flags = {} - for p, v in six.iteritems(flags): + for p, v in flags.items(): if p in self.flags: self.flags[p] = v changed_flags[p] = v @@ -840,7 +839,7 @@ def GetRelevantParams(self, analysis): cols = self.vnetProperties[analysis]["cmdParams"]["cols"] - for col, v in six.iteritems(cols): + for col, v in cols.items(): if "inputField" in col: colInptF = v["inputField"] else: diff --git a/gui/wxpython/vnet/widgets.py b/gui/wxpython/vnet/widgets.py index a620903056a..ba0d35048bf 100644 --- a/gui/wxpython/vnet/widgets.py +++ b/gui/wxpython/vnet/widgets.py @@ -19,8 +19,6 @@ """ import os -import sys -import six from copy import copy, deepcopy import wx @@ -41,9 +39,6 @@ CheckListCtrlMixin, ) -if sys.version_info.major >= 3: - basestring = str - class PointsList( ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin, ColumnSorterMixin @@ -189,7 +184,7 @@ def AddItem(self): self.selIdxs.append(itemIndexes) - for hCol in six.itervalues(self.hiddenCols): + for hCol in self.hiddenCols.values(): defVal = hCol["colsData"][iDefVal] if type(hCol["colsData"][iColEd]).__name__ == "list": hCol["itemDataMap"].append(hCol["colsData"][iColEd][defVal]) @@ -250,7 +245,7 @@ def EditCellIndex(self, index, colName, cellData): self.selIdxs[key][colNum] = -1 self.itemDataMap[key][colNum] = cellVal - if not isinstance(cellVal, basestring): + if not isinstance(cellVal, str): cellVal = str(cellVal) self.SetItem(index, colNum, cellVal) @@ -270,7 +265,7 @@ def EditCellKey(self, key, colName, cellData): index = self._findIndex(key) if index != -1: - if not isinstance(cellVal, basestring): + if not isinstance(cellVal, str): cellVal = str(cellVal) self.SetItem(index, colNum, cellVal) @@ -303,7 +298,7 @@ def DeleteItem(self): self.selIdxs.pop(key) # update hidden columns - for hCol in six.itervalues(self.hiddenCols): + for hCol in self.hiddenCols.values(): hCol["itemDataMap"].pop(key) hCol["selIdxs"].pop(key) @@ -408,7 +403,7 @@ def OnItemActivated(self, event): for editedCell in editedData: if editedCell[1] != data[i][1]: value = editedCell[1] - if not isinstance(editedCell[1], basestring): + if not isinstance(editedCell[1], str): value = str(editedCell[1]) self.SetItem(index, editedCell[0], value) self.itemDataMap[key][editedCell[0]] = editedCell[1] @@ -617,7 +612,7 @@ def __init__( TextCtrl(parent=panel, id=wx.ID_ANY, size=(150, -1)) ) value = cell[1] - if not isinstance(cell[1], basestring): + if not isinstance(cell[1], str): value = str(cell[1]) self.fields[iField].SetValue(value) diff --git a/gui/wxpython/web_services/dialogs.py b/gui/wxpython/web_services/dialogs.py index 533d4fc2bdf..f6f76103585 100644 --- a/gui/wxpython/web_services/dialogs.py +++ b/gui/wxpython/web_services/dialogs.py @@ -21,7 +21,6 @@ import wx import os -import six import shutil from copy import deepcopy @@ -140,7 +139,7 @@ def _createWidgets(self): ) self.layerName = TextCtrl(parent=self.reqDataPanel, id=wx.ID_ANY) - for ws in six.iterkeys(self.ws_panels): + for ws in self.ws_panels.keys(): # set class WSPanel argument layerNameTxtCtrl self.ws_panels[ws]["panel"] = WSPanel( parent=self.reqDataPanel, web_service=ws @@ -225,7 +224,7 @@ def _doLayout(self): self.ch_ws_sizer, proportion=0, flag=wx.TOP | wx.EXPAND, border=5 ) - for ws in six.iterkeys(self.ws_panels): + for ws in self.ws_panels.keys(): reqDataSizer.Add( self.ws_panels[ws]["panel"], proportion=1, @@ -339,7 +338,7 @@ def OnClose(self, event): def _getCapFiles(self): ws_cap_files = {} - for v in six.itervalues(self.ws_panels): + for v in self.ws_panels.values(): ws_cap_files[v["panel"].GetWebService()] = v["panel"].GetCapFile() return ws_cap_files @@ -360,7 +359,7 @@ def OnServer(self, event): def OnOutputLayerName(self, event): """Update layer name to web service panel""" lname = event.GetString() - for v in six.itervalues(self.ws_panels): + for v in self.ws_panels.values(): v["panel"].SetOutputLayerName(lname.strip()) def OnConnect(self, event): @@ -384,7 +383,7 @@ def OnConnect(self, event): # number of panels already connected self.finished_panels_num = 0 - for ws in six.iterkeys(self.ws_panels): + for ws in self.ws_panels.keys(): self.ws_panels[ws]["panel"].ConnectToServer( url=server, username=self.username.GetValue(), @@ -418,7 +417,7 @@ def _getConnectedWS(self): :return: list of found web services on server (identified as keys in self.ws_panels) """ conn_ws = [] - for ws, data in six.iteritems(self.ws_panels): + for ws, data in self.ws_panels.items(): if data["panel"].IsConnected(): conn_ws.append(ws) @@ -660,7 +659,7 @@ def __init__( self.revert_cmd = cmd ws_cap = self._getWSfromCmd(cmd) - for ws in six.iterkeys(self.ws_panels): + for ws in self.ws_panels.keys(): # cap file used in cmd will be deleted, thanks to the dialogs # destructor if ws == ws_cap and "capfile" in cmd[1]: @@ -675,11 +674,11 @@ def __init__( self.btn_ok.SetDefault() def __del__(self): - for f in six.itervalues(self.revert_ws_cap_files): + for f in self.revert_ws_cap_files.values(): grass.try_remove(f) def _setRevertCapFiles(self, ws_cap_files): - for ws, f in six.iteritems(ws_cap_files): + for ws, f in ws_cap_files.items(): if os.path.isfile(ws_cap_files[ws]): shutil.copyfile(f, self.revert_ws_cap_files[ws]) else: @@ -734,7 +733,7 @@ def LoadCapFiles(self, ws_cap_files, cmd): self.layerName.SetValue(cmd[1]["map"]) - for ws, data in six.iteritems(self.ws_panels): + for ws, data in self.ws_panels.items(): cap_file = None if ws in ws_cap_files: @@ -751,7 +750,7 @@ def _getServerConnFromCmd(self, cmd): """Get url/server/passwod from cmd tuple""" conn = {"url": "", "username": "", "password": ""} - for k in six.iterkeys(conn): + for k in conn.keys(): if k in cmd[1]: conn[k] = cmd[1][k] return conn diff --git a/gui/wxpython/web_services/widgets.py b/gui/wxpython/web_services/widgets.py index b9cbdca1903..c1aeccb72ab 100644 --- a/gui/wxpython/web_services/widgets.py +++ b/gui/wxpython/web_services/widgets.py @@ -19,16 +19,12 @@ import re import os import sys -import six import shutil from copy import deepcopy from core import globalvar -try: - from xml.etree.ElementTree import ParseError -except ImportError: # < Python 2.7 - from xml.parsers.expat import ExpatError as ParseError +from xml.etree.ElementTree import ParseError import wx @@ -526,7 +522,7 @@ def _prepareForNewConn(self, url, username, password): self.conn = {"url": url, "password": password, "username": username} conn_cmd = [] - for k, v in six.iteritems(self.conn): + for k, v in self.conn.items(): if v: conn_cmd.append("%s=%s" % (k, v)) @@ -649,7 +645,7 @@ def UpdateWidgetsByCmd(self, cmd): if "method" in dcmd: params["method"] = dcmd["method"] - for p, v in six.iteritems(params): + for p, v in params.items(): if self.params[p]: self.params[p].SetStringSelection(v) @@ -1164,8 +1160,8 @@ def _layout(self): def OnAddDefaultServers(self, event): setts = self.GetSettings() self.servers_to_add = {} - for k, v in six.iteritems(self.default_servers): - if k not in six.iterkeys(setts): + for k, v in self.default_servers.items(): + if k not in setts.keys(): self.servers_to_add[k] = v elif v != setts[k]: GMessage( diff --git a/gui/wxpython/wxgui.py b/gui/wxpython/wxgui.py index 48a1b4d7630..03166ad851b 100644 --- a/gui/wxpython/wxgui.py +++ b/gui/wxpython/wxgui.py @@ -17,8 +17,6 @@ @author Vaclav Petras (menu customization) """ -from __future__ import print_function - import os import sys import getopt diff --git a/gui/wxpython/wxplot/base.py b/gui/wxpython/wxplot/base.py index 2e05f8639fa..3ae016db748 100755 --- a/gui/wxpython/wxplot/base.py +++ b/gui/wxpython/wxplot/base.py @@ -16,7 +16,6 @@ """ import os -import six import wx from random import randint @@ -117,7 +116,7 @@ def _createColorDict(self): for assigning colors to images in imagery groups""" self.colorDict = {} - for clr in six.iterkeys(grass.named_colors): + for clr in grass.named_colors.keys(): if clr == "white": continue r = int(grass.named_colors[clr][0] * 255) diff --git a/gui/wxpython/wxplot/profile.py b/gui/wxpython/wxplot/profile.py index 88a4ec0eeb0..e69161c357d 100644 --- a/gui/wxpython/wxplot/profile.py +++ b/gui/wxpython/wxplot/profile.py @@ -17,7 +17,6 @@ import os import sys -import six import math import numpy @@ -229,7 +228,7 @@ def SetupProfile(self): self.ylabel = "" i = 0 - for r in six.iterkeys(self.raster): + for r in self.raster.keys(): self.raster[r]["datalist"] = [] datalist = self.CreateDatalist(r, self.coordstr) if len(datalist) > 0: @@ -440,7 +439,7 @@ def OnStats(self, event): message = [] title = _("Statistics for Profile(s)") - for r in six.iterkeys(self.raster): + for r in self.raster.keys(): try: rast = r.split("@")[0] statstr = "Profile of %s\n\n" % rast diff --git a/locale/grass_po_stats.py b/locale/grass_po_stats.py index a6480705bd9..81ccbab167d 100644 --- a/locale/grass_po_stats.py +++ b/locale/grass_po_stats.py @@ -14,13 +14,12 @@ # ############################################################################# -from __future__ import print_function - -import os, sys -import subprocess -import json -import glob import codecs +import glob +import json +import os +import subprocess +import sys def read_po_files(inputdirpath): diff --git a/man/parser_standard_options.py b/man/parser_standard_options.py index 55e53f9eb0c..6c48d5ffb0f 100644 --- a/man/parser_standard_options.py +++ b/man/parser_standard_options.py @@ -3,16 +3,18 @@ @author: pietro """ -from __future__ import print_function import argparse +import os import sys -try: - from urllib.request import urlopen -except ImportError: - from urllib2 import urlopen +from urllib.request import urlopen -from build_html import * +from build_html import ( + header1_tmpl, + grass_version, + headerpso_tmpl, + write_html_footer, +) def parse_options(lines, startswith="Opt"): diff --git a/mswindows/osgeo4w/setup.hint.tmpl b/mswindows/osgeo4w/setup.hint.tmpl index 1034b30b299..00cc0c14174 100644 --- a/mswindows/osgeo4w/setup.hint.tmpl +++ b/mswindows/osgeo4w/setup.hint.tmpl @@ -1,7 +1,7 @@ sdesc: "GRASS GIS - daily builds of development version" ldesc: "Geographic Resources Analysis Support System (GRASS GIS) - daily builds of the main branch from Git" category: Desktop -requires: liblas gdal303-runtime proj81-runtime avce00 gpsbabel gs python3-gdal python3-matplotlib libtiff python3-wxpython python3-pillow python3-pip python3-ply python3-pyopengl python3-psycopg2-binary python3-six zstd python3-pywin32 +requires: liblas gdal303-runtime proj81-runtime avce00 gpsbabel gs python3-gdal python3-matplotlib libtiff python3-wxpython python3-pillow python3-pip python3-ply python3-pyopengl python3-psycopg2-binary zstd python3-pywin32 maintainer: MartinLanda curr: @GRASS_VERSION_NUMBER@-1 prev: @GRASS_VERSION_NUMBER@-1 diff --git a/python/.pylintrc b/python/.pylintrc index 72e4a44c0e3..89244f98dae 100644 --- a/python/.pylintrc +++ b/python/.pylintrc @@ -293,7 +293,7 @@ init-import=no # List of qualified module names which can have objects that can redefine # builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io +redefining-builtins-modules=past.builtins,future.builtins,builtins,io [SIMILARITIES] diff --git a/python/grass/gunittest/case.py b/python/grass/gunittest/case.py index 7e9362d4a57..ee80ff6ad26 100644 --- a/python/grass/gunittest/case.py +++ b/python/grass/gunittest/case.py @@ -8,12 +8,10 @@ :authors: Vaclav Petras """ -from __future__ import print_function import os import shutil import subprocess -import sys import hashlib import uuid import unittest @@ -35,13 +33,7 @@ from .utils import safe_repr from .gutils import is_map_in_mapset -pyversion = sys.version_info[0] -if pyversion == 2: - from StringIO import StringIO -else: - from io import StringIO - - unicode = str +from io import StringIO class TestCase(unittest.TestCase): @@ -199,11 +191,9 @@ def assertLooksLike(self, actual, reference, msg=None): # actual is in the system codec while the passed reference is in utf-8; # re-decode reference into the system codec for proper comparison reference = decode(encode(reference, "utf-8")) + self.assertTrue(isinstance(actual, str), ("actual argument is not a string")) self.assertTrue( - isinstance(actual, (str, unicode)), ("actual argument is not a string") - ) - self.assertTrue( - isinstance(reference, (str, unicode)), + isinstance(reference, str), ("reference argument is not a string"), ) if os.linesep != "\n" and os.linesep in actual: diff --git a/python/grass/gunittest/checkers.py b/python/grass/gunittest/checkers.py index c32bd289243..37a5cb612ca 100644 --- a/python/grass/gunittest/checkers.py +++ b/python/grass/gunittest/checkers.py @@ -615,7 +615,7 @@ def text_file_md5( regexp = re.compile(exclude_re) if prepend_lines: for line in prepend_lines: - hasher.update(line if sys.version_info[0] == 2 else encode(line)) + hasher.update(encode(line)) with open(filename, "r") as f: for line in f: # replace platform newlines by standard newline @@ -625,10 +625,10 @@ def text_file_md5( continue if exclude_re and regexp.match(line): continue - hasher.update(line if sys.version_info[0] == 2 else encode(line)) + hasher.update(encode(line)) if append_lines: for line in append_lines: - hasher.update(line if sys.version_info[0] == 2 else encode(line)) + hasher.update(encode(line)) return hasher.hexdigest() diff --git a/python/grass/gunittest/invoker.py b/python/grass/gunittest/invoker.py index baf510a5d69..b45316a3ad9 100644 --- a/python/grass/gunittest/invoker.py +++ b/python/grass/gunittest/invoker.py @@ -9,10 +9,11 @@ :authors: Vaclav Petras """ +import collections import os -import sys import shutil import subprocess +import sys from .checkers import text_to_keyvalue @@ -32,12 +33,7 @@ import grass.script as gs from grass.script.utils import decode, _get_encoding -try: - from string import maketrans -except ImportError: - maketrans = str.maketrans - -import collections +maketrans = str.maketrans # TODO: this might be more extend then update diff --git a/python/grass/gunittest/reporters.py b/python/grass/gunittest/reporters.py index 9d5f1e39108..805f1207db2 100644 --- a/python/grass/gunittest/reporters.py +++ b/python/grass/gunittest/reporters.py @@ -14,7 +14,6 @@ import xml.sax.saxutils as saxutils import xml.etree.ElementTree as et import subprocess -import sys import collections import re from collections.abc import Iterable @@ -23,10 +22,7 @@ from .checkers import text_to_keyvalue -if sys.version_info[0] == 2: - from StringIO import StringIO -else: - from io import StringIO +from io import StringIO # TODO: change text_to_keyvalue to same sep as here diff --git a/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_python_unittest.py b/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_python_unittest.py index 622d2c605b5..c2e344269da 100644 --- a/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_python_unittest.py +++ b/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_python_unittest.py @@ -1,4 +1,3 @@ -from __future__ import print_function from unittest import TestCase, main diff --git a/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_success.py b/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_success.py index 423b57a8cec..12cdf8da24e 100644 --- a/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_success.py +++ b/python/grass/gunittest/testsuite/data/samplecode/testsuite/test_success.py @@ -1,5 +1,3 @@ -from __future__ import print_function - from grass.gunittest.case import TestCase from grass.gunittest.main import test diff --git a/python/grass/gunittest/utils.py b/python/grass/gunittest/utils.py index 53a6926c4dc..d97ce9d8250 100644 --- a/python/grass/gunittest/utils.py +++ b/python/grass/gunittest/utils.py @@ -9,10 +9,10 @@ :authors: Vaclav Petras """ +import errno import os -import sys import shutil -import errno +import sys def ensure_dir(directory): @@ -55,10 +55,8 @@ def new_translator(string): sys.displayhook = new_displayhook - try: - import __builtin__ - except ImportError: - import builtins as __builtin__ + import builtins as __builtin__ + __builtin__._ = new_translator diff --git a/python/grass/pydispatch/dispatcher.py b/python/grass/pydispatch/dispatcher.py index 30961495b32..2106494b5d8 100644 --- a/python/grass/pydispatch/dispatcher.py +++ b/python/grass/pydispatch/dispatcher.py @@ -25,7 +25,6 @@ deletion, (considerably speeds up the cleanup process vs. the original code.) """ -from __future__ import generators import weakref from grass.pydispatch import saferef, robustapply, errors diff --git a/python/grass/pydispatch/saferef.py b/python/grass/pydispatch/saferef.py index cd2ecf6c11e..573e27fbf06 100644 --- a/python/grass/pydispatch/saferef.py +++ b/python/grass/pydispatch/saferef.py @@ -1,16 +1,11 @@ """Refactored "safe reference" from dispatcher.py""" -from __future__ import print_function import weakref import traceback import sys -if sys.hexversion >= 0x3000000: - im_func = "__func__" - im_self = "__self__" -else: - im_func = "im_func" - im_self = "im_self" +im_func = "__func__" +im_self = "__self__" def safeRef(target, onDelete=None): diff --git a/python/grass/pygrass/Makefile b/python/grass/pygrass/Makefile index 80c478d3ed9..7a2f7a60783 100644 --- a/python/grass/pygrass/Makefile +++ b/python/grass/pygrass/Makefile @@ -7,7 +7,7 @@ PYDIR = $(ETC)/python GDIR = $(PYDIR)/grass DSTDIR = $(GDIR)/pygrass -MODULES = errors utils orderdict +MODULES = errors utils CLEAN_SUBDIRS = messages modules raster vector gis shell tests rpc diff --git a/python/grass/pygrass/gis/__init__.py b/python/grass/pygrass/gis/__init__.py index b9614577c30..eb501c44798 100644 --- a/python/grass/pygrass/gis/__init__.py +++ b/python/grass/pygrass/gis/__init__.py @@ -1,14 +1,5 @@ #!/usr/bin/env python3 -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) from os import listdir from os.path import join, isdir import shutil diff --git a/python/grass/pygrass/gis/region.py b/python/grass/pygrass/gis/region.py index 9bb2be8e9a5..18fd7d558ca 100644 --- a/python/grass/pygrass/gis/region.py +++ b/python/grass/pygrass/gis/region.py @@ -3,15 +3,6 @@ @author: Pietro Zambelli """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import ctypes import grass.lib.gis as libgis import grass.lib.raster as libraster diff --git a/python/grass/pygrass/modules/grid/grid.py b/python/grass/pygrass/modules/grid/grid.py index 14d80562b3e..6924422dd02 100644 --- a/python/grass/pygrass/modules/grid/grid.py +++ b/python/grass/pygrass/modules/grid/grid.py @@ -1,12 +1,3 @@ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import contextlib import os import sys diff --git a/python/grass/pygrass/modules/grid/patch.py b/python/grass/pygrass/modules/grid/patch.py index bb97d019d30..3d7c5432e43 100644 --- a/python/grass/pygrass/modules/grid/patch.py +++ b/python/grass/pygrass/modules/grid/patch.py @@ -3,15 +3,6 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) from grass.pygrass.gis.region import Region from grass.pygrass.raster import RasterRow from grass.pygrass.utils import coor2pixel diff --git a/python/grass/pygrass/modules/grid/split.py b/python/grass/pygrass/modules/grid/split.py index 435530d4c80..a32665f5fcc 100644 --- a/python/grass/pygrass/modules/grid/split.py +++ b/python/grass/pygrass/modules/grid/split.py @@ -3,15 +3,6 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) from grass.pygrass.gis.region import Region from grass.pygrass.vector.basic import Bbox diff --git a/python/grass/pygrass/modules/interface/env.py b/python/grass/pygrass/modules/interface/env.py index 262033bad34..98e5208ef5b 100644 --- a/python/grass/pygrass/modules/interface/env.py +++ b/python/grass/pygrass/modules/interface/env.py @@ -3,7 +3,6 @@ @author: pietro """ -from __future__ import print_function import os import sys diff --git a/python/grass/pygrass/modules/interface/flag.py b/python/grass/pygrass/modules/interface/flag.py index 430b661d4a2..bc5b417c53c 100644 --- a/python/grass/pygrass/modules/interface/flag.py +++ b/python/grass/pygrass/modules/interface/flag.py @@ -1,12 +1,3 @@ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) from grass.pygrass.modules.interface.docstring import docstring_property from grass.pygrass.modules.interface import read diff --git a/python/grass/pygrass/modules/interface/module.py b/python/grass/pygrass/modules/interface/module.py index 3fd215aab7f..a9b35271a00 100644 --- a/python/grass/pygrass/modules/interface/module.py +++ b/python/grass/pygrass/modules/interface/module.py @@ -1,13 +1,3 @@ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) -import sys from multiprocessing import cpu_count, Process, Queue import time from xml.etree.ElementTree import fromstring @@ -22,12 +12,7 @@ from .read import GETFROMTAG, DOC from .env import G_debug -if sys.version_info[0] == 2: - from itertools import izip_longest as zip_longest -else: - from itertools import zip_longest - - unicode = str +from itertools import zip_longest def _get_bash(self, *args, **kargs): @@ -528,9 +513,7 @@ def f(*args, **kargs): """ def __init__(self, cmd, *args, **kargs): - if isinstance(cmd, unicode): - self.name = str(cmd) - elif isinstance(cmd, str): + if isinstance(cmd, str): self.name = cmd else: raise GrassError("Problem initializing the module {s}".format(s=cmd)) diff --git a/python/grass/pygrass/modules/interface/parameter.py b/python/grass/pygrass/modules/interface/parameter.py index 26b0e179886..a7107434426 100644 --- a/python/grass/pygrass/modules/interface/parameter.py +++ b/python/grass/pygrass/modules/interface/parameter.py @@ -3,15 +3,6 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import re from grass.pygrass.modules.interface.docstring import docstring_property diff --git a/python/grass/pygrass/modules/interface/read.py b/python/grass/pygrass/modules/interface/read.py index c3376bf6e0c..e485828b3e7 100644 --- a/python/grass/pygrass/modules/interface/read.py +++ b/python/grass/pygrass/modules/interface/read.py @@ -3,15 +3,6 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) def do_nothing(p): diff --git a/python/grass/pygrass/modules/interface/testsuite/test_flag.py b/python/grass/pygrass/modules/interface/testsuite/test_flag.py index 1eb563afdd8..26b9ba531ff 100644 --- a/python/grass/pygrass/modules/interface/testsuite/test_flag.py +++ b/python/grass/pygrass/modules/interface/testsuite/test_flag.py @@ -3,7 +3,6 @@ @author: pietro """ -from __future__ import unicode_literals from grass.gunittest.case import TestCase from grass.gunittest.main import test diff --git a/python/grass/pygrass/modules/interface/testsuite/test_parameter.py b/python/grass/pygrass/modules/interface/testsuite/test_parameter.py index bd6cf4ccc6c..e3bf9921bfd 100644 --- a/python/grass/pygrass/modules/interface/testsuite/test_parameter.py +++ b/python/grass/pygrass/modules/interface/testsuite/test_parameter.py @@ -3,7 +3,6 @@ @author: pietro """ -from __future__ import print_function from grass.gunittest.case import TestCase from grass.gunittest.main import test diff --git a/python/grass/pygrass/modules/interface/typedict.py b/python/grass/pygrass/modules/interface/typedict.py index b6176e7b400..651bb7d777b 100644 --- a/python/grass/pygrass/modules/interface/typedict.py +++ b/python/grass/pygrass/modules/interface/typedict.py @@ -3,22 +3,9 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) +from collections import OrderedDict from copy import deepcopy -try: - from collections import OrderedDict -except ImportError: - from grass.pygrass.orderdict import OrderedDict - from grass.pygrass.modules.interface.docstring import docstring_property diff --git a/python/grass/pygrass/modules/shortcuts.py b/python/grass/pygrass/modules/shortcuts.py index 53893030fce..834bab8d0f3 100644 --- a/python/grass/pygrass/modules/shortcuts.py +++ b/python/grass/pygrass/modules/shortcuts.py @@ -1,12 +1,3 @@ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import fnmatch diff --git a/python/grass/pygrass/orderdict.py b/python/grass/pygrass/orderdict.py deleted file mode 100644 index b8ed36c2109..00000000000 --- a/python/grass/pygrass/orderdict.py +++ /dev/null @@ -1,261 +0,0 @@ -# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. -# Passes Python2.7's test suite and incorporates all the latest updates. -# Created by Raymond Hettinger on Wed, 18 Mar 2009 (MIT License) - -try: - from thread import get_ident as _get_ident -except ImportError: - from dummy_thread import get_ident as _get_ident - -try: - from _abcoll import KeysView, ValuesView, ItemsView -except ImportError: - pass - - -class OrderedDict(dict): - "Dictionary that remembers insertion order" - # An inherited dict maps keys to values. - # The inherited dict provides __getitem__, __len__, __contains__, and get. - # The remaining methods are order-aware. - # Big-O running times for all methods are the same as for regular dictionaries. - - # The internal self.__map dictionary maps keys to links in a doubly linked list. - # The circular doubly linked list starts and ends with a sentinel element. - # The sentinel element never gets deleted (this simplifies the algorithm). - # Each link is stored as a list of length three: [PREV, NEXT, KEY]. - - def __init__(self, *args, **kwds): - """Initialize an ordered dictionary. Signature is the same as for - regular dictionaries, but keyword arguments are not recommended - because their insertion order is arbitrary. - - """ - if len(args) > 1: - raise TypeError("expected at most 1 arguments, got %d" % len(args)) - try: - self.__root - except AttributeError: - self.__root = root = [] # sentinel node - root[:] = [root, root, None] - self.__map = {} - self.__update(*args, **kwds) - - def __setitem__(self, key, value, dict_setitem=dict.__setitem__): - "od.__setitem__(i, y) <==> od[i]=y" - # Setting a new item creates a new link which goes at the end of the linked - # list, and the inherited dictionary is updated with the new key/value pair. - if key not in self: - root = self.__root - last = root[0] - last[1] = root[0] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) - - def __delitem__(self, key, dict_delitem=dict.__delitem__): - "od.__delitem__(y) <==> del od[y]" - # Deleting an existing item uses self.__map to find the link which is - # then removed by updating the links in the predecessor and successor nodes. - dict_delitem(self, key) - link_prev, link_next, key = self.__map.pop(key) - link_prev[1] = link_next - link_next[0] = link_prev - - def __iter__(self): - "od.__iter__() <==> iter(od)" - root = self.__root - curr = root[1] - while curr is not root: - yield curr[2] - curr = curr[1] - - def __reversed__(self): - "od.__reversed__() <==> reversed(od)" - root = self.__root - curr = root[0] - while curr is not root: - yield curr[2] - curr = curr[0] - - def clear(self): - "od.clear() -> None. Remove all items from od." - try: - for node in self.__map.itervalues(): - del node[:] - root = self.__root - root[:] = [root, root, None] - self.__map.clear() - except AttributeError: - pass - dict.clear(self) - - def popitem(self, last=True): - """od.popitem() -> (k, v), return and remove a (key, value) pair. - Pairs are returned in LIFO order if last is true or FIFO order if false. - - """ - if not self: - raise KeyError("dictionary is empty") - root = self.__root - if last: - link = root[0] - link_prev = link[0] - link_prev[1] = root - root[0] = link_prev - else: - link = root[1] - link_next = link[1] - root[1] = link_next - link_next[0] = root - key = link[2] - del self.__map[key] - value = dict.pop(self, key) - return key, value - - # -- the following methods do not depend on the internal structure -- - - def keys(self): - "od.keys() -> list of keys in od" - return list(self) - - def values(self): - "od.values() -> list of values in od" - return [self[key] for key in self] - - def items(self): - "od.items() -> list of (key, value) pairs in od" - return [(key, self[key]) for key in self] - - def iterkeys(self): - "od.iterkeys() -> an iterator over the keys in od" - return iter(self) - - def itervalues(self): - "od.itervalues -> an iterator over the values in od" - for k in self: - yield self[k] - - def iteritems(self): - "od.iteritems -> an iterator over the (key, value) items in od" - for k in self: - yield (k, self[k]) - - def update(*args, **kwds): - """od.update(E, **F) -> None. Update od from dict/iterable E and F. - - If E is a dict instance, does: for k in E: od[k] = E[k] - If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] - Or if E is an iterable of items, does: for k, v in E: od[k] = v - In either case, this is followed by: for k, v in F.items(): od[k] = v - - """ - if len(args) > 2: - raise TypeError( - "update() takes at most 2 positional " - "arguments (%d given)" % (len(args),) - ) - elif not args: - raise TypeError("update() takes at least 1 argument (0 given)") - self = args[0] - # Make progressively weaker assumptions about "other" - other = () - if len(args) == 2: - other = args[1] - if isinstance(other, dict): - for key in other: - self[key] = other[key] - elif hasattr(other, "keys"): - for key in other.keys(): - self[key] = other[key] - else: - for key, value in other: - self[key] = value - for key, value in kwds.items(): - self[key] = value - - __update = update # let subclasses override update without breaking __init__ - - __marker = object() - - def pop(self, key, default=__marker): - """od.pop(k[,d]) -> v, remove specified key and return the corresponding value. - If key is not found, d is returned if given, otherwise KeyError is raised. - - """ - if key in self: - result = self[key] - del self[key] - return result - if default is self.__marker: - raise KeyError(key) - return default - - def setdefault(self, key, default=None): - "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od" - if key in self: - return self[key] - self[key] = default - return default - - def __repr__(self, _repr_running={}): - "od.__repr__() <==> repr(od)" - call_key = id(self), _get_ident() - if call_key in _repr_running: - return "..." - _repr_running[call_key] = 1 - try: - if not self: - return "%s()" % (self.__class__.__name__,) - return "%s(%r)" % (self.__class__.__name__, self.items()) - finally: - del _repr_running[call_key] - - def __reduce__(self): - "Return state information for pickling" - items = [[k, self[k]] for k in self] - inst_dict = vars(self).copy() - for k in vars(OrderedDict()): - inst_dict.pop(k, None) - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - - def copy(self): - "od.copy() -> a shallow copy of od" - return self.__class__(self) - - @classmethod - def fromkeys(cls, iterable, value=None): - """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S - and values equal to v (which defaults to None). - - """ - d = cls() - for key in iterable: - d[key] = value - return d - - def __eq__(self, other): - """od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive - while comparison to a regular mapping is order-insensitive. - - """ - if isinstance(other, OrderedDict): - return len(self) == len(other) and self.items() == other.items() - return dict.__eq__(self, other) - - def __ne__(self, other): - return not self == other - - # -- the following methods are only used in Python 2.7 -- - - def viewkeys(self): - "od.viewkeys() -> a set-like object providing a view on od's keys" - return KeysView(self) - - def viewvalues(self): - "od.viewvalues() -> an object providing a view on od's values" - return ValuesView(self) - - def viewitems(self): - "od.viewitems() -> a set-like object providing a view on od's items" - return ItemsView(self) diff --git a/python/grass/pygrass/raster/__init__.py b/python/grass/pygrass/raster/__init__.py index 0df8e6305e6..b86444a26bc 100644 --- a/python/grass/pygrass/raster/__init__.py +++ b/python/grass/pygrass/raster/__init__.py @@ -1,12 +1,3 @@ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import ctypes import numpy as np diff --git a/python/grass/pygrass/raster/abstract.py b/python/grass/pygrass/raster/abstract.py index 40856a76c52..3f607bf2f29 100644 --- a/python/grass/pygrass/raster/abstract.py +++ b/python/grass/pygrass/raster/abstract.py @@ -3,15 +3,6 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import ctypes # diff --git a/python/grass/pygrass/tests/benchmark.py b/python/grass/pygrass/tests/benchmark.py index b1f3ac162c9..bd46dfa79a3 100644 --- a/python/grass/pygrass/tests/benchmark.py +++ b/python/grass/pygrass/tests/benchmark.py @@ -3,15 +3,6 @@ @author: soeren """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import optparse diff --git a/python/grass/pygrass/tests/set_mapset.py b/python/grass/pygrass/tests/set_mapset.py index 682613072df..f9d4a96fabf 100644 --- a/python/grass/pygrass/tests/set_mapset.py +++ b/python/grass/pygrass/tests/set_mapset.py @@ -4,15 +4,6 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) import os import subprocess diff --git a/python/grass/pygrass/vector/__init__.py b/python/grass/pygrass/vector/__init__.py index e9508daa077..979e8e0d0f3 100644 --- a/python/grass/pygrass/vector/__init__.py +++ b/python/grass/pygrass/vector/__init__.py @@ -1,5 +1,3 @@ -from __future__ import print_function - from os.path import join, exists import grass.lib.gis as libgis diff --git a/python/grass/pygrass/vector/table.py b/python/grass/pygrass/vector/table.py index 455210a1abb..f6f9e6ca858 100644 --- a/python/grass/pygrass/vector/table.py +++ b/python/grass/pygrass/vector/table.py @@ -3,28 +3,14 @@ @author: pietro """ -from __future__ import ( - nested_scopes, - generators, - division, - absolute_import, - with_statement, - print_function, - unicode_literals, -) +import ctypes import os -import sys +from collections import OrderedDict -import ctypes import numpy as np from sqlite3 import OperationalError -try: - from collections import OrderedDict -except ImportError: - from grass.pygrass.orderdict import OrderedDict - import grass.lib.vector as libvect from grass.pygrass.gis import Mapset from grass.exceptions import DBError @@ -36,11 +22,6 @@ from grass.lib.ctypes_preamble import ReturnString -if sys.version_info.major >= 3: - long = int - unicode = str - - # For test purposes test_vector_name = "table_doctest_map" @@ -452,14 +433,14 @@ def check(col_type): [ check(col_type), ] - if isinstance(col_type, (str, unicode)) + if isinstance(col_type, str) else [check(col) for col in col_type] ) col_name = ( [ col_name, ] - if isinstance(col_name, (str, unicode)) + if isinstance(col_name, str) else col_name ) sqlcode = [ @@ -821,7 +802,7 @@ def connection(self): np.uint32, np.uint64, ): - sqlite3.register_adapter(t, long) + sqlite3.register_adapter(t, int) dbpath = get_path(self.database, self.table_name) dbdirpath = os.path.split(dbpath)[0] if not os.path.exists(dbdirpath): @@ -1009,7 +990,7 @@ def remove(self, key, force=False): link = self.by_name(key) table = link.table() table.drop(force=force) - if isinstance(key, unicode): + if isinstance(key, str): key = self.from_name_to_num(key) libvect.Vect_map_del_dblink(self.c_mapinfo, key) diff --git a/python/grass/pygrass/vector/testsuite/test_table.py b/python/grass/pygrass/vector/testsuite/test_table.py index cbdd1a63190..6105dcabcff 100644 --- a/python/grass/pygrass/vector/testsuite/test_table.py +++ b/python/grass/pygrass/vector/testsuite/test_table.py @@ -5,7 +5,6 @@ """ import os import sqlite3 -import sys import tempfile as tmp from string import ascii_letters, digits from random import choice @@ -17,14 +16,11 @@ from grass.pygrass.vector.table import Table, get_path -if sys.version_info.major >= 3: - long = int - # dictionary that generate random data COL2VALS = { "INT": lambda n: np.random.randint(9, size=n), "INTEGER": lambda n: np.random.randint(9, size=n), - "INTEGER PRIMARY KEY": lambda n: np.arange(1, n + 1, dtype=long), + "INTEGER PRIMARY KEY": lambda n: np.arange(1, n + 1, dtype=int), "REAL": lambda n: np.random.rand(n), "TEXT": lambda n: np.array([randstr() for _ in range(n)]), } diff --git a/python/grass/script/__init__.py b/python/grass/script/__init__.py index 5cabefa4122..8589e8a1521 100644 --- a/python/grass/script/__init__.py +++ b/python/grass/script/__init__.py @@ -1,6 +1,5 @@ """Python interface to launch GRASS GIS modules in scripts """ -from __future__ import absolute_import from .core import * from .db import * diff --git a/python/grass/script/array.py b/python/grass/script/array.py index da22d876d27..f9981f0ef5f 100644 --- a/python/grass/script/array.py +++ b/python/grass/script/array.py @@ -109,8 +109,6 @@ .. sectionauthor:: Glynn Clements """ -from __future__ import absolute_import - import numpy from .utils import try_remove diff --git a/python/grass/script/core.py b/python/grass/script/core.py index 349e6ff866a..e6d71540aa8 100644 --- a/python/grass/script/core.py +++ b/python/grass/script/core.py @@ -17,7 +17,6 @@ .. sectionauthor:: Martin Landa .. sectionauthor:: Michael Barton """ -from __future__ import absolute_import, print_function import os import sys diff --git a/python/grass/script/db.py b/python/grass/script/db.py index 7d1d8d911cd..2aa2e983c78 100644 --- a/python/grass/script/db.py +++ b/python/grass/script/db.py @@ -18,7 +18,6 @@ .. sectionauthor:: Glynn Clements .. sectionauthor:: Martin Landa """ -from __future__ import absolute_import import os from .core import ( diff --git a/python/grass/script/raster.py b/python/grass/script/raster.py index f690827f301..4b3bfe656de 100644 --- a/python/grass/script/raster.py +++ b/python/grass/script/raster.py @@ -17,10 +17,8 @@ .. sectionauthor:: Glynn Clements .. sectionauthor:: Martin Landa """ -from __future__ import absolute_import import os -import sys import string import time @@ -39,10 +37,6 @@ from .utils import encode, float_or_dms, parse_key_val, try_remove -if sys.version_info.major >= 3: - unicode = str - - def raster_history(map, overwrite=False, env=None): """Set the command history for a raster map to the command used to invoke the script (interface to `r.support`). @@ -225,7 +219,7 @@ def raster_what(map, coord, env=None, localized=False): query :param env: """ - if isinstance(map, (bytes, unicode)): + if isinstance(map, (bytes, str)): map_list = [map] else: map_list = map diff --git a/python/grass/script/raster3d.py b/python/grass/script/raster3d.py index 4097eef3dac..75aa3d8fc4e 100644 --- a/python/grass/script/raster3d.py +++ b/python/grass/script/raster3d.py @@ -18,7 +18,6 @@ .. sectionauthor:: Martin Landa .. sectionauthor:: Soeren Gebbert """ -from __future__ import absolute_import import os import time diff --git a/python/grass/script/task.py b/python/grass/script/task.py index 7b73b9dfcd4..31102835db4 100644 --- a/python/grass/script/task.py +++ b/python/grass/script/task.py @@ -20,24 +20,14 @@ import os import re import sys +import xml.etree.ElementTree as etree +from xml.parsers import expat from grass.exceptions import ScriptError from .utils import decode, split from .core import Popen, PIPE, get_real_command -import xml.etree.ElementTree as etree -from xml.parsers import expat # TODO: works for any Python? - -# Get the XML parsing exceptions to catch. The behavior chnaged with Python 2.7 -# and ElementTree 1.3. -if hasattr(etree, "ParseError"): - ETREE_EXCEPTIONS = (etree.ParseError, expat.ExpatError) -else: - ETREE_EXCEPTIONS = expat.ExpatError - - -if sys.version_info.major >= 3: - unicode = str +ETREE_EXCEPTIONS = (etree.ParseError, expat.ExpatError) class grassTask: @@ -157,7 +147,7 @@ def get_param(self, value, element="name", raiseError=True): if isinstance(val, (list, tuple)): if value in val: return p - elif isinstance(val, (bytes, unicode)): + elif isinstance(val, (bytes, str)): if p[element][: len(value)] == value: return p else: diff --git a/python/grass/script/testsuite/test_utils.py b/python/grass/script/testsuite/test_utils.py index 5f092e0eaed..f55f1ca86d0 100644 --- a/python/grass/script/testsuite/test_utils.py +++ b/python/grass/script/testsuite/test_utils.py @@ -1,5 +1,4 @@ import os -import sys from grass.gunittest.case import TestCase from grass.gunittest.main import test @@ -49,24 +48,15 @@ def test_bytes_garbage_in_out(self): def test_int(self): """If the input is an integer return bytes""" - if sys.version_info.major >= 3: - self.assertRaises(TypeError, utils.encode, 1234567890) - else: - self.assertEqual("1234567890", utils.encode(1234567890)) + self.assertRaises(TypeError, utils.encode, 1234567890) def test_float(self): """If the input is a float return bytes""" - if sys.version_info.major >= 3: - self.assertRaises(TypeError, utils.encode, 12345.6789) - else: - self.assertEqual("12345.6789", utils.encode(12345.6789)) + self.assertRaises(TypeError, utils.encode, 12345.6789) def test_none(self): """If the input is a boolean return bytes""" - if sys.version_info.major >= 3: - self.assertRaises(TypeError, utils.encode, None) - else: - self.assertEqual("None", utils.encode(None)) + self.assertRaises(TypeError, utils.encode, None) class TestDecode(TestCase): @@ -80,24 +70,15 @@ def test_unicode(self): def test_int(self): """If the input is an integer return bytes""" - if sys.version_info.major >= 3: - self.assertRaises(TypeError, utils.decode, 1234567890) - else: - self.assertEqual("1234567890", utils.decode(1234567890)) + self.assertRaises(TypeError, utils.decode, 1234567890) def test_float(self): """If the input is a float return bytes""" - if sys.version_info.major >= 3: - self.assertRaises(TypeError, utils.decode, 12345.6789) - else: - self.assertEqual("12345.6789", utils.decode(12345.6789)) + self.assertRaises(TypeError, utils.decode, 12345.6789) def test_none(self): """If the input is a boolean return bytes""" - if sys.version_info.major >= 3: - self.assertRaises(TypeError, utils.decode, None) - else: - self.assertEqual("None", utils.decode(None)) + self.assertRaises(TypeError, utils.decode, None) class TestEncodeLcAllC(TestEncode, LcAllC): diff --git a/python/grass/script/utils.py b/python/grass/script/utils.py index df7ee11f525..fece92e8884 100644 --- a/python/grass/script/utils.py +++ b/python/grass/script/utils.py @@ -307,12 +307,7 @@ def get_num_suffix(number, max_number): def split(s): """!Platform specific shlex.split""" - if sys.version_info >= (2, 6): - return shlex.split(s, posix=(sys.platform != "win32")) - elif sys.platform == "win32": - return shlex.split(s.replace("\\", r"\\")) - else: - return shlex.split(s) + return shlex.split(s, posix=(sys.platform != "win32")) # source: @@ -474,12 +469,9 @@ def set_path(modulename, dirname=None, path="."): def clock(): """ Return time counter to measure performance for chunks of code. - Uses time.clock() for Py < 3.3, time.perf_counter() for Py >= 3.3. Should be used only as difference between the calls. """ - if sys.version_info > (3, 2): - return time.perf_counter() - return time.clock() + return time.perf_counter() def legalize_vector_name(name, fallback_prefix="x"): diff --git a/python/grass/script/vector.py b/python/grass/script/vector.py index 880764e8790..ce7d1612efc 100644 --- a/python/grass/script/vector.py +++ b/python/grass/script/vector.py @@ -16,7 +16,6 @@ .. sectionauthor:: Glynn Clements .. sectionauthor:: Martin Landa """ -from __future__ import absolute_import import os import sys @@ -31,8 +30,6 @@ from grass.exceptions import CalledModuleError, ScriptError -unicode = str - def vector_db(map, env=None, **kwargs): """Return the database connection details for a vector map @@ -380,7 +377,7 @@ def vector_what( if "LC_ALL" in env: env["LC_ALL"] = "C" - if isinstance(map, (bytes, unicode)): + if isinstance(map, (bytes, str)): map_list = [map] else: map_list = map diff --git a/python/grass/temporal/__init__.py b/python/grass/temporal/__init__.py index fa8319c2463..9edbcbd0040 100644 --- a/python/grass/temporal/__init__.py +++ b/python/grass/temporal/__init__.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from .core import * from .base import * from .spatial_extent import * diff --git a/python/grass/temporal/abstract_map_dataset.py b/python/grass/temporal/abstract_map_dataset.py index ee0edf4a2a0..035e64c7622 100644 --- a/python/grass/temporal/abstract_map_dataset.py +++ b/python/grass/temporal/abstract_map_dataset.py @@ -9,8 +9,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function - import grass.script as gs from grass.exceptions import ImplementationError from datetime import datetime diff --git a/python/grass/temporal/abstract_space_time_dataset.py b/python/grass/temporal/abstract_space_time_dataset.py index ea6bd6cfaa2..2f956ffb268 100644 --- a/python/grass/temporal/abstract_space_time_dataset.py +++ b/python/grass/temporal/abstract_space_time_dataset.py @@ -9,7 +9,6 @@ class that is the base class for all space time datasets. :authors: Soeren Gebbert """ -from __future__ import print_function import sys import uuid import os diff --git a/python/grass/temporal/base.py b/python/grass/temporal/base.py index acecf68b4ee..f99da678ff4 100644 --- a/python/grass/temporal/base.py +++ b/python/grass/temporal/base.py @@ -24,7 +24,6 @@ :author: Soeren Gebbert """ -from __future__ import print_function from datetime import datetime from .core import ( get_tgis_message_interface, diff --git a/python/grass/temporal/core.py b/python/grass/temporal/core.py index d90affda3e8..5a44bc33968 100644 --- a/python/grass/temporal/core.py +++ b/python/grass/temporal/core.py @@ -30,7 +30,6 @@ """ # import traceback import os -import sys import grass.script as gscript from .c_libraries_interface import CLibrariesInterface @@ -53,9 +52,6 @@ import atexit from datetime import datetime -if sys.version_info.major >= 3: - long = int - ############################################################################### @@ -66,11 +62,8 @@ def profile_function(func): if do_profiling == "True" or do_profiling == "1": import cProfile import pstats + import io - try: - import StringIO as io - except ImportError: - import io pr = cProfile.Profile() pr.enable() func() @@ -1449,7 +1442,7 @@ def mogrify_sql_statement(self, content): statement[0:pos], statement[pos + 1 :], ) - elif isinstance(args[count], (int, long)): + elif isinstance(args[count], int): statement = "%s%d%s" % ( statement[0:pos], args[count], diff --git a/python/grass/temporal/datetime_math.py b/python/grass/temporal/datetime_math.py index 4a6118f705c..e79709302a6 100644 --- a/python/grass/temporal/datetime_math.py +++ b/python/grass/temporal/datetime_math.py @@ -8,7 +8,6 @@ :authors: Soeren Gebbert """ -import sys from datetime import datetime, timedelta from .core import get_tgis_message_interface import copy @@ -20,8 +19,6 @@ except: has_dateutil = False -if sys.version_info[0] >= 3: - unicode = str DAY_IN_SECONDS = 86400 SECOND_AS_DAY = 1.1574074074074073e-05 @@ -858,7 +855,7 @@ def string_to_datetime(time_string): could not be converted """ - if not isinstance(time_string, unicode) and not isinstance(time_string, str): + if not isinstance(time_string, str): return None time_object = check_datetime_string(time_string) diff --git a/python/grass/temporal/metadata.py b/python/grass/temporal/metadata.py index 37b5198eab4..84e7633e833 100644 --- a/python/grass/temporal/metadata.py +++ b/python/grass/temporal/metadata.py @@ -21,7 +21,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function from .base import SQLDatabaseInterface from .core import SQLDatabaseInterfaceConnection, get_tgis_db_version_from_metadata diff --git a/python/grass/temporal/sampling.py b/python/grass/temporal/sampling.py index 2370fbda60f..38fdd1aed53 100644 --- a/python/grass/temporal/sampling.py +++ b/python/grass/temporal/sampling.py @@ -16,7 +16,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function from .core import ( get_current_mapset, get_tgis_message_interface, diff --git a/python/grass/temporal/spatial_extent.py b/python/grass/temporal/spatial_extent.py index 3cfb89a59ae..4288b7eadc6 100644 --- a/python/grass/temporal/spatial_extent.py +++ b/python/grass/temporal/spatial_extent.py @@ -33,7 +33,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function from .base import SQLDatabaseInterface diff --git a/python/grass/temporal/spatial_topology_dataset_connector.py b/python/grass/temporal/spatial_topology_dataset_connector.py index fde302973a4..79adf4b30ee 100644 --- a/python/grass/temporal/spatial_topology_dataset_connector.py +++ b/python/grass/temporal/spatial_topology_dataset_connector.py @@ -13,7 +13,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function import copy diff --git a/python/grass/temporal/spatio_temporal_relationships.py b/python/grass/temporal/spatio_temporal_relationships.py index b41ce3c08bd..40c885ba870 100644 --- a/python/grass/temporal/spatio_temporal_relationships.py +++ b/python/grass/temporal/spatio_temporal_relationships.py @@ -17,7 +17,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function from datetime import datetime from .core import init_dbif from .abstract_dataset import AbstractDatasetComparisonKeyStartTime diff --git a/python/grass/temporal/temporal_algebra.py b/python/grass/temporal/temporal_algebra.py index 75102a6f2c2..37fad7e4971 100644 --- a/python/grass/temporal/temporal_algebra.py +++ b/python/grass/temporal/temporal_algebra.py @@ -438,7 +438,6 @@ LexToken(RPAREN,')',1,48) """ -from __future__ import print_function try: import ply.lex as lex @@ -447,9 +446,9 @@ pass import os -import sys import copy from datetime import datetime + import grass.pygrass.modules as pymod from .core import ( init_dbif, @@ -476,9 +475,6 @@ from .datetime_math import create_time_suffix from .datetime_math import create_numeric_suffix -if sys.version_info[0] >= 3: - unicode = str - class TemporalAlgebraLexer(object): """Lexical analyzer for the GRASS GIS temporal algebra""" @@ -1231,7 +1227,7 @@ def check_stds(self, input, clear=False, stds_type=None, check_type=True): :return: List of maps. """ - if isinstance(input, unicode) or isinstance(input, str): + if isinstance(input, str): # Check for mapset in given stds input. if input.find("@") >= 0: id_input = input diff --git a/python/grass/temporal/temporal_extent.py b/python/grass/temporal/temporal_extent.py index bb51b794bdc..4d033c89102 100644 --- a/python/grass/temporal/temporal_extent.py +++ b/python/grass/temporal/temporal_extent.py @@ -19,7 +19,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function from .base import SQLDatabaseInterface ############################################################################### diff --git a/python/grass/temporal/temporal_granularity.py b/python/grass/temporal/temporal_granularity.py index 8a7c271c54b..8c646af2ec7 100644 --- a/python/grass/temporal/temporal_granularity.py +++ b/python/grass/temporal/temporal_granularity.py @@ -17,7 +17,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function from .datetime_math import compute_datetime_delta from functools import reduce from collections import OrderedDict diff --git a/python/grass/temporal/temporal_operator.py b/python/grass/temporal/temporal_operator.py index 44a72981be7..9e1538e3d2d 100644 --- a/python/grass/temporal/temporal_operator.py +++ b/python/grass/temporal/temporal_operator.py @@ -139,8 +139,6 @@ SyntaxError: Unknown optype rter, must be one of ['select', 'boolean', 'raster', 'hash', 'relation', 'overlay'] """ -from __future__ import print_function - try: import ply.lex as lex import ply.yacc as yacc diff --git a/python/grass/temporal/temporal_raster3d_algebra.py b/python/grass/temporal/temporal_raster3d_algebra.py index b9502526f6a..536f035130c 100644 --- a/python/grass/temporal/temporal_raster3d_algebra.py +++ b/python/grass/temporal/temporal_raster3d_algebra.py @@ -10,8 +10,6 @@ :authors: Thomas Leppelt and Soeren Gebbert """ -from __future__ import print_function - try: import ply.yacc as yacc except ImportError: diff --git a/python/grass/temporal/temporal_raster_algebra.py b/python/grass/temporal/temporal_raster_algebra.py index 2f21394f953..7811ec90416 100644 --- a/python/grass/temporal/temporal_raster_algebra.py +++ b/python/grass/temporal/temporal_raster_algebra.py @@ -51,7 +51,6 @@ LexToken(FLOAT,2.45,1,42) """ -from __future__ import print_function try: import ply.yacc as yacc diff --git a/python/grass/temporal/temporal_raster_base_algebra.py b/python/grass/temporal/temporal_raster_base_algebra.py index 3a384998d4f..12daadf2f3b 100644 --- a/python/grass/temporal/temporal_raster_base_algebra.py +++ b/python/grass/temporal/temporal_raster_base_algebra.py @@ -40,9 +40,8 @@ LexToken(NAME,'B',1,23) """ -from __future__ import print_function - import copy + import grass.pygrass.modules as pymod from grass.exceptions import FatalError from .temporal_algebra import ( diff --git a/python/grass/temporal/temporal_topology_dataset_connector.py b/python/grass/temporal/temporal_topology_dataset_connector.py index b71a4b9a16e..f82265832b5 100644 --- a/python/grass/temporal/temporal_topology_dataset_connector.py +++ b/python/grass/temporal/temporal_topology_dataset_connector.py @@ -15,7 +15,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function import copy diff --git a/python/grass/temporal/temporal_vector_algebra.py b/python/grass/temporal/temporal_vector_algebra.py index ed39016c7e6..5e545e08574 100644 --- a/python/grass/temporal/temporal_vector_algebra.py +++ b/python/grass/temporal/temporal_vector_algebra.py @@ -41,8 +41,6 @@ LexToken(RPAREN,')',1,16) """ -from __future__ import print_function - try: import ply.yacc as yacc except ImportError: diff --git a/python/grass/temporal/unit_tests.py b/python/grass/temporal/unit_tests.py index 04a36757741..fd412ee6cf2 100644 --- a/python/grass/temporal/unit_tests.py +++ b/python/grass/temporal/unit_tests.py @@ -8,8 +8,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function - import copy from datetime import datetime import grass.script.core as core diff --git a/python/grass/temporal/univar_statistics.py b/python/grass/temporal/univar_statistics.py index b3c17c9ca4e..95cd4fd9868 100755 --- a/python/grass/temporal/univar_statistics.py +++ b/python/grass/temporal/univar_statistics.py @@ -18,7 +18,6 @@ :authors: Soeren Gebbert """ -from __future__ import print_function from multiprocessing import Pool from subprocess import PIPE diff --git a/python/libgrass_interface_generator/ctypesgen/main.py b/python/libgrass_interface_generator/ctypesgen/main.py index 54a9dae0ae1..b0fc8f76ef4 100644 --- a/python/libgrass_interface_generator/ctypesgen/main.py +++ b/python/libgrass_interface_generator/ctypesgen/main.py @@ -35,7 +35,9 @@ def option_callback_W(option, opt, value, parser): raise optparse.BadOptionError("not in '-Wl,' form: %s%s" % (opt, value)) opt = value[2:] if opt not in ["-L", "-R", "--rpath"]: - raise optparse.BadOptionError("-Wl option must be -L, -R" " or --rpath, not " + value[2:]) + raise optparse.BadOptionError( + "-Wl option must be -L, -R" " or --rpath, not " + value[2:] + ) # Push the linker option onto the list for further parsing. parser.rargs.insert(0, value) @@ -313,13 +315,8 @@ def main(givenargs=None): dest="output_language", metavar="LANGUAGE", default="py", - choices=("py", "py32", "py27", "py25", "json"), - help="Choose output language (`py'[default], `py32', `py27', `py25', or " - "`json'). The implementation for py32 does appear to be " - "compatible down to at least Python2.7.15. py25 and py27 are in " - "any case _not_ compatible with >= Python3. The default choice " - "(py) attempts to select `py32', `py27', or `py25' based on the " - "version of Python that runs this script.", + choices=("py", "json"), + help="Choose output language (`py'[default], or `json').", ) op.add_option( "-P", @@ -390,7 +387,9 @@ def main(givenargs=None): elif options.output_language == "json": printer = printer_json.WrapperPrinter else: - msgs.error_message("No such output language `" + options.output_language + "'", cls="usage") + msgs.error_message( + "No such output language `" + options.output_language + "'", cls="usage" + ) sys.exit(1) # Step 1: Parse diff --git a/python/libgrass_interface_generator/ctypesgen/parser/lex.py b/python/libgrass_interface_generator/ctypesgen/parser/lex.py index 52df51b58bd..52019189adf 100644 --- a/python/libgrass_interface_generator/ctypesgen/parser/lex.py +++ b/python/libgrass_interface_generator/ctypesgen/parser/lex.py @@ -42,12 +42,7 @@ import inspect # This tuple contains known string types -try: - # Python 2.6 - StringTypes = (types.StringType, types.UnicodeType) -except AttributeError: - # Python 3.0 - StringTypes = (str, bytes) +StringTypes = (str, bytes) # This regular expression is used to match valid token names _is_identifier = re.compile(r'^[a-zA-Z0-9_]+$') diff --git a/raster/r.sim/simlib/hydro.c b/raster/r.sim/simlib/hydro.c index cf21e760fc8..2acc8648d40 100644 --- a/raster/r.sim/simlib/hydro.c +++ b/raster/r.sim/simlib/hydro.c @@ -305,7 +305,7 @@ void main_loop(void) } if (zz[k][l] != UNDEF) { - if (infil != NULL) { /* infiltration part */ + if (inf[k][l] != UNDEF) { /* infiltration part */ if (inf[k][l] - si[k][l] > 0.) { decr = pow( diff --git a/raster/r.sim/simlib/input.c b/raster/r.sim/simlib/input.c index 081664d6e37..e9f41b88709 100644 --- a/raster/r.sim/simlib/input.c +++ b/raster/r.sim/simlib/input.c @@ -299,7 +299,6 @@ int input_data(void) int rows = my, cols = mx; /* my and mx are global variables */ int max_walkers; double unitconv = 0.000000278; /* mm/hr to m/s */ - int if_rain = 0; G_debug(1, "Running MAR 2011 version, started modifications on 20080211"); G_debug(1, "Reading input data"); @@ -328,39 +327,33 @@ int input_data(void) /* Rain: read rain map or use a single value for all cells */ if (rain != NULL) { si = read_double_raster_map(rows, cols, rain, unitconv); - if_rain = 1; } else if (rain_val >= 0.0) { /* If no value set its set to -999.99 */ si = create_double_matrix(rows, cols, rain_val * unitconv); - if_rain = 1; } else { si = create_double_matrix(rows, cols, (double)UNDEF); - if_rain = 0; } /* Update elevation map */ copy_matrix_undef_double_to_float_values(rows, cols, si, zz); - /* Load infiltration and traps if rain is present */ - if (if_rain == 1) { - /* Infiltration: read map or use a single value */ - if (infil != NULL) { - inf = read_double_raster_map(rows, cols, infil, unitconv); - } - else if (infil_val >= 0.0) { /* If no value set its set to -999.99 */ - inf = create_double_matrix(rows, cols, infil_val * unitconv); - } - else { - inf = create_double_matrix(rows, cols, (double)UNDEF); - } - - /* Traps */ - if (traps != NULL) - trap = read_float_raster_map(rows, cols, traps, 1.0); - else - trap = create_float_matrix(rows, cols, (double)UNDEF); + /* Infiltration: read map or use a single value */ + if (infil != NULL) { + inf = read_double_raster_map(rows, cols, infil, unitconv); + } + else if (infil_val >= 0.0) { /* If no value set its set to -999.99 */ + inf = create_double_matrix(rows, cols, infil_val * unitconv); } + else { + inf = create_double_matrix(rows, cols, (double)UNDEF); + } + + /* Traps */ + if (traps != NULL) + trap = read_float_raster_map(rows, cols, traps, 1.0); + else + trap = create_float_matrix(rows, cols, (double)UNDEF); if (detin != NULL) { dc = read_float_raster_map(rows, cols, detin, 1.0); diff --git a/rpm/grass-pkgconfig.patch b/rpm/grass-pkgconfig.patch index 233ec379d81..9ffc5a0f96b 100644 --- a/rpm/grass-pkgconfig.patch +++ b/rpm/grass-pkgconfig.patch @@ -1,10 +1,10 @@ -Index: grass-7.8.6/grass.pc.in -=================================================================== ---- grass-7.8.6.orig/grass.pc.in -+++ grass-7.8.6/grass.pc.in +diff --git a/grass.pc.in b/grass.pc.in +index 94ca57b65..aec77d095 100644 +--- a/grass.pc.in ++++ b/grass.pc.in @@ -2,13 +2,13 @@ # - # See also: grass@GRASS_VERSION_MAJOR@@GRASS_VERSION_MINOR@ --config + # See also: grass --config -prefix=@prefix@/grass-@GRASS_VERSION_MAJOR@.@GRASS_VERSION_MINOR@.@GRASS_VERSION_RELEASE@ -exec_prefix=@prefix@/grass-@GRASS_VERSION_MAJOR@.@GRASS_VERSION_MINOR@.@GRASS_VERSION_RELEASE@ diff --git a/rpm/grass.spec b/rpm/grass.spec index a72e71f3a17..a68453145bc 100644 --- a/rpm/grass.spec +++ b/rpm/grass.spec @@ -1,9 +1,9 @@ -%global shortver 82 +%global shortver 83 %global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) Name: grass -Version: 8.2.1 -Release: 1%{?dist} +Version: 8.3.0 +Release: 3%{?dist} Summary: GRASS GIS - Geographic Resources Analysis Support System %if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 @@ -29,7 +29,7 @@ URL: https://grass.osgeo.org Source0: https://grass.osgeo.org/%{name}%{shortver}/source/%{name}-%{version}.tar.gz # fix pkgconfig file -Patch0: grass-pkgconfig.patch +Patch 0: grass-pkgconfig.patch BuildRequires: bison %if %{with flexiblas} @@ -42,16 +42,12 @@ BuildRequires: gcc-c++ BuildRequires: desktop-file-utils BuildRequires: fftw-devel BuildRequires: flex -%if (0%{?rhel} > 6 || 0%{?fedora}) BuildRequires: freetype-devel -%endif BuildRequires: gdal-devel BuildRequires: geos-devel BuildRequires: gettext BuildRequires: laszip-devel -%if (0%{?rhel} > 6 || 0%{?fedora}) BuildRequires: libappstream-glib -%endif BuildRequires: libpng-devel BuildRequires: libtiff-devel BuildRequires: libXmu-devel @@ -62,9 +58,7 @@ BuildRequires: mariadb-connector-c-devel openssl-devel %else BuildRequires: mysql-devel %endif -%if (0%{?rhel} > 6 || 0%{?fedora}) BuildRequires: netcdf-devel -%endif BuildRequires: python3 %if 0%{?rhel} == 7 # EPEL7 @@ -72,16 +66,12 @@ BuildRequires: python%{python3_version_nodots}-numpy %else BuildRequires: python3-numpy %endif -%if 0%{?rhel} && 0%{?rhel} <= 7 +%if 0%{?rhel} && 0%{?rhel} == 7 BuildRequires: postgresql-devel %else BuildRequires: libpq-devel %endif BuildRequires: proj-devel -%if (0%{?rhel} <= 6 && !0%{?fedora}) -# argparse is included in python2.7+ but not python2.6 -BuildRequires: python-argparse -%endif %if 0%{?rhel} == 7 # EPEL7 BuildRequires: python%{python3_version_nodots}-dateutil @@ -89,12 +79,7 @@ BuildRequires: python%{python3_version_nodots}-dateutil BuildRequires: python3-dateutil %endif BuildRequires: python3-devel -%if (0%{?rhel} > 6 || 0%{?fedora}) BuildRequires: python3-pillow -%else -# EPEL6 -BuildRequires: python-imaging -%endif BuildRequires: PDAL BuildRequires: PDAL-libs BuildRequires: PDAL-devel @@ -122,23 +107,13 @@ Requires: python%{python3_version_nodots}-numpy %else Requires: python3-numpy %endif -%if 0%{?rhel} > 6 -# EPEL7/EPEL8 -#Requires: python3-matplotlib-wx -%else -Requires: python3-matplotlib -%endif %if 0%{?rhel} == 7 # EPEL7 Requires: python%{python3_version_nodots}-dateutil %else Requires: python3-dateutil %endif -%if 0%{?rhel} && 0%{?rhel} < 7 -Requires: wxPython -%else Requires: python3-wxpython4 -%endif Requires: PDAL Requires: PDAL-libs @@ -180,7 +155,7 @@ GRASS GIS development headers %prep %setup -q -%patch0 -p1 -b.libdir +%patch 0 -p1 -b.libdir # Correct mysql_config query sed -i -e 's/--libmysqld-libs/--libs/g' configure @@ -214,9 +189,7 @@ find -name \*.pl | xargs sed -i -e 's,#!/usr/bin/env perl,#!%{__perl},' --with-lapack-includes=%{_includedir}/flexiblas \ %endif --with-cairo \ -%if (0%{?rhel} > 6 || 0%{?fedora}) --with-freetype \ -%endif --with-nls \ --with-pdal \ --with-readline \ @@ -225,9 +198,7 @@ find -name \*.pl | xargs sed -i -e 's,#!/usr/bin/env perl,#!%{__perl},' --with-gdal=%{_bindir}/gdal-config \ --with-wxwidgets=%{_bindir}/wx-config \ --with-geos=%{_bindir}/geos-config \ -%if (0%{?rhel} > 6 || 0%{?fedora}) --with-netcdf=%{_bindir}/nc-config \ -%endif --with-mysql-includes=%{_includedir}/mysql \ %if (0%{?fedora} >= 27) --with-mysql-libs=%{_libdir} \ @@ -316,7 +287,7 @@ cat > %{buildroot}%{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf</dev/null || : @@ -352,7 +323,6 @@ fi %license AUTHORS COPYING GPL.TXT CHANGES %{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf %{_libdir}/%{name}%{shortver}/lib/*.so -%{_libdir}/%{name}%{shortver}/lib/*.a %dir %{_libdir}/%{name}%{shortver}/driver %dir %{_libdir}/%{name}%{shortver}/driver/db %{_libdir}/%{name}%{shortver}/driver/db/* @@ -368,6 +338,18 @@ fi %{_libdir}/%{name}%{shortver}/include %changelog +* Sun Aug 06 2023 Alexandre Detiste - 8.3.0-3 +- Remove support for RHEL6: Grass is now Python3 only + +* Thu Jul 20 2023 Fedora Release Engineering - 8.3.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Sun Jun 25 2023 Markus Neteler 8.3.0-1 +- New upstream version GRASS GIS 8.3.0 + +* Thu May 11 2023 Sandro Mani - 8.2.1-2 +- Rebuild (gdal) + * Sat Jan 21 2023 Markus Neteler 8.2.1-1 - New upstream version GRASS GIS 8.2.1 diff --git a/scripts/g.manual/g.manual.py b/scripts/g.manual/g.manual.py index 3abb7303860..582dd2e7a7c 100755 --- a/scripts/g.manual/g.manual.py +++ b/scripts/g.manual/g.manual.py @@ -48,12 +48,7 @@ import sys import os - -try: - from urllib2 import urlopen -except ImportError: - # python3 - from urllib.request import urlopen +from urllib.request import urlopen import webbrowser diff --git a/scripts/g.search.modules/g.search.modules.py b/scripts/g.search.modules/g.search.modules.py index 01701f04d8d..e96600e1495 100755 --- a/scripts/g.search.modules/g.search.modules.py +++ b/scripts/g.search.modules/g.search.modules.py @@ -63,17 +63,13 @@ # % guisection: Output # %end -from __future__ import print_function import os import sys from grass.script import core as grass from grass.exceptions import CalledModuleError -try: - import xml.etree.ElementTree as etree -except ImportError: - import elementtree.ElementTree as etree # Python <= 2.4 +import xml.etree.ElementTree as etree COLORIZE = False diff --git a/scripts/i.image.mosaic/i.image.mosaic.py b/scripts/i.image.mosaic/i.image.mosaic.py index 6ba5984bb6b..ddd89553b22 100755 --- a/scripts/i.image.mosaic/i.image.mosaic.py +++ b/scripts/i.image.mosaic/i.image.mosaic.py @@ -32,7 +32,6 @@ # %end # %option G_OPT_R_OUTPUT # %end -from __future__ import print_function import grass.script as gscript diff --git a/scripts/r.fillnulls/r.fillnulls.html b/scripts/r.fillnulls/r.fillnulls.html index 240d3259394..f2d7321d6b2 100644 --- a/scripts/r.fillnulls/r.fillnulls.html +++ b/scripts/r.fillnulls/r.fillnulls.html @@ -27,7 +27,7 @@

NOTES

may pay attention to below notes.

If interpolation fails, temporary raster and vector maps are left in place to allow -unfilled map hole (NULL area) identification and manual repair. +unfilled map holes (NULL areas) to be identified and manually repaired.

When using the default RST method, the algorithm is based diff --git a/scripts/r.fillnulls/r.fillnulls.py b/scripts/r.fillnulls/r.fillnulls.py index 7aff6204ccc..219f9dafa07 100755 --- a/scripts/r.fillnulls/r.fillnulls.py +++ b/scripts/r.fillnulls/r.fillnulls.py @@ -296,7 +296,16 @@ def main(): os.remove(cats_file_name) if len(cat_list) < 1: - grass.fatal(_("Input map has no holes. Check region settings.")) + # no holes found in current region + grass.run_command( + "g.copy", raster="%s,%sfilled" % (input, prefix), overwrite=True + ) + grass.warning( + _( + "Input map <%s> has no holes. Copying to output without modification." + ) + % (input,) + ) # GTC Hole is NULL area in a raster map grass.message(_("Processing %d map holes") % len(cat_list)) diff --git a/scripts/r.in.wms/wms_base.py b/scripts/r.in.wms/wms_base.py index c333ea8f9aa..71c2d1404f4 100644 --- a/scripts/r.in.wms/wms_base.py +++ b/scripts/r.in.wms/wms_base.py @@ -14,18 +14,12 @@ @author Stepan Turek (Mentor: Martin Landa) """ +import base64 import os +from http.client import HTTPException from math import ceil - -import base64 - -try: - from urllib2 import Request, urlopen, HTTPError - from httplib import HTTPException -except ImportError: - from urllib.request import Request, urlopen - from urllib.error import HTTPError - from http.client import HTTPException +from urllib.request import Request, urlopen +from urllib.error import HTTPError import grass.script as grass diff --git a/scripts/r.tileset/r.tileset.py b/scripts/r.tileset/r.tileset.py index 7a606f8878c..240a0911d58 100644 --- a/scripts/r.tileset/r.tileset.py +++ b/scripts/r.tileset/r.tileset.py @@ -106,7 +106,6 @@ # An array of points indexed by 0 for "x" and 4 for "y" + by number 0, 1, 2, and 3 # A reprojector [0] is name of source projection, [1] is name of destination # A projection - [0] is proj.4 text, [1] is scale -from __future__ import print_function import sys import tempfile diff --git a/scripts/v.in.geonames/v.in.geonames.py b/scripts/v.in.geonames/v.in.geonames.py index a202a1b8b72..401cca5c134 100755 --- a/scripts/v.in.geonames/v.in.geonames.py +++ b/scripts/v.in.geonames/v.in.geonames.py @@ -35,10 +35,7 @@ # %end import os -import sys -if sys.version_info.major == 2: - from io import open import grass.script as grass diff --git a/scripts/v.in.wfs/v.in.wfs.py b/scripts/v.in.wfs/v.in.wfs.py index 484db071b12..3d712fb6d32 100755 --- a/scripts/v.in.wfs/v.in.wfs.py +++ b/scripts/v.in.wfs/v.in.wfs.py @@ -94,15 +94,10 @@ from grass.script.utils import try_remove from grass.script import core as grass -try: - from urllib2 import urlopen, URLError, HTTPError - from urllib2 import build_opener, install_opener - from urllib2 import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler -except ImportError: - from urllib.request import urlopen - from urllib.request import build_opener, install_opener - from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler - from urllib.error import URLError, HTTPError +from urllib.request import urlopen +from urllib.request import build_opener, install_opener +from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler +from urllib.error import URLError, HTTPError def main(): diff --git a/temporal/t.info/t.info.py b/temporal/t.info/t.info.py index bfa604a59b9..24faee35940 100755 --- a/temporal/t.info/t.info.py +++ b/temporal/t.info/t.info.py @@ -53,7 +53,6 @@ # % description: Print information about the temporal DBMI interface and exit # % suppress_required: yes # %end -from __future__ import print_function import grass.script as grass diff --git a/temporal/t.list/t.list.py b/temporal/t.list/t.list.py index fba0933d6da..26be3c9b453 100755 --- a/temporal/t.list/t.list.py +++ b/temporal/t.list/t.list.py @@ -87,9 +87,8 @@ # % guisection: Formatting # %end -from __future__ import print_function -import grass.script as gscript import sys +import grass.script as gscript ############################################################################ diff --git a/temporal/t.rast.accumulate/t.rast.accumulate.py b/temporal/t.rast.accumulate/t.rast.accumulate.py index cd50b326340..7f9cc35f58a 100644 --- a/temporal/t.rast.accumulate/t.rast.accumulate.py +++ b/temporal/t.rast.accumulate/t.rast.accumulate.py @@ -152,10 +152,9 @@ # % key: r # % description: Reverse time direction in cyclic accumulation # %end -from __future__ import print_function +from copy import copy import grass.script as grass -from copy import copy ############################################################################ diff --git a/temporal/t.rast.neighbors/t.rast.neighbors.py b/temporal/t.rast.neighbors/t.rast.neighbors.py index c568ea5dd04..e4864695c9d 100755 --- a/temporal/t.rast.neighbors/t.rast.neighbors.py +++ b/temporal/t.rast.neighbors/t.rast.neighbors.py @@ -106,9 +106,8 @@ # % description: Ignore the current region settings and use the raster map regions # %end -from __future__ import print_function - import copy + import grass.script as grass diff --git a/temporal/t.rast.to.rast3/t.rast.to.rast3.py b/temporal/t.rast.to.rast3/t.rast.to.rast3.py index 6df3a2a3400..b11728488f2 100755 --- a/temporal/t.rast.to.rast3/t.rast.to.rast3.py +++ b/temporal/t.rast.to.rast3/t.rast.to.rast3.py @@ -35,11 +35,10 @@ # %option G_OPT_R3_OUTPUT # %end -from __future__ import print_function - import os -import grass.script as grass from datetime import datetime + +import grass.script as grass from grass.exceptions import CalledModuleError ############################################################################ diff --git a/temporal/t.register/t.register.py b/temporal/t.register/t.register.py index 344e11bf54f..0dcd3ab9bcd 100755 --- a/temporal/t.register/t.register.py +++ b/temporal/t.register/t.register.py @@ -149,13 +149,7 @@ def main(): # lazy imports import grass.temporal as tgis - try: - from builtins import StandardError - except ImportError: - # python 3 - StandardError = Exception - try: tgis.profile_function(main) - except StandardError as e: + except Exception as e: grass.fatal(e) diff --git a/temporal/t.topology/t.topology.py b/temporal/t.topology/t.topology.py index 1a71999917b..f531e096099 100755 --- a/temporal/t.topology/t.topology.py +++ b/temporal/t.topology/t.topology.py @@ -47,8 +47,6 @@ # % key: s # % description: Print spatio-temporal topological relationships and exit # %end -from __future__ import print_function - import grass.script as grass diff --git a/temporal/t.vect.db.select/t.vect.db.select.py b/temporal/t.vect.db.select/t.vect.db.select.py index fa5cbe7e963..5d5911efdc8 100755 --- a/temporal/t.vect.db.select/t.vect.db.select.py +++ b/temporal/t.vect.db.select/t.vect.db.select.py @@ -49,7 +49,6 @@ # %option G_OPT_T_WHERE # % key: t_where # %end -from __future__ import print_function import grass.script as grass diff --git a/utils/g.html2man/g.html2man.py b/utils/g.html2man/g.html2man.py index af72bfb5820..e134160d240 100755 --- a/utils/g.html2man/g.html2man.py +++ b/utils/g.html2man/g.html2man.py @@ -4,12 +4,7 @@ from ghtml import HTMLParser from ggroff import Formatter -try: - # Python 2 str - bytes version - from StringIO import StringIO -except ImportError: - # Python 3 str - unicode version - from io import StringIO +from io import StringIO entities = {"nbsp": " ", "bull": "*"} @@ -59,8 +54,7 @@ def main(): # write groff with open(sys.argv[2], "wb") as outf: - if sys.version_info.major >= 3: - s = s.encode("UTF-8") + s = s.encode("UTF-8") outf.write(s)