From 3d64ac062829cb65f52f7f95b24bcb06f5b02e03 Mon Sep 17 00:00:00 2001 From: Isaac Benitez Date: Wed, 22 Jun 2022 17:38:29 -0700 Subject: [PATCH 1/2] Added Type Annotations --- adafruit_display_shapes/circle.py | 24 ++++++++++--- adafruit_display_shapes/line.py | 13 ++++++-- adafruit_display_shapes/polygon.py | 25 +++++++++++--- adafruit_display_shapes/rect.py | 25 +++++++++++--- adafruit_display_shapes/roundrect.py | 46 ++++++++++++++++--------- adafruit_display_shapes/sparkline.py | 50 +++++++++++++++++++--------- adafruit_display_shapes/triangle.py | 32 +++++++++++++++--- 7 files changed, 163 insertions(+), 52 deletions(-) diff --git a/adafruit_display_shapes/circle.py b/adafruit_display_shapes/circle.py index c7636d5..df919af 100644 --- a/adafruit_display_shapes/circle.py +++ b/adafruit_display_shapes/circle.py @@ -21,6 +21,11 @@ """ +try: + from typing import Optional +except ImportError: + pass + from adafruit_display_shapes.roundrect import RoundRect __version__ = "0.0.0-auto.0" @@ -42,7 +47,16 @@ class Circle(RoundRect): """ - def __init__(self, x0, y0, r, *, fill=None, outline=None, stroke=1): + def __init__( + self, + x0: int, + y0: int, + r: int, + *, + fill: Optional[int] = None, + outline: Optional[int] = None, + stroke: int = 1, + ) -> None: super().__init__( x0 - r, y0 - r, @@ -56,19 +70,19 @@ def __init__(self, x0, y0, r, *, fill=None, outline=None, stroke=1): self.r = r @property - def x0(self): + def x0(self) -> int: """The x-position of the center of the circle.""" return self.x + self.r @property - def y0(self): + def y0(self) -> int: """The y-position of the center of the circle.""" return self.y + self.r @x0.setter - def x0(self, x0): + def x0(self, x0: int) -> None: self.x = x0 - self.r @y0.setter - def y0(self, y0): + def y0(self, y0: int) -> None: self.y = y0 - self.r diff --git a/adafruit_display_shapes/line.py b/adafruit_display_shapes/line.py index f030548..aaada0c 100644 --- a/adafruit_display_shapes/line.py +++ b/adafruit_display_shapes/line.py @@ -38,15 +38,22 @@ class Line(Polygon): :param color: The color of the line. """ - def __init__(self, x0, y0, x1, y1, color): + def __init__( + self, + x0: int, + y0: int, + x1: int, + y1: int, + color: int, + ) -> None: super().__init__([(x0, y0), (x1, y1)], outline=color) @property - def color(self): + def color(self) -> int: """The line color value. Can be a hex value for a color or ``None`` for no line color.""" return self.outline @color.setter - def color(self, color): + def color(self, color: int) -> None: self.outline = color diff --git a/adafruit_display_shapes/polygon.py b/adafruit_display_shapes/polygon.py index d36f896..b9c3a72 100644 --- a/adafruit_display_shapes/polygon.py +++ b/adafruit_display_shapes/polygon.py @@ -21,6 +21,11 @@ """ +try: + from typing import Optional, List, Tuple +except ImportError: + pass + import displayio __version__ = "0.0.0-auto.0" @@ -36,7 +41,12 @@ class Polygon(displayio.TileGrid): ``None`` for no outline. """ - def __init__(self, points, *, outline=None): + def __init__( + self, + points: List[Tuple[int, int]], + *, + outline: Optional[int] = None, + ) -> None: xs = [] ys = [] @@ -77,7 +87,14 @@ def __init__(self, points, *, outline=None): ) # pylint: disable=invalid-name, too-many-locals, too-many-branches - def _line(self, x0, y0, x1, y1, color): + def _line( + self, + x0: int, + y0: int, + x1: int, + y1: int, + color: int, + ) -> None: if x0 == x1: if y0 > y1: y0, y1 = y1, y0 @@ -121,13 +138,13 @@ def _line(self, x0, y0, x1, y1, color): # pylint: enable=invalid-name, too-many-locals, too-many-branches @property - def outline(self): + def outline(self) -> int: """The outline of the polygon. Can be a hex value for a color or ``None`` for no outline.""" return self._palette[1] @outline.setter - def outline(self, color): + def outline(self, color: int) -> None: if color is None: self._palette[1] = 0 self._palette.make_transparent(1) diff --git a/adafruit_display_shapes/rect.py b/adafruit_display_shapes/rect.py index 3f051eb..c2a7393 100644 --- a/adafruit_display_shapes/rect.py +++ b/adafruit_display_shapes/rect.py @@ -21,6 +21,11 @@ """ +try: + from typing import Optional +except ImportError: + pass + import displayio __version__ = "0.0.0-auto.0" @@ -43,7 +48,17 @@ class Rect(displayio.TileGrid): """ - def __init__(self, x, y, width, height, *, fill=None, outline=None, stroke=1): + def __init__( + self, + x: int, + y: int, + width: int, + height: int, + *, + fill: Optional[int] = None, + outline: Optional[int] = None, + stroke: int = 1, + ) -> None: self._bitmap = displayio.Bitmap(width, height, 2) self._palette = displayio.Palette(2) @@ -67,13 +82,13 @@ def __init__(self, x, y, width, height, *, fill=None, outline=None, stroke=1): super().__init__(self._bitmap, pixel_shader=self._palette, x=x, y=y) @property - def fill(self): + def fill(self) -> int: """The fill of the rectangle. Can be a hex value for a color or ``None`` for transparent.""" return self._palette[0] @fill.setter - def fill(self, color): + def fill(self, color: int) -> None: if color is None: self._palette[0] = 0 self._palette.make_transparent(0) @@ -82,13 +97,13 @@ def fill(self, color): self._palette.make_opaque(0) @property - def outline(self): + def outline(self) -> int: """The outline of the rectangle. Can be a hex value for a color or ``None`` for no outline.""" return self._palette[1] @outline.setter - def outline(self, color): + def outline(self, color: int) -> None: if color is None: self._palette[1] = 0 self._palette.make_transparent(1) diff --git a/adafruit_display_shapes/roundrect.py b/adafruit_display_shapes/roundrect.py index 0df799b..b4d4ecb 100644 --- a/adafruit_display_shapes/roundrect.py +++ b/adafruit_display_shapes/roundrect.py @@ -11,6 +11,11 @@ """ +try: + from typing import Optional +except ImportError: + pass + import displayio __version__ = "0.0.0-auto.0" @@ -35,7 +40,18 @@ class RoundRect(displayio.TileGrid): """ - def __init__(self, x, y, width, height, r, *, fill=None, outline=None, stroke=1): + def __init__( + self, + x: int, + y: int, + width: int, + height: int, + r: int, + *, + fill: Optional[int] = None, + outline: Optional[int] = None, + stroke: int = 1, + ) -> None: self._palette = displayio.Palette(3) self._palette.make_transparent(0) self._bitmap = displayio.Bitmap(width, height, 3) @@ -85,17 +101,17 @@ def __init__(self, x, y, width, height, r, *, fill=None, outline=None, stroke=1) # pylint: disable=invalid-name, too-many-locals, too-many-branches def _helper( self, - x0, - y0, - r, + x0: int, + y0: int, + r: int, *, - color, - x_offset=0, - y_offset=0, - stroke=1, - corner_flags=0xF, - fill=False - ): + color: int, + x_offset: int = 0, + y_offset: int = 0, + stroke: int = 1, + corner_flags: int = 0xF, + fill: bool = False, + ) -> None: f = 1 - r ddF_x = 1 ddF_y = -2 * r @@ -142,13 +158,13 @@ def _helper( # pylint: enable=invalid-name, too-many-locals, too-many-branches @property - def fill(self): + def fill(self) -> int: """The fill of the rounded-corner rectangle. Can be a hex value for a color or ``None`` for transparent.""" return self._palette[2] @fill.setter - def fill(self, color): + def fill(self, color: int) -> None: if color is None: self._palette[2] = 0 self._palette.make_transparent(2) @@ -157,13 +173,13 @@ def fill(self, color): self._palette.make_opaque(2) @property - def outline(self): + def outline(self) -> int: """The outline of the rounded-corner rectangle. Can be a hex value for a color or ``None`` for no outline.""" return self._palette[1] @outline.setter - def outline(self, color): + def outline(self, color: int) -> None: if color is None: self._palette[1] = 0 self._palette.make_transparent(1) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index d122be9..051572a 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -39,6 +39,10 @@ # pylint: disable=too-many-instance-attributes +try: + from typing import Optional, List +except ImportError: + pass import displayio from adafruit_display_shapes.line import Line @@ -59,15 +63,15 @@ class Sparkline(displayio.Group): def __init__( self, - width, - height, - max_items, - y_min=None, # None = autoscaling - y_max=None, # None = autoscaling - x=0, - y=0, - color=0xFFFFFF, # line color, default is WHITE - ): + width: int, + height: int, + max_items: int, + y_min: Optional[int] = None, # None = autoscaling + y_max: Optional[int] = None, # None = autoscaling + x: int = 0, + y: int = 0, + color: int = 0xFFFFFF, # line color, default is WHITE + ) -> None: # define class instance variables self.width = width # in pixels @@ -88,14 +92,14 @@ def __init__( super().__init__(x=x, y=y) # self is a group of lines - def clear_values(self): + def clear_values(self) -> None: """Removes all values from the _spark_list list and removes all lines in the group""" for _ in range(len(self)): # remove all items from the current group self.pop() self._spark_list = [] # empty the list - def add_value(self, value): + def add_value(self, value: float) -> None: """Add a value to the sparkline. :param value: The value to be added to the sparkline """ @@ -111,8 +115,14 @@ def add_value(self, value): # pylint: disable=no-else-return @staticmethod def _xintercept( - x_1, y_1, x_2, y_2, horizontal_y - ): # finds intercept of the line and a horizontal line at horizontalY + x_1: int, + y_1: float, + x_2: int, + y_2: float, + horizontal_y: int, + ) -> Optional[ + int + ]: # finds intercept of the line and a horizontal line at horizontalY slope = (y_2 - y_1) / (x_2 - x_1) b = y_1 - slope * x_1 @@ -124,7 +134,15 @@ def _xintercept( ) / slope # calculate the x-intercept at position y=horizontalY return int(xint) - def _plotline(self, x_1, last_value, x_2, value, y_bottom, y_top): + def _plotline( + self, + x_1: int, + last_value: float, + x_2: int, + value: float, + y_bottom: int, + y_top: int, + ) -> None: y_2 = int(self.height * (y_top - value) / (y_top - y_bottom)) y_1 = int(self.height * (y_top - last_value) / (y_top - y_bottom)) @@ -132,7 +150,7 @@ def _plotline(self, x_1, last_value, x_2, value, y_bottom, y_top): # pylint: disable= too-many-branches, too-many-nested-blocks - def update(self): + def update(self) -> None: """Update the drawing of the sparkline.""" # get the y range @@ -224,7 +242,7 @@ def update(self): last_value = value # store value for the next iteration - def values(self): + def values(self) -> List[float]: """Returns the values displayed on the sparkline.""" return self._spark_list diff --git a/adafruit_display_shapes/triangle.py b/adafruit_display_shapes/triangle.py index 3f3b47a..c025691 100644 --- a/adafruit_display_shapes/triangle.py +++ b/adafruit_display_shapes/triangle.py @@ -21,6 +21,11 @@ """ +try: + from typing import Optional +except ImportError: + pass + from adafruit_display_shapes.polygon import Polygon __version__ = "0.0.0-auto.0" @@ -43,7 +48,18 @@ class Triangle(Polygon): ``None`` for no outline. """ # pylint: disable=too-many-locals - def __init__(self, x0, y0, x1, y1, x2, y2, *, fill=None, outline=None): + def __init__( + self, + x0: int, + y0: int, + x1: int, + y1: int, + x2: int, + y2: int, + *, + fill: Optional[int] = None, + outline: Optional[int] = None, + ) -> None: # Sort coordinates by Y order (y2 >= y1 >= y0) if y0 > y1: y0, y1 = y1, y0 @@ -89,7 +105,15 @@ def __init__(self, x0, y0, x1, y1, x2, y2, *, fill=None, outline=None): ) # pylint: disable=invalid-name, too-many-branches - def _draw_filled(self, x0, y0, x1, y1, x2, y2): + def _draw_filled( + self, + x0: int, + y0: int, + x1: int, + y1: int, + x2: int, + y2: int, + ) -> None: if y0 == y2: # Handle awkward all-on-same-line case as its own thing a = x0 b = x0 @@ -129,13 +153,13 @@ def _draw_filled(self, x0, y0, x1, y1, x2, y2): # pylint: enable=invalid-name, too-many-locals, too-many-branches @property - def fill(self): + def fill(self) -> int: """The fill of the triangle. Can be a hex value for a color or ``None`` for transparent.""" return self._palette[2] @fill.setter - def fill(self, color): + def fill(self, color: int) -> None: if color is None: self._palette[2] = 0 self._palette.make_transparent(2) From e0a85bec4213f8b2c11cca554a1e974df28d10bb Mon Sep 17 00:00:00 2001 From: Isaac Benitez Date: Fri, 24 Jun 2022 21:07:25 -0700 Subject: [PATCH 2/2] Corrected Type Annotations --- adafruit_display_shapes/line.py | 9 +++++++-- adafruit_display_shapes/polygon.py | 4 ++-- adafruit_display_shapes/rect.py | 8 ++++---- adafruit_display_shapes/roundrect.py | 8 ++++---- adafruit_display_shapes/sparkline.py | 6 +++--- adafruit_display_shapes/triangle.py | 4 ++-- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/adafruit_display_shapes/line.py b/adafruit_display_shapes/line.py index aaada0c..da23897 100644 --- a/adafruit_display_shapes/line.py +++ b/adafruit_display_shapes/line.py @@ -21,6 +21,11 @@ """ +try: + from typing import Optional +except ImportError: + pass + from adafruit_display_shapes.polygon import Polygon __version__ = "0.0.0-auto.0" @@ -49,11 +54,11 @@ def __init__( super().__init__([(x0, y0), (x1, y1)], outline=color) @property - def color(self) -> int: + def color(self) -> Optional[int]: """The line color value. Can be a hex value for a color or ``None`` for no line color.""" return self.outline @color.setter - def color(self, color: int) -> None: + def color(self, color: Optional[int]) -> None: self.outline = color diff --git a/adafruit_display_shapes/polygon.py b/adafruit_display_shapes/polygon.py index b9c3a72..216e4fb 100644 --- a/adafruit_display_shapes/polygon.py +++ b/adafruit_display_shapes/polygon.py @@ -138,13 +138,13 @@ def _line( # pylint: enable=invalid-name, too-many-locals, too-many-branches @property - def outline(self) -> int: + def outline(self) -> Optional[int]: """The outline of the polygon. Can be a hex value for a color or ``None`` for no outline.""" return self._palette[1] @outline.setter - def outline(self, color: int) -> None: + def outline(self, color: Optional[int]) -> None: if color is None: self._palette[1] = 0 self._palette.make_transparent(1) diff --git a/adafruit_display_shapes/rect.py b/adafruit_display_shapes/rect.py index c2a7393..306672e 100644 --- a/adafruit_display_shapes/rect.py +++ b/adafruit_display_shapes/rect.py @@ -82,13 +82,13 @@ def __init__( super().__init__(self._bitmap, pixel_shader=self._palette, x=x, y=y) @property - def fill(self) -> int: + def fill(self) -> Optional[int]: """The fill of the rectangle. Can be a hex value for a color or ``None`` for transparent.""" return self._palette[0] @fill.setter - def fill(self, color: int) -> None: + def fill(self, color: Optional[int]) -> None: if color is None: self._palette[0] = 0 self._palette.make_transparent(0) @@ -97,13 +97,13 @@ def fill(self, color: int) -> None: self._palette.make_opaque(0) @property - def outline(self) -> int: + def outline(self) -> Optional[int]: """The outline of the rectangle. Can be a hex value for a color or ``None`` for no outline.""" return self._palette[1] @outline.setter - def outline(self, color: int) -> None: + def outline(self, color: Optional[int]) -> None: if color is None: self._palette[1] = 0 self._palette.make_transparent(1) diff --git a/adafruit_display_shapes/roundrect.py b/adafruit_display_shapes/roundrect.py index b4d4ecb..ba58de4 100644 --- a/adafruit_display_shapes/roundrect.py +++ b/adafruit_display_shapes/roundrect.py @@ -158,13 +158,13 @@ def _helper( # pylint: enable=invalid-name, too-many-locals, too-many-branches @property - def fill(self) -> int: + def fill(self) -> Optional[int]: """The fill of the rounded-corner rectangle. Can be a hex value for a color or ``None`` for transparent.""" return self._palette[2] @fill.setter - def fill(self, color: int) -> None: + def fill(self, color: Optional[int]) -> None: if color is None: self._palette[2] = 0 self._palette.make_transparent(2) @@ -173,13 +173,13 @@ def fill(self, color: int) -> None: self._palette.make_opaque(2) @property - def outline(self) -> int: + def outline(self) -> Optional[int]: """The outline of the rounded-corner rectangle. Can be a hex value for a color or ``None`` for no outline.""" return self._palette[1] @outline.setter - def outline(self, color: int) -> None: + def outline(self, color: Optional[int]) -> None: if color is None: self._palette[1] = 0 self._palette.make_transparent(1) diff --git a/adafruit_display_shapes/sparkline.py b/adafruit_display_shapes/sparkline.py index 051572a..39e8056 100644 --- a/adafruit_display_shapes/sparkline.py +++ b/adafruit_display_shapes/sparkline.py @@ -115,11 +115,11 @@ def add_value(self, value: float) -> None: # pylint: disable=no-else-return @staticmethod def _xintercept( - x_1: int, + x_1: float, y_1: float, - x_2: int, + x_2: float, y_2: float, - horizontal_y: int, + horizontal_y: float, ) -> Optional[ int ]: # finds intercept of the line and a horizontal line at horizontalY diff --git a/adafruit_display_shapes/triangle.py b/adafruit_display_shapes/triangle.py index c025691..1e7185a 100644 --- a/adafruit_display_shapes/triangle.py +++ b/adafruit_display_shapes/triangle.py @@ -153,13 +153,13 @@ def _draw_filled( # pylint: enable=invalid-name, too-many-locals, too-many-branches @property - def fill(self) -> int: + def fill(self) -> Optional[int]: """The fill of the triangle. Can be a hex value for a color or ``None`` for transparent.""" return self._palette[2] @fill.setter - def fill(self, color: int) -> None: + def fill(self, color: Optional[int]) -> None: if color is None: self._palette[2] = 0 self._palette.make_transparent(2)