From 779912fdb94fa7fc376553894c4f16923a2e520b Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 10:11:51 +0200 Subject: [PATCH 01/17] ruff 019 unnecessary key check --- gui/wxpython/core/menutree.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/wxpython/core/menutree.py b/gui/wxpython/core/menutree.py index a418ffcd98a..886467b046e 100644 --- a/gui/wxpython/core/menutree.py +++ b/gui/wxpython/core/menutree.py @@ -192,9 +192,9 @@ def printStrings(node, fh): if node.label and not node.data: fh.write(" _(%r),\n" % str(node.label)) if node.data: - if "label" in node.data and node.data["label"]: + if node.data.get("label"): fh.write(" _(%r),\n" % str(node.data["label"])) - if "description" in node.data and node.data["description"]: + if node.data.get("description"): fh.write(" _(%r),\n" % str(node.data["description"])) for child in node.children: printStrings(node=child, fh=fh) From e6d66cb0ee4b907f9acdc136185b635346799fa3 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 10:13:13 +0200 Subject: [PATCH 02/17] ruff 019 unnecessary key check --- gui/wxpython/core/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py index 127694280c0..58523066ae0 100644 --- a/gui/wxpython/core/utils.py +++ b/gui/wxpython/core/utils.py @@ -193,7 +193,7 @@ def GetLayerNameFromCmd(dcmd, fullyQualified=False, param=None, layerType=None): if p == "layer": continue dcmd[i] = p + "=" + v - if i in mapsets and mapsets[i]: + if mapsets.get(i): dcmd[i] += "@" + mapsets[i] maps = [] From abda11936158a82af20746baf60173a9e6980d41 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 10:15:11 +0200 Subject: [PATCH 03/17] ruff 019 unnecessary key check --- python/grass/pygrass/modules/interface/parameter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/grass/pygrass/modules/interface/parameter.py b/python/grass/pygrass/modules/interface/parameter.py index 7ced719de2c..47a5bf308c2 100644 --- a/python/grass/pygrass/modules/interface/parameter.py +++ b/python/grass/pygrass/modules/interface/parameter.py @@ -201,7 +201,7 @@ def __init__(self, xparameter=None, diz=None): # # default # - if "default" in diz and diz["default"]: + if diz.get("default"): if self.multiple or self.keydescvalues: self.default = [self.type(v) for v in diz["default"].split(",")] else: @@ -214,7 +214,7 @@ def __init__(self, xparameter=None, diz=None): # # gisprompt # - if "gisprompt" in diz and diz["gisprompt"]: + if diz.get("gisprompt"): self.typedesc = diz["gisprompt"].get("prompt", "") self.input = diz["gisprompt"]["age"] != "new" else: From 250a57116496611951eda86075d4594fe927be53 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 10:15:39 +0200 Subject: [PATCH 04/17] ruff 019 unnecessary key check --- gui/wxpython/gmodeler/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index f8e3525cac6..16032d727cb 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -1272,7 +1272,7 @@ def _properties(self): % (" " * self.indent, self.properties["author"]) ) - if "overwrite" in self.properties and self.properties["overwrite"]: + if self.properties.get("overwrite"): self.fd.write('%s\n' % (" " * self.indent)) self.indent -= 4 self.fd.write("%s\n" % (" " * self.indent)) From 6dfc90e0c66cd81df6268a44ac5171a211cda062 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:10:48 +0200 Subject: [PATCH 05/17] PTH104 os rename --- gui/wxpython/image2target/ii2t_gis_set.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/gui/wxpython/image2target/ii2t_gis_set.py b/gui/wxpython/image2target/ii2t_gis_set.py index d31d9eaa48e..8d21fe10914 100644 --- a/gui/wxpython/image2target/ii2t_gis_set.py +++ b/gui/wxpython/image2target/ii2t_gis_set.py @@ -721,9 +721,8 @@ def RenameMapset(self, event): ) else: try: - os.rename( - os.path.join(self.gisdbase, location, mapset), - os.path.join(self.gisdbase, location, newmapset), + Path(self.gisdbase, location, mapset).rename( + Path(self.gisdbase, location, newmapset) ) self.OnSelectLocation(None) self.lbmapsets.SetSelection(self.listOfMapsets.index(newmapset)) @@ -767,9 +766,8 @@ def RenameLocation(self, event): ) else: try: - os.rename( - os.path.join(self.gisdbase, location), - os.path.join(self.gisdbase, newlocation), + Path(self.gisdbase, location).rename( + Path(self.gisdbase, newlocation) ) self.UpdateLocations(self.gisdbase) self.lblocations.SetSelection( From 3e17a9ed51a1730c3defa704bbd9da0cb3e87b21 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:11:16 +0200 Subject: [PATCH 06/17] PTH104 os rename --- gui/wxpython/rlisetup/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/wxpython/rlisetup/frame.py b/gui/wxpython/rlisetup/frame.py index e8b5cfc2cbe..84e712255c5 100644 --- a/gui/wxpython/rlisetup/frame.py +++ b/gui/wxpython/rlisetup/frame.py @@ -280,7 +280,7 @@ def OnRename(self, event): if dlg.ShowModal() == wx.ID_OK: res = dlg.GetValue() newname = "%s%s%s" % (self.rlipath, os.sep, res) - os.rename(os.path.join(self.rlipath, confile), newname) + Path(self.rlipath, confile).rename(newname) self.listfiles = self.ListFiles() self.listfileBox.Clear() self.listfileBox.Set(self.listfiles) From f3a84ceff4c4ba0815894fb9a5530410b6eb32f8 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:11:34 +0200 Subject: [PATCH 07/17] PTH104 os rename --- man/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/build.py b/man/build.py index eeac778e111..b7767b41a6c 100644 --- a/man/build.py +++ b/man/build.py @@ -81,7 +81,7 @@ def replace_file(name): os.remove(name) except OSError: pass - os.rename(temp, name) + Path(temp).rename(name) def copy_file(src, dst): From f2223fa543e8622c54af9c4adde5ff5c1a8fac16 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:11:54 +0200 Subject: [PATCH 08/17] PTH104 os rename --- man/build_rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/build_rest.py b/man/build_rest.py index d308d45ee7b..a74eee0e525 100644 --- a/man/build_rest.py +++ b/man/build_rest.py @@ -299,7 +299,7 @@ def replace_file(name): os.remove(name) except OSError: pass - os.rename(temp, name) + Path(temp).rename(name) def copy_file(src, dst): From dc30766d8602c66b66076ff30392dbf73f5d8e91 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:12:21 +0200 Subject: [PATCH 09/17] PTH104 os rename --- python/grass/grassdb/manage.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/python/grass/grassdb/manage.py b/python/grass/grassdb/manage.py index 0187579167d..15e4ed0ba10 100644 --- a/python/grass/grassdb/manage.py +++ b/python/grass/grassdb/manage.py @@ -41,15 +41,13 @@ def rename_mapset(database, location, old_name, new_name): """Rename mapset from *old_name* to *new_name*""" if old_name == "PERMANENT": raise ValueError(_("Mapset PERMANENT cannot be renamed")) - location_path = os.path.join(database, location) - os.rename( - os.path.join(location_path, old_name), os.path.join(location_path, new_name) - ) + location_path = Path(database, location) + (location_path / old_name).rename(location_path / new_name) def rename_location(database, old_name, new_name): """Rename location from *old_name* to *new_name*""" - os.rename(os.path.join(database, old_name), os.path.join(database, new_name)) + Path(database, old_name).rename(Path(database, new_name)) class MapsetPath: From 8a5e81a361965e1e5c49c8b1abc24e14a5d623a9 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:12:43 +0200 Subject: [PATCH 10/17] PTH104 os rename --- python/grass/gunittest/reporters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/grass/gunittest/reporters.py b/python/grass/gunittest/reporters.py index fde3d6800a6..43f6440f84b 100644 --- a/python/grass/gunittest/reporters.py +++ b/python/grass/gunittest/reporters.py @@ -69,7 +69,7 @@ def replace_in_file(file_path, pattern, repl) -> None: os.remove(file_path) # replace old file by new file # TODO: this can fail in some (random) cases on MS Windows - os.rename(tmp_file_path, file_path) + Path(tmp_file_path).rename(file_path) class NoopFileAnonymizer: From aa2cd64504503de1de22aec098c1e2117114f31f Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:13:09 +0200 Subject: [PATCH 11/17] PTH104 os rename --- scripts/g.extension/g.extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/g.extension/g.extension.py b/scripts/g.extension/g.extension.py index ab1428e5934..dda5216d647 100755 --- a/scripts/g.extension/g.extension.py +++ b/scripts/g.extension/g.extension.py @@ -477,7 +477,7 @@ def replace_shebang_win(python_file): out_file.write(new_line) os.remove(python_file) # remove original - os.rename(tmp_name, python_file) # rename temp to original name + Path(tmp_name).rename(python_file) # rename temp to original name def urlretrieve(url, filename, *args, **kwargs): From e28efd04ca5a49477e000f8947c4c992aa6e6510 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 11:13:32 +0200 Subject: [PATCH 12/17] PTH104 os rename --- scripts/r.in.srtm/r.in.srtm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/r.in.srtm/r.in.srtm.py b/scripts/r.in.srtm/r.in.srtm.py index b05d8016b8c..f89041f698f 100755 --- a/scripts/r.in.srtm/r.in.srtm.py +++ b/scripts/r.in.srtm/r.in.srtm.py @@ -217,7 +217,7 @@ def main(): gs.fatal(_("Unable to unzip file.")) gs.message(_("Converting input file to BIL...")) - os.rename(hgtfile, bilfile) + Path(hgtfile).rename(bilfile) north = tile[0] ll_latitude = int(tile[1:3]) From 80a0bbccab2180a6475dfa8e7eaa1f391201ce82 Mon Sep 17 00:00:00 2001 From: KBlumentrath Date: Tue, 14 Jul 2026 15:47:37 +0200 Subject: [PATCH 13/17] checks: Remove fixed rules from ruff ignore list --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b4a922f7fb5..b0f86eae7e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -265,7 +265,6 @@ ignore = [ "PLW3201", # bad-dunder-method-name "PTH100", # os-path-abspath "PTH101", # os-chmod - "PTH104", # os-rename "PTH106", # os-rmdir "PTH107", # os-remove "PTH108", # os-unlink @@ -282,7 +281,6 @@ ignore = [ "RUF005", # collection-literal-concatenation "RUF012", # mutable-class-default "RUF015", # unnecessary-iterable-allocation-for-first-element - "RUF019", # unnecessary-key-check "RUF050", # unnecessary-if "RUF059", # unused-unpacked-variable "RUF067", # non-empty-init-module From 06b5abe30d410041fab0c134718a29880e83461f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:03:32 +0000 Subject: [PATCH 14/17] python: Add typing for investigated functions and dependent ones --- python/grass/pygrass/modules/interface/flag.py | 14 +++++++++++++- python/grass/pygrass/modules/interface/module.py | 8 +++++--- .../grass/pygrass/modules/interface/parameter.py | 12 +++++++++++- python/grass/pygrass/modules/interface/read.py | 12 ++++++++++-- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/python/grass/pygrass/modules/interface/flag.py b/python/grass/pygrass/modules/interface/flag.py index 7c12849c1a5..3123683a286 100644 --- a/python/grass/pygrass/modules/interface/flag.py +++ b/python/grass/pygrass/modules/interface/flag.py @@ -1,7 +1,15 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + from grass.pygrass.modules.interface.docstring import docstring_property from grass.pygrass.modules.interface import read +if TYPE_CHECKING: + from xml.etree.ElementTree import Element + + class Flag: """The Flag object store all information about a flag of module. @@ -21,7 +29,11 @@ class Flag: True """ - def __init__(self, xflag=None, diz=None): + def __init__( + self, + xflag: Element[str] | None = None, + diz: dict[str, str | bool | None] | None = None, + ): self.value = False diz = read.element2dict(xflag) if xflag is not None else diz self.name = diz["name"] diff --git a/python/grass/pygrass/modules/interface/module.py b/python/grass/pygrass/modules/interface/module.py index fda610d6e40..def9638217e 100644 --- a/python/grass/pygrass/modules/interface/module.py +++ b/python/grass/pygrass/modules/interface/module.py @@ -587,7 +587,9 @@ def __init__(self, cmd, *args, **kargs): # # extract parameters from the xml # - self.params_list = [Parameter(p) for p in tree.findall("parameter")] + self.params_list: list[Parameter] = [ + Parameter(xparameter=p) for p in tree.findall("parameter") + ] self.inputs = TypeDict(Parameter) self.outputs = TypeDict(Parameter) self.required = [] @@ -604,7 +606,7 @@ def __init__(self, cmd, *args, **kargs): # # extract flags from the xml # - flags_list = [Flag(f) for f in tree.findall("flag")] + flags_list = [Flag(xflag=f) for f in tree.findall("flag")] self.flags = TypeDict(Flag) for flag in flags_list: self.flags[flag.name] = flag @@ -620,7 +622,7 @@ def __init__(self, cmd, *args, **kargs): self.stdin = None self.stdout_ = None self.stderr_ = None - diz = { + diz: dict[str, str | bool | list | tuple | None] = { "name": "stdin", "required": False, "multiple": False, diff --git a/python/grass/pygrass/modules/interface/parameter.py b/python/grass/pygrass/modules/interface/parameter.py index 47a5bf308c2..beab3cd0142 100644 --- a/python/grass/pygrass/modules/interface/parameter.py +++ b/python/grass/pygrass/modules/interface/parameter.py @@ -4,11 +4,17 @@ @author: pietro """ +from __future__ import annotations import re +from typing import TYPE_CHECKING + from grass.pygrass.modules.interface.docstring import docstring_property from grass.pygrass.modules.interface.read import GETTYPE, element2dict, DOC +if TYPE_CHECKING: + from xml.etree.ElementTree import Element + def _check_value(param, value): """Function to check the correctness of a value and @@ -153,7 +159,11 @@ class Parameter: ... """ # noqa: E501 - def __init__(self, xparameter=None, diz=None): + def __init__( + self, + xparameter: Element[str] | None = None, + diz: dict[str, str | bool | float | list | tuple | None] | None = None, + ): self._value = None self._rawvalue = None self.min = None diff --git a/python/grass/pygrass/modules/interface/read.py b/python/grass/pygrass/modules/interface/read.py index 4276586a416..1e64a935bee 100644 --- a/python/grass/pygrass/modules/interface/read.py +++ b/python/grass/pygrass/modules/interface/read.py @@ -4,6 +4,14 @@ @author: pietro """ +from __future__ import annotations + +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from xml.etree.ElementTree import Element + def do_nothing(p): return p @@ -56,7 +64,7 @@ def read_keydesc(par): } -def element2dict(xparameter): +def element2dict(xparameter: Element[str]) -> dict: diz = dict(xparameter.items()) for p in xparameter: if p.tag in GETFROMTAG: @@ -67,7 +75,7 @@ def element2dict(xparameter): # dictionary used to create docstring for the objects -DOC = { +DOC: dict[str, str] = { # ------------------------------------------------------------ # head "head": """{cmd_name}({cmd_params}) From 5eea566102c9702f1a3752f3a4e56a0b25d441e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:11:28 +0000 Subject: [PATCH 15/17] python: Add typing for investigated functions and dependent ones --- .../grass/pygrass/modules/interface/read.py | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/python/grass/pygrass/modules/interface/read.py b/python/grass/pygrass/modules/interface/read.py index 1e64a935bee..a9640798f28 100644 --- a/python/grass/pygrass/modules/interface/read.py +++ b/python/grass/pygrass/modules/interface/read.py @@ -10,36 +10,47 @@ if TYPE_CHECKING: + from collections.abc import Callable + from typing import TypeVar, Never from xml.etree.ElementTree import Element + T = TypeVar(name="T") -def do_nothing(p): + +def do_nothing(p: T) -> T: return p -def get_None(p): +def get_None(p: Never) -> None: return None -def get_dict(p): +def get_dict(p: Element[str]) -> dict[str, str]: return dict(p.items()) -def get_values(p): - return [e.text.strip() for e in p.findall("value/name")] +def get_values(p: Element[str]) -> list[str]: + return [e.text.strip() for e in p.findall(path="value/name")] -def read_text(p): +def read_text(p: Element[str]) -> str: return p.text.strip() -def read_keydesc(par): - name = par.text.strip() - items = [e.text.strip() for e in par.findall("item")] +def read_keydesc(par: Element[str]) -> tuple[str, tuple[str, ...] | None]: + name: str = par.text.strip() + items: list[str] = [e.text.strip() for e in par.findall("item")] return name, tuple(items) if len(items) > 1 else None -GETFROMTAG = { +GETFROMTAG: dict[ + str, + Callable[Element[str], str] + | Callable[Element[str], tuple[str, tuple[str, ...] | None]] + | Callable[Element[str], dict[str, str]] + | Callable[Element[str], list[str]] + | Callable[Never, None], +] = { "description": read_text, "keydesc": read_keydesc, "gisprompt": get_dict, @@ -64,8 +75,8 @@ def read_keydesc(par): } -def element2dict(xparameter: Element[str]) -> dict: - diz = dict(xparameter.items()) +def element2dict(xparameter: Element[str]): + diz: dict[str, str] = dict(xparameter.items()) for p in xparameter: if p.tag in GETFROMTAG: diz[p.tag] = GETFROMTAG[p.tag](p) From 13b9ff894a4488cf4ad59e34f7e38cca7c993fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Wed, 15 Jul 2026 09:34:02 +0000 Subject: [PATCH 16/17] python: Add typing for investigated functions and dependent ones --- gui/wxpython/gmodeler/model.py | 10 ++++++++-- gui/wxpython/gmodeler/panels.py | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py index 16032d727cb..56a0f4a9bd4 100644 --- a/gui/wxpython/gmodeler/model.py +++ b/gui/wxpython/gmodeler/model.py @@ -17,6 +17,9 @@ @author Ondrej Pesek """ +from __future__ import annotations +from typing import TYPE_CHECKING + import os import getpass import copy @@ -54,6 +57,9 @@ from grass.script import task as gtask +if TYPE_CHECKING: + from typing_extensions import Writer + class Model: """Class representing the model""" @@ -1192,8 +1198,8 @@ def _processComments(self): class WriteModelFile: """Generic class for writing model file""" - def __init__(self, fd, model): - self.fd = fd + def __init__(self, fd: Writer[str], model: Model): + self.fd = fd # Should be io.Writer when Python 3.14 is possible to use self.model = model self.properties = model.GetProperties() self.variables = model.GetVariables() diff --git a/gui/wxpython/gmodeler/panels.py b/gui/wxpython/gmodeler/panels.py index fabe132637b..62bc506019c 100644 --- a/gui/wxpython/gmodeler/panels.py +++ b/gui/wxpython/gmodeler/panels.py @@ -18,6 +18,8 @@ @author Python exports Ondrej Pesek """ +from __future__ import annotations + import os import time import stat @@ -147,7 +149,7 @@ def __init__( ) self.canvas.SetCursor(self.cursors["default"]) - self.model = Model(giface=self._giface, canvas=self.canvas) + self.model: Model = Model(giface=self._giface, canvas=self.canvas) self.variablePanel = VariablePanel(parent=self) From 750e00eb10d2158a32a0b6369cfd2e2083f9c7b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Wed, 15 Jul 2026 10:09:20 +0000 Subject: [PATCH 17/17] python: Add typing for investigated functions and dependent ones --- gui/wxpython/core/menutree.py | 14 +++++++++++--- python/grass/pygrass/modules/interface/read.py | 12 ++++++------ python/grass/script/core.py | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/gui/wxpython/core/menutree.py b/gui/wxpython/core/menutree.py index 886467b046e..8f4d1b2d158 100644 --- a/gui/wxpython/core/menutree.py +++ b/gui/wxpython/core/menutree.py @@ -33,11 +33,15 @@ @author Anna Petrasova """ +from __future__ import annotations + import os import sys import copy import xml.etree.ElementTree as ET +from typing import TYPE_CHECKING + import wx from core.treemodel import TreeModel, ModuleNode @@ -50,8 +54,12 @@ if not os.getenv("GISBASE"): sys.exit("GRASS is not running. Exiting...") +if TYPE_CHECKING: + from typing_extensions import Writer # TODO: change the system to remove strange derived classes + + class MenuTreeModelBuilder: """Abstract menu data class""" @@ -69,7 +77,7 @@ def __init__(self, filename, expandAddons=True, message_handler=GError): message_handler(message) clearToolboxMessages() - self.model = TreeModel(ModuleNode) + self.model: TreeModel = TreeModel(ModuleNode) self._createModel(xmlTree) def _createModel(self, xmlTree): @@ -152,7 +160,7 @@ def PrintTree(self, fh): for child in self.model.root.children: printTree(node=child, fh=fh) - def PrintStrings(self, fh): + def PrintStrings(self, fh: Writer[str]): """Print menu strings to file (used for localization) :param fh: file descriptor @@ -186,7 +194,7 @@ def printTree(node, fh, indent=0): printTree(node=child, fh=fh, indent=indent + 2) -def printStrings(node, fh): +def printStrings(node, fh: Writer[str]): # node.label - with module in brackets # node.data['label'] - without module in brackets if node.label and not node.data: diff --git a/python/grass/pygrass/modules/interface/read.py b/python/grass/pygrass/modules/interface/read.py index a9640798f28..40e8d0a8e72 100644 --- a/python/grass/pygrass/modules/interface/read.py +++ b/python/grass/pygrass/modules/interface/read.py @@ -45,11 +45,11 @@ def read_keydesc(par: Element[str]) -> tuple[str, tuple[str, ...] | None]: GETFROMTAG: dict[ str, - Callable[Element[str], str] - | Callable[Element[str], tuple[str, tuple[str, ...] | None]] - | Callable[Element[str], dict[str, str]] - | Callable[Element[str], list[str]] - | Callable[Never, None], + Callable[[Element[str]], str] + | Callable[[Element[str]], tuple[str, tuple[str, ...] | None]] + | Callable[[Element[str]], dict[str, str]] + | Callable[[Element[str]], list[str]] + | Callable[[Never], None], ] = { "description": read_text, "keydesc": read_keydesc, @@ -76,7 +76,7 @@ def read_keydesc(par: Element[str]) -> tuple[str, tuple[str, ...] | None]: def element2dict(xparameter: Element[str]): - diz: dict[str, str] = dict(xparameter.items()) + diz: dict[str, str | bool | float | list | tuple | None] = dict(xparameter.items()) for p in xparameter: if p.tag in GETFROMTAG: diz[p.tag] = GETFROMTAG[p.tag](p) diff --git a/python/grass/script/core.py b/python/grass/script/core.py index a36b2fa7cc5..7dee4424dfe 100644 --- a/python/grass/script/core.py +++ b/python/grass/script/core.py @@ -1569,7 +1569,7 @@ def del_temp_region(): # interface to g.findfile -def find_file(name, element="cell", mapset=None, env=None): +def find_file(name: str, element: str = "cell", mapset: str | None = None, env=None): """Returns the output from running g.findfile as a dictionary.