Skip to content

Commit 7645421

Browse files
authored
Merge pull request #30 from SebastienFauque/feature/typingLEDs
Add typing to LEDs
2 parents 43a70e8 + 238b2c2 commit 7645421

File tree

1 file changed

+63
-34
lines changed

1 file changed

+63
-34
lines changed

adafruit_fancyled/adafruit_fancyled.py

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@
1313
1414
* Author(s): PaintYourDragon
1515
"""
16-
17-
# imports
16+
from __future__ import annotations
1817

1918
__version__ = "0.0.0+auto.0"
2019
__repo__ = "https://github.com/Adafruit/Adafruit_CircuitPython_FancyLED.git"
2120

21+
# imports
2222
from math import floor
2323

24+
try:
25+
from typing import Tuple, Union, Optional, List, Any
26+
from circuitpython_typing.led import FillBasedColorUnion
27+
except ImportError:
28+
pass
29+
2430

2531
# FancyLED provides color- and palette-related utilities for LED projects,
2632
# offering a buttery smooth look instead of the usual 8-bit-like "blip blip"
@@ -46,16 +52,16 @@ class CRGB:
4652
c = CRGB(CHSV(0.0, 1.0, 1.0))
4753
"""
4854

49-
def __init__(self, red, green=0.0, blue=0.0):
55+
def __init__(self, red: CHSV, green: float = 0.0, blue: float = 0.0) -> None:
5056
# pylint: disable=too-many-branches
5157
if isinstance(red, CHSV):
5258
# If first/only argument is a CHSV type, perform HSV to RGB
5359
# conversion.
54-
hsv = red # 'red' is CHSV, this is just more readable
55-
hue = hsv.hue * 6.0 # Hue circle = 0.0 to 6.0
56-
sxt = floor(hue) # Sextant index is next-lower integer of hue
57-
frac = hue - sxt # Fraction-within-sextant is 0.0 to <1.0
58-
sxt = int(sxt) % 6 # mod6 the sextant so it's always 0 to 5
60+
hsv: CHSV = red # 'red' is CHSV, this is just more readable
61+
hue: float = hsv.hue * 6.0 # Hue circle = 0.0 to 6.0
62+
sxt: int = floor(hue) # Sextant index is next-lower integer of hue
63+
frac: float = hue - sxt # Fraction-within-sextant is 0.0 to <1.0
64+
sxt: int = int(sxt) % 6 # mod6 the sextant so it's always 0 to 5
5965

6066
if sxt == 0: # Red to <yellow
6167
r, g, b = 1.0, frac, 0.0
@@ -70,7 +76,7 @@ def __init__(self, red, green=0.0, blue=0.0):
7076
else: # Magenta to <red
7177
r, g, b = 1.0, 0.0, 1.0 - frac
7278

73-
invsat = 1.0 - hsv.saturation # Inverse-of-saturation
79+
invsat: float = 1.0 - hsv.saturation # Inverse-of-saturation
7480

7581
self.red = ((r * hsv.saturation) + invsat) * hsv.value
7682
self.green = ((g * hsv.saturation) + invsat) * hsv.value
@@ -81,17 +87,17 @@ def __init__(self, red, green=0.0, blue=0.0):
8187
self.green = clamp_norm(green)
8288
self.blue = clamp_norm(blue)
8389

84-
def __repr__(self): # pylint: disable=invalid-repr-returned
90+
def __repr__(self) -> Tuple[int, int, int]: # pylint: disable=invalid-repr-returned
8591
return (self.red, self.green, self.blue)
8692

87-
def __str__(self):
93+
def __str__(self) -> str:
8894
return "(%s, %s, %s)" % (self.red, self.green, self.blue)
8995

90-
def __len__(self):
96+
def __len__(self) -> int:
9197
"""Retrieve total number of color-parts available."""
9298
return 3
9399

94-
def __getitem__(self, key):
100+
def __getitem__(self, key: int) -> float:
95101
"""Retrieve red, green or blue value as iterable."""
96102
if key == 0:
97103
return self.red
@@ -101,7 +107,7 @@ def __getitem__(self, key):
101107
return self.blue
102108
raise IndexError
103109

104-
def pack(self, white=None):
110+
def pack(self, white: Optional[float] = None) -> FillBasedColorUnion:
105111
"""'Pack' a `CRGB` color into a 24-bit RGB integer, OR, optionally
106112
assign a white element for RGBW NeoPixels and return as a 4-tuple,
107113
either of which can be passed to the NeoPixel setter.
@@ -181,25 +187,27 @@ class CHSV:
181187
"""
182188

183189
# pylint: disable=invalid-name
184-
def __init__(self, h, s=1.0, v=1.0):
190+
def __init__(self, h: float, s: float = 1.0, v: float = 1.0) -> None:
185191
if isinstance(h, float):
186-
self.hue = h # Don't clamp! Hue can wrap around forever.
192+
self.hue: float = h # Don't clamp! Hue can wrap around forever.
187193
else:
188-
self.hue = float(h) / 256.0
189-
self.saturation = clamp_norm(s)
190-
self.value = clamp_norm(v)
194+
self.hue: float = float(h) / 256.0
195+
self.saturation: float = clamp_norm(s)
196+
self.value: float = clamp_norm(v)
191197

192-
def __repr__(self): # pylint: disable=invalid-repr-returned
198+
def __repr__( # pylint: disable=invalid-repr-returned
199+
self,
200+
) -> Tuple[float, float, float]:
193201
return (self.hue, self.saturation, self.value)
194202

195-
def __str__(self):
203+
def __str__(self) -> str:
196204
return "(%s, %s, %s)" % (self.hue, self.saturation, self.value)
197205

198-
def __len__(self):
206+
def __len__(self) -> int:
199207
"""Retrieve total number of 'color-parts' available."""
200208
return 3
201209

202-
def __getitem__(self, key):
210+
def __getitem__(self, key: int) -> float:
203211
"""Retrieve hue, saturation or value as iterable."""
204212
if key == 0:
205213
return self.hue
@@ -209,7 +217,7 @@ def __getitem__(self, key):
209217
return self.value
210218
raise IndexError
211219

212-
def pack(self, white=None):
220+
def pack(self, white: Optional[float] = None) -> FillBasedColorUnion:
213221
"""'Pack' a `CHSV` color into a 24-bit RGB integer, OR, optionally
214222
assign a white element for RGBW NeoPixels and return as a 4-tuple,
215223
either of which can be passed to the NeoPixel setter.
@@ -228,12 +236,16 @@ def pack(self, white=None):
228236
return CRGB(self).pack(white)
229237

230238

231-
def clamp(val, lower, upper):
239+
def clamp(
240+
val: Union[int, float], lower: Union[int, float], upper: Union[int, float]
241+
) -> Union[int, float]:
232242
"""Constrain value within a numeric range (inclusive)."""
233243
return max(lower, min(val, upper))
234244

235245

236-
def normalize(val, inplace=False):
246+
def normalize(
247+
val: int, inplace: Optional[bool] = False
248+
) -> Union[None, float, List[float]]:
237249
"""Convert 8-bit (0 to 255) value to normalized (0.0 to 1.0) value.
238250
239251
Accepts integer, 0 to 255 range (input is clamped) or a list or tuple
@@ -259,7 +271,7 @@ def normalize(val, inplace=False):
259271
return [normalize(n) for n in val]
260272

261273

262-
def clamp_norm(val):
274+
def clamp_norm(val: Union[float, int]) -> Union[float, int]:
263275
"""Clamp or normalize a value as appropriate to its type. If a float is
264276
received, the return value is the input clamped to a 0.0 to 1.0 range.
265277
If an integer is received, a range of 0-255 is scaled to a float value
@@ -270,7 +282,9 @@ def clamp_norm(val):
270282
return normalize(val)
271283

272284

273-
def denormalize(val, inplace=False):
285+
def denormalize(
286+
val: Union[float, List[float], Tuple[float]], inplace: bool = False
287+
) -> Union[int, List[int]]:
274288
"""Convert normalized (0.0 to 1.0) value to 8-bit (0 to 255) value
275289
276290
Accepts float, 0.0 to 1.0 range or a list or tuple of floats. In
@@ -300,7 +314,7 @@ def denormalize(val, inplace=False):
300314
return [denormalize(n) for n in val]
301315

302316

303-
def unpack(val):
317+
def unpack(val: int) -> CRGB:
304318
"""'Unpack' a 24-bit color into a `CRGB` instance.
305319
306320
:param int val: 24-bit integer a la ``0x00RRGGBB``.
@@ -318,7 +332,9 @@ def unpack(val):
318332
) # Blue
319333

320334

321-
def mix(color1, color2, weight2=0.5):
335+
def mix(
336+
color1: Union[CRGB, CHSV], color2: Union[CRGB, CHSV], weight2: float = 0.5
337+
) -> CRGB:
322338
"""Blend between two colors using given ratio. Accepts two colors (each
323339
may be `CRGB`, `CHSV` or packed integer), and weighting (0.0 to 1.0)
324340
of second color.
@@ -327,7 +343,7 @@ def mix(color1, color2, weight2=0.5):
327343
"""
328344

329345
clamp(weight2, 0.0, 1.0)
330-
weight1 = 1.0 - weight2
346+
weight1: float = 1.0 - weight2
331347

332348
if isinstance(color1, CHSV):
333349
if isinstance(color2, CHSV):
@@ -369,7 +385,12 @@ def mix(color1, color2, weight2=0.5):
369385
GFACTOR = 2.7 # Default gamma-correction factor for function below
370386

371387

372-
def gamma_adjust(val, gamma_value=None, brightness=1.0, inplace=False):
388+
def gamma_adjust(
389+
val: Any,
390+
gamma_value: Any = None,
391+
brightness: Optional[Union[float, Tuple[int, int, int]]] = 1.0,
392+
inplace: Optional[bool] = False,
393+
) -> Union[float, CRGB, List[Union[float, CRGB]]]:
373394
"""Provides gamma adjustment for single values, `CRGB` and `CHSV` types
374395
and lists of any of these.
375396
@@ -506,7 +527,9 @@ def gamma_adjust(val, gamma_value=None, brightness=1.0, inplace=False):
506527
)
507528

508529

509-
def palette_lookup(palette, position):
530+
def palette_lookup(
531+
palette: Union[List[CRGB], List[CHSV], List[int]], position: float
532+
) -> Union[CRGB, CHSV]:
510533
"""Fetch color from color palette, with interpolation.
511534
512535
:param palette: color palette (list of CRGB, CHSV and/or packed integers)
@@ -528,7 +551,13 @@ def palette_lookup(palette, position):
528551
return mix(color1, color2, weight2)
529552

530553

531-
def expand_gradient(gradient, length):
554+
def expand_gradient(
555+
gradient: Union[
556+
List[List[float, Union[int, CRGB, CHSV]]],
557+
Tuple[Tuple[float, Union[int, CRGB, CHSV]]],
558+
],
559+
length: float,
560+
) -> List[CRGB]:
532561
"""Convert gradient palette into standard equal-interval palette.
533562
534563
:param sequence gradient: List or tuple of of 2-element lists/tuples

0 commit comments

Comments
 (0)