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 424a035..b5539ba 100644 --- a/README.rst +++ b/README.rst @@ -13,9 +13,9 @@ Introduction :target: https://github.com/adafruit/Adafruit_CircuitPython_Display_Text/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 Displays text using CircuitPython's displayio. diff --git a/adafruit_display_text/__init__.py b/adafruit_display_text/__init__.py index e154a54..31c829d 100755 --- a/adafruit_display_text/__init__.py +++ b/adafruit_display_text/__init__.py @@ -13,7 +13,8 @@ from displayio import Group, Palette try: - from typing import Optional, List, Tuple + from typing import List, Optional, Tuple + from fontio import FontProtocol except ImportError: pass @@ -26,8 +27,6 @@ def wrap_text_to_pixels( indent0: str = "", indent1: str = "", ) -> List[str]: - # pylint: disable=too-many-branches, too-many-locals, too-many-nested-blocks, too-many-statements - """wrap_text_to_pixels function A helper that will return a list of lines with word-break wrapping. Leading and trailing whitespace in your string will be removed. If @@ -92,9 +91,7 @@ def measure(text): > max_width ): if cur_part: - word_parts.append( - "".join(partial) + leadchar + cur_part + "-" - ) + word_parts.append("".join(partial) + leadchar + cur_part + "-") else: word_parts.append("".join(partial)) @@ -111,20 +108,19 @@ def measure(text): width = measure(word_parts[-1]) if firstword: firstword = False + elif firstword: + partial.append(word) + firstword = False + width += wwidth + elif width + swidth + wwidth < max_width: + if index > 0: + partial.append(" ") + partial.append(word) + width += wwidth + swidth else: - if firstword: - partial.append(word) - firstword = False - width += wwidth - elif width + swidth + wwidth < max_width: - if index > 0: - partial.append(" ") - partial.append(word) - width += wwidth + swidth - else: - lines.append("".join(partial)) - partial = [indent1, word] - width = measure(indent1) + wwidth + lines.append("".join(partial)) + partial = [indent1, word] + width = measure(indent1) + wwidth if newline: newline = False @@ -162,7 +158,7 @@ def chunks(lst, n): the_lines.append(the_line) parts = [] for part in chunks(w, max_chars - 1): - parts.append("{}-".format(part)) + parts.append(f"{part}-") the_lines.extend(parts[:-1]) the_line = parts[-1][:-1] continue @@ -186,8 +182,6 @@ def chunks(lst, n): class LabelBase(Group): - # pylint: disable=too-many-instance-attributes - """Superclass that all other types of labels will extend. This contains all of the properties and functions that work the same way in all labels. @@ -247,8 +241,6 @@ def __init__( label_direction: str = "LTR", verbose: bool = False, ) -> None: - # pylint: disable=too-many-arguments, too-many-locals - super().__init__(x=x, y=y, scale=1) self._font = font @@ -316,7 +308,7 @@ def font(self) -> FontProtocol: return self._font def _set_font(self, new_font: FontProtocol) -> None: - raise NotImplementedError("{} MUST override '_set_font'".format(type(self))) + raise NotImplementedError(f"{type(self)} MUST override '_set_font'") @font.setter def font(self, new_font: FontProtocol) -> None: @@ -343,9 +335,7 @@ def background_color(self) -> int: return self._background_color def _set_background_color(self, new_color): - raise NotImplementedError( - "{} MUST override '_set_background_color'".format(type(self)) - ) + raise NotImplementedError(f"{type(self)} MUST override '_set_background_color'") @background_color.setter def background_color(self, new_color: int) -> None: @@ -404,7 +394,7 @@ def scale(self, new_scale: int) -> None: self.anchored_position = self._anchored_position # update the anchored_position def _set_text(self, new_text: str, scale: int) -> None: - raise NotImplementedError("{} MUST override '_set_text'".format(type(self))) + raise NotImplementedError(f"{type(self)} MUST override '_set_text'") @property def text(self) -> str: @@ -440,9 +430,7 @@ def line_spacing(self) -> float: return self._line_spacing def _set_line_spacing(self, new_line_spacing: float) -> None: - raise NotImplementedError( - "{} MUST override '_set_line_spacing'".format(type(self)) - ) + raise NotImplementedError(f"{type(self)} MUST override '_set_line_spacing'") @line_spacing.setter def line_spacing(self, new_line_spacing: float) -> None: @@ -454,14 +442,10 @@ def label_direction(self) -> str: return self._label_direction def _set_label_direction(self, new_label_direction: str) -> None: - raise NotImplementedError( - "{} MUST override '_set_label_direction'".format(type(self)) - ) + raise NotImplementedError(f"{type(self)} MUST override '_set_label_direction'") def _get_valid_label_directions(self) -> Tuple[str, ...]: - raise NotImplementedError( - "{} MUST override '_get_valid_label_direction'".format(type(self)) - ) + raise NotImplementedError(f"{type(self)} MUST override '_get_valid_label_direction'") @label_direction.setter def label_direction(self, new_label_direction: str) -> None: diff --git a/adafruit_display_text/bitmap_label.py b/adafruit_display_text/bitmap_label.py index 997eb02..0539f85 100755 --- a/adafruit_display_text/bitmap_label.py +++ b/adafruit_display_text/bitmap_label.py @@ -27,6 +27,7 @@ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git" import displayio + from adafruit_display_text import LabelBase try: @@ -37,12 +38,12 @@ try: from typing import Optional, Tuple + from fontio import FontProtocol except ImportError: pass -# pylint: disable=too-many-instance-attributes class Label(LabelBase): """A label displaying a string of text that is stored in a bitmap. Note: This ``bitmap_label.py`` library utilizes a :py:class:`~displayio.Bitmap` @@ -125,8 +126,6 @@ def _reset_text( line_spacing: Optional[float] = None, scale: Optional[int] = None, ) -> None: - # pylint: disable=too-many-branches, too-many-statements, too-many-locals - # Store all the instance variables if font is not None: self._font = font @@ -143,7 +142,7 @@ def _reset_text( self._text = None # save a None value since text string is not saved # Check for empty string - if (text == "") or ( + if (not text) or ( text is None ): # If empty string, just create a zero-sized bounding box and that's it. self._bounding_box = ( @@ -199,11 +198,7 @@ def _reset_text( # Create the Bitmap unless it can be reused new_bitmap = None - if ( - self._bitmap is None - or self._bitmap.width != box_x - or self._bitmap.height != box_y - ): + if self._bitmap is None or self._bitmap.width != box_x or self._bitmap.height != box_y: new_bitmap = displayio.Bitmap(box_x, box_y, len(self._palette)) self._bitmap = new_bitmap else: @@ -240,20 +235,16 @@ def _reset_text( # the bitmap_label for _ in self._local_group: self._local_group.pop(0) - self._local_group.append( - self._tilegrid - ) # add the bitmap's tilegrid to the group + self._local_group.append(self._tilegrid) # add the bitmap's tilegrid to the group # Set TileGrid properties based on label_direction if self._label_direction != self._prev_label_direction: tg1 = self._tilegrid - tg1.transpose_xy, tg1.flip_x, tg1.flip_y = self._DIR_MAP[ - self._label_direction - ] + tg1.transpose_xy, tg1.flip_x, tg1.flip_y = self._DIR_MAP[self._label_direction] # Update bounding_box values. Note: To be consistent with label.py, # this is the bounding box for the text only, not including the background. - if self._label_direction in ("UPR", "DWR"): + if self._label_direction in {"UPR", "DWR"}: if self._label_direction == "UPR": top = self._padding_right left = self._padding_top @@ -292,8 +283,6 @@ def _line_spacing_ypixels(font: FontProtocol, line_spacing: float) -> int: def _text_bounding_box( self, text: str, font: FontProtocol ) -> Tuple[int, int, int, int, int, int]: - # pylint: disable=too-many-locals,too-many-branches - bbox = font.get_bounding_box() if len(bbox) == 4: ascender_max, descender_max = bbox[1], -bbox[3] @@ -322,7 +311,7 @@ def _text_bounding_box( my_glyph = font.get_glyph(ord(char)) if my_glyph is None: # Error checking: no glyph found - print("Glyph not found: {}".format(repr(char))) + print(f"Glyph not found: {repr(char)}") else: if newlines: xposition = x_start # reset to left column @@ -353,9 +342,9 @@ def _text_bounding_box( final_box_height_tight = bottom - top final_y_offset_tight = -top + y_offset_tight - final_box_height_loose = (lines - 1) * self._line_spacing_ypixels( - font, line_spacing - ) + (ascender_max + descender_max) + final_box_height_loose = (lines - 1) * self._line_spacing_ypixels(font, line_spacing) + ( + ascender_max + descender_max + ) final_y_offset_loose = ascender_max # return (final_box_width, final_box_height, left, final_y_offset) @@ -369,7 +358,6 @@ def _text_bounding_box( final_y_offset_loose, ) - # pylint: disable = too-many-branches def _place_text( self, bitmap: displayio.Bitmap, @@ -381,8 +369,6 @@ def _place_text( # when copying glyph bitmaps (this is important for slanted text # where rectangular glyph boxes overlap) ) -> Tuple[int, int, int, int]: - # pylint: disable=too-many-arguments, too-many-locals - # placeText - Writes text into a bitmap at the specified location. # # Note: scale is pushed up to Group level @@ -406,7 +392,7 @@ def _place_text( my_glyph = font.get_glyph(ord(char)) if my_glyph is None: # Error checking: no glyph found - print("Glyph not found: {}".format(repr(char))) + print(f"Glyph not found: {repr(char)}") else: if xposition == x_start: if left is None: @@ -437,19 +423,11 @@ def _place_text( y_clip = -y_blit_target # clip this amount from top of bitmap y_blit_target = 0 # draw the clipped bitmap at y=0 if self._verbose: - print( - 'Warning: Glyph clipped, exceeds Ascent property: "{}"'.format( - char - ) - ) + print(f'Warning: Glyph clipped, exceeds Ascent property: "{char}"') if (y_blit_target + my_glyph.height) > bitmap.height: if self._verbose: - print( - 'Warning: Glyph clipped, exceeds descent property: "{}"'.format( - char - ) - ) + print(f'Warning: Glyph clipped, exceeds descent property: "{char}"') self._blit( bitmap, @@ -481,8 +459,6 @@ def _blit( skip_index: int = None, # palette index that will not be copied # (for example: the background color of a glyph) ) -> None: - # pylint: disable=no-self-use, too-many-arguments - if hasattr(bitmap, "blit"): # if bitmap has a built-in blit function, call it # this function should perform its own input checks bitmap.blit( diff --git a/adafruit_display_text/label.py b/adafruit_display_text/label.py index 775845c..94d127f 100755 --- a/adafruit_display_text/label.py +++ b/adafruit_display_text/label.py @@ -27,18 +27,18 @@ from displayio import Bitmap, Palette, TileGrid + from adafruit_display_text import LabelBase try: from typing import Optional, Tuple + from fontio import FontProtocol except ImportError: pass class Label(LabelBase): - # pylint: disable=too-many-instance-attributes - """A label displaying a string of text. The origin point set by ``x`` and ``y`` properties will be the left edge of the bounding box, and in the center of a M glyph (if its one line), or the (number of lines * linespacing + M)/2. That is, @@ -99,7 +99,6 @@ def __init__(self, font: FontProtocol, **kwargs) -> None: if text is not None: self._reset_text(str(text)) - # pylint: disable=too-many-branches def _create_background_box(self, lines: int, y_offset: int) -> TileGrid: """Private Class function to create a background_box :param lines: int number of lines @@ -115,10 +114,8 @@ def _create_background_box(self, lines: int, y_offset: int) -> TileGrid: else: # draw a "loose" bounding box to include any ascenders/descenders. ascent, descent = self._ascent, self._descent - if self._label_direction in ("DWR", "UPR"): - box_height = ( - self._bounding_box[3] + self._padding_right + self._padding_left - ) + if self._label_direction in {"DWR", "UPR"}: + box_height = self._bounding_box[3] + self._padding_right + self._padding_left x_box_offset = -self._padding_left box_width = ( (ascent + descent) @@ -127,9 +124,7 @@ def _create_background_box(self, lines: int, y_offset: int) -> TileGrid: + self._padding_bottom ) elif self._label_direction == "TTB": - box_height = ( - self._bounding_box[3] + self._padding_top + self._padding_bottom - ) + box_height = self._bounding_box[3] + self._padding_top + self._padding_bottom x_box_offset = -self._padding_left box_width = ( (ascent + descent) @@ -138,9 +133,7 @@ def _create_background_box(self, lines: int, y_offset: int) -> TileGrid: + self._padding_left ) else: - box_width = ( - self._bounding_box[2] + self._padding_left + self._padding_right - ) + box_width = self._bounding_box[2] + self._padding_left + self._padding_right x_box_offset = -self._padding_left box_height = ( (ascent + descent) @@ -189,7 +182,6 @@ def _create_background_box(self, lines: int, y_offset: int) -> TileGrid: return tile_grid - # pylint: enable=too-many-branches def _set_background_color(self, new_color: Optional[int]) -> None: """Private class function that allows updating the font box background color @@ -217,39 +209,23 @@ def _set_background_color(self, new_color: Optional[int]) -> None: # add bitmap if text is present and bitmap sizes > 0 pixels if ( (len(self._text) > 0) - and ( - self._bounding_box[2] + self._padding_left + self._padding_right > 0 - ) - and ( - self._bounding_box[3] + self._padding_top + self._padding_bottom > 0 - ) + and (self._bounding_box[2] + self._padding_left + self._padding_right > 0) + and (self._bounding_box[3] + self._padding_top + self._padding_bottom > 0) ): - self._local_group.insert( - 0, self._create_background_box(lines, y_offset) - ) + self._local_group.insert(0, self._create_background_box(lines, y_offset)) self._added_background_tilegrid = True - else: # a bitmap is present in the self Group - # update bitmap if text is present and bitmap sizes > 0 pixels - if ( - (len(self._text) > 0) - and ( - self._bounding_box[2] + self._padding_left + self._padding_right > 0 - ) - and ( - self._bounding_box[3] + self._padding_top + self._padding_bottom > 0 - ) - ): - self._local_group[0] = self._create_background_box( - lines, self._y_offset - ) - else: # delete the existing bitmap - self._local_group.pop(0) - self._added_background_tilegrid = False + elif ( + (len(self._text) > 0) + and (self._bounding_box[2] + self._padding_left + self._padding_right > 0) + and (self._bounding_box[3] + self._padding_top + self._padding_bottom > 0) + ): + self._local_group[0] = self._create_background_box(lines, self._y_offset) + else: # delete the existing bitmap + self._local_group.pop(0) + self._added_background_tilegrid = False def _update_text(self, new_text: str) -> None: - # pylint: disable=too-many-branches,too-many-statements - x = 0 y = 0 if self._added_background_tilegrid: @@ -283,7 +259,7 @@ def _update_text(self, new_text: str) -> None: position_x, position_y = 0, 0 - if self._label_direction in ("LTR", "RTL"): + if self._label_direction in {"LTR", "RTL"}: bottom = max(bottom, y - glyph.dy + self._y_offset) if y == 0: # first line, find the Ascender height top = min(top, -glyph.height - glyph.dy + self._y_offset) @@ -298,9 +274,7 @@ def _update_text(self, new_text: str) -> None: left = min(left, glyph.dx) position_x = x + glyph.dx else: - left = max( - left, abs(x) + glyph.shift_x, abs(x) + glyph.width + glyph.dx - ) + left = max(left, abs(x) + glyph.shift_x, abs(x) + glyph.width + glyph.dx) if x == 0: if right is None: right = 0 @@ -318,9 +292,7 @@ def _update_text(self, new_text: str) -> None: top = min(top, -glyph.dy) bottom = max(bottom, y + glyph.height, y + glyph.height + glyph.dy) - right = max( - right, x + glyph.width + glyph.dx, x + glyph.shift_x + glyph.dx - ) + right = max(right, x + glyph.width + glyph.dx, x + glyph.shift_x + glyph.dx) position_y = y + glyph.dy position_x = x - glyph.width // 2 + self._y_offset @@ -401,7 +373,6 @@ def _update_text(self, new_text: str) -> None: self._local_group.pop() if self._label_direction == "RTL": - # pylint: disable=invalid-unary-operand-type # type-checkers think left can be None self._bounding_box = (-left, top, left - right, bottom - top) if self._label_direction == "TTB": diff --git a/adafruit_display_text/outlined_label.py b/adafruit_display_text/outlined_label.py index 1c66a99..059c56e 100644 --- a/adafruit_display_text/outlined_label.py +++ b/adafruit_display_text/outlined_label.py @@ -22,15 +22,18 @@ https://circuitpython.org/downloads """ + __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git" import bitmaptools -from displayio import Palette, Bitmap +from displayio import Bitmap, Palette + from adafruit_display_text import bitmap_label try: from typing import Optional, Tuple, Union + from fontio import FontProtocol except ImportError: pass @@ -46,7 +49,6 @@ class OutlinedLabel(bitmap_label.Label): """ - # pylint: disable=too-many-arguments def __init__( self, font, @@ -56,7 +58,7 @@ def __init__( padding_bottom: Optional[int] = None, padding_left: Optional[int] = None, padding_right: Optional[int] = None, - **kwargs + **kwargs, ): if padding_top is None: padding_top = outline_size + 0 @@ -73,7 +75,7 @@ def __init__( padding_bottom=padding_bottom, padding_left=padding_left, padding_right=padding_right, - **kwargs + **kwargs, ) _background_color = self._palette[0] @@ -176,9 +178,7 @@ def outline_size(self, new_outline_size): self._padding_left = new_outline_size + 0 self._padding_right = new_outline_size + 0 - self._stamp_source = Bitmap( - (new_outline_size * 2) + 1, (new_outline_size * 2) + 1, 3 - ) + self._stamp_source = Bitmap((new_outline_size * 2) + 1, (new_outline_size * 2) + 1, 3) self._stamp_source.fill(2) self._reset_text( font=self._font, diff --git a/adafruit_display_text/scrolling_label.py b/adafruit_display_text/scrolling_label.py index 2a2b6e5..67159c0 100644 --- a/adafruit_display_text/scrolling_label.py +++ b/adafruit_display_text/scrolling_label.py @@ -27,10 +27,12 @@ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git" import adafruit_ticks + from adafruit_display_text import bitmap_label try: from typing import Optional + from fontio import FontProtocol except ImportError: pass @@ -50,7 +52,6 @@ class ScrollingLabel(bitmap_label.Label): :param int current_index: The index of the first visible character in the label. Default is 0, the first character. Will increase while scrolling.""" - # pylint: disable=too-many-arguments def __init__( self, font: FontProtocol, @@ -58,7 +59,7 @@ def __init__( text: Optional[str] = "", animate_time: Optional[float] = 0.3, current_index: Optional[int] = 0, - **kwargs + **kwargs, ) -> None: super().__init__(font, **kwargs) self.animate_time = animate_time @@ -67,7 +68,7 @@ def __init__( self.max_characters = max_characters if text and text[-1] != " ": - text = "{} ".format(text) + text = f"{text} " self._full_text = text self.update() @@ -99,14 +100,11 @@ def update(self, force: bool = False) -> None: _showing_string_start = self.full_text[self.current_index :] _showing_string_end = "{}".format( self.full_text[ - : (self.current_index + self.max_characters) - % len(self.full_text) + : (self.current_index + self.max_characters) % len(self.full_text) ] ) - _showing_string = "{}{}".format( - _showing_string_start, _showing_string_end - ) + _showing_string = f"{_showing_string_start}{_showing_string_end}" super()._set_text(_showing_string, self.scale) self.current_index += 1 self._last_animate_time = _now @@ -140,7 +138,7 @@ def full_text(self) -> str: @full_text.setter def full_text(self, new_text: str) -> None: if new_text and new_text[-1] != " ": - new_text = "{} ".format(new_text) + new_text = f"{new_text} " if new_text != self._full_text: self._full_text = new_text self.current_index = 0 diff --git a/adafruit_display_text/text_box.py b/adafruit_display_text/text_box.py index 7f890ba..50607bf 100644 --- a/adafruit_display_text/text_box.py +++ b/adafruit_display_text/text_box.py @@ -29,17 +29,16 @@ import displayio from micropython import const -from adafruit_display_text import wrap_text_to_pixels -from adafruit_display_text import bitmap_label +from adafruit_display_text import bitmap_label, wrap_text_to_pixels try: from typing import Optional, Tuple + from fontio import FontProtocol except ImportError: pass -# pylint: disable=too-many-instance-attributes, duplicate-code class TextBox(bitmap_label.Label): """ TextBox has a constrained width and optionally height. @@ -77,10 +76,8 @@ def __init__( else: self.dynamic_height = True - if align not in (TextBox.ALIGN_LEFT, TextBox.ALIGN_CENTER, TextBox.ALIGN_RIGHT): - raise ValueError( - "Align must be one of: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT" - ) + if align not in {TextBox.ALIGN_LEFT, TextBox.ALIGN_CENTER, TextBox.ALIGN_RIGHT}: + raise ValueError("Align must be one of: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT") self._align = align self._padding_left = kwargs.get("padding_left", 0) @@ -117,8 +114,6 @@ def _place_text( # when copying glyph bitmaps (this is important for slanted text # where rectangular glyph boxes overlap) ) -> Tuple[int, int, int, int]: - # pylint: disable=too-many-arguments, too-many-locals, too-many-statements, too-many-branches - # placeText - Writes text into a bitmap at the specified location. # # Note: scale is pushed up to Group level @@ -135,7 +130,7 @@ def _place_text( unused_space = self._width - cur_line_width x_start = original_xposition + unused_space - self._padding_right - xposition = x_start # pylint: disable=used-before-assignment + xposition = x_start y_start = yposition @@ -147,9 +142,7 @@ def _place_text( for char in text: if char == "\n": # newline cur_line_index += 1 - cur_line_width = self._text_bounding_box( - self.lines[cur_line_index], self.font - )[0] + cur_line_width = self._text_bounding_box(self.lines[cur_line_index], self.font)[0] if self.align == self.ALIGN_LEFT: x_start = original_xposition # starting x position (left margin) if self.align == self.ALIGN_CENTER: @@ -168,7 +161,7 @@ def _place_text( my_glyph = font.get_glyph(ord(char)) if my_glyph is None: # Error checking: no glyph found - print("Glyph not found: {}".format(repr(char))) + print(f"Glyph not found: {repr(char)}") else: if xposition == x_start: if left is None: @@ -199,19 +192,11 @@ def _place_text( y_clip = -y_blit_target # clip this amount from top of bitmap y_blit_target = 0 # draw the clipped bitmap at y=0 if self._verbose: - print( - 'Warning: Glyph clipped, exceeds Ascent property: "{}"'.format( - char - ) - ) + print(f'Warning: Glyph clipped, exceeds Ascent property: "{char}"') if (y_blit_target + my_glyph.height) > bitmap.height: if self._verbose: - print( - 'Warning: Glyph clipped, exceeds descent property: "{}"'.format( - char - ) - ) + print(f'Warning: Glyph clipped, exceeds descent property: "{char}"') try: self._blit( bitmap, @@ -240,8 +225,6 @@ def _reset_text( line_spacing: Optional[float] = None, scale: Optional[int] = None, ) -> None: - # pylint: disable=too-many-branches, too-many-statements, too-many-locals - # Store all the instance variables if font is not None: self._font = font @@ -255,7 +238,7 @@ def _reset_text( self._text = self._replace_tabs(text) # Check for empty string - if (text == "") or ( + if (not text) or ( text is None ): # If empty string, just create a zero-sized bounding box and that's it. self._bounding_box = ( @@ -319,9 +302,7 @@ def _reset_text( or self._bitmap.width != self._width or self._bitmap.height != self._height ): - new_bitmap = displayio.Bitmap( - self._width, self._height, len(self._palette) - ) + new_bitmap = displayio.Bitmap(self._width, self._height, len(self._palette)) self._bitmap = new_bitmap else: self._bitmap.fill(0) @@ -357,9 +338,7 @@ def _reset_text( # the bitmap_label for _ in self._local_group: self._local_group.pop(0) - self._local_group.append( - self._tilegrid - ) # add the bitmap's tilegrid to the group + self._local_group.append(self._tilegrid) # add the bitmap's tilegrid to the group self._bounding_box = ( self._tilegrid.x + self._padding_left, @@ -419,8 +398,6 @@ def align(self): @align.setter def align(self, align: int) -> None: - if align not in (TextBox.ALIGN_LEFT, TextBox.ALIGN_CENTER, TextBox.ALIGN_RIGHT): - raise ValueError( - "Align must be one of: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT" - ) + if align not in {TextBox.ALIGN_LEFT, TextBox.ALIGN_CENTER, TextBox.ALIGN_RIGHT}: + raise ValueError("Align must be one of: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT") self._align = align diff --git a/docs/api.rst b/docs/api.rst index bb959a9..a1bd8b3 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,6 +4,8 @@ .. 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_display_text :members: diff --git a/docs/conf.py b/docs/conf.py index cb73a8f..fa4bcad 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,12 +1,10 @@ -# -*- coding: utf-8 -*- - # SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # # SPDX-License-Identifier: MIT +import datetime import os import sys -import datetime sys.path.insert(0, os.path.abspath("..")) @@ -53,9 +51,7 @@ creation_year = "2019" 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 + " Scott Shawcroft" author = "Scott Shawcroft" diff --git a/examples/display_text_advance_example.py b/examples/display_text_advance_example.py index 38072c7..0f3818f 100644 --- a/examples/display_text_advance_example.py +++ b/examples/display_text_advance_example.py @@ -7,12 +7,14 @@ """ import time + import board import displayio -import terminalio import fontio +import terminalio from adafruit_bitmap_font import bitmap_font -from adafruit_display_text import label, bitmap_label + +from adafruit_display_text import bitmap_label, label display = board.DISPLAY main_group = displayio.Group() diff --git a/examples/display_text_anchored_position.py b/examples/display_text_anchored_position.py index 9fe48ff..9dbae99 100644 --- a/examples/display_text_anchored_position.py +++ b/examples/display_text_anchored_position.py @@ -4,9 +4,11 @@ """ This examples shows the use of anchor_point and anchored_position. """ + import board -import terminalio import displayio +import terminalio + from adafruit_display_text import label DISPLAY_WIDTH = 320 diff --git a/examples/display_text_background_color.py b/examples/display_text_background_color.py index 4dfa1fc..800f9c4 100644 --- a/examples/display_text_background_color.py +++ b/examples/display_text_background_color.py @@ -4,27 +4,28 @@ """ This example shows the use color and background_color """ + import time + import board import terminalio + from adafruit_display_text import label text = " Color Background Hello world" -text_area = label.Label( - terminalio.FONT, text=text, color=0x0000FF, background_color=0xFFAA00 -) +text_area = label.Label(terminalio.FONT, text=text, color=0x0000FF, background_color=0xFFAA00) text_area.x = 10 text_area.y = 10 -print("background color is {:06x}".format(text_area.background_color)) +print(f"background color is {text_area.background_color:06x}") board.DISPLAY.root_group = text_area time.sleep(2) text_area.background_color = 0xFF0000 -print("background color is {:06x}".format(text_area.background_color)) +print(f"background color is {text_area.background_color:06x}") time.sleep(2) text_area.background_color = None -print("background color is {}".format(text_area.background_color)) +print(f"background color is {text_area.background_color}") while True: pass diff --git a/examples/display_text_background_color_padding.py b/examples/display_text_background_color_padding.py index 8b9e29e..5c4fc9a 100755 --- a/examples/display_text_background_color_padding.py +++ b/examples/display_text_background_color_padding.py @@ -4,13 +4,14 @@ """ This example shows the use color and background_color """ + import time + import board import displayio - from adafruit_bitmap_font import bitmap_font -from adafruit_display_text import label +from adafruit_display_text import label # Setup the SPI display if "DISPLAY" in dir(board): @@ -110,7 +111,7 @@ text_area[i].anchored_position = (this_x, this_y) myGroup.append(text_area[i]) -print("background color is {}".format(text_area[0].background_color)) +print(f"background color is {text_area[0].background_color}") while True: @@ -121,20 +122,20 @@ for area in text_area: area.background_color = 0xFF0000 - print("background color is {:06x}".format(text_area[0].background_color)) + print(f"background color is {text_area[0].background_color:06x}") time.sleep(2) for area in text_area: area.background_color = 0x000088 - print("background color is {:06x}".format(text_area[0].background_color)) + print(f"background color is {text_area[0].background_color:06x}") time.sleep(2) for area in text_area: area.background_color = 0x00FF00 - print("background color is {:06x}".format(text_area[0].background_color)) + print(f"background color is {text_area[0].background_color:06x}") time.sleep(2) for area in text_area: area.background_color = 0xFF0000 - print("background color is {:06x}".format(text_area[0].background_color)) + print(f"background color is {text_area[0].background_color:06x}") time.sleep(2) for area in text_area: area.background_color = None - print("background color is {}".format(text_area[0].background_color)) + print(f"background color is {text_area[0].background_color}") diff --git a/examples/display_text_bitmap_label_simpletest.py b/examples/display_text_bitmap_label_simpletest.py index 49b20b9..9009497 100644 --- a/examples/display_text_bitmap_label_simpletest.py +++ b/examples/display_text_bitmap_label_simpletest.py @@ -3,8 +3,8 @@ import board import terminalio -from adafruit_display_text import bitmap_label +from adafruit_display_text import bitmap_label text = "Hello world" text_area = bitmap_label.Label(terminalio.FONT, text=text) diff --git a/examples/display_text_label_align_baseline_comparison.py b/examples/display_text_label_align_baseline_comparison.py index 6ebe843..9d08fa8 100644 --- a/examples/display_text_label_align_baseline_comparison.py +++ b/examples/display_text_label_align_baseline_comparison.py @@ -8,8 +8,8 @@ import board import displayio from adafruit_bitmap_font import bitmap_font -from adafruit_display_text import label +from adafruit_display_text import label display = board.DISPLAY diff --git a/examples/display_text_label_vs_bitmap_label_comparison.py b/examples/display_text_label_vs_bitmap_label_comparison.py index f4d107c..fcb951f 100644 --- a/examples/display_text_label_vs_bitmap_label_comparison.py +++ b/examples/display_text_label_vs_bitmap_label_comparison.py @@ -3,19 +3,14 @@ # Sample for comparing label and bitmap_label positioning with Builtin or loaded BDF fonts -# pylint: disable=no-member - import gc + import board import displayio import terminalio from adafruit_bitmap_font import bitmap_font -from adafruit_display_text import bitmap_label -from adafruit_display_text import label - -# pylint: disable=no-member - +from adafruit_display_text import bitmap_label, label ########## # Use this Boolean variables to select which font style to use @@ -93,16 +88,12 @@ print("Display is started") -preload_glyphs = ( - True # set this to True if you want to preload the font glyphs into memory -) +preload_glyphs = True # set this to True if you want to preload the font glyphs into memory # preloading the glyphs will help speed up the rendering of text but will use more RAM if preload_glyphs and not use_builtinfont: # identify the glyphs to load into memory -> increases rendering speed - glyphs = ( - b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/-_,.:?!'\n " - ) + glyphs = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/-_,.:?!'\n " print("loading glyphs...") fontToUse.load_glyphs(glyphs) @@ -157,7 +148,7 @@ gc.collect() bitmap_label_end = gc.mem_free() -print("bitmap_label used: {} memory".format(bitmap_label_start - bitmap_label_end)) +print(f"bitmap_label used: {bitmap_label_start - bitmap_label_end} memory") bmap_group = displayio.Group() # Create a group for displaying bmap_group.append(bmap_label1) @@ -205,7 +196,7 @@ gc.collect() label_end = gc.mem_free() -print("label used: {} memory".format(label_start - label_end)) +print(f"label used: {label_start - label_end} memory") label_group = displayio.Group() # Create a group for displaying label_group.append(label1) label_group.append(label2) diff --git a/examples/display_text_magtag.py b/examples/display_text_magtag.py index bb59156..a90d0cf 100644 --- a/examples/display_text_magtag.py +++ b/examples/display_text_magtag.py @@ -5,10 +5,13 @@ Basic display_text.label example script adapted for use on MagTag. """ + import time + import board import displayio import terminalio + from adafruit_display_text import label # use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) diff --git a/examples/display_text_matrixportal.py b/examples/display_text_matrixportal.py index fb0923f..e92a95a 100644 --- a/examples/display_text_matrixportal.py +++ b/examples/display_text_matrixportal.py @@ -10,8 +10,10 @@ Copy it from the current libraries bundle into the lib folder on your device. """ + import terminalio from adafruit_matrixportal.matrix import Matrix + from adafruit_display_text import label matrix = Matrix() diff --git a/examples/display_text_outlined_label_simpletest.py b/examples/display_text_outlined_label_simpletest.py index f82ca15..f698a64 100644 --- a/examples/display_text_outlined_label_simpletest.py +++ b/examples/display_text_outlined_label_simpletest.py @@ -3,6 +3,7 @@ import board import terminalio + from adafruit_display_text import outlined_label if board.DISPLAY.width <= 150: diff --git a/examples/display_text_pyportal.py b/examples/display_text_pyportal.py index 6b95bce..de1c040 100644 --- a/examples/display_text_pyportal.py +++ b/examples/display_text_pyportal.py @@ -8,19 +8,18 @@ import os import time + import board import displayio - from adafruit_bitmap_font import bitmap_font + from adafruit_display_text.label import Label FONT_DIR = "/fonts/" -fonts = list( - filter(lambda x: x.endswith("bdf") and not x.startswith("."), os.listdir(FONT_DIR)) -) +fonts = list(filter(lambda x: x.endswith("bdf") and not x.startswith("."), os.listdir(FONT_DIR))) fonts = [bitmap_font.load_font(FONT_DIR + x) for x in fonts] if len(fonts) == 0: - print("No fonts found in '{}'".format(FONT_DIR)) + print(f"No fonts found in '{FONT_DIR}'") print("fade up") # Fade up the backlight @@ -40,10 +39,8 @@ y = 0 while len(splash): splash.pop() - print("Font load {}".format(font.name)) - area = Label( - font, text=demo_text, anchor_point=(0, 0), anchored_position=(0, y) - ) + print(f"Font load {font.name}") + area = Label(font, text=demo_text, anchor_point=(0, 0), anchored_position=(0, y)) splash.append(area) y += area.height diff --git a/examples/display_text_scrolling_label.py b/examples/display_text_scrolling_label.py index 02fd4cc..decccff 100644 --- a/examples/display_text_scrolling_label.py +++ b/examples/display_text_scrolling_label.py @@ -3,13 +3,11 @@ import board import terminalio -from adafruit_display_text.scrolling_label import ScrollingLabel +from adafruit_display_text.scrolling_label import ScrollingLabel text = "Hello world CircuitPython scrolling label" -my_scrolling_label = ScrollingLabel( - terminalio.FONT, text=text, max_characters=20, animate_time=0.3 -) +my_scrolling_label = ScrollingLabel(terminalio.FONT, text=text, max_characters=20, animate_time=0.3) my_scrolling_label.x = 10 my_scrolling_label.y = 10 board.DISPLAY.root_group = my_scrolling_label diff --git a/examples/display_text_simpletest.py b/examples/display_text_simpletest.py index 7a367bf..c9a6a21 100644 --- a/examples/display_text_simpletest.py +++ b/examples/display_text_simpletest.py @@ -3,8 +3,8 @@ import board import terminalio -from adafruit_display_text import label +from adafruit_display_text import label text = "Hello world" text_area = label.Label(terminalio.FONT, text=text) diff --git a/examples/display_text_text_box_simpletest.py b/examples/display_text_text_box_simpletest.py index 1512f7c..42c4774 100644 --- a/examples/display_text_text_box_simpletest.py +++ b/examples/display_text_text_box_simpletest.py @@ -4,6 +4,7 @@ import board import displayio import terminalio + from adafruit_display_text.text_box import TextBox main_group = displayio.Group() diff --git a/examples/display_text_textarea_boundingbox.py b/examples/display_text_textarea_boundingbox.py index 46047ea..3c0cbd7 100644 --- a/examples/display_text_textarea_boundingbox.py +++ b/examples/display_text_textarea_boundingbox.py @@ -2,11 +2,12 @@ # SPDX-License-Identifier: MIT import os + import board import displayio from adafruit_bitmap_font import bitmap_font -from adafruit_display_text.label import Label +from adafruit_display_text.label import Label # the current working directory (where this file is) cwd = ("/" + __file__).rsplit("/", 1)[0] diff --git a/examples/display_text_wrap_pixels_test.py b/examples/display_text_wrap_pixels_test.py index 29f6a17..8d8a9a7 100644 --- a/examples/display_text_wrap_pixels_test.py +++ b/examples/display_text_wrap_pixels_test.py @@ -10,6 +10,7 @@ import board import displayio import terminalio + from adafruit_display_text import label, wrap_text_to_pixels WRAP_WIDTH = 140 diff --git a/examples/display_text_wraptest.py b/examples/display_text_wraptest.py index 5286694..2ff8db0 100644 --- a/examples/display_text_wraptest.py +++ b/examples/display_text_wraptest.py @@ -5,8 +5,10 @@ This example illustrates how to use the wrap_text_to_lines helper function. """ + import board import terminalio + from adafruit_display_text import label, wrap_text_to_lines # use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.) diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..759f251 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,106 @@ +# 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 + "PLR0912", # too-many-branches + "PLR0913", # too-many-arguments + "PLR0914", # too-many-locals + "PLR0915", # too-many-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 local branches + "PLR0913", # too many arguments + "PLR0914", # too many local variables + "PLR0915", # too many statements + "PLR0917", # too many positional arguments + "PLR1702", # too many nested blocks + "PLR6301", # Method could be a function, class method, or static method +] + +[format] +line-ending = "lf"