diff --git a/LabGym/__init__.py b/LabGym/__init__.py index 56e590e5..72041bfd 100644 --- a/LabGym/__init__.py +++ b/LabGym/__init__.py @@ -1,5 +1,3 @@ -# suppress '__init__.py:1:0: C0103: Module name "LabGym" doesn't conform to snake_case naming style (invalid-name)' -# pylint: disable=invalid-name ''' Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/LabGym/__main__.py b/LabGym/__main__.py index a9aafe58..f75e9230 100644 --- a/LabGym/__main__.py +++ b/LabGym/__main__.py @@ -1,4 +1,3 @@ -# pylint: disable=line-too-long ''' Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @@ -19,19 +18,18 @@ # noqa -# pylint: enable=line-too-long # Standard library imports. import logging from pathlib import Path -# block begin +# Regarding the use of logging and mylogging functions before the +# "Related third party imports." section: # These statements are intentionally positioned before this module's # other imports (against the guidance of PEP 8), to log the loading of # this module before other import statements are executed and # potentially produce their own log messages. -# pylint: disable=wrong-import-position -from LabGym import mylogging # pylint: disable=ungrouped-imports +from LabGym import mylogging # Collect logrecords and defer handling until logging is configured. mylogging.defer() @@ -43,8 +41,6 @@ # Configure logging based on configfile, then handle collected logrecords. mylogging.configure() -# pylint: enable=wrong-import-position -# block end # Related third party imports. from packaging import version # Core utilities for Python packages @@ -53,6 +49,7 @@ import wx # wxPython, Cross platform GUI toolkit for Python, "Phoenix" version # Local application/library specific imports. +# pylint: disable=ungrouped-imports # pylint: disable-next=unused-import from LabGym import mypkg_resources # replace deprecated pkg_resources from LabGym import __version__, gui_main, probes diff --git a/LabGym/analyzebehavior.py b/LabGym/analyzebehavior.py index bb5913d9..ee81788b 100644 --- a/LabGym/analyzebehavior.py +++ b/LabGym/analyzebehavior.py @@ -30,8 +30,8 @@ # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -logger = logging.getLogger(__name__) # pylint: disable=wrong-import-position -logger.debug('loading %s', __file__) # pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('loading %s', __file__) # Related third party imports. import cv2 diff --git a/LabGym/gui_analyzer.py b/LabGym/gui_analyzer.py index 9f44d14d..9daa13dd 100644 --- a/LabGym/gui_analyzer.py +++ b/LabGym/gui_analyzer.py @@ -26,8 +26,8 @@ # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -logger = logging.getLogger(__name__) # pylint: disable=wrong-import-position -logger.debug('loading %s', __file__) # pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('loading %s', __file__) # Related third party imports. import matplotlib as mpl diff --git a/LabGym/gui_categorizer.py b/LabGym/gui_categorizer.py index 41763070..afaf3e92 100644 --- a/LabGym/gui_categorizer.py +++ b/LabGym/gui_categorizer.py @@ -21,14 +21,14 @@ import json import logging import os -from pathlib import Path +# from pathlib import Path import shutil # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -logger = logging.getLogger(__name__) # pylint: disable=wrong-import-position -logger.debug('loading %s', __file__) # pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('loading %s', __file__) # Related third party imports. import cv2 diff --git a/LabGym/gui_detector.py b/LabGym/gui_detector.py index ce726d7f..0e5e83bc 100644 --- a/LabGym/gui_detector.py +++ b/LabGym/gui_detector.py @@ -21,14 +21,14 @@ import json import logging import os -from pathlib import Path +# from pathlib import Path import shutil # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -logger = logging.getLogger(__name__) # pylint: disable=wrong-import-position -logger.debug('loading %s', __file__) # pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('loading %s', __file__) # Related third party imports. import wx diff --git a/LabGym/gui_main.py b/LabGym/gui_main.py index 21a75582..30adacec 100644 --- a/LabGym/gui_main.py +++ b/LabGym/gui_main.py @@ -25,8 +25,8 @@ # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -logger = logging.getLogger(__name__) # pylint: disable=wrong-import-position -logger.debug('loading %s', __file__) # pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('loading %s', __file__) # Related third party imports. import wx diff --git a/LabGym/gui_preprocessor.py b/LabGym/gui_preprocessor.py index ef3585fa..1a8b7bb5 100644 --- a/LabGym/gui_preprocessor.py +++ b/LabGym/gui_preprocessor.py @@ -24,8 +24,8 @@ # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -logger = logging.getLogger(__name__) # pylint: disable=wrong-import-position -logger.debug('loading %s', __file__) # pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('loading %s', __file__) # Related third party imports. import cv2 diff --git a/LabGym/myargparse.py b/LabGym/myargparse.py index 4cfa6dc5..cf40702a 100644 --- a/LabGym/myargparse.py +++ b/LabGym/myargparse.py @@ -19,7 +19,9 @@ import os import sys import textwrap -from typing import List, Union, Dict, Any +# from typing import Any, Dict, List, Union +from typing import Dict, List, Union + # Related third party imports. # (none) diff --git a/LabGym/mylogging.py b/LabGym/mylogging.py index 50650924..ce17dd2b 100644 --- a/LabGym/mylogging.py +++ b/LabGym/mylogging.py @@ -1,4 +1,3 @@ -# pylint: disable=line-too-long """Provide functions for configuring the logging system. Functions @@ -97,7 +96,6 @@ logger.debug'%s: %r', '(__name__, __package__', (__name__, __package__)) """ # noqa: E501 -# pylint: enable=line-too-long # Allow use of newer syntax Python 3.10 type hints in Python 3.9. from __future__ import annotations diff --git a/LabGym/mywx/custom.py b/LabGym/mywx/custom.py index d91bd5fd..5cb9eda4 100644 --- a/LabGym/mywx/custom.py +++ b/LabGym/mywx/custom.py @@ -120,6 +120,7 @@ def add_buttons(self, panel, button_sizer): self.Bind(wx.EVT_BUTTON, self.on_ok, id=wx.ID_OK) def on_ok(self, event): + """End the modal state of this dialog object.""" self.EndModal(wx.ID_OK) @@ -136,4 +137,5 @@ def add_buttons(self, panel, button_sizer): self.Bind(wx.EVT_BUTTON, self.on_cancel, id=wx.ID_CANCEL) def on_cancel(self, event): + """End the modal state of this dialog object.""" self.EndModal(wx.ID_CANCEL) diff --git a/LabGym/probes.py b/LabGym/probes.py index 7273c1c0..7e6d643a 100644 --- a/LabGym/probes.py +++ b/LabGym/probes.py @@ -19,11 +19,9 @@ # other imports (against the guidance of PEP 8), to log the load of this # module before other import statements are executed and potentially # produce their own log messages. -# pylint: disable=wrong-import-position logger = logging.getLogger(__name__) logger.debug('%s', f'loading {__file__}') logger.debug('%s: %r', '(__name__, __package__)', (__name__, __package__)) -# pylint: enable=wrong-import-position # Related third party imports. import certifi # Python package for providing Mozilla's CA Bundle. diff --git a/LabGym/tests/INIT.sh b/LabGym/tests/INIT.sh index ab6b3ea7..1475db15 100644 --- a/LabGym/tests/INIT.sh +++ b/LabGym/tests/INIT.sh @@ -7,6 +7,8 @@ ERROR () { printf "ERROR\t%s\n" "$(printf "$@")" >& 2; } DEBUG () { printf "DEBUG\t%s\n" "$(printf "$@")" >& 2; } IS_VENV () { [ -n "$VIRTUAL_ENV+1" ]; } # works in sh, bash, and zsh + +AWK () { awk "$@"; } PYFILES=$(cd .. && echo *.py) # printf "%s: %s\n" "\$PYFILES" "$PYFILES" diff --git a/LabGym/tests/pylint.sh b/LabGym/tests/pylint.sh index 0fef2b29..373b2ed6 100644 --- a/LabGym/tests/pylint.sh +++ b/LabGym/tests/pylint.sh @@ -1,6 +1,16 @@ +# Examples +# # Run pylint with custom options on ../*.py. +# sh pylint.sh +# +# # Run pylint with custom options on two files. +# sh pylint.sh ../categorizer.py ../detector.py +# +# # Don't run pylint... just summarize existing results in tmp.pylint. +# sh pylint.sh --summarize + source INIT.sh -PYFILES=$(echo ../*.py) +PYFILES=$(echo ../*.py ../mywx/*.py) OP=pylint # default OP while [ $# -gt 0 ]; do @@ -13,7 +23,7 @@ while [ $# -gt 0 ]; do done case $OP in -pylint) + pylint) #----------------------------------------------------------------------- if [ $# -gt 0 ]; then PYFILES=$* @@ -25,32 +35,48 @@ IS_VENV || { ERROR "Expected a venv..."; exit 1; } OUTDIR=tmp.pylint +OPTS="--rcfile pylintrc" + +# # Disable invalid-name. +# OPTS="$OPTS${OPTS:+ }--disable=invalid-name" +# --disable=invalid-name is now represented in pylintrc, so removed here. + setopt SH_WORD_SPLIT 2> /dev/null -( - for F in $PYFILES; do - OUTFILE=$OUTDIR/pylint.$(echo $F | tr / . | sed "s/^\.\.\.//").out - OPTS="--rcfile pylintrc" - - # C0301: Line too long (232/100) (line-too-long) - # W0311: Bad indentation. Found 2 spaces, expected 8 (bad-indentation) - OPTS="$OPTS${OPTS:+ }--disable=C0301,W0311" - - (set -x; pylint $OPTS $F > $OUTFILE) - grep -n "^Your code has been rated " $OUTFILE - done -) + +for F in $PYFILES; do + OUTFILE=$OUTDIR/pylint.$(echo $F | tr / . | sed "s/^\.\.\.//").out + + # (set -x; pylint $OPTS $F > $OUTFILE) + printf "%s\n" "+ pylint $OPTS $F > $OUTFILE" + pylint $OPTS $F > $OUTFILE + + grep -n "^Your code has been rated " $OUTFILE +done #----------------------------------------------------------------------- -;; + ;; -summarize) + summarize) + # Don't run pylint... just summarize existing results in tmp.pylint. #----------------------------------------------------------------------- -(cd tmp.pylint && grep -n "Your code has been rated at" *.out) | -sed "s/ (previous.*//" | -sed "s/^pylint\.\(.*.py\).out:\([0-9]*\):Your code has been rated at \(.*\)/\3\t\2\t\1/" | +[ $# -eq 0 ] || { ERROR "Bad usage. \$#: $#"; exit 1; } + +(cd tmp.pylint && grep -n "Your code has been rated at" *.out) | + +sed \ + -e "s/^pylint\.//" \ + -e "s/ (previous run: .*//" \ + -e "s/\(.*.py\).out:\([0-9]*\):/\1\t\2\t/" \ + -e "s/Your code has been rated at //" | + +# print rating, number of messages (assuming N-3), filename +AWK -F"\t" 'BEGIN {OFS = "\t"}; {print $3, $2-3, $1}' | + expand -10,16 | cat -n #----------------------------------------------------------------------- -;; + ;; + + *) { ERROR "Impossible. \$OP: $OP"; exit 1; };; esac exit $? @@ -98,7 +124,7 @@ Main: specific errors. --verbose , -v In verbose mode, extra non-checker-related info will be displayed. - --enable-all-extensions + --enable-all-extensions Load and enable all available extensions. Use --list- extensions to see a list all available extensions. --ignore [,...] diff --git a/LabGym/tests/pylintrc b/LabGym/tests/pylintrc index 6ee72fa5..1e8550be 100644 --- a/LabGym/tests/pylintrc +++ b/LabGym/tests/pylintrc @@ -64,7 +64,7 @@ ignore-patterns=^\.# # 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= +ignored-modules = AppKit # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). @@ -104,10 +104,6 @@ recursive=no # source root. source-roots= -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no @@ -234,6 +230,11 @@ name-group= # not require a docstring. no-docstring-rgx=^_ +# Regular expression matching correct parameter specification variable names. +# If left empty, parameter specification variable names will be checked with +# the set naming style. +#paramspec-rgx= + # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. # These decorators are taken in consideration only for invalid-name. @@ -247,6 +248,10 @@ property-classes=abc.abstractproperty # variable names will be checked with the set naming style. #typevar-rgx= +# Regular expression matching correct type variable tuple names. If left empty, +# type variable tuple names will be checked with the set naming style. +#typevartuple-rgx= + # Naming style matching correct variable names. variable-naming-style=snake_case @@ -344,7 +349,9 @@ indent-after-paren=4 # tab). indent-string=' ' -# Maximum number of characters on a single line. +# Maximum number of characters on a single line. Pylint's default of 100 is +# based on PEP 8's guidance that teams may choose line lengths up to 99 +# characters. max-line-length=100 # Maximum number of lines in a module. @@ -434,11 +441,33 @@ disable=raw-checker-failed, locally-disabled, file-ignored, suppressed-message, - useless-suppression, + # useless-suppression, deprecated-pragma, use-symbolic-message-instead, use-implicit-booleaness-not-comparison-to-string, - use-implicit-booleaness-not-comparison-to-zero + use-implicit-booleaness-not-comparison-to-zero, + + # For example, + # C0301: Line too long (232/100) (line-too-long) + line-too-long, + + # For example, + # C0413: Import "import wx" should be placed at the top of the module (wrong-import-position) + wrong-import-position, + + # For example, + # W0311: Bad indentation. Found 2 spaces, expected 8 (bad-indentation) + bad-indentation, + + # For example, + # C0103: Class name "PanelLv1_AnalysisModule" doesn't conform to PascalCase naming style (invalid-name) + # C0103: Constant name "development_mode" doesn't conform to UPPER_CASE naming style (invalid-name) + # C0103: Argument name "ID_colors" doesn't conform to snake_case naming style (invalid-name) + # C0103: Attribute name "ID_colors" doesn't conform to snake_case naming style (invalid-name) + # C0103: Function name "_myLogRecord" doesn't conform to snake_case naming style (invalid-name) + # C0103: Method name "GetInputValues" doesn't conform to snake_case naming style (invalid-name) + # C0103: Variable name "currentSet" doesn't conform to snake_case naming style (invalid-name) + invalid-name, # 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 @@ -456,6 +485,9 @@ timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests. [MISCELLANEOUS] +# Whether or not to search for fixme's in docstrings. +check-fixme-in-docstring=no + # List of note tags to take in consideration, separated by a comma. notes=FIXME, XXX, @@ -571,7 +603,7 @@ 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=cv2,wx +generated-members = cv2, wx # Tells whether to warn about missing members when the owner of the attribute # is inferred to be None. diff --git a/LabGym/tests/pylintrc- b/LabGym/tests/pylintrc- index 8d36ac78..1007ba21 100644 --- a/LabGym/tests/pylintrc- +++ b/LabGym/tests/pylintrc- @@ -104,10 +104,6 @@ recursive=no # source root. source-roots= -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no @@ -234,6 +230,11 @@ name-group= # not require a docstring. no-docstring-rgx=^_ +# Regular expression matching correct parameter specification variable names. +# If left empty, parameter specification variable names will be checked with +# the set naming style. +#paramspec-rgx= + # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. # These decorators are taken in consideration only for invalid-name. @@ -247,6 +248,10 @@ property-classes=abc.abstractproperty # variable names will be checked with the set naming style. #typevar-rgx= +# Regular expression matching correct type variable tuple names. If left empty, +# type variable tuple names will be checked with the set naming style. +#typevartuple-rgx= + # Naming style matching correct variable names. variable-naming-style=snake_case @@ -344,7 +349,9 @@ indent-after-paren=4 # tab). indent-string=' ' -# Maximum number of characters on a single line. +# Maximum number of characters on a single line. Pylint's default of 100 is +# based on PEP 8's guidance that teams may choose line lengths up to 99 +# characters. max-line-length=100 # Maximum number of lines in a module. @@ -456,6 +463,9 @@ timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests. [MISCELLANEOUS] +# Whether or not to search for fixme's in docstrings. +check-fixme-in-docstring=no + # List of note tags to take in consideration, separated by a comma. notes=FIXME, XXX, diff --git a/LabGym/tools.py b/LabGym/tools.py index 867ab452..1bdc909c 100644 --- a/LabGym/tools.py +++ b/LabGym/tools.py @@ -31,8 +31,8 @@ # Log the load of this module (by the module loader, on first import). # Intentionally positioning these statements before other imports, against the # guidance of PEP-8, to log the load before other imports log messages. -logger = logging.getLogger(__name__) # pylint: disable=wrong-import-position -logger.debug('loading %s', __file__) # pylint: disable=wrong-import-position +logger = logging.getLogger(__name__) +logger.debug('loading %s', __file__) # Related third party imports. import cv2