From acbf9a52f6f1480a4fc49b9d2f4a50b0c40d8c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edouard=20Choini=C3=A8re?= <27212526+echoix@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:30:46 +0000 Subject: [PATCH] gui: Fix possibly indexing None in psmap.utils.convertRGB Fully type check and annotate convertRGB() and the grass.script.core.parse_color() functions --- gui/wxpython/psmap/utils.py | 23 ++++++++++++++++------- python/grass/script/core.py | 10 ++++++---- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/gui/wxpython/psmap/utils.py b/gui/wxpython/psmap/utils.py index 2eb3ec3d927..10b10f96297 100644 --- a/gui/wxpython/psmap/utils.py +++ b/gui/wxpython/psmap/utils.py @@ -19,6 +19,7 @@ from __future__ import annotations from math import ceil, cos, floor, fmod, radians, sin +from typing import overload import wx from core.gcmd import GError, RunCommand @@ -148,7 +149,17 @@ def convert(self, value, fromUnit=None, toUnit=None): return float(value) / self._units[fromUnit]["val"] * self._units[toUnit]["val"] -def convertRGB(rgb): +@overload +def convertRGB(rgb: wx.Colour) -> str: + pass + + +@overload +def convertRGB(rgb: str) -> wx.Colour | None: + pass + + +def convertRGB(rgb: wx.Colour | str) -> str | wx.Colour | None: """Converts wx.Colour(r,g,b,a) to string 'r:g:b' or named color, or named color/r:g:b string to wx.Colour, depending on input""" # transform a wx.Colour tuple into an r:g:b string @@ -162,12 +173,10 @@ def convertRGB(rgb): return name return str(rgb.Red()) + ":" + str(rgb.Green()) + ":" + str(rgb.Blue()) # transform a GRASS named color or an r:g:b string into a wx.Colour tuple - color = ( - int(gs.parse_color(rgb)[0] * 255), - int(gs.parse_color(rgb)[1] * 255), - int(gs.parse_color(rgb)[2] * 255), - ) - color = wx.Colour(*color) + parsed_color = gs.parse_color(rgb) + if parsed_color is None: + return None + color = wx.Colour(*tuple(int(x * 255) for x in parsed_color)) if color.IsOk(): return color return None diff --git a/python/grass/script/core.py b/python/grass/script/core.py index c3491d2e5e4..e6e95d68c2f 100644 --- a/python/grass/script/core.py +++ b/python/grass/script/core.py @@ -1575,7 +1575,7 @@ def list_grouped( # color parsing -named_colors = { +named_colors: dict[str, tuple[float, float, float]] = { "white": (1.00, 1.00, 1.00), "black": (0.00, 0.00, 0.00), "red": (1.00, 0.00, 0.00), @@ -1595,7 +1595,9 @@ def list_grouped( } -def parse_color(val, dflt=None): +def parse_color( + val: str, dflt: tuple[float, float, float] | None = None +) -> tuple[float, float, float] | None: """Parses the string "val" as a GRASS colour, which can be either one of the named colours or an R:G:B tuple e.g. 255:255:255. Returns an (r,g,b) triple whose components are floating point values between 0 @@ -1614,9 +1616,9 @@ def parse_color(val, dflt=None): if val in named_colors: return named_colors[val] - vals = val.split(":") + vals: list[str] = val.split(":") if len(vals) == 3: - return tuple(float(v) / 255 for v in vals) + return (float(vals[0]) / 255, float(vals[1]) / 255, float(vals[2]) / 255) return dflt