diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..21c125c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2024 Justin Myers for Adafruit Industries +# +# SPDX-License-Identifier: Unlicense + +.py text eol=lf +.rst text eol=lf +.txt text eol=lf +.yaml text eol=lf +.toml text eol=lf +.license text eol=lf +.md text eol=lf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 70ade69..ff19dde 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,42 +1,21 @@ -# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò +# SPDX-FileCopyrightText: 2024 Justin Myers for Adafruit Industries # # SPDX-License-Identifier: Unlicense repos: - - repo: https://github.com/python/black - rev: 23.3.0 - hooks: - - id: black - - repo: https://github.com/fsfe/reuse-tool - rev: v1.1.2 - hooks: - - id: reuse - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - - repo: https://github.com/pycqa/pylint - rev: v2.17.4 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.4 hooks: - - id: pylint - name: pylint (library code) - types: [python] - args: - - --disable=consider-using-f-string - exclude: "^(docs/|examples/|tests/|setup.py$)" - - id: pylint - name: pylint (example code) - description: Run pylint rules on "examples/*.py" files - types: [python] - files: "^examples/" - args: - - --disable=missing-docstring,invalid-name,consider-using-f-string,duplicate-code - - id: pylint - name: pylint (test code) - description: Run pylint rules on "tests/*.py" files - types: [python] - files: "^tests/" - args: - - --disable=missing-docstring,consider-using-f-string,duplicate-code + - id: ruff-format + - id: ruff + args: ["--fix"] + - repo: https://github.com/fsfe/reuse-tool + rev: v3.0.1 + hooks: + - id: reuse diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index f945e92..0000000 --- a/.pylintrc +++ /dev/null @@ -1,399 +0,0 @@ -# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries -# -# SPDX-License-Identifier: Unlicense - -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist= - -# Add files or directories to the ignore-list. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the ignore-list. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. -jobs=1 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins=pylint.extensions.no_self_use - -# Pickle collected data for later comparisons. -persistent=yes - -# Specify a configuration file. -#rcfile= - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -# disable=import-error,raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,deprecated-str-translate-call -disable=raw-checker-failed,bad-inline-option,locally-disabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,import-error,pointless-string-statement,unspecified-encoding - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable= - - -[REPORTS] - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio).You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -# notes=FIXME,XXX,TODO -notes=FIXME,XXX - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules=board - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,future.builtins - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -# expected-line-ending-format= -expected-line-ending-format=LF - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=100 - -# Maximum number of lines in a module -max-module-lines=1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=yes - -# Minimum lines number of a similarity. -min-similarity-lines=12 - - -[BASIC] - -# Regular expression matching correct argument names -argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct attribute names -attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct class names -# class-rgx=[A-Z_][a-zA-Z0-9]+$ -class-rgx=[A-Z_][a-zA-Z0-9_]+$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Regular expression matching correct function names -function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Good variable names which should always be accepted, separated by a comma -# good-names=i,j,k,ex,Run,_ -good-names=r,g,b,w,i,j,k,n,x,y,z,ex,ok,Run,_ - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct method names -method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -property-classes=abc.abstractproperty - -# Regular expression matching correct variable names -variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - - -[IMPORTS] - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=optparse,tkinter.tix - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Maximum number of attributes for a class (see R0902). -# max-attributes=7 -max-attributes=11 - -# Maximum number of boolean expressions in a if statement -max-bool-expr=5 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of statements in function / method body -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=1 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=builtins.Exception diff --git a/README.rst b/README.rst index a797fcd..b9628db 100644 --- a/README.rst +++ b/README.rst @@ -13,9 +13,9 @@ Introduction :target: https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout/actions :alt: Build Status -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/psf/black - :alt: Code Style: Black +.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json + :target: https://github.com/astral-sh/ruff + :alt: Code Style: Ruff CircuitPython helper library for displayio layouts and widgets. diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index fd06895..5d2be9b 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -22,6 +22,7 @@ https://github.com/adafruit/circuitpython/releases """ + try: # Used only for typing from typing import Any, List, Optional, Tuple, Union @@ -29,6 +30,7 @@ pass import math + import displayio from vectorio import Rectangle @@ -58,8 +60,6 @@ class GridLayout(displayio.Group): """ - # pylint: disable=too-many-arguments - # pylint: disable=too-many-instance-attributes def __init__( self, x: int, @@ -106,9 +106,7 @@ def __init__( self.v_divider_line_cols.append(_x) # use at least 1 padding so that content is inside the divider lines - if cell_padding == 0 and ( - divider_lines or h_divider_line_rows or v_divider_line_cols - ): + if cell_padding == 0 and (divider_lines or h_divider_line_rows or v_divider_line_cols): self.cell_padding = 1 def layout_cells(self): @@ -116,7 +114,6 @@ def layout_cells(self): self._layout_cells() def _layout_cells(self) -> None: - # pylint: disable=too-many-locals, too-many-branches, too-many-statements for line_obj in self._divider_lines: self.remove(line_obj["rect"]) for cell in self._cell_content_list: @@ -310,11 +307,8 @@ def _layout_cells(self) -> None: areas larger than 1x1 cells. For 1x1 cells this will equal zero and not change anything. """ - if ( - grid_position_y + content_cell_size_y - 1 - ) == grid_size_y - 1 and ( - (grid_position_y + content_cell_size_y - 1) + 1 - in self.h_divider_line_rows + if (grid_position_y + content_cell_size_y - 1) == grid_size_y - 1 and ( + (grid_position_y + content_cell_size_y - 1) + 1 in self.h_divider_line_rows ): self._divider_lines.append( { @@ -350,11 +344,8 @@ def _layout_cells(self) -> None: areas larger than 1x1 cells. For 1x1 cells this will equal zero and not change anything. """ - if ( - grid_position_x + content_cell_size_x - 1 - ) == grid_size_x - 1 and ( - (grid_position_x + content_cell_size_x - 1) + 1 - in self.v_divider_line_cols + if (grid_position_x + content_cell_size_x - 1) == grid_size_x - 1 and ( + (grid_position_x + content_cell_size_x - 1) + 1 in self.v_divider_line_cols ): self._divider_lines.append( { @@ -426,11 +417,7 @@ def get_cell(self, cell_coordinates: Tuple[int, int]) -> displayio.Group: ): return self._cell_content_list[index]["content"] - raise KeyError( - "GridLayout does not contain cell at coordinates {}".format( - cell_coordinates - ) - ) + raise KeyError(f"GridLayout does not contain cell at coordinates {cell_coordinates}") @property def cell_size_pixels(self) -> Tuple[int, int]: diff --git a/adafruit_displayio_layout/layouts/linear_layout.py b/adafruit_displayio_layout/layouts/linear_layout.py index 3bcd6cb..9815300 100644 --- a/adafruit_displayio_layout/layouts/linear_layout.py +++ b/adafruit_displayio_layout/layouts/linear_layout.py @@ -54,7 +54,7 @@ def __init__( self.x = x self.y = y self.padding = padding - if orientation not in [self.VERTICAL_ORIENTATION, self.HORIZONTAL_ORIENTATION]: + if orientation not in {self.VERTICAL_ORIENTATION, self.HORIZONTAL_ORIENTATION}: raise ValueError( "Orientation must be either LinearLayout.VERTICAL_ORIENTATION" " or LinearLayout.HORIZONTAL_ORIENTATION" @@ -77,7 +77,6 @@ def add_content(self, content): self._layout() def _layout(self): - # pylint: disable=too-many-branches, protected-access self._prev_content_end = 0 for _, content in enumerate(self._content_list): @@ -100,14 +99,10 @@ def _layout(self): else: content.x = self._prev_content_end if not hasattr(content, "tile_width"): - self._prev_content_end = ( - content.x + content.width + (self.padding * 2) - ) + self._prev_content_end = content.x + content.width + (self.padding * 2) else: self._prev_content_end = ( - content.x - + (content.width * content.tile_width) - + (self.padding * 2) + content.x + (content.width * content.tile_width) + (self.padding * 2) ) else: # use anchor point content.anchor_point = ( @@ -130,9 +125,7 @@ def _layout(self): else: original_achored_pos_y = ( - content.anchored_position[1] - if content.anchored_position is not None - else 0 + content.anchored_position[1] if content.anchored_position is not None else 0 ) content.anchored_position = ( diff --git a/adafruit_displayio_layout/layouts/page_layout.py b/adafruit_displayio_layout/layouts/page_layout.py index 040ccbd..8e69c63 100644 --- a/adafruit_displayio_layout/layouts/page_layout.py +++ b/adafruit_displayio_layout/layouts/page_layout.py @@ -22,9 +22,9 @@ https://github.com/adafruit/circuitpython/releases """ + try: # Used only for typing - # pylint: disable=unused-import from typing import Tuple except ImportError: @@ -90,16 +90,12 @@ def _check_args(self, page_name, page_index): raise AttributeError("Must pass either page_name or page_index") if page_index is not None and page_name is not None: - raise AttributeError( - "Must pass either page_name or page_index only one or the other" - ) + raise AttributeError("Must pass either page_name or page_index only one or the other") if page_index is not None: if page_index >= len(self.page_content_list): raise KeyError( - "KeyError at index {} in list length {}".format( - page_index, len(self.page_content_list) - ), + f"KeyError at index {page_index} in list length {len(self.page_content_list)}", ) if page_name is not None: @@ -110,7 +106,7 @@ def _check_args(self, page_name, page_index): _found = True if not _found: - raise KeyError("Page with name {} not found".format(page_name)) + raise KeyError(f"Page with name {page_name} not found") def get_page(self, page_name=None, page_index=None): """ @@ -133,9 +129,7 @@ def get_page(self, page_name=None, page_index=None): return cell raise KeyError( - "PageLayout does not contain page: {}".format( - page_index if page_index else page_name - ) + f"PageLayout does not contain page: {page_index if page_index else page_name}" ) def show_page(self, page_name=None, page_index=None): @@ -205,11 +199,10 @@ def next_page(self, loop=True): if self._cur_showing_index + 1 < len(self.page_content_list): self.show_page(page_index=self._cur_showing_index + 1) + elif not loop: + print("No more pages") else: - if not loop: - print("No more pages") - else: - self.show_page(page_index=0) + self.show_page(page_index=0) def previous_page(self, loop=True): """ @@ -219,8 +212,7 @@ def previous_page(self, loop=True): """ if self._cur_showing_index - 1 >= 0: self.show_page(page_index=self._cur_showing_index - 1) + elif not loop: + print("No more pages") else: - if not loop: - print("No more pages") - else: - self.show_page(page_index=len(self.page_content_list) - 1) + self.show_page(page_index=len(self.page_content_list) - 1) diff --git a/adafruit_displayio_layout/layouts/tab_layout.py b/adafruit_displayio_layout/layouts/tab_layout.py index e63f021..ac5875d 100644 --- a/adafruit_displayio_layout/layouts/tab_layout.py +++ b/adafruit_displayio_layout/layouts/tab_layout.py @@ -22,19 +22,22 @@ https://github.com/adafruit/circuitpython/releases """ + try: - from typing import Optional, Union, Tuple - from fontio import BuiltinFont + from typing import Optional, Tuple, Union + from adafruit_bitmap_font.bdf import BDF from adafruit_bitmap_font.pcf import PCF + from fontio import BuiltinFont except ImportError: pass -import terminalio -import displayio import adafruit_imageload +import displayio +import terminalio from adafruit_display_text.bitmap_label import Label from adafruit_imageload.tilegrid_inflator import inflate_tilegrid + from adafruit_displayio_layout.layouts.page_layout import PageLayout __version__ = "0.0.0+auto.0" @@ -68,8 +71,6 @@ class TabLayout(displayio.Group): :param int tab_count: How many tabs to draw in the layout. Positive whole numbers are valid. """ - # pylint: disable=too-many-instance-attributes, too-many-arguments, invalid-name, too-many-branches - def __init__( self, x: int = 0, @@ -86,8 +87,7 @@ def __init__( tab_count: int = None, ): if display is None: - # pylint: disable=import-outside-toplevel - import board + import board # noqa: PLC0415, non-top-level-import if hasattr(board, "DISPLAY"): display = board.DISPLAY @@ -100,9 +100,7 @@ def __init__( super().__init__(x=x, y=y) self.tab_count = tab_count - self._active_bmp, self._active_palette = adafruit_imageload.load( - showing_tab_spritesheet - ) + self._active_bmp, self._active_palette = adafruit_imageload.load(showing_tab_spritesheet) self._inactive_bmp, self._inactive_palette = adafruit_imageload.load( inactive_tab_spritesheet ) @@ -121,9 +119,7 @@ def __init__( for index in inactive_tab_transparent_indexes: self._inactive_palette.make_transparent(index) else: - raise AttributeError( - "inactive_tab_transparent_indexes must be int or tuple" - ) + raise AttributeError("inactive_tab_transparent_indexes must be int or tuple") self.tab_height = self._active_bmp.height self.display = display @@ -147,8 +143,7 @@ def _draw_tabs(self): bmp_obj=self._inactive_bmp, bmp_palette=self._inactive_palette, target_size=( - (self.display.width // self.tab_count) - // (self._active_bmp.width // 3), + (self.display.width // self.tab_count) // (self._active_bmp.width // 3), 3, ), ) @@ -165,8 +160,7 @@ def _draw_tabs(self): _tab_label.anchor_point = (0.5, 0.5) _tab_label.anchored_position = ( - _tab_tilegrid.x - + ((_tab_tilegrid.width * _tab_tilegrid.tile_width) // 2), + _tab_tilegrid.x + ((_tab_tilegrid.width * _tab_tilegrid.tile_width) // 2), (_tab_tilegrid.height * _tab_tilegrid.tile_height) // 2, ) _new_tab_group.append(_tab_label) @@ -282,8 +276,6 @@ def handle_touch_events(self, touch_event): if touch_event: if 0 <= touch_event[1] <= self.tab_height: - touched_tab_index = touch_event[0] // ( - self.display.width // self.tab_count - ) + touched_tab_index = touch_event[0] // (self.display.width // self.tab_count) print(f"{touch_event[0]} - {touched_tab_index}") self.showing_page_index = touched_tab_index diff --git a/adafruit_displayio_layout/widgets/cartesian.py b/adafruit_displayio_layout/widgets/cartesian.py index bcb11dc..50ca8a3 100644 --- a/adafruit_displayio_layout/widgets/cartesian.py +++ b/adafruit_displayio_layout/widgets/cartesian.py @@ -21,13 +21,11 @@ """ -# pylint: disable=too-many-lines, too-many-instance-attributes, too-many-arguments -# pylint: disable=too-many-locals, too-many-statements - import displayio import terminalio -from adafruit_display_text import bitmap_label import vectorio +from adafruit_display_text import bitmap_label + from adafruit_displayio_layout.widgets.widget import Widget try: @@ -229,28 +227,20 @@ def __init__( self._valuey = self.height / 100 self._factory = 100 / (self._yrange[1] - self._yrange[0]) - self._tick_bitmap = displayio.Bitmap( - self._tick_line_thickness, self._tick_line_height, 3 - ) + self._tick_bitmap = displayio.Bitmap(self._tick_line_thickness, self._tick_line_height, 3) self._tick_bitmap.fill(1) self._subticks = subticks axesx_height = ( - 2 - + self._axes_line_thickness - + self._font_height - + self._tick_line_height // 2 + 2 + self._axes_line_thickness + self._font_height + self._tick_line_height // 2 ) self._axesx_bitmap = displayio.Bitmap(self.width, axesx_height, 4) self._axesx_bitmap.fill(0) self._axesy_width = ( - 2 - + self._axes_line_thickness - + self._font_width - + self._tick_line_height // 2 + 2 + self._axes_line_thickness + self._font_width + self._tick_line_height // 2 ) self._axesy_bitmap = displayio.Bitmap(self._axesy_width, self.height, 4) @@ -408,20 +398,14 @@ def _draw_ticks(self) -> None: self._font, color=self._font_color, text=text_tick, - x=-shift_label_x - - self._axes_line_thickness - - self._tick_line_height - - 2, + x=-shift_label_x - self._axes_line_thickness - self._tick_line_height - 2, y=0 + self.height - text_dist, ) self.append(tick_text) bitmaptools.fill_region( self._axesy_bitmap, - self._axesy_width - - self._axes_line_thickness - - self._tick_line_height - - 1, + self._axesy_width - self._axes_line_thickness - self._tick_line_height - 1, text_dist, self._axesy_width - self._axes_line_thickness - 1, text_dist + self._tick_line_thickness, @@ -453,9 +437,7 @@ def _draw_pointers(self, x: int, y: int) -> None: self.append(self._pointer) def _calc_local_xy(self, x: int, y: int) -> Tuple[int, int]: - local_x = ( - int((x - self._xrange[0]) * self._factorx * self._valuex) + self._nudge_x - ) + local_x = int((x - self._xrange[0]) * self._factorx * self._valuex) + self._nudge_x # details on `+ (self.height - 1)` : # the bitmap is set to self.width & self.height # but we are only allowed to draw to pixels 0..height-1 and 0..width-1 @@ -473,9 +455,7 @@ def _check_local_y_in_range(self, local_y: int) -> bool: return 0 <= local_y < self.height def _check_local_xy_in_range(self, local_x: int, local_y: int) -> bool: - return self._check_local_x_in_range(local_x) and self._check_local_y_in_range( - local_y - ) + return self._check_local_x_in_range(local_x) and self._check_local_y_in_range(local_y) def _check_x_in_range(self, x: int) -> bool: return self._xrange[0] <= x <= self._xrange[1] @@ -498,30 +478,15 @@ def _add_point(self, x: int, y: int) -> None: if self._verbose: print("") print( - "xy: ({: >4}, {: >4}) " - "_xrange: ({: >4}, {: >4}) " - "_yrange: ({: >4}, {: >4}) " - "".format( - x, - y, - self._xrange[0], - self._xrange[1], - self._yrange[0], - self._yrange[1], - ) + f"xy: ({x: >4}, {y: >4}) " + + f"_xrange: ({self._xrange[0]: >4}, {self._xrange[1]: >4}) " + + f"_yrange: ({self._yrange[0]: >4}, {self._yrange[1]: >4}) " + "" ) print( - "local_*: ({: >4}, {: >4}) " - " width: ({: >4}, {: >4}) " - " height: ({: >4}, {: >4}) " - "".format( - local_x, - local_y, - 0, - self.width, - 0, - self.height, - ) + f"local_*: ({local_x: >4}, {local_y: >4}) " + + f" width: ({0: >4}, {self.width: >4}) " + + f" height: ({0: >4}, {self.height: >4}) " ) if self._check_xy_in_range(x, y): if self._check_local_xy_in_range(local_x, local_y): @@ -536,44 +501,28 @@ def _add_point(self, x: int, y: int) -> None: if not self._check_local_x_in_range(local_x): raise ValueError( "local_x out of range: " - "local_x:{: >4}; _xrange({: >4}, {: >4})" - "".format( - local_x, - 0, - self.width, - ) + f"local_x:{local_x: >4}; _xrange({0: >4}, {self.width: >4})" + "" ) if not self._check_local_y_in_range(local_y): raise ValueError( "local_y out of range: " - "local_y:{: >4}; _yrange({: >4}, {: >4})" - "".format( - local_y, - 0, - self.height, - ) + f"local_y:{local_y: >4}; _yrange({0: >4}, {self.height: >4})" + "" ) else: # for better error messages we check in detail what failed... if not self._check_x_in_range(x): raise ValueError( "x out of range: " - "x:{: >4}; xrange({: >4}, {: >4})" - "".format( - x, - self._xrange[0], - self._xrange[1], - ) + f"x:{x: >4}; xrange({self._xrange[0]: >4}, {self._xrange[1]: >4})" + "" ) if not self._check_y_in_range(y): raise ValueError( "y out of range: " - "y:{: >4}; yrange({: >4}, {: >4})" - "".format( - y, - self._yrange[0], - self._yrange[1], - ) + f"y:{y: >4}; yrange({self._yrange[0]: >4}, {self._yrange[1]: >4})" + "" ) def update_pointer(self, x: int, y: int) -> None: diff --git a/adafruit_displayio_layout/widgets/control.py b/adafruit_displayio_layout/widgets/control.py index f9e5a2b..464804e 100644 --- a/adafruit_displayio_layout/widgets/control.py +++ b/adafruit_displayio_layout/widgets/control.py @@ -30,8 +30,6 @@ __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout.git" -# pylint: disable=unsubscriptable-object, unnecessary-pass - class Control: """A Control class for responsive elements, including touch response functions for displays. diff --git a/adafruit_displayio_layout/widgets/easing.py b/adafruit_displayio_layout/widgets/easing.py index 9a1e9a9..db2d2d0 100644 --- a/adafruit_displayio_layout/widgets/easing.py +++ b/adafruit_displayio_layout/widgets/easing.py @@ -75,7 +75,6 @@ import math - __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout.git" @@ -285,7 +284,7 @@ def exponential_easeinout(pos: float) -> float: """ Easing function for animations: Exponential Ease In & Out """ - if pos in (0.0, 1.0): + if pos in {0.0, 1.0}: return pos if pos < 0.5: return 0.5 * math.pow(2, (20 * pos) - 10) @@ -318,8 +317,7 @@ def elastic_easeinout(pos: float) -> float: if pos < 0.5: return 0.5 * math.sin(13 * math.pi * pos) * math.pow(2, 10 * ((2 * pos) - 1)) return 0.5 * ( - math.sin(-13 * math.pi / 2 * ((2 * pos - 1) + 1)) * pow(2, -10 * (2 * pos - 1)) - + 2 + math.sin(-13 * math.pi / 2 * ((2 * pos - 1) + 1)) * pow(2, -10 * (2 * pos - 1)) + 2 ) diff --git a/adafruit_displayio_layout/widgets/flip_input.py b/adafruit_displayio_layout/widgets/flip_input.py index 1474225..cbdae52 100644 --- a/adafruit_displayio_layout/widgets/flip_input.py +++ b/adafruit_displayio_layout/widgets/flip_input.py @@ -23,20 +23,18 @@ import gc import time -import displayio -from terminalio import FONT +import displayio from adafruit_display_shapes.triangle import Triangle - from adafruit_display_text import bitmap_label -from adafruit_displayio_layout.widgets.widget import Widget -from adafruit_displayio_layout.widgets.control import Control +from terminalio import FONT -# pylint: disable=reimported +from adafruit_displayio_layout.widgets.control import Control # select the two "easing" functions to use for animations from adafruit_displayio_layout.widgets.easing import back_easeinout as easein from adafruit_displayio_layout.widgets.easing import back_easeinout as easeout +from adafruit_displayio_layout.widgets.widget import Widget try: from typing import Any, List, Optional, Tuple @@ -48,10 +46,6 @@ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout.git" -# pylint: disable=too-many-arguments, too-many-branches, too-many-statements -# pylint: disable=too-many-locals, too-many-instance-attributes - - class FlipInput(Widget, Control): """A flip style input selector. The value changes based on touch inputs on the two halves of the indicator with optional arrows added. @@ -121,7 +115,6 @@ def __init__( # initialize the Control superclass - # pylint: disable=bad-super-call super(Control, self).__init__() self.value_list = value_list @@ -157,18 +150,14 @@ def __init__( for i, character in enumerate(this_value): glyph = self._font.get_glyph(ord(character)) - if ( - i == 0 - ): # if it's the first character in the string, check the left value + if i == 0: # if it's the first character in the string, check the left value if left is None: left = glyph.dx else: left = min(left, glyph.dx) if right is None: - right = max( - xposition + glyph.dx + glyph.width, xposition + glyph.shift_x - ) + right = max(xposition + glyph.dx + glyph.width, xposition + glyph.shift_x) else: right = max( right, @@ -189,12 +178,7 @@ def __init__( xposition = xposition + glyph.shift_x # Something is wrong if left, right, top, or bottom are still None here - assert ( - right is not None - and left is not None - and top is not None - and bottom is not None - ) + assert right is not None and left is not None and top is not None and bottom is not None self._bounding_box = [ 0, @@ -226,10 +210,7 @@ def __init__( if horizontal: # horizontal orientation, add arrow padding to x-dimension and # alt_padding to y-dimension self.touch_boundary = ( - self._bounding_box[0] - - self._arrow_gap - - arrow_height - - self._arrow_touch_padding, + self._bounding_box[0] - self._arrow_gap - arrow_height - self._arrow_touch_padding, self._bounding_box[1] - self._alt_touch_padding, self._bounding_box[2] + 2 * (self._arrow_gap + arrow_height + self._arrow_touch_padding), @@ -239,10 +220,7 @@ def __init__( # alt_padding to x-dimension self.touch_boundary = ( self._bounding_box[0] - self._alt_touch_padding, - self._bounding_box[1] - - self._arrow_gap - - arrow_height - - self._arrow_touch_padding, + self._bounding_box[1] - self._arrow_gap - arrow_height - self._arrow_touch_padding, self._bounding_box[2] + 2 * self._alt_touch_padding, self._bounding_box[3] + 2 * (self._arrow_gap + arrow_height + self._arrow_touch_padding), @@ -263,11 +241,7 @@ def __init__( if (arrow_color is not None) or (arrow_outline is not None): if horizontal: # horizontal orientation, add left and right arrows - if ( - (arrow_width is not None) - and (arrow_height is not None) - and (arrow_width > 0) - ): + if (arrow_width is not None) and (arrow_height is not None) and (arrow_width > 0): mid_point_y = self._bounding_box[1] + self._bounding_box[3] // 2 self.append( Triangle( @@ -284,13 +258,9 @@ def __init__( self.append( Triangle( - self._bounding_box[0] - + self._bounding_box[2] - + self._arrow_gap, + self._bounding_box[0] + self._bounding_box[2] + self._arrow_gap, mid_point_y - arrow_height // 2, - self._bounding_box[0] - + self._bounding_box[2] - + self._arrow_gap, + self._bounding_box[0] + self._bounding_box[2] + self._arrow_gap, mid_point_y + arrow_height // 2, self._bounding_box[0] + self._bounding_box[2] @@ -301,44 +271,35 @@ def __init__( outline=arrow_outline, ) ) - else: # vertical orientation, add upper and lower arrows - if ( - (arrow_height is not None) - and (arrow_width is not None) - and (arrow_height > 0) - ): - mid_point_x = self._bounding_box[0] + self._bounding_box[2] // 2 - self.append( - Triangle( - mid_point_x - arrow_width // 2, - self._bounding_box[1] - self._arrow_gap, - mid_point_x + arrow_width // 2, - self._bounding_box[1] - self._arrow_gap, - mid_point_x, - self._bounding_box[1] - self._arrow_gap - arrow_height, - fill=arrow_color, - outline=arrow_outline, - ) + elif (arrow_height is not None) and (arrow_width is not None) and (arrow_height > 0): + mid_point_x = self._bounding_box[0] + self._bounding_box[2] // 2 + self.append( + Triangle( + mid_point_x - arrow_width // 2, + self._bounding_box[1] - self._arrow_gap, + mid_point_x + arrow_width // 2, + self._bounding_box[1] - self._arrow_gap, + mid_point_x, + self._bounding_box[1] - self._arrow_gap - arrow_height, + fill=arrow_color, + outline=arrow_outline, ) - self.append( - Triangle( - mid_point_x - arrow_width // 2, - self._bounding_box[1] - + self._bounding_box[3] - + self._arrow_gap, - mid_point_x + arrow_width // 2, - self._bounding_box[1] - + self._bounding_box[3] - + self._arrow_gap, - mid_point_x, - self._bounding_box[1] - + self._bounding_box[3] - + self._arrow_gap - + arrow_height, - fill=arrow_color, - outline=arrow_outline, - ) + ) + self.append( + Triangle( + mid_point_x - arrow_width // 2, + self._bounding_box[1] + self._bounding_box[3] + self._arrow_gap, + mid_point_x + arrow_width // 2, + self._bounding_box[1] + self._bounding_box[3] + self._arrow_gap, + mid_point_x, + self._bounding_box[1] + + self._bounding_box[3] + + self._arrow_gap + + arrow_height, + fill=arrow_color, + outline=arrow_outline, ) + ) # Draw function to update the current value def _update_value(self, new_value: int, animate: bool = True) -> None: @@ -370,9 +331,7 @@ def _update_value(self, new_value: int, animate: bool = True) -> None: palette = displayio.Palette(2) palette.make_transparent(0) palette[1] = self._color - animation_tilegrid = displayio.TileGrid( - animation_bitmap, pixel_shader=palette - ) + animation_tilegrid = displayio.TileGrid(animation_bitmap, pixel_shader=palette) # add bitmap to the animation_group self._animation_group.append(animation_tilegrid) @@ -452,9 +411,7 @@ def contains( # offsetting for self.x and self.y before calling the Control superclass function # ###### - touch_x = ( - touch_point[0] - self.x - ) # adjust touch position for the local position + touch_x = touch_point[0] - self.x # adjust touch position for the local position touch_y = touch_point[1] - self.y return super().contains((touch_x, touch_y, 0)) @@ -475,29 +432,22 @@ def selected(self, touch_point: Tuple[int, int, Optional[int]]) -> None: self.value = self.value - 1 elif ( - (t_b[0] + t_b[2] // 2) - <= (touch_point[0] - self.x) - <= (t_b[0] + t_b[2]) + (t_b[0] + t_b[2] // 2) <= (touch_point[0] - self.x) <= (t_b[0] + t_b[2]) ): # in right half of touch_boundary self.value = self.value + 1 - else: - if ( - t_b[1] <= (touch_point[1] - self.y) < (t_b[1] + t_b[3] // 2) - ): # in upper half of touch_boundary - self.value = self.value + 1 + elif ( + t_b[1] <= (touch_point[1] - self.y) < (t_b[1] + t_b[3] // 2) + ): # in upper half of touch_boundary + self.value = self.value + 1 - elif ( - (t_b[1] + t_b[3] // 2) - <= (touch_point[1] - self.y) - <= (t_b[1] + t_b[3]) - ): # in lower half of touch_boundary - self.value = self.value - 1 + elif ( + (t_b[1] + t_b[3] // 2) <= (touch_point[1] - self.y) <= (t_b[1] + t_b[3]) + ): # in lower half of touch_boundary + self.value = self.value - 1 self._pressed = True # update the state variable - self._last_pressed = ( - time.monotonic() - ) # value changed, so update cool_down timer + self._last_pressed = time.monotonic() # value changed, so update cool_down timer def released(self) -> None: """Response function when the Control is released. Resets the state variables @@ -525,9 +475,7 @@ def value( try: new_value = self.value_list.index(new_value) except ValueError: - print( - 'ValueError: Value "{}" not found in value_list.'.format(new_value) - ) + print(f'ValueError: Value "{new_value}" not found in value_list.') return None new_value = new_value % len(self.value_list) # Update the value @@ -590,9 +538,6 @@ def _draw_position( ) -# pylint: disable=invalid-name - - # _blit_constrained: Copies bitmaps with constraints to the dimensions def _blit_constrained( target: displayio.Bitmap, @@ -633,12 +578,7 @@ def _blit_constrained( if y2 > source.height: y2 = source.height - if ( - (x > target.width) - or (y > target.height) - or (x1 > source.width) - or (y1 > source.height) - ): + if (x > target.width) or (y > target.height) or (x1 > source.width) or (y1 > source.height): return target.blit(x, y, source, x1=x1, y1=y1, x2=x2, y2=y2) @@ -683,9 +623,7 @@ def _animate_bitmap( this_time = time.monotonic() target_position = ( start_position - + (end_position - start_position) - * (this_time - start_time) - / animation_time + + (end_position - start_position) * (this_time - start_time) / animation_time ) display.auto_refresh = False diff --git a/adafruit_displayio_layout/widgets/icon_animated.py b/adafruit_displayio_layout/widgets/icon_animated.py index 2e5db2f..2e43821 100644 --- a/adafruit_displayio_layout/widgets/icon_animated.py +++ b/adafruit_displayio_layout/widgets/icon_animated.py @@ -21,19 +21,23 @@ https://github.com/adafruit/circuitpython/releases """ + import gc import time from math import pi -import bitmaptools -from displayio import TileGrid, Bitmap, Palette + import adafruit_imageload -from adafruit_displayio_layout.widgets.icon_widget import IconWidget -from adafruit_displayio_layout.widgets.easing import quadratic_easeout as easein +import bitmaptools +from displayio import Bitmap, Palette, TileGrid + from adafruit_displayio_layout.widgets.easing import quadratic_easein as easeout +from adafruit_displayio_layout.widgets.easing import quadratic_easeout as easein +from adafruit_displayio_layout.widgets.icon_widget import IconWidget try: from typing import Any, Optional, Tuple - from displayio import Display # pylint: disable=ungrouped-imports + + from busdisplay import BusDisplay except ImportError: pass @@ -43,7 +47,6 @@ class IconAnimated(IconWidget): - """ An animated touch enabled widget that holds an icon image loaded with OnDiskBitmap and a text label centered beneath it. Includes optional @@ -76,9 +79,6 @@ class IconAnimated(IconWidget): :type anchored_position: Tuple[int, int] """ - # pylint: disable=bad-super-call, too-many-instance-attributes, too-many-locals - # pylint: disable=too-many-arguments, unused-argument - display = None # The other Class variables are created in Class method `init_class`: # max_scale, bitmap_buffer, palette_buffer @@ -86,7 +86,7 @@ class IconAnimated(IconWidget): @classmethod def init_class( cls, - display: Optional[Display], + display: Optional[BusDisplay], max_scale: float = 1.5, max_icon_size: Tuple[int, int] = (80, 80), max_color_depth: int = 256, @@ -168,9 +168,8 @@ def __init__( if scale > self.__class__.max_scale: print( "Warning - IconAnimated: max_scale is constrained by value of " - "IconAnimated.max_scale set by IconAnimated.init_class(): {}".format( - self.__class__.max_scale - ) + "IconAnimated.max_scale set by " + f"IconAnimated.init_class(): {self.__class__.max_scale}" ) self._scale = max(0, min(scale, self.__class__.max_scale)) @@ -233,9 +232,7 @@ def zoom_animation(self, touch_point: Tuple[int, int, Optional[int]]) -> None: ) # blit the image into the center of the zoom_bitmap # place zoom_bitmap at same location as image - animation_tilegrid = TileGrid( - animation_bitmap, pixel_shader=animation_palette - ) + animation_tilegrid = TileGrid(animation_bitmap, pixel_shader=animation_palette) animation_tilegrid.x = -(animation_bitmap.width - _image.width) // 2 animation_tilegrid.y = -(animation_bitmap.height - _image.height) // 2 diff --git a/adafruit_displayio_layout/widgets/icon_widget.py b/adafruit_displayio_layout/widgets/icon_widget.py index 318d1c6..2a262cc 100644 --- a/adafruit_displayio_layout/widgets/icon_widget.py +++ b/adafruit_displayio_layout/widgets/icon_widget.py @@ -22,11 +22,11 @@ """ - -import terminalio -from displayio import TileGrid, OnDiskBitmap import adafruit_imageload +import terminalio from adafruit_display_text import bitmap_label +from displayio import OnDiskBitmap, TileGrid + from adafruit_displayio_layout.widgets.control import Control from adafruit_displayio_layout.widgets.widget import Widget @@ -41,7 +41,6 @@ class IconWidget(Widget, Control): - """ A touch enabled widget that holds an icon image loaded with adafruit_imageload and a text label centered beneath it. @@ -63,8 +62,6 @@ class IconWidget(Widget, Control): :type anchored_position: Tuple[int, int] """ - # pylint: disable=too-many-arguments - def __init__( self, label_text: str, @@ -72,7 +69,7 @@ def __init__( on_disk: bool = False, transparent_index: Optional[int] = None, label_background: Optional[int] = None, - **kwargs: Any + **kwargs: Any, ) -> None: super().__init__(**kwargs) @@ -120,9 +117,7 @@ def contains( :return: Boolean """ - touch_x = ( - touch_point[0] - self.x - ) # adjust touch position for the local position + touch_x = touch_point[0] - self.x # adjust touch position for the local position touch_y = touch_point[1] - self.y return super().contains((touch_x, touch_y, 0)) diff --git a/adafruit_displayio_layout/widgets/switch_round.py b/adafruit_displayio_layout/widgets/switch_round.py index e583b18..8ce0320 100644 --- a/adafruit_displayio_layout/widgets/switch_round.py +++ b/adafruit_displayio_layout/widgets/switch_round.py @@ -35,14 +35,16 @@ # import time + from adafruit_display_shapes.circle import Circle -from adafruit_display_shapes.roundrect import RoundRect from adafruit_display_shapes.rect import Rect -from adafruit_displayio_layout.widgets.widget import Widget +from adafruit_display_shapes.roundrect import RoundRect + from adafruit_displayio_layout.widgets.control import Control # modify the "easing" function that is imported to change the switch animation behaviour from adafruit_displayio_layout.widgets.easing import back_easeinout as easing +from adafruit_displayio_layout.widgets.widget import Widget try: from typing import Any, Optional, Tuple, Union @@ -55,7 +57,6 @@ class SwitchRound(Widget, Control): - """ .. note:: Jump directly to: @@ -419,9 +420,6 @@ class functions. The `Widget` class handles the overall sizing and positioning """ - # pylint: disable=too-many-instance-attributes, too-many-arguments, too-many-locals - # pylint: disable=too-many-branches, too-many-statements - def __init__( self, x: int = 0, @@ -469,7 +467,6 @@ def __init__( # initialize the Control superclass - # pylint: disable=bad-super-call super(Control, self).__init__() self._horizontal = horizontal @@ -698,9 +695,7 @@ def _draw_position(self, position: float) -> None: position = easing(position) # Get the position offset from the motion function - x_offset, y_offset, _ = self._get_offset_position( - position - ) # ignore angle_offset + x_offset, y_offset, _ = self._get_offset_position(position) # ignore angle_offset # Update the switch and text x- and y-positions self._switch_circle.x = self._switch_initial_x + x_offset @@ -711,9 +706,7 @@ def _draw_position(self, position: float) -> None: self._text_1.y = self._text_1_initial_y + y_offset # Set the color to the correct fade - self._switch_circle.fill = _color_fade( - self._fill_color_off, self._fill_color_on, position - ) + self._switch_circle.fill = _color_fade(self._fill_color_off, self._fill_color_on, position) self._switch_circle.outline = _color_fade( self._outline_color_off, self._outline_color_on, position ) @@ -774,9 +767,7 @@ def _animate_switch(self) -> None: elapsed_time = self._animation_time if self._value: - position = ( - 1 - (elapsed_time) / self._animation_time - ) # fraction from 0 to 1 + position = 1 - (elapsed_time) / self._animation_time # fraction from 0 to 1 else: # fraction from 0 to 1 position = (elapsed_time) / self._animation_time @@ -789,9 +780,7 @@ def _animate_switch(self) -> None: if (position >= 1) and not self._value: self._value = True break - if ( - position <= 0 - ) and self._value: # ensures that the final position is drawn + if (position <= 0) and self._value: # ensures that the final position is drawn self._value = False break @@ -807,9 +796,7 @@ def selected(self, touch_point: Tuple[int, int, Optional[int]]) -> None: self._animate_switch() # show the animation and switch the self._value - touch_x = ( - touch_point[0] - self.x - ) # adjust touch position for the local position + touch_x = touch_point[0] - self.x # adjust touch position for the local position touch_y = touch_point[1] - self.y # Call the parent's .selected function in case there is any work up there. @@ -827,9 +814,7 @@ def contains( :return: Boolean """ - touch_x = ( - touch_point[0] - self.x - ) # adjust touch position for the local position + touch_x = touch_point[0] - self.x # adjust touch position for the local position touch_y = touch_point[1] - self.y return super().contains((touch_x, touch_y, 0)) @@ -945,7 +930,5 @@ def _color_fade( faded_color = [0, 0, 0] for i in range(3): - faded_color[i] = start_color[i] - int( - (start_color[i] - end_color[i]) * fraction - ) + faded_color[i] = start_color[i] - int((start_color[i] - end_color[i]) * fraction) return tuple(faded_color) diff --git a/adafruit_displayio_layout/widgets/widget.py b/adafruit_displayio_layout/widgets/widget.py index 7a376f1..2e6bd8d 100644 --- a/adafruit_displayio_layout/widgets/widget.py +++ b/adafruit_displayio_layout/widgets/widget.py @@ -33,8 +33,6 @@ __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout.git" -# pylint: disable=too-many-arguments - class Widget(displayio.Group): """ diff --git a/docs/api.rst b/docs/api.rst index a707e30..0cddc93 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,6 +4,9 @@ .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) .. use this format as the module name: "adafruit_foo.foo" +API Reference +############# + .. automodule:: adafruit_displayio_layout.layouts.grid_layout :members: :private-members: diff --git a/docs/conf.py b/docs/conf.py index a314186..a0e4431 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,12 +1,10 @@ -# -*- coding: utf-8 -*- - # SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries # # SPDX-License-Identifier: MIT +import datetime import os import sys -import datetime sys.path.insert(0, os.path.abspath("..")) @@ -55,9 +53,7 @@ creation_year = "2021" current_year = str(datetime.datetime.now().year) year_duration = ( - current_year - if current_year == creation_year - else creation_year + " - " + current_year + current_year if current_year == creation_year else creation_year + " - " + current_year ) copyright = year_duration + " Tim Cocks" author = "Tim Cocks" diff --git a/examples/displayio_layout_cartesian_advanced_test.py b/examples/displayio_layout_cartesian_advanced_test.py index e10a765..3acda2e 100644 --- a/examples/displayio_layout_cartesian_advanced_test.py +++ b/examples/displayio_layout_cartesian_advanced_test.py @@ -10,6 +10,7 @@ import board import displayio import terminalio + from adafruit_displayio_layout.widgets.cartesian import Cartesian # Fonts used for the Dial tick labels diff --git a/examples/displayio_layout_cartesian_lineplot.py b/examples/displayio_layout_cartesian_lineplot.py index 14683a0..54ac442 100644 --- a/examples/displayio_layout_cartesian_lineplot.py +++ b/examples/displayio_layout_cartesian_lineplot.py @@ -7,8 +7,10 @@ """ import time + import board import displayio + from adafruit_displayio_layout.widgets.cartesian import Cartesian # create the display on the PyPortal or Clue or PyBadge(for example) diff --git a/examples/displayio_layout_cartesian_simpletest.py b/examples/displayio_layout_cartesian_simpletest.py index e859380..ba1353c 100644 --- a/examples/displayio_layout_cartesian_simpletest.py +++ b/examples/displayio_layout_cartesian_simpletest.py @@ -7,9 +7,11 @@ """ import time + import board import displayio import terminalio + from adafruit_displayio_layout.widgets.cartesian import Cartesian # Fonts used for the Dial tick labels diff --git a/examples/displayio_layout_flip_input_simpletest.py b/examples/displayio_layout_flip_input_simpletest.py index c51c00d..c6c3ce0 100755 --- a/examples/displayio_layout_flip_input_simpletest.py +++ b/examples/displayio_layout_flip_input_simpletest.py @@ -6,13 +6,13 @@ This is a basic demonstration of a FlipInput widget. """ -# pylint: disable=invalid-name - import time + +import adafruit_touchscreen import board import displayio -import adafruit_touchscreen from adafruit_bitmap_font import bitmap_font + from adafruit_displayio_layout.widgets.flip_input import FlipInput display = board.DISPLAY # create the display on the PyPortal, @@ -62,7 +62,7 @@ anchor_point=[0.0, 0.0], anchored_position=[220, 40], color=0xFF2222, # reddish orange color - value_list=["{0:02d}".format(x) for x in range(1, 31 + 1)], + value_list=[f"{x:02d}" for x in range(1, 31 + 1)], # use a list of strings from 01 through 31 # use the {0:02d} format string to always use two digits (e.g. '03') font_scale=5, @@ -75,7 +75,7 @@ anchor_point=[0.5, 1.0], anchored_position=[320 // 2, 240 - 10], color=0xFF2222, # reddish orange color - value_list=["{}".format(x) for x in range(1985, 2022, 1)], + value_list=[f"{x}" for x in range(1985, 2022, 1)], # use a list with values of stringsfrom 1985 to 2022 font=my_font, horizontal=True, # use horizontal arrows diff --git a/examples/displayio_layout_grid_layout_get_cell_test.py b/examples/displayio_layout_grid_layout_get_cell_test.py index 9e6d674..06ccfd0 100644 --- a/examples/displayio_layout_grid_layout_get_cell_test.py +++ b/examples/displayio_layout_grid_layout_get_cell_test.py @@ -5,10 +5,12 @@ Make green and purple rectangles and then update the color and text values of the labels using the get_cell() function. """ + import board import displayio import terminalio from adafruit_display_text import label + from adafruit_displayio_layout.layouts.grid_layout import GridLayout # use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) @@ -31,15 +33,11 @@ _labels = [] _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077) ) layout.add_content(_labels[0], grid_position=(0, 0), cell_size=(1, 1)) _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700) ) layout.add_content(_labels[1], grid_position=(1, 0), cell_size=(1, 1)) _labels.append(label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello")) diff --git a/examples/displayio_layout_gridlayout_dividers.py b/examples/displayio_layout_gridlayout_dividers.py index d7cefab..34e47b9 100644 --- a/examples/displayio_layout_gridlayout_dividers.py +++ b/examples/displayio_layout_gridlayout_dividers.py @@ -4,10 +4,12 @@ """ Illustrate how to use divider lines with GridLayout """ + import board import displayio import terminalio from adafruit_display_text import label + from adafruit_displayio_layout.layouts.grid_layout import GridLayout # use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) @@ -31,15 +33,11 @@ _labels = [] _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077) ) layout.add_content(_labels[0], grid_position=(0, 0), cell_size=(1, 1)) _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700) ) layout.add_content(_labels[1], grid_position=(1, 0), cell_size=(1, 1)) _labels.append(label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello")) diff --git a/examples/displayio_layout_gridlayout_pygame_display_simpletest.py b/examples/displayio_layout_gridlayout_pygame_display_simpletest.py index 15fa6d9..f0a5623 100644 --- a/examples/displayio_layout_gridlayout_pygame_display_simpletest.py +++ b/examples/displayio_layout_gridlayout_pygame_display_simpletest.py @@ -7,12 +7,12 @@ Requires: https://github.com/FoamyGuy/Blinka_Displayio_PyGameDisplay """ + import displayio import terminalio from adafruit_display_text import label from blinka_displayio_pygamedisplay import PyGameDisplay - # Make the display context. Change size if you want from adafruit_displayio_layout.layouts.grid_layout import GridLayout @@ -31,15 +31,11 @@ _labels = [] _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077) ) layout.add_content(_labels[0], grid_position=(0, 0), cell_size=(1, 1)) _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700) ) layout.add_content(_labels[1], grid_position=(1, 0), cell_size=(1, 1)) _labels.append(label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello")) diff --git a/examples/displayio_layout_gridlayout_simpletest.py b/examples/displayio_layout_gridlayout_simpletest.py index 0816dd7..2d0b3ad 100644 --- a/examples/displayio_layout_gridlayout_simpletest.py +++ b/examples/displayio_layout_gridlayout_simpletest.py @@ -5,10 +5,12 @@ Make green and purple rectangles and a "Hello World" label. """ + import board import displayio import terminalio from adafruit_display_text import label + from adafruit_displayio_layout.layouts.grid_layout import GridLayout # use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) @@ -31,15 +33,11 @@ _labels = [] _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077) ) layout.add_content(_labels[0], grid_position=(0, 0), cell_size=(1, 1)) _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700) ) layout.add_content(_labels[1], grid_position=(1, 0), cell_size=(1, 1)) _labels.append(label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello")) diff --git a/examples/displayio_layout_icon_animated_simpletest.py b/examples/displayio_layout_icon_animated_simpletest.py index c8cb37a..3ec9851 100644 --- a/examples/displayio_layout_icon_animated_simpletest.py +++ b/examples/displayio_layout_icon_animated_simpletest.py @@ -4,10 +4,13 @@ """ Creates two animated icons with touch response: zoom and shrink animations. """ + import time + +import adafruit_touchscreen import board import displayio -import adafruit_touchscreen + from adafruit_displayio_layout.widgets.icon_animated import IconAnimated display = board.DISPLAY @@ -22,9 +25,7 @@ ) -IconAnimated.init_class( - display, max_scale=1.5, max_icon_size=(48, 48), max_color_depth=255 -) +IconAnimated.init_class(display, max_scale=1.5, max_icon_size=(48, 48), max_color_depth=255) icon_zoom = IconAnimated( "Zoom", diff --git a/examples/displayio_layout_linearlayout_simpletest.py b/examples/displayio_layout_linearlayout_simpletest.py index 4090561..1925330 100644 --- a/examples/displayio_layout_linearlayout_simpletest.py +++ b/examples/displayio_layout_linearlayout_simpletest.py @@ -5,11 +5,13 @@ Illustrates usage of LinearLayout to display a text label to the right of an icon. """ + import adafruit_imageload import board import displayio import terminalio from adafruit_display_text import label + from adafruit_displayio_layout.layouts.linear_layout import LinearLayout # use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) @@ -21,9 +23,7 @@ main_group = displayio.Group() display.root_group = main_group -layout = LinearLayout( - x=10, y=10, padding=4, orientation=LinearLayout.HORIZONTAL_ORIENTATION -) +layout = LinearLayout(x=10, y=10, padding=4, orientation=LinearLayout.HORIZONTAL_ORIENTATION) lbl = label.Label(terminalio.FONT, scale=4, x=0, y=0, text="Hello") diff --git a/examples/displayio_layout_page_layout_advancedtest.py b/examples/displayio_layout_page_layout_advancedtest.py index 9a6bde8..7dbdca7 100644 --- a/examples/displayio_layout_page_layout_advancedtest.py +++ b/examples/displayio_layout_page_layout_advancedtest.py @@ -4,14 +4,17 @@ """ Make a PageLayout and illustrate all of it's features """ + import time -import displayio + import board +import displayio import terminalio -from adafruit_display_text.bitmap_label import Label -from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle +from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.triangle import Triangle +from adafruit_display_text.bitmap_label import Label + from adafruit_displayio_layout.layouts.page_layout import PageLayout # built-in display @@ -77,22 +80,22 @@ # change page with function by name test_page_layout.show_page(page_name="page_3") -print("showing page index:{}".format(test_page_layout.showing_page_index)) +print(f"showing page index:{test_page_layout.showing_page_index}") time.sleep(1) # change page with function by index test_page_layout.show_page(page_index=0) -print("showing page name: {}".format(test_page_layout.showing_page_name)) +print(f"showing page name: {test_page_layout.showing_page_name}") time.sleep(1) # change page by updating the page name property test_page_layout.showing_page_name = "page_3" -print("showing page index: {}".format(test_page_layout.showing_page_index)) +print(f"showing page index: {test_page_layout.showing_page_index}") time.sleep(1) # change page by updating the page index property test_page_layout.showing_page_index = 1 -print("showing page name: {}".format(test_page_layout.showing_page_name)) +print(f"showing page name: {test_page_layout.showing_page_name}") time.sleep(5) another_text = Label( diff --git a/examples/displayio_layout_page_layout_simpletest.py b/examples/displayio_layout_page_layout_simpletest.py index b11c02c..74e3120 100644 --- a/examples/displayio_layout_page_layout_simpletest.py +++ b/examples/displayio_layout_page_layout_simpletest.py @@ -4,13 +4,16 @@ """ Make a PageLayout with two pages and change between them. """ + import time -import displayio + import board +import displayio import terminalio -from adafruit_display_text.bitmap_label import Label -from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle +from adafruit_display_shapes.rect import Rect +from adafruit_display_text.bitmap_label import Label + from adafruit_displayio_layout.layouts.page_layout import PageLayout # built-in display diff --git a/examples/displayio_layout_pygame_display_switch_round.py b/examples/displayio_layout_pygame_display_switch_round.py index c21111b..c85f241 100644 --- a/examples/displayio_layout_pygame_display_switch_round.py +++ b/examples/displayio_layout_pygame_display_switch_round.py @@ -7,11 +7,12 @@ Requires: https://github.com/FoamyGuy/Blinka_Displayio_PyGameDisplay """ + import displayio import pygame from blinka_displayio_pygamedisplay import PyGameDisplay -from adafruit_displayio_layout.widgets.switch_round import SwitchRound as Switch +from adafruit_displayio_layout.widgets.switch_round import SwitchRound as Switch # Make the display context. Change size if you want display = PyGameDisplay(width=320, height=240) diff --git a/examples/displayio_layout_simpletest.py b/examples/displayio_layout_simpletest.py index 16b3bb4..2b79736 100644 --- a/examples/displayio_layout_simpletest.py +++ b/examples/displayio_layout_simpletest.py @@ -7,10 +7,12 @@ Make green and purple rectangles and a "Hello World" label. """ + import board import displayio import terminalio from adafruit_display_text import label + from adafruit_displayio_layout.layouts.grid_layout import GridLayout # use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) @@ -33,15 +35,11 @@ _labels = [] _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello", background_color=0x770077) ) layout.add_content(_labels[0], grid_position=(0, 0), cell_size=(1, 1)) _labels.append( - label.Label( - terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700 - ) + label.Label(terminalio.FONT, scale=2, x=0, y=0, text="World", background_color=0x007700) ) layout.add_content(_labels[1], grid_position=(1, 0), cell_size=(1, 1)) _labels.append(label.Label(terminalio.FONT, scale=2, x=0, y=0, text="Hello")) diff --git a/examples/displayio_layout_switch_multiple.py b/examples/displayio_layout_switch_multiple.py index 6cb1bab..5f8a2ce 100755 --- a/examples/displayio_layout_switch_multiple.py +++ b/examples/displayio_layout_switch_multiple.py @@ -6,9 +6,11 @@ """ import time + +import adafruit_touchscreen import board import displayio -import adafruit_touchscreen + from adafruit_displayio_layout.widgets.switch_round import SwitchRound as Switch display = board.DISPLAY diff --git a/examples/displayio_layout_switch_simpletest.py b/examples/displayio_layout_switch_simpletest.py index a9cfbc8..432c1e0 100644 --- a/examples/displayio_layout_switch_simpletest.py +++ b/examples/displayio_layout_switch_simpletest.py @@ -6,9 +6,11 @@ """ import time + +import adafruit_touchscreen import board import displayio -import adafruit_touchscreen + from adafruit_displayio_layout.widgets.switch_round import SwitchRound as Switch display = board.DISPLAY diff --git a/examples/displayio_layout_tab_layout_simpletest.py b/examples/displayio_layout_tab_layout_simpletest.py index 188cd75..c8c73b4 100644 --- a/examples/displayio_layout_tab_layout_simpletest.py +++ b/examples/displayio_layout_tab_layout_simpletest.py @@ -4,14 +4,17 @@ """ Make a TabLayout and illustrate the most basic features and usage. """ + import time -import displayio + import board +import displayio import terminalio -from adafruit_display_text.bitmap_label import Label -from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle +from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.triangle import Triangle +from adafruit_display_text.bitmap_label import Label + from adafruit_displayio_layout.layouts.tab_layout import TabLayout CHANGE_DELAY = 1.0 # Seconds to wait before auto-advancing to the next tab @@ -108,22 +111,22 @@ # change page with function by name test_page_layout.show_page(page_name="Thr") -print("showing page index:{}".format(test_page_layout.showing_page_index)) +print(f"showing page index:{test_page_layout.showing_page_index}") time.sleep(1) # change page with function by index test_page_layout.show_page(page_index=0) -print("showing page name: {}".format(test_page_layout.showing_page_name)) +print(f"showing page name: {test_page_layout.showing_page_name}") time.sleep(1) # change page by updating the page name property test_page_layout.showing_page_name = "Thr" -print("showing page index: {}".format(test_page_layout.showing_page_index)) +print(f"showing page index: {test_page_layout.showing_page_index}") time.sleep(1) # change page by updating the page index property test_page_layout.showing_page_index = 1 -print("showing page name: {}".format(test_page_layout.showing_page_name)) +print(f"showing page name: {test_page_layout.showing_page_name}") time.sleep(5) another_text = Label( diff --git a/examples/displayio_layout_tab_layout_touchtest.py b/examples/displayio_layout_tab_layout_touchtest.py index e8fe6ee..a58db70 100644 --- a/examples/displayio_layout_tab_layout_touchtest.py +++ b/examples/displayio_layout_tab_layout_touchtest.py @@ -4,14 +4,16 @@ """ Make a TabLayout change tabs with the touchscreen """ -import displayio + +import adafruit_touchscreen import board +import displayio import terminalio -import adafruit_touchscreen -from adafruit_display_text.bitmap_label import Label -from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle +from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.triangle import Triangle +from adafruit_display_text.bitmap_label import Label + from adafruit_displayio_layout.layouts.tab_layout import TabLayout # built-in display diff --git a/examples/hotplug_sensor_examples/displayio_layout_hotplug_rtc.py b/examples/hotplug_sensor_examples/displayio_layout_hotplug_rtc.py index 041bbcf..1268b53 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_hotplug_rtc.py +++ b/examples/hotplug_sensor_examples/displayio_layout_hotplug_rtc.py @@ -6,16 +6,18 @@ """ import time -import displayio + +import adafruit_tmp117 import board +import displayio import terminalio -import adafruit_tmp117 -from adafruit_ds3231 import DS3231 -from adafruit_display_text.bitmap_label import Label -from adafruit_display_shapes.rect import Rect +from adafruit_bitmap_font import bitmap_font from adafruit_display_shapes.circle import Circle +from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.triangle import Triangle -from adafruit_bitmap_font import bitmap_font +from adafruit_display_text.bitmap_label import Label +from adafruit_ds3231 import DS3231 + from adafruit_displayio_layout.layouts.tab_layout import TabLayout # +-------------------------------------------------------+ @@ -89,13 +91,9 @@ def write(self, s, value): # key: {}".format(s, n)) self.g_vars[n] = value else: - raise KeyError( - "variable '{:" ">20s}' not found in self.gVars_rDict".format(s) - ) + raise KeyError("variable '{:" ">20s}' not found in self.gVars_rDict".format(s)) else: - raise TypeError( - "myVars.write(): param s expected str, {} received".format(type(s)) - ) + raise TypeError(f"myVars.write(): param s expected str, {type(s)} received") def read(self, s): RetVal = None @@ -135,8 +133,7 @@ def clean(self): def list(self): for i in range(0, len(self.g_vars) - 1): print( - "self.g_vars['{:" - ">20s}'] = {}".format( + "self.g_vars['{:" ">20s}'] = {}".format( self.gVarsDict[i], self.g_vars[i] if i in self.g_vars else "None" ) ) @@ -358,22 +355,22 @@ def list(self): # change page with function by name test_page_layout.show_page(page_name=pages[2]) -print("showing page index:{}".format(test_page_layout.showing_page_index)) +print(f"showing page index:{test_page_layout.showing_page_index}") time.sleep(1) # change page with function by index test_page_layout.show_page(page_index=0) -print("showing page name: {}".format(test_page_layout.showing_page_name)) +print(f"showing page name: {test_page_layout.showing_page_name}") time.sleep(1) # change page by updating the page name property test_page_layout.showing_page_name = pages[2] -print("showing page index: {}".format(test_page_layout.showing_page_index)) +print(f"showing page index: {test_page_layout.showing_page_index}") time.sleep(1) # change page by updating the page index property test_page_layout.showing_page_index = 1 -print("showing page name: {}".format(test_page_layout.showing_page_name)) +print(f"showing page name: {test_page_layout.showing_page_name}") time.sleep(5) """ @@ -471,12 +468,8 @@ def get_temp(): temp = myVars.read("temp_sensor").temperature if myVars.read("temp_in_fahrenheit"): temp = (temp * 1.8) + 32 - t = "{:5.2f} ".format(temp) + myVars.read("t1") - if ( - myVars.read("my_debug") - and temp is not None - and not myVars.read("temp_in_REPL") - ): + t = f"{temp:5.2f} " + myVars.read("t1") + if myVars.read("my_debug") and temp is not None and not myVars.read("temp_in_REPL"): myVars.write("temp_in_REPL", True) print("get_temp(): {} {}".format(myVars.read("t0"), t)) if showing_page_idx == 3: # show temperature on most right Tab page @@ -485,7 +478,7 @@ def get_temp(): "old_temp" ): # Only update if there is a change in temperature myVars.write("old_temp", temp) - t = "{:5.2f} ".format(temp) + myVars.read("t1") + t = f"{temp:5.2f} " + myVars.read("t1") pge4_lbl.text = "" pge4_lbl2.text = myVars.read("t0") pge4_lbl3.text = t @@ -500,20 +493,13 @@ def get_temp(): print("Temperature sensor has disconnected") t = "" myVars.write("temp_sensor", None) - pge4_lbl.text = myVars.read( - "pge4_lbl_dflt" - ) # clean the line (eventually: t2) + pge4_lbl.text = myVars.read("pge4_lbl_dflt") # clean the line (eventually: t2) pge4_lbl2.text = "" pge4_lbl3.text = "" return RetVal -""" - Function called by get_dt() - Created to repair pylint error R0912: Too many branches (13/12) -""" - yy = 0 mo = 1 dd = 2 @@ -562,14 +548,14 @@ def handle_dt(dt): if myVars.read("c_secs") != myVars.read("o_secs"): myVars.write("o_secs", myVars.read("c_secs")) - sDT3 = s + "{} {}".format(sDT, sDT2) + sDT3 = s + f"{sDT} {sDT2}" print(sDT3) pge3_lbl3.text = sDT2 if myVars.read("my_debug"): - print("pge3_lbl.text = {}".format(pge3_lbl.text)) - print("pge3_lbl2.text = {}".format(pge3_lbl2.text)) - print("pge3_lbl3.text = {}".format(pge3_lbl3.text)) + print(f"pge3_lbl.text = {pge3_lbl.text}") + print(f"pge3_lbl2.text = {pge3_lbl2.text}") + print(f"pge3_lbl3.text = {pge3_lbl3.text}") RetVal = True # Return from here with a False but don't set the pge3_lbl to default. @@ -627,7 +613,7 @@ def main(): cnt = 0 while True: try: - print("Loop nr: {:03d}".format(cnt)) + print(f"Loop nr: {cnt:03d}") # print("main(): type(rtc) object = ", type(myVars.read("rtc"))) if myVars.read("rtc") is not None: get_dt() diff --git a/examples/hotplug_sensor_examples/displayio_layout_hotplug_temp_sensor.py b/examples/hotplug_sensor_examples/displayio_layout_hotplug_temp_sensor.py index 6ec1cb1..81cd23d 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_hotplug_temp_sensor.py +++ b/examples/hotplug_sensor_examples/displayio_layout_hotplug_temp_sensor.py @@ -9,26 +9,28 @@ However, when the flag 'use_ntp' is set, the DS3231 will not be used instead the NTP class from adafruit_ntp.py will be used. """ + import time + +import adafruit_tmp117 +import adafruit_touchscreen import board import busio import displayio +import neopixel import terminalio -import adafruit_tmp117 +from adafruit_bitmap_font import bitmap_font +from adafruit_display_shapes.circle import Circle +from adafruit_display_shapes.rect import Rect +from adafruit_display_shapes.triangle import Triangle +from adafruit_display_text.bitmap_label import Label from adafruit_ds3231 import DS3231 -from digitalio import DigitalInOut -import neopixel -import adafruit_touchscreen from adafruit_esp32spi import adafruit_esp32spi from adafruit_ntp import NTP from adafruit_pyportal import PyPortal -from adafruit_display_text.bitmap_label import Label -from adafruit_display_shapes.rect import Rect -from adafruit_display_shapes.circle import Circle -from adafruit_display_shapes.triangle import Triangle -from adafruit_bitmap_font import bitmap_font -from adafruit_displayio_layout.layouts.tab_layout import TabLayout +from digitalio import DigitalInOut +from adafruit_displayio_layout.layouts.tab_layout import TabLayout # +-------------------------------------------------------+ # | Definition for variables in the past defined as global| @@ -115,13 +117,9 @@ def write(self, s, value): # key: {}".format(s, n)) self.g_vars[n] = value else: - raise KeyError( - "variable '{:" ">20s}' not found in self.gVars_rDict".format(s) - ) + raise KeyError("variable '{:" ">20s}' not found in self.gVars_rDict".format(s)) else: - raise TypeError( - "myVars.write(): param s expected str, {} received".format(type(s)) - ) + raise TypeError(f"myVars.write(): param s expected str, {type(s)} received") def read(self, s): RetVal = None @@ -168,8 +166,7 @@ def clean(self): def list(self): for i in range(0, len(self.g_vars) - 1): print( - "self.g_vars['{:" - ">20s}'] = {}".format( + "self.g_vars['{:" ">20s}'] = {}".format( self.gVarsDict[i], self.g_vars[i] if i in self.g_vars else "None" ) ) @@ -337,10 +334,7 @@ def list(self): print("Please wait...") if myVars.read("my_debug"): print("My IP address is", esp.pretty_ip(esp.ip_address)) - print( - "IP lookup adafruit.com: %s" - % esp.pretty_ip(esp.get_host_by_name("adafruit.com")) - ) + print("IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))) print("Ping google.com: %d ms" % esp.ping("google.com")) @@ -368,7 +362,7 @@ def refresh_from_NTP(): # (defined in secrets.h) ntp_current_time = time.time() if myVars.read("my_debug"): - print("Seconds since Jan 1, 1970: {} seconds".format(ntp_current_time)) + print(f"Seconds since Jan 1, 1970: {ntp_current_time} seconds") # Convert the current time in seconds since Jan 1, 1970 to a struct_time myVars.write("default_dt", time.localtime(ntp_current_time)) @@ -761,33 +755,22 @@ def get_temp(): print("Temperature sensor has disconnected") t = "" myVars.write("temp_sensor", None) - pge4_lbl.text = myVars.read( - "pge4_lbl_dflt" - ) # clean the line (eventually: t2) + pge4_lbl.text = myVars.read("pge4_lbl_dflt") # clean the line (eventually: t2) pge4_lbl2.text = "Sensor disconnected." pge4_lbl3.text = "Check wiring." return RetVal -# Moved these six definitions outside handle_dt() -# to correct pylint error 'too many variables' dt_ridxs = {"yy": 0, "mo": 1, "dd": 2, "hh": 3, "mm": 4, "ss": 5} # print("dict dt_ridxs =", dt_ridxs.keys()) -""" Function called by get_dt() - Created to repair pylint error R0912: Too many branches (13/12)""" - - def handle_dt(dt): my_debug = myVars.read("my_debug") RetVal = False s = "Date/time: " sYY = str(dt[dt_ridxs["yy"]]) # was: str(dt[yy]) - # print("dt_ridxs["mo"] = ", dt_ridxs["mo"]) - # modified mo because plynt error R0914 'Too many local variables' - # mo = dt_ridxs["mo"] dd = dt_ridxs["dd"] hh = dt_ridxs["hh"] mm = dt_ridxs["mm"] @@ -831,14 +814,14 @@ def handle_dt(dt): if myVars.read("c_secs") != myVars.read("o_secs"): myVars.write("o_secs", myVars.read("c_secs")) - sDT3 = s + "{} {}".format(sDT, sDT2) + sDT3 = s + f"{sDT} {sDT2}" print(sDT3) pge3_lbl3.text = sDT2 if my_debug: - print("pge3_lbl.text = {}".format(pge3_lbl.text)) - print("pge3_lbl2.text = {}".format(pge3_lbl2.text)) - print("pge3_lbl3.text = {}".format(pge3_lbl3.text)) + print(f"pge3_lbl.text = {pge3_lbl.text}") + print(f"pge3_lbl2.text = {pge3_lbl2.text}") + print(f"pge3_lbl3.text = {pge3_lbl3.text}") RetVal = True # Return from here with a False but don't set the pge3_lbl to default. @@ -898,11 +881,6 @@ def hms_to_cnt(): return (dt.tm_hour * 3600) + (dt.tm_min * 60) + dt.tm_sec -""" Created this function to correct pylint errors: - 'Too many branches' R0912 and - 'Too many statements' R0915""" - - def ck_next_NTP_sync(): s_cnt = myVars.read("s_cnt") c_cnt = hms_to_cnt() # set current count (seconds) @@ -917,9 +895,7 @@ def ck_next_NTP_sync(): myVars.write("s_cnt", hms_to_cnt()) # --- five minutes count down calculations #1 --- if my_debug: - print( - TAG + "five_min = {}, s_cnt = {}, c_cnt = {}".format(five_min, s_cnt, c_cnt) - ) + print(TAG + f"five_min = {five_min}, s_cnt = {s_cnt}, c_cnt = {c_cnt}") print(TAG + "c_elapsed = ", c_elapsed) # --- five minutes count down calculations #2 --- @@ -928,7 +904,7 @@ def ck_next_NTP_sync(): myVars.write("five_min_cnt", five_min) # remember count mm2 = five_min // 60 ss2 = five_min - (mm2 * 60) - t2 = "{:02d}:{:02d}".format(mm2, ss2) + t2 = f"{mm2:02d}:{ss2:02d}" t0 = t1 + t2 + t3 print(t0) pge3_lbl4.text = t0 @@ -973,7 +949,7 @@ def main(): if otp and ntp_refresh: refresh_from_NTP() # first re-synchronize internal clock from NTP server if get_dt(): - print("Loop nr: {:03d}".format(cnt)) + print(f"Loop nr: {cnt:03d}") else: connect_rtc() if myVars.read("temp_sensor") is not None: diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..5a5dbf0 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,101 @@ +# SPDX-FileCopyrightText: 2024 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +target-version = "py38" +line-length = 100 + +[lint] +preview = true +select = ["I", "PL", "UP"] + +extend-select = [ + "D419", # empty-docstring + "E501", # line-too-long + "W291", # trailing-whitespace + "PLC0414", # useless-import-alias + "PLC2401", # non-ascii-name + "PLC2801", # unnecessary-dunder-call + "PLC3002", # unnecessary-direct-lambda-call + "E999", # syntax-error + "PLE0101", # return-in-init + "F706", # return-outside-function + "F704", # yield-outside-function + "PLE0116", # continue-in-finally + "PLE0117", # nonlocal-without-binding + "PLE0241", # duplicate-bases + "PLE0302", # unexpected-special-method-signature + "PLE0604", # invalid-all-object + "PLE0605", # invalid-all-format + "PLE0643", # potential-index-error + "PLE0704", # misplaced-bare-raise + "PLE1141", # dict-iter-missing-items + "PLE1142", # await-outside-async + "PLE1205", # logging-too-many-args + "PLE1206", # logging-too-few-args + "PLE1307", # bad-string-format-type + "PLE1310", # bad-str-strip-call + "PLE1507", # invalid-envvar-value + "PLE2502", # bidirectional-unicode + "PLE2510", # invalid-character-backspace + "PLE2512", # invalid-character-sub + "PLE2513", # invalid-character-esc + "PLE2514", # invalid-character-nul + "PLE2515", # invalid-character-zero-width-space + "PLR0124", # comparison-with-itself + "PLR0202", # no-classmethod-decorator + "PLR0203", # no-staticmethod-decorator + "UP004", # useless-object-inheritance + "PLR0206", # property-with-parameters + "PLR0904", # too-many-public-methods + "PLR0911", # too-many-return-statements + "PLR0916", # too-many-boolean-expressions + "PLR1702", # too-many-nested-blocks + "PLR1704", # redefined-argument-from-local + "PLR1711", # useless-return + "C416", # unnecessary-comprehension + "PLR1733", # unnecessary-dict-index-lookup + "PLR1736", # unnecessary-list-index-lookup + + # ruff reports this rule is unstable + #"PLR6301", # no-self-use + + "PLW0108", # unnecessary-lambda + "PLW0120", # useless-else-on-loop + "PLW0127", # self-assigning-variable + "PLW0129", # assert-on-string-literal + "B033", # duplicate-value + "PLW0131", # named-expr-without-context + "PLW0245", # super-without-brackets + "PLW0406", # import-self + "PLW0602", # global-variable-not-assigned + "PLW0603", # global-statement + "PLW0604", # global-at-module-level + + # fails on the try: import typing used by libraries + #"F401", # unused-import + + "F841", # unused-variable + "E722", # bare-except + "PLW0711", # binary-op-exception + "PLW1501", # bad-open-mode + "PLW1508", # invalid-envvar-default + "PLW1509", # subprocess-popen-preexec-fn + "PLW2101", # useless-with-lock + "PLW3301", # nested-min-max +] + +ignore = [ + "PLR2004", # magic-value-comparison + "UP030", # format literals + "PLW1514", # unspecified-encoding + "PLR0912", # too-many-branches + "PLR0913", # too-many-arguments + "PLR0914", # too-many-locals + "PLR0915", # too-many-statements + "PLR0917", # too-many-positional-arguments + +] + +[format] +line-ending = "lf"