From afa8204b29f89a1c84f45006fffdfd3a0232bef7 Mon Sep 17 00:00:00 2001 From: Sebastien Fauque Date: Tue, 25 Apr 2023 10:12:41 -0600 Subject: [PATCH 1/7] added more return types. --- adafruit_fancyled/adafruit_fancyled.py | 63 ++++++++++++++++++-------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/adafruit_fancyled/adafruit_fancyled.py b/adafruit_fancyled/adafruit_fancyled.py index d32b6fb..8b71b83 100644 --- a/adafruit_fancyled/adafruit_fancyled.py +++ b/adafruit_fancyled/adafruit_fancyled.py @@ -21,6 +21,12 @@ from math import floor +try: + from typing import Tuple, Union, Optional, List, Any + from Adafruit_CircuitPython_Typing import FillBasedColorUnion +except ImportError: + pass + # FancyLED provides color- and palette-related utilities for LED projects, # offering a buttery smooth look instead of the usual 8-bit-like "blip blip" @@ -46,7 +52,7 @@ class CRGB: c = CRGB(CHSV(0.0, 1.0, 1.0)) """ - def __init__(self, red, green=0.0, blue=0.0): + def __init__(self, red: float, green: float = 0.0, blue: float = 0.0) -> None: # pylint: disable=too-many-branches if isinstance(red, CHSV): # If first/only argument is a CHSV type, perform HSV to RGB @@ -81,17 +87,17 @@ def __init__(self, red, green=0.0, blue=0.0): self.green = clamp_norm(green) self.blue = clamp_norm(blue) - def __repr__(self): # pylint: disable=invalid-repr-returned + def __repr__(self) -> Tuple[int, int, int]: # pylint: disable=invalid-repr-returned return (self.red, self.green, self.blue) - def __str__(self): + def __str__(self) -> str: return "(%s, %s, %s)" % (self.red, self.green, self.blue) - def __len__(self): + def __len__(self) -> int: """Retrieve total number of color-parts available.""" return 3 - def __getitem__(self, key): + def __getitem__(self, key: int) -> float: """Retrieve red, green or blue value as iterable.""" if key == 0: return self.red @@ -101,7 +107,7 @@ def __getitem__(self, key): return self.blue raise IndexError - def pack(self, white=None): + def pack(self, white: Optional[float] = None) -> FillBasedColorUnion: """'Pack' a `CRGB` color into a 24-bit RGB integer, OR, optionally assign a white element for RGBW NeoPixels and return as a 4-tuple, either of which can be passed to the NeoPixel setter. @@ -181,7 +187,7 @@ class CHSV: """ # pylint: disable=invalid-name - def __init__(self, h, s=1.0, v=1.0): + def __init__(self, h: float, s: float = 1.0, v: float = 1.0): if isinstance(h, float): self.hue = h # Don't clamp! Hue can wrap around forever. else: @@ -189,17 +195,19 @@ def __init__(self, h, s=1.0, v=1.0): self.saturation = clamp_norm(s) self.value = clamp_norm(v) - def __repr__(self): # pylint: disable=invalid-repr-returned + def __repr__( + self, + ): # pylint: disable=invalid-repr-returned return (self.hue, self.saturation, self.value) - def __str__(self): + def __str__(self) -> str: return "(%s, %s, %s)" % (self.hue, self.saturation, self.value) - def __len__(self): + def __len__(self) -> int: """Retrieve total number of 'color-parts' available.""" return 3 - def __getitem__(self, key): + def __getitem__(self, key: int) -> float: """Retrieve hue, saturation or value as iterable.""" if key == 0: return self.hue @@ -209,7 +217,7 @@ def __getitem__(self, key): return self.value raise IndexError - def pack(self, white=None): + def pack(self, white: Optional[float] = None) -> FillBasedColorUnion: """'Pack' a `CHSV` color into a 24-bit RGB integer, OR, optionally assign a white element for RGBW NeoPixels and return as a 4-tuple, either of which can be passed to the NeoPixel setter. @@ -228,12 +236,16 @@ def pack(self, white=None): return CRGB(self).pack(white) -def clamp(val, lower, upper): +def clamp( + val: Union[int, float], lower: Union[int, float], upper: Union[int, float] +) -> Union[int, float]: """Constrain value within a numeric range (inclusive).""" return max(lower, min(val, upper)) -def normalize(val, inplace=False): +def normalize( + val: int, inplace: Optional[bool] = False +) -> Union[None, float, List[float]]: """Convert 8-bit (0 to 255) value to normalized (0.0 to 1.0) value. Accepts integer, 0 to 255 range (input is clamped) or a list or tuple @@ -259,7 +271,7 @@ def normalize(val, inplace=False): return [normalize(n) for n in val] -def clamp_norm(val): +def clamp_norm(val: Union[float, int]) -> Union[float, int]: """Clamp or normalize a value as appropriate to its type. If a float is received, the return value is the input clamped to a 0.0 to 1.0 range. If an integer is received, a range of 0-255 is scaled to a float value @@ -270,7 +282,7 @@ def clamp_norm(val): return normalize(val) -def denormalize(val, inplace=False): +def denormalize(val: Union[float, List[float]], inplace=False) -> Union[int, List[int]]: """Convert normalized (0.0 to 1.0) value to 8-bit (0 to 255) value Accepts float, 0.0 to 1.0 range or a list or tuple of floats. In @@ -300,7 +312,7 @@ def denormalize(val, inplace=False): return [denormalize(n) for n in val] -def unpack(val): +def unpack(val: int) -> CRGB: """'Unpack' a 24-bit color into a `CRGB` instance. :param int val: 24-bit integer a la ``0x00RRGGBB``. @@ -318,7 +330,9 @@ def unpack(val): ) # Blue -def mix(color1, color2, weight2=0.5): +def mix( + color1: Union[CRGB, CHSV], color2: Union[CRGB, CHSV], weight2: float = 0.5 +) -> CRGB: """Blend between two colors using given ratio. Accepts two colors (each may be `CRGB`, `CHSV` or packed integer), and weighting (0.0 to 1.0) of second color. @@ -506,7 +520,9 @@ def gamma_adjust(val, gamma_value=None, brightness=1.0, inplace=False): ) -def palette_lookup(palette, position): +def palette_lookup( + palette: Union[List[CRGB], List[CHSV], List[int]], position: float +) -> Union[CRGB, CHSV]: """Fetch color from color palette, with interpolation. :param palette: color palette (list of CRGB, CHSV and/or packed integers) @@ -528,7 +544,14 @@ def palette_lookup(palette, position): return mix(color1, color2, weight2) -def expand_gradient(gradient, length): +# gradient: Union[ +# List[Union[List[Union[float, CRGB, CHSV]], Tuple[Union[float, CRGB, CHSV]]]], +# Tuple[Union[List[Union[float, CRGB, CHSV]], Tuple[Union[float, CRGB, CHSV]]]], +# ], +def expand_gradient( + gradient: Any, + length: float, +) -> List[CRGB]: """Convert gradient palette into standard equal-interval palette. :param sequence gradient: List or tuple of of 2-element lists/tuples From 0ac0a9b2cf1e206dbf355d825af790c8fd0adc60 Mon Sep 17 00:00:00 2001 From: Sebastien Fauque Date: Tue, 25 Apr 2023 11:14:01 -0600 Subject: [PATCH 2/7] added a return type --- adafruit_fancyled/adafruit_fancyled.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_fancyled/adafruit_fancyled.py b/adafruit_fancyled/adafruit_fancyled.py index 8b71b83..627878c 100644 --- a/adafruit_fancyled/adafruit_fancyled.py +++ b/adafruit_fancyled/adafruit_fancyled.py @@ -195,9 +195,9 @@ def __init__(self, h: float, s: float = 1.0, v: float = 1.0): self.saturation = clamp_norm(s) self.value = clamp_norm(v) - def __repr__( + def __repr__( # pylint: disable=invalid-repr-returned self, - ): # pylint: disable=invalid-repr-returned + ) -> Tuple[float, float, float]: return (self.hue, self.saturation, self.value) def __str__(self) -> str: @@ -341,7 +341,7 @@ def mix( """ clamp(weight2, 0.0, 1.0) - weight1 = 1.0 - weight2 + weight1: float = 1.0 - weight2 if isinstance(color1, CHSV): if isinstance(color2, CHSV): From c598f8483f8b503e63a65cd2dcf2697032b2ca41 Mon Sep 17 00:00:00 2001 From: Sebastien Fauque Date: Tue, 25 Apr 2023 11:50:05 -0600 Subject: [PATCH 3/7] fixed module import --- adafruit_fancyled/adafruit_fancyled.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_fancyled/adafruit_fancyled.py b/adafruit_fancyled/adafruit_fancyled.py index 627878c..e65bdd5 100644 --- a/adafruit_fancyled/adafruit_fancyled.py +++ b/adafruit_fancyled/adafruit_fancyled.py @@ -23,7 +23,7 @@ try: from typing import Tuple, Union, Optional, List, Any - from Adafruit_CircuitPython_Typing import FillBasedColorUnion + from circuitpython_typing.led import FillBasedColorUnion except ImportError: pass From 5acca0e28ef7abb9382614f098b18035c84f817c Mon Sep 17 00:00:00 2001 From: Sebastien Fauque Date: Tue, 25 Apr 2023 14:46:38 -0600 Subject: [PATCH 4/7] import annotations from future to expect to find the modules that are missing --- adafruit_fancyled/adafruit_fancyled.py | 1 + 1 file changed, 1 insertion(+) diff --git a/adafruit_fancyled/adafruit_fancyled.py b/adafruit_fancyled/adafruit_fancyled.py index e65bdd5..f05832d 100644 --- a/adafruit_fancyled/adafruit_fancyled.py +++ b/adafruit_fancyled/adafruit_fancyled.py @@ -13,6 +13,7 @@ * Author(s): PaintYourDragon """ +from __future__ import annotations # imports From aea2e2d2a64de6c86e2905a7627c74d571805d10 Mon Sep 17 00:00:00 2001 From: Sebastien Fauque Date: Tue, 25 Apr 2023 17:22:49 -0600 Subject: [PATCH 5/7] Added return typing to gamma_adjust, recommending rewriting function as a future issue. --- adafruit_fancyled/adafruit_fancyled.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/adafruit_fancyled/adafruit_fancyled.py b/adafruit_fancyled/adafruit_fancyled.py index f05832d..f050325 100644 --- a/adafruit_fancyled/adafruit_fancyled.py +++ b/adafruit_fancyled/adafruit_fancyled.py @@ -188,7 +188,7 @@ class CHSV: """ # pylint: disable=invalid-name - def __init__(self, h: float, s: float = 1.0, v: float = 1.0): + def __init__(self, h: float, s: float = 1.0, v: float = 1.0) -> None: if isinstance(h, float): self.hue = h # Don't clamp! Hue can wrap around forever. else: @@ -283,7 +283,9 @@ def clamp_norm(val: Union[float, int]) -> Union[float, int]: return normalize(val) -def denormalize(val: Union[float, List[float]], inplace=False) -> Union[int, List[int]]: +def denormalize( + val: Union[float, List[float], Tuple[float]], inplace=False +) -> Union[int, List[int]]: """Convert normalized (0.0 to 1.0) value to 8-bit (0 to 255) value Accepts float, 0.0 to 1.0 range or a list or tuple of floats. In @@ -384,7 +386,9 @@ def mix( GFACTOR = 2.7 # Default gamma-correction factor for function below -def gamma_adjust(val, gamma_value=None, brightness=1.0, inplace=False): +def gamma_adjust( + val: Any, gamma_value: Any = None, brightness: Any = 1.0, inplace=False +) -> Union[float, CRGB, List[Union[float, CRGB]]]: """Provides gamma adjustment for single values, `CRGB` and `CHSV` types and lists of any of these. @@ -545,12 +549,11 @@ def palette_lookup( return mix(color1, color2, weight2) -# gradient: Union[ -# List[Union[List[Union[float, CRGB, CHSV]], Tuple[Union[float, CRGB, CHSV]]]], -# Tuple[Union[List[Union[float, CRGB, CHSV]], Tuple[Union[float, CRGB, CHSV]]]], -# ], def expand_gradient( - gradient: Any, + gradient: Union[ + List[List[float, Union[int, CRGB, CHSV]]], + Tuple[Tuple[float, Union[int, CRGB, CHSV]]], + ], length: float, ) -> List[CRGB]: """Convert gradient palette into standard equal-interval palette. From e4e80ec9503cf9fa47c062f8caa334fdc9bcadae Mon Sep 17 00:00:00 2001 From: Sebastien Fauque Date: Thu, 27 Apr 2023 21:13:21 -0700 Subject: [PATCH 6/7] added requested fixes, added more specificity to gamma_adjust. --- adafruit_fancyled/adafruit_fancyled.py | 34 ++++++++++++++------------ 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/adafruit_fancyled/adafruit_fancyled.py b/adafruit_fancyled/adafruit_fancyled.py index f050325..46626c9 100644 --- a/adafruit_fancyled/adafruit_fancyled.py +++ b/adafruit_fancyled/adafruit_fancyled.py @@ -13,16 +13,15 @@ * Author(s): PaintYourDragon """ -from __future__ import annotations - -# imports __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/Adafruit/Adafruit_CircuitPython_FancyLED.git" +# imports from math import floor try: + from __future__ import annotations from typing import Tuple, Union, Optional, List, Any from circuitpython_typing.led import FillBasedColorUnion except ImportError: @@ -53,16 +52,16 @@ class CRGB: c = CRGB(CHSV(0.0, 1.0, 1.0)) """ - def __init__(self, red: float, green: float = 0.0, blue: float = 0.0) -> None: + def __init__(self, red: CHSV, green: float = 0.0, blue: float = 0.0) -> None: # pylint: disable=too-many-branches if isinstance(red, CHSV): # If first/only argument is a CHSV type, perform HSV to RGB # conversion. - hsv = red # 'red' is CHSV, this is just more readable - hue = hsv.hue * 6.0 # Hue circle = 0.0 to 6.0 - sxt = floor(hue) # Sextant index is next-lower integer of hue - frac = hue - sxt # Fraction-within-sextant is 0.0 to <1.0 - sxt = int(sxt) % 6 # mod6 the sextant so it's always 0 to 5 + hsv: CHSV = red # 'red' is CHSV, this is just more readable + hue: float = hsv.hue * 6.0 # Hue circle = 0.0 to 6.0 + sxt: int = floor(hue) # Sextant index is next-lower integer of hue + frac: float = hue - sxt # Fraction-within-sextant is 0.0 to <1.0 + sxt: int = int(sxt) % 6 # mod6 the sextant so it's always 0 to 5 if sxt == 0: # Red to None: else: # Magenta to None: if isinstance(h, float): - self.hue = h # Don't clamp! Hue can wrap around forever. + self.hue: float = h # Don't clamp! Hue can wrap around forever. else: - self.hue = float(h) / 256.0 - self.saturation = clamp_norm(s) - self.value = clamp_norm(v) + self.hue: float = float(h) / 256.0 + self.saturation: float = clamp_norm(s) + self.value: float = clamp_norm(v) def __repr__( # pylint: disable=invalid-repr-returned self, @@ -284,7 +283,7 @@ def clamp_norm(val: Union[float, int]) -> Union[float, int]: def denormalize( - val: Union[float, List[float], Tuple[float]], inplace=False + val: Union[float, List[float], Tuple[float]], inplace: bool = False ) -> Union[int, List[int]]: """Convert normalized (0.0 to 1.0) value to 8-bit (0 to 255) value @@ -387,7 +386,10 @@ def mix( def gamma_adjust( - val: Any, gamma_value: Any = None, brightness: Any = 1.0, inplace=False + val: Any, + gamma_value: Any = None, + brightness: Optional[Union[float, Tuple[int, int, int]]] = 1.0, + inplace: Optional[bool] = False, ) -> Union[float, CRGB, List[Union[float, CRGB]]]: """Provides gamma adjustment for single values, `CRGB` and `CHSV` types and lists of any of these. From 238b2c2be16f0e08f232eee2c2b3aeda6e5a0014 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Fri, 28 Apr 2023 17:30:38 -0500 Subject: [PATCH 7/7] move __future__ import back --- adafruit_fancyled/adafruit_fancyled.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_fancyled/adafruit_fancyled.py b/adafruit_fancyled/adafruit_fancyled.py index 46626c9..6054486 100644 --- a/adafruit_fancyled/adafruit_fancyled.py +++ b/adafruit_fancyled/adafruit_fancyled.py @@ -13,6 +13,7 @@ * Author(s): PaintYourDragon """ +from __future__ import annotations __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/Adafruit/Adafruit_CircuitPython_FancyLED.git" @@ -21,7 +22,6 @@ from math import floor try: - from __future__ import annotations from typing import Tuple, Union, Optional, List, Any from circuitpython_typing.led import FillBasedColorUnion except ImportError: