From e2d4fbabe5c04b38387333c13cb219975576ef71 Mon Sep 17 00:00:00 2001 From: Alexandre Detiste Date: Tue, 8 Aug 2023 17:13:54 +0200 Subject: [PATCH 1/9] Python: Remove code for Python 2, remove six from requirements (#3079) * remove unused code * removing six dependency from CI * remove reference to removed orderdict.py * python2: remove old py3-compat imports from __future__ * python2 removal: review all "except ImportError:" * python2 removal: update ctypesgen help text * python2 removal: Ctypes is a builtin now * rpm: remove reference to RHEL6 python2 packages --------- Co-authored-by: Anna Petrasova --- .github/workflows/apt.txt | 1 - .github/workflows/osgeo4w.yml | 4 +- .pylintrc | 2 +- .travis/linux.install.sh | 1 - REQUIREMENTS.md | 8 - Vagrantfile | 1 - docker/alpine/Dockerfile | 1 - gui/wxpython/.pylintrc | 2 +- gui/wxpython/animation/dialogs.py | 2 - gui/wxpython/animation/frame.py | 3 +- gui/wxpython/animation/nviztask.py | 7 +- gui/wxpython/animation/temporal_manager.py | 2 - gui/wxpython/animation/utils.py | 3 +- gui/wxpython/core/gcmd.py | 5 - gui/wxpython/core/gconsole.py | 10 +- gui/wxpython/core/gthread.py | 5 +- gui/wxpython/core/menutree.py | 8 +- gui/wxpython/core/settings.py | 2 - gui/wxpython/core/toolboxes.py | 38 +-- gui/wxpython/core/treemodel.py | 3 +- gui/wxpython/core/units.py | 3 +- gui/wxpython/core/utils.py | 3 +- gui/wxpython/core/workspace.py | 37 ++- gui/wxpython/dbmgr/base.py | 6 +- gui/wxpython/dbmgr/dialogs.py | 6 +- gui/wxpython/dbmgr/sqlbuilder.py | 13 +- gui/wxpython/dbmgr/vinfo.py | 46 +-- gui/wxpython/gcp/manager.py | 5 +- gui/wxpython/gmodeler/dialogs.py | 11 +- gui/wxpython/gmodeler/frame.py | 5 +- gui/wxpython/gmodeler/model.py | 20 +- gui/wxpython/gui_core/dialogs.py | 5 +- gui/wxpython/gui_core/forms.py | 20 +- gui/wxpython/gui_core/ghelp.py | 3 +- gui/wxpython/gui_core/gselect.py | 13 +- gui/wxpython/gui_core/mapdisp.py | 3 +- gui/wxpython/gui_core/pyedit.py | 5 +- gui/wxpython/gui_core/query.py | 5 +- gui/wxpython/gui_core/treeview.py | 2 - gui/wxpython/gui_core/widgets.py | 3 +- gui/wxpython/iclass/frame.py | 3 +- gui/wxpython/iclass/statistics.py | 3 +- gui/wxpython/iclass/toolbars.py | 2 - gui/wxpython/icons/icon.py | 8 +- gui/wxpython/image2target/ii2t_manager.py | 6 +- gui/wxpython/iscatt/controllers.py | 15 +- gui/wxpython/iscatt/core_c.py | 11 +- gui/wxpython/iscatt/dialogs.py | 10 +- gui/wxpython/iscatt/frame.py | 4 +- gui/wxpython/iscatt/iscatt_core.py | 27 +- gui/wxpython/iscatt/plots.py | 5 +- gui/wxpython/lmgr/giface.py | 2 - gui/wxpython/lmgr/pyshell.py | 2 - gui/wxpython/location_wizard/wizard.py | 7 +- gui/wxpython/mapdisp/main.py | 5 +- gui/wxpython/mapwin/base.py | 9 +- gui/wxpython/mapwin/buffered.py | 2 - gui/wxpython/modules/colorrules.py | 7 +- gui/wxpython/nviz/mapwindow.py | 3 +- gui/wxpython/nviz/tools.py | 35 ++- gui/wxpython/nviz/wxnviz.py | 5 +- gui/wxpython/photo2image/ip2i_manager.py | 5 +- gui/wxpython/psmap/frame.py | 5 +- gui/wxpython/psmap/instructions.py | 3 +- gui/wxpython/startup/locdownload.py | 2 - gui/wxpython/timeline/frame.py | 11 +- gui/wxpython/tools/build_modules_xml.py | 2 - gui/wxpython/tools/update_menudata.py | 7 +- gui/wxpython/tplot/frame.py | 17 +- gui/wxpython/vdigit/dialogs.py | 3 +- gui/wxpython/vdigit/mapwindow.py | 5 +- gui/wxpython/vdigit/preferences.py | 7 +- gui/wxpython/vdigit/wxdigit.py | 4 +- gui/wxpython/vdigit/wxdisplay.py | 7 +- gui/wxpython/vnet/dialogs.py | 35 +-- gui/wxpython/vnet/vnet_core.py | 19 +- gui/wxpython/vnet/vnet_data.py | 17 +- gui/wxpython/vnet/widgets.py | 17 +- gui/wxpython/web_services/dialogs.py | 23 +- gui/wxpython/web_services/widgets.py | 14 +- gui/wxpython/wxgui.py | 2 - gui/wxpython/wxplot/base.py | 3 +- gui/wxpython/wxplot/profile.py | 5 +- locale/grass_po_stats.py | 11 +- man/parser_standard_options.py | 14 +- mswindows/osgeo4w/setup.hint.tmpl | 2 +- python/.pylintrc | 2 +- python/grass/gunittest/case.py | 16 +- python/grass/gunittest/checkers.py | 6 +- python/grass/gunittest/invoker.py | 10 +- python/grass/gunittest/reporters.py | 6 +- .../testsuite/test_python_unittest.py | 1 - .../data/samplecode/testsuite/test_success.py | 2 - python/grass/gunittest/utils.py | 10 +- python/grass/pydispatch/dispatcher.py | 1 - python/grass/pydispatch/saferef.py | 9 +- python/grass/pygrass/Makefile | 2 +- python/grass/pygrass/gis/__init__.py | 9 - python/grass/pygrass/gis/region.py | 9 - python/grass/pygrass/modules/grid/grid.py | 9 - python/grass/pygrass/modules/grid/patch.py | 9 - python/grass/pygrass/modules/grid/split.py | 9 - python/grass/pygrass/modules/interface/env.py | 1 - .../grass/pygrass/modules/interface/flag.py | 9 - .../grass/pygrass/modules/interface/module.py | 21 +- .../pygrass/modules/interface/parameter.py | 9 - .../grass/pygrass/modules/interface/read.py | 9 - .../modules/interface/testsuite/test_flag.py | 1 - .../interface/testsuite/test_parameter.py | 1 - .../pygrass/modules/interface/typedict.py | 15 +- python/grass/pygrass/modules/shortcuts.py | 9 - python/grass/pygrass/orderdict.py | 261 ------------------ python/grass/pygrass/raster/__init__.py | 9 - python/grass/pygrass/raster/abstract.py | 9 - python/grass/pygrass/tests/benchmark.py | 9 - python/grass/pygrass/tests/set_mapset.py | 9 - python/grass/pygrass/vector/__init__.py | 2 - python/grass/pygrass/vector/table.py | 31 +-- .../pygrass/vector/testsuite/test_table.py | 6 +- python/grass/script/__init__.py | 1 - python/grass/script/array.py | 2 - python/grass/script/core.py | 1 - python/grass/script/db.py | 1 - python/grass/script/raster.py | 8 +- python/grass/script/raster3d.py | 1 - python/grass/script/task.py | 18 +- python/grass/script/testsuite/test_utils.py | 31 +-- python/grass/script/utils.py | 12 +- python/grass/script/vector.py | 5 +- python/grass/temporal/__init__.py | 2 - python/grass/temporal/abstract_map_dataset.py | 2 - .../temporal/abstract_space_time_dataset.py | 1 - python/grass/temporal/base.py | 1 - python/grass/temporal/core.py | 11 +- python/grass/temporal/datetime_math.py | 5 +- python/grass/temporal/metadata.py | 1 - python/grass/temporal/sampling.py | 1 - python/grass/temporal/spatial_extent.py | 1 - .../spatial_topology_dataset_connector.py | 1 - .../temporal/spatio_temporal_relationships.py | 1 - python/grass/temporal/temporal_algebra.py | 8 +- python/grass/temporal/temporal_extent.py | 1 - python/grass/temporal/temporal_granularity.py | 1 - python/grass/temporal/temporal_operator.py | 2 - .../temporal/temporal_raster3d_algebra.py | 2 - .../grass/temporal/temporal_raster_algebra.py | 1 - .../temporal/temporal_raster_base_algebra.py | 3 +- .../temporal_topology_dataset_connector.py | 1 - .../grass/temporal/temporal_vector_algebra.py | 2 - python/grass/temporal/unit_tests.py | 2 - python/grass/temporal/univar_statistics.py | 1 - .../ctypesgen/main.py | 17 +- .../ctypesgen/parser/lex.py | 7 +- rpm/grass.spec | 9 - scripts/g.manual/g.manual.py | 7 +- scripts/g.search.modules/g.search.modules.py | 6 +- scripts/i.image.mosaic/i.image.mosaic.py | 1 - scripts/r.in.wms/wms_base.py | 14 +- scripts/r.tileset/r.tileset.py | 1 - scripts/v.in.geonames/v.in.geonames.py | 3 - scripts/v.in.wfs/v.in.wfs.py | 13 +- temporal/t.info/t.info.py | 1 - temporal/t.list/t.list.py | 3 +- .../t.rast.accumulate/t.rast.accumulate.py | 3 +- temporal/t.rast.neighbors/t.rast.neighbors.py | 3 +- temporal/t.rast.to.rast3/t.rast.to.rast3.py | 5 +- temporal/t.register/t.register.py | 8 +- temporal/t.topology/t.topology.py | 2 - temporal/t.vect.db.select/t.vect.db.select.py | 1 - utils/g.html2man/g.html2man.py | 10 +- 170 files changed, 328 insertions(+), 1171 deletions(-) delete mode 100644 python/grass/pygrass/orderdict.py 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/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/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/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/rpm/grass.spec b/rpm/grass.spec index a72e71f3a17..42858c67ea5 100644 --- a/rpm/grass.spec +++ b/rpm/grass.spec @@ -78,10 +78,6 @@ BuildRequires: postgresql-devel 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 +85,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 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.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) From ead8e8dd3a5e5db4387e111c5f1ac31f1cd16016 Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Tue, 8 Aug 2023 18:18:00 +0200 Subject: [PATCH 2/9] CITATION.cff: make license entry SPDX conform (#3115) Use proper short code from https://spdx.org: https://spdx.org/licenses/GPL-2.0-or-later.html --- CITATION.cff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index 340a17784c6..667d1bbcde8 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -106,7 +106,7 @@ authors: 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 From ebfa95db6a15cea8875c7845d8b9ae908e7b1232 Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Wed, 9 Aug 2023 23:26:20 +0200 Subject: [PATCH 3/9] pkg: remove support for RHEL6 in grass.spec (#3117) Use the latest grass.spec from Fedora Git repo, https://src.fedoraproject.org/rpms/grass/blob/rawhide/f/grass.spec Fixes #3114 Co-authored-by: @a-detiste --- rpm/grass-pkgconfig.patch | 10 ++++----- rpm/grass.spec | 47 ++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 33 deletions(-) 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 42858c67ea5..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,7 +66,7 @@ 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 @@ -113,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 @@ -171,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 @@ -205,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 \ @@ -216,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} \ @@ -307,7 +287,7 @@ cat > %{buildroot}%{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf</dev/null || : @@ -343,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/* @@ -359,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 From aa8d19a1c46adcc226b6f21021112e52e22a4f17 Mon Sep 17 00:00:00 2001 From: Anna Petrasova Date: Thu, 10 Aug 2023 12:26:45 -0400 Subject: [PATCH 4/9] r.sim: fix previously ignored infil_value (#3111) --- raster/r.sim/simlib/hydro.c | 2 +- raster/r.sim/simlib/input.c | 37 +++++++++++++++---------------------- 2 files changed, 16 insertions(+), 23 deletions(-) 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); From 43b34097fcb9ed0d4c61429363ff08df6707ed78 Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Mon, 14 Aug 2023 16:51:14 +0200 Subject: [PATCH 5/9] r.fillnulls: proceed if no holes present (RST method) (#3122) Proceed if no holes present also for `rst` method - now all methods behave the same. In case no holes are in the current region of the raster input map the map is copied over and no fatal error is issues (same for all methods). Fixes #2986 --- scripts/r.fillnulls/r.fillnulls.html | 2 +- scripts/r.fillnulls/r.fillnulls.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) 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)) From 5c489c96b61cf205a47d68baf57efa556d1ff4e0 Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Tue, 15 Aug 2023 09:02:36 -0400 Subject: [PATCH 6/9] RFC: Version Numbering is adopted (#3120) In May, several people agreed to merge the finalized RFC in #2357 before it was adopted in a face-to-face meeting. In the meantime, the RFC was adopted. This updates the status. Adoption email: https://lists.osgeo.org/pipermail/grass-psc/2023-June/002724.html --- doc/development/rfc/version_numbering.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From b500bb04edc2bebba669c3b9cdfbaa00835a9ecf Mon Sep 17 00:00:00 2001 From: Ondrej Pesek Date: Tue, 15 Aug 2023 15:30:20 +0200 Subject: [PATCH 7/9] doc examples: remove a call of non-existent function raw_input() (#3124) in Python3, it was replaced by input() --- doc/python/raster_example_ctypes.py | 2 +- doc/python/vector_example_ctypes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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("") From 0f13c4d70c9c9cbb46f164257771465cb49f612e Mon Sep 17 00:00:00 2001 From: Markus Neteler Date: Tue, 15 Aug 2023 22:13:34 +0200 Subject: [PATCH 8/9] docs: fix syntax of CITATION.cff file (#3123) Syntax errors fixed (needed for Zenodo.org auto-upload and also in general). Validated successfully: ``` cffconvert --validate Citation metadata are valid according to schema version 1.2.0. ``` with ``` cffconvert --version 3.0.0a0 ``` --- CITATION.cff | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 667d1bbcde8..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,7 +107,6 @@ authors: - given-names: Hamish family-names: Bowman email: hamish_b@yahoo.com - repository-code: https://github.com/OSGeo/grass license: GPL-2.0-or-later doi: 10.5281/zenodo.4621728 @@ -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 From 14d056a42dfef48361289aefafea5751b475f2e7 Mon Sep 17 00:00:00 2001 From: Carmen Tawalika Date: Fri, 18 Aug 2023 16:30:00 +0200 Subject: [PATCH 9/9] docker: CI update and simplification (#3075) * simplify docker gh workflow (see PR for details) --- .github/workflows/docker.yml | 158 +++++------------------------------ 1 file changed, 23 insertions(+), 135 deletions(-) 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 }}