Skip to content

Commit

Permalink
gui: Fix possibly indexing None in psmap.utils.convertRGB (#4875)
Browse files Browse the repository at this point in the history
Fully type check and annotate convertRGB() and the grass.script.core.parse_color() functions
  • Loading branch information
echoix authored Dec 23, 2024
1 parent 5cbcbc6 commit 57a646b
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 11 deletions.
23 changes: 16 additions & 7 deletions gui/wxpython/psmap/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
10 changes: 6 additions & 4 deletions python/grass/script/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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
Expand All @@ -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

Expand Down

0 comments on commit 57a646b

Please sign in to comment.