Code Style Checker eric7

Mon, 17 Feb 2025 16:28:25 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Mon, 17 Feb 2025 16:28:25 +0100
branch
eric7
changeset 11140
b823386f7591
parent 11139
cd22e8e705f4
child 11141
2f5f73c51c7c

Code Style Checker
- Added a checker for `Structural Pattern Matching' based on `flake8-spm` v0.0.1

docs/ThirdParty.md file | annotate | diff | comparison | revisions
docs/changelog.md file | annotate | diff | comparison | revisions
src/eric7/APIs/Python3/eric7.api file | annotate | diff | comparison | revisions
src/eric7/APIs/Python3/eric7.bas file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qch file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/MiscellaneousChecker.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_cs.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_de.qm file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_de.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_empty.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_en.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_es.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_fr.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_it.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_pt.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_ru.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_tr.ts file | annotate | diff | comparison | revisions
src/eric7/i18n/eric7_zh_CN.ts file | annotate | diff | comparison | revisions
--- a/docs/ThirdParty.md	Sun Feb 16 15:06:29 2025 +0100
+++ b/docs/ThirdParty.md	Mon Feb 17 16:28:25 2025 +0100
@@ -19,6 +19,7 @@
 | Name                          |  Version  | License                            |
 |:-----------------------------:|:---------:|:-----------------------------------|
 | bandit                        |   1.8.2   | Apache License 2.0                 |
+| flake8-2020                   |   1.8.1   | MIT License (MIT)                  |
 | flake8-alphabetize            |   0.0.21  | MIT License (MIT No Attribution)   |
 | flake8-annotations            |   3.1.1   | MIT License (MIT)                  |
 | flake8-annotations-complexity |   0.0.8   | MIT License (MIT)                  |
@@ -33,6 +34,7 @@
 | flake8-pep585                 |   0.1.7   | Mozilla Public License Version 2.0 |
 | flake8-pep604                 |   1.1.0   | MIT License (MIT)                  |
 | flake8_simplify               |   0.21.0  | MIT License (MIT)                  |
+| flake8-spm                    |   0.0.1   | MIT License (MIT)                  |
 | flake8-tidy-imports           |   4.11.0  | MIT License (MIT)                  |
 | flake8-unused-arguments       |   0.0.13  | MIT License (MIT)                  |
 | flake8-unused-globals         |   0.1.10  | MIT License (MIT)                  |
--- a/docs/changelog.md	Sun Feb 16 15:06:29 2025 +0100
+++ b/docs/changelog.md	Mon Feb 17 16:28:25 2025 +0100
@@ -9,6 +9,8 @@
         - Miscellaneous to `flake8-bugbear` v24.12.12
         - Miscellaneous to `flake8-comprehensions` v3.16.0
         - Security to `bandit` v1.8.2
+    - Added these checkers to support more case.
+        - 'Structural Pattern Matching' based on `flake8-spm` v0.0.1
 - pip Interface
     - Added a field to search for packages in the dependencies list.
 
--- a/src/eric7/APIs/Python3/eric7.api	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/APIs/Python3/eric7.api	Mon Feb 17 16:28:25 2025 +0100
@@ -4446,6 +4446,8 @@
 eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.BugbearMutableLiterals?7
 eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.DateTimeVisitor.visit_Call?4(node)
 eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.DateTimeVisitor?1()
+eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.DefaultMatchCaseVisitor.visit_Match?4(node)
+eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.DefaultMatchCaseVisitor?1()
 eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.ExceptBaseExceptionVisitor.reRaised?4()
 eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.ExceptBaseExceptionVisitor.visit_ExceptHandler?4(node: ast.ExceptHandler)
 eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.ExceptBaseExceptionVisitor.visit_Raise?4(node)
--- a/src/eric7/APIs/Python3/eric7.bas	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/APIs/Python3/eric7.bas	Mon Feb 17 16:28:25 2025 +0100
@@ -171,6 +171,7 @@
 DebuggerPropertiesFile QObject
 DebuggerPython3Page ConfigurationPageBase Ui_DebuggerPython3Page
 DeepLEngine TranslationEngine
+DefaultMatchCaseVisitor ast.NodeVisitor
 DefaultResolver BaseResolver
 DelayedFileWatcher EricFileSystemWatcher
 DeleteFilesConfirmationDialog QDialog Ui_DeleteFilesConfirmationDialog
Binary file src/eric7/Documentation/Help/source.qch has changed
--- a/src/eric7/Documentation/Help/source.qhp	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/Documentation/Help/source.qhp	Mon Feb 17 16:28:25 2025 +0100
@@ -4362,6 +4362,14 @@
       <keyword name="DeepLEngine.engineName" id="DeepLEngine.engineName" ref="eric7.Plugins.UiExtensionPlugins.Translator.TranslatorEngines.DeepLEngine.html#DeepLEngine.engineName" />
       <keyword name="DeepLEngine.getTranslation" id="DeepLEngine.getTranslation" ref="eric7.Plugins.UiExtensionPlugins.Translator.TranslatorEngines.DeepLEngine.html#DeepLEngine.getTranslation" />
       <keyword name="DeepLEngine.supportedLanguages" id="DeepLEngine.supportedLanguages" ref="eric7.Plugins.UiExtensionPlugins.Translator.TranslatorEngines.DeepLEngine.html#DeepLEngine.supportedLanguages" />
+      <keyword name="DefaultMatchCaseVisitor" id="DefaultMatchCaseVisitor" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor" />
+      <keyword name="DefaultMatchCaseVisitor (Constructor)" id="DefaultMatchCaseVisitor (Constructor)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor.__init__" />
+      <keyword name="DefaultMatchCaseVisitor.__badNodes" id="DefaultMatchCaseVisitor.__badNodes" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor.__badNodes" />
+      <keyword name="DefaultMatchCaseVisitor.__emptyMatchDefault" id="DefaultMatchCaseVisitor.__emptyMatchDefault" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor.__emptyMatchDefault" />
+      <keyword name="DefaultMatchCaseVisitor.__findBadNode" id="DefaultMatchCaseVisitor.__findBadNode" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor.__findBadNode" />
+      <keyword name="DefaultMatchCaseVisitor.__lastStatementDoesNotRaise" id="DefaultMatchCaseVisitor.__lastStatementDoesNotRaise" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor.__lastStatementDoesNotRaise" />
+      <keyword name="DefaultMatchCaseVisitor.__returnPrecedesExceptionRaising" id="DefaultMatchCaseVisitor.__returnPrecedesExceptionRaising" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor.__returnPrecedesExceptionRaising" />
+      <keyword name="DefaultMatchCaseVisitor.visit_Match" id="DefaultMatchCaseVisitor.visit_Match" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DefaultMatchCaseVisitor.visit_Match" />
       <keyword name="DefaultResolver" id="DefaultResolver" ref="eric7.DebugClients.Python.DebugVariables.html#DefaultResolver" />
       <keyword name="DefaultResolver.getVariableList" id="DefaultResolver.getVariableList" ref="eric7.DebugClients.Python.DebugVariables.html#DefaultResolver.getVariableList" />
       <keyword name="DefaultSearchEngines (Package)" id="DefaultSearchEngines (Package)" ref="index-eric7.WebBrowser.OpenSearch.DefaultSearchEngines.html" />
@@ -12018,6 +12026,7 @@
       <keyword name="MiscellaneousChecker.__checkComprehensions" id="MiscellaneousChecker.__checkComprehensions" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#MiscellaneousChecker.__checkComprehensions" />
       <keyword name="MiscellaneousChecker.__checkCopyright" id="MiscellaneousChecker.__checkCopyright" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#MiscellaneousChecker.__checkCopyright" />
       <keyword name="MiscellaneousChecker.__checkDateTime" id="MiscellaneousChecker.__checkDateTime" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#MiscellaneousChecker.__checkDateTime" />
+      <keyword name="MiscellaneousChecker.__checkDefaultMatchCase" id="MiscellaneousChecker.__checkDefaultMatchCase" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#MiscellaneousChecker.__checkDefaultMatchCase" />
       <keyword name="MiscellaneousChecker.__checkDictWithSortedKeys" id="MiscellaneousChecker.__checkDictWithSortedKeys" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#MiscellaneousChecker.__checkDictWithSortedKeys" />
       <keyword name="MiscellaneousChecker.__checkExplicitStringConcat" id="MiscellaneousChecker.__checkExplicitStringConcat" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#MiscellaneousChecker.__checkExplicitStringConcat" />
       <keyword name="MiscellaneousChecker.__checkFormatString" id="MiscellaneousChecker.__checkFormatString" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#MiscellaneousChecker.__checkFormatString" />
--- a/src/eric7/Documentation/Source/eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/Documentation/Source/eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html	Mon Feb 17 16:28:25 2025 +0100
@@ -31,6 +31,10 @@
 <td>Class implementing a node visitor to check datetime function calls.</td>
 </tr>
 <tr>
+<td><a href="#DefaultMatchCaseVisitor">DefaultMatchCaseVisitor</a></td>
+<td>Class implementing a node visitor to check default match cases.</td>
+</tr>
+<tr>
 <td><a href="#ExceptBaseExceptionVisitor">ExceptBaseExceptionVisitor</a></td>
 <td>Class to determine, if a 'BaseException' is re-raised.</td>
 </tr>
@@ -1854,6 +1858,222 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
+<a NAME="DefaultMatchCaseVisitor" ID="DefaultMatchCaseVisitor"></a>
+<h2>DefaultMatchCaseVisitor</h2>
+<p>
+    Class implementing a node visitor to check default match cases.
+</p>
+<p>
+    Note: This class is modeled after flake8-spm v0.0.1.
+</p>
+
+<h3>Derived from</h3>
+ast.NodeVisitor
+<h3>Class Attributes</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<h3>Class Methods</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<h3>Methods</h3>
+<table>
+<tr>
+<td><a href="#DefaultMatchCaseVisitor.__init__">DefaultMatchCaseVisitor</a></td>
+<td>Constructor</td>
+</tr>
+<tr>
+<td><a href="#DefaultMatchCaseVisitor.__badNodes">__badNodes</a></td>
+<td>Private method to yield bad match nodes.</td>
+</tr>
+<tr>
+<td><a href="#DefaultMatchCaseVisitor.__emptyMatchDefault">__emptyMatchDefault</a></td>
+<td>Private method to check for an empty default match case.</td>
+</tr>
+<tr>
+<td><a href="#DefaultMatchCaseVisitor.__findBadNode">__findBadNode</a></td>
+<td>Private method returning a reference to the bad node of a case node.</td>
+</tr>
+<tr>
+<td><a href="#DefaultMatchCaseVisitor.__lastStatementDoesNotRaise">__lastStatementDoesNotRaise</a></td>
+<td>Private method to check that the last case statement does not raise an exception.</td>
+</tr>
+<tr>
+<td><a href="#DefaultMatchCaseVisitor.__returnPrecedesExceptionRaising">__returnPrecedesExceptionRaising</a></td>
+<td>Private method to check that no return precedes an exception raising.</td>
+</tr>
+<tr>
+<td><a href="#DefaultMatchCaseVisitor.visit_Match">visit_Match</a></td>
+<td>Public method to handle Match nodes.</td>
+</tr>
+</table>
+
+<h3>Static Methods</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+
+
+<a NAME="DefaultMatchCaseVisitor.__init__" ID="DefaultMatchCaseVisitor.__init__"></a>
+<h4>DefaultMatchCaseVisitor (Constructor)</h4>
+<b>DefaultMatchCaseVisitor</b>(<i></i>)
+<p>
+        Constructor
+</p>
+
+<a NAME="DefaultMatchCaseVisitor.__badNodes" ID="DefaultMatchCaseVisitor.__badNodes"></a>
+<h4>DefaultMatchCaseVisitor.__badNodes</h4>
+<b>__badNodes</b>(<i>node</i>)
+<p>
+        Private method to yield bad match nodes.
+</p>
+
+<dl>
+
+<dt><i>node</i> (ast.Match)</dt>
+<dd>
+reference to the node to be processed
+</dd>
+</dl>
+<dl>
+<dt>Yield:</dt>
+<dd>
+tuple containing a reference to bad match case node and the corresponding
+            issue code
+</dd>
+</dl>
+<dl>
+<dt>Yield Type:</dt>
+<dd>
+tyuple of (ast.AST, str)
+</dd>
+</dl>
+<a NAME="DefaultMatchCaseVisitor.__emptyMatchDefault" ID="DefaultMatchCaseVisitor.__emptyMatchDefault"></a>
+<h4>DefaultMatchCaseVisitor.__emptyMatchDefault</h4>
+<b>__emptyMatchDefault</b>(<i>case</i>)
+<p>
+        Private method to check for an empty default match case.
+</p>
+
+<dl>
+
+<dt><i>case</i> (ast.match_case)</dt>
+<dd>
+reference to the node to be processed
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating an empty default match case
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<a NAME="DefaultMatchCaseVisitor.__findBadNode" ID="DefaultMatchCaseVisitor.__findBadNode"></a>
+<h4>DefaultMatchCaseVisitor.__findBadNode</h4>
+<b>__findBadNode</b>(<i>case</i>)
+<p>
+        Private method returning a reference to the bad node of a case node.
+</p>
+
+<dl>
+
+<dt><i>case</i> (ast.match_case)</dt>
+<dd>
+reference to the node to be processed
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+reference to the bad node
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+ast.AST
+</dd>
+</dl>
+<a NAME="DefaultMatchCaseVisitor.__lastStatementDoesNotRaise" ID="DefaultMatchCaseVisitor.__lastStatementDoesNotRaise"></a>
+<h4>DefaultMatchCaseVisitor.__lastStatementDoesNotRaise</h4>
+<b>__lastStatementDoesNotRaise</b>(<i>case</i>)
+<p>
+        Private method to check that the last case statement does not raise an
+        exception.
+</p>
+
+<dl>
+
+<dt><i>case</i> (ast.match_case)</dt>
+<dd>
+reference to the node to be processed
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating that the last case statement does not raise an
+            exception
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<a NAME="DefaultMatchCaseVisitor.__returnPrecedesExceptionRaising" ID="DefaultMatchCaseVisitor.__returnPrecedesExceptionRaising"></a>
+<h4>DefaultMatchCaseVisitor.__returnPrecedesExceptionRaising</h4>
+<b>__returnPrecedesExceptionRaising</b>(<i>case</i>)
+<p>
+        Private method to check that no return precedes an exception raising.
+</p>
+
+<dl>
+
+<dt><i>case</i> (ast.match_case)</dt>
+<dd>
+reference to the node to be processed
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating that a return precedes an exception raising
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
+<a NAME="DefaultMatchCaseVisitor.visit_Match" ID="DefaultMatchCaseVisitor.visit_Match"></a>
+<h4>DefaultMatchCaseVisitor.visit_Match</h4>
+<b>visit_Match</b>(<i>node</i>)
+<p>
+        Public method to handle Match nodes.
+</p>
+
+<dl>
+
+<dt><i>node</i> (ast.Match)</dt>
+<dd>
+reference to the node to be processed
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
 <a NAME="ExceptBaseExceptionVisitor" ID="ExceptBaseExceptionVisitor"></a>
 <h2>ExceptBaseExceptionVisitor</h2>
 <p>
@@ -2510,6 +2730,10 @@
 <td>Private method to check use of naive datetime functions.</td>
 </tr>
 <tr>
+<td><a href="#MiscellaneousChecker.__checkDefaultMatchCase">__checkDefaultMatchCase</a></td>
+<td>Private method to check the default match case.</td>
+</tr>
+<tr>
 <td><a href="#MiscellaneousChecker.__checkDictWithSortedKeys">__checkDictWithSortedKeys</a></td>
 <td>Private method to check, if dictionary keys appear in sorted order.</td>
 </tr>
@@ -2693,6 +2917,13 @@
         Private method to check use of naive datetime functions.
 </p>
 
+<a NAME="MiscellaneousChecker.__checkDefaultMatchCase" ID="MiscellaneousChecker.__checkDefaultMatchCase"></a>
+<h4>MiscellaneousChecker.__checkDefaultMatchCase</h4>
+<b>__checkDefaultMatchCase</b>(<i></i>)
+<p>
+        Private method to check the default match case.
+</p>
+
 <a NAME="MiscellaneousChecker.__checkDictWithSortedKeys" ID="MiscellaneousChecker.__checkDictWithSortedKeys"></a>
 <h4>MiscellaneousChecker.__checkDictWithSortedKeys</h4>
 <b>__checkDictWithSortedKeys</b>(<i></i>)
@@ -3694,7 +3925,7 @@
     sys.version_info.
 </p>
 <p>
-    Note: This class is modeled after flake8-2020 checker.
+    Note: This class is modeled after flake8-2020 v1.8.1.
 </p>
 
 <h3>Derived from</h3>
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/MiscellaneousChecker.py	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/MiscellaneousChecker.py	Mon Feb 17 16:28:25 2025 +0100
@@ -247,6 +247,9 @@
         "M853",
         ## commented code
         "M891",
+        ## structural pattern matching
+        "M901",
+        "M902",
     ]
 
     Formatter = Formatter()
@@ -452,6 +455,7 @@
             (self.__checkImplicitStringConcat, ("M851", "M852")),
             (self.__checkExplicitStringConcat, ("M853",)),
             (self.__checkCommentedCode, ("M891",)),
+            (self.__checkDefaultMatchCase, ("M901", "M902")),
         ]
 
         # the eradicate whitelist
@@ -1502,6 +1506,21 @@
             ):
                 self.__error(node.lineno - 1, node.col_offset, "M853")
 
+    #################################################################################
+    ## The following method checks default match cases.
+    #################################################################################
+
+    def __checkDefaultMatchCase(self):
+        """
+        Private method to check the default match case.
+        """
+        visitor = DefaultMatchCaseVisitor()
+        visitor.visit(self.__tree)
+        for violation in visitor.violations:
+            node = violation[0]
+            reason = violation[1]
+            self.__error(node.lineno - 1, node.col_offset, reason)
+
 
 class TextVisitor(ast.NodeVisitor):
     """
@@ -4237,7 +4256,7 @@
     Class implementing a node visitor to check the use of sys.version and
     sys.version_info.
 
-    Note: This class is modeled after flake8-2020 checker.
+    Note: This class is modeled after flake8-2020 v1.8.1.
     """
 
     def __init__(self):
@@ -4418,5 +4437,116 @@
         self.generic_visit(node)
 
 
+class DefaultMatchCaseVisitor(ast.NodeVisitor):
+    """
+    Class implementing a node visitor to check default match cases.
+
+    Note: This class is modeled after flake8-spm v0.0.1.
+    """
+
+    def __init__(self):
+        """
+        Constructor
+        """
+        super().__init__()
+
+        self.violations = []
+
+    def visit_Match(self, node):
+        """
+        Public method to handle Match nodes.
+
+        @param node reference to the node to be processed
+        @type ast.Match
+        """
+        for badNode, issueCode in self.__badNodes(node):
+            self.violations.append((badNode, issueCode))
+
+        self.generic_visit(node)
+
+    def __badNodes(self, node):
+        """
+        Private method to yield bad match nodes.
+
+        @param node reference to the node to be processed
+        @type ast.Match
+        @yield tuple containing a reference to bad match case node and the corresponding
+            issue code
+        @ytype tyuple of (ast.AST, str)
+        """
+        for case in node.cases:
+            if self.__emptyMatchDefault(case):
+                if self.__lastStatementDoesNotRaise(case):
+                    yield self.__findBadNode(case), "M901"
+                elif self.__returnPrecedesExceptionRaising(case):
+                    yield self.__findBadNode(case), "M902"
+
+    def __emptyMatchDefault(self, case):
+        """
+        Private method to check for an empty default match case.
+
+        @param case reference to the node to be processed
+        @type ast.match_case
+        @return flag indicating an empty default match case
+        @rtype bool
+        """
+        pattern = case.pattern
+        return isinstance(pattern, ast.MatchAs) and (
+            pattern.pattern is None
+            or (
+                isinstance(pattern.pattern, ast.MatchAs)
+                and pattern.pattern.pattern is None
+            )
+        )
+
+    def __lastStatementDoesNotRaise(self, case):
+        """
+        Private method to check that the last case statement does not raise an
+        exception.
+
+        @param case reference to the node to be processed
+        @type ast.match_case
+        @return flag indicating that the last case statement does not raise an
+            exception
+        @rtype bool
+        """
+        return not isinstance(case.body[-1], ast.Raise)
+
+    def __returnPrecedesExceptionRaising(self, case):
+        """
+        Private method to check that no return precedes an exception raising.
+
+        @param case reference to the node to be processed
+        @type ast.match_case
+        @return flag indicating that a return precedes an exception raising
+        @rtype bool
+        """
+        returnIndex = -1
+        raiseIndex = -1
+        for index, body in enumerate(case.body):
+            if isinstance(body, ast.Return):
+                returnIndex = index
+            elif isinstance(body, ast.Raise):
+                raiseIndex = index
+        return returnIndex >= 0 and returnIndex < raiseIndex
+
+    def __findBadNode(self, case) -> ast.AST:
+        """
+        Private method returning a reference to the bad node of a case node.
+
+        @param case reference to the node to be processed
+        @type ast.match_case
+        @return reference to the bad node
+        @rtype ast.AST
+        """
+        for body in case.body:
+            # Handle special case when return precedes exception raising.
+            # In this case the bad node is that with the return statement.
+            if isinstance(body, ast.Return):
+                return body
+
+        return case.body[-1]
+
+
 #
 # eflag: noqa = M891
--- a/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py	Mon Feb 17 16:28:25 2025 +0100
@@ -636,6 +636,16 @@
         "MiscellaneousChecker",
         "commented code lines should be removed",
     ),
+    ## structural pattern matching
+    "M901": QCoreApplication.translate(
+        "MiscellaneousChecker",
+        "matching a default value should raise a `ValueError` exception",
+    ),
+    "M902": QCoreApplication.translate(
+        "MiscellaneousChecker",
+        "matching a default value should not contain a `return` statement before "
+        "raising a `ValueError` exception",
+    ),
 }
 
 _miscellaneousMessagesSampleArgs = {
--- a/src/eric7/i18n/eric7_cs.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_cs.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56348,6 +56348,16 @@
       <source>commented code lines should be removed</source>
       <translation type="unfinished" />
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
Binary file src/eric7/i18n/eric7_de.qm has changed
--- a/src/eric7/i18n/eric7_de.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_de.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56379,6 +56379,16 @@
       <source>commented code lines should be removed</source>
       <translation>auskommentierte Codezeilen sollten entfernt werden</translation>
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation>Prüfung auf einen Standardwert sollte eine `ValueError`-Ausnahme auslösen</translation>
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation>Prüfung auf einen Standardwert sollte kein `return`-Statement vor einer `ValueError`-Ausnahme besitzen</translation>
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
--- a/src/eric7/i18n/eric7_empty.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_empty.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56110,6 +56110,16 @@
       <source>commented code lines should be removed</source>
       <translation type="unfinished" />
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
--- a/src/eric7/i18n/eric7_en.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_en.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56160,6 +56160,16 @@
       <source>commented code lines should be removed</source>
       <translation type="unfinished" />
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
--- a/src/eric7/i18n/eric7_es.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_es.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56384,6 +56384,16 @@
       <translation>las líneas de código comentadas se deberían eliminar</translation>
     </message>
     <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
       <source>return/continue/break inside finally blocks cause exceptions to be silenced. Exceptions should be silenced in except blocks. Control statements can be moved outside the finally block.</source>
       <translation type="vanished">return/continue/break dentro de bloques finally hace que las excepciones se silencien. Las excepciones se deben silenciar en bloques except. Las sentencias de control se pueden extraer a un bloque finally.</translation>
     </message>
--- a/src/eric7/i18n/eric7_fr.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_fr.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56395,6 +56395,16 @@
       <source>commented code lines should be removed</source>
       <translation>les lignes de code commentées devraient être supprimées</translation>
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
--- a/src/eric7/i18n/eric7_it.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_it.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56384,6 +56384,16 @@
       <source>commented code lines should be removed</source>
       <translation type="unfinished" />
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
--- a/src/eric7/i18n/eric7_pt.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_pt.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56396,6 +56396,16 @@
       <source>commented code lines should be removed</source>
       <translation type="unfinished" />
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
--- a/src/eric7/i18n/eric7_ru.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_ru.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56470,6 +56470,16 @@
       <translation>закомментированные строки кода должны быть удалены</translation>
     </message>
     <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
       <source>return/continue/break inside finally blocks cause exceptions to be silenced. Exceptions should be silenced in except blocks. Control statements can be moved outside the finally block.</source>
       <translation type="vanished">return/continue/break внутри блоков finally заставляют исключения отключаться. Исключения должны быть отключены в блоках except. Управляющие операторы могут быть перемещены за пределы блока finally.</translation>
     </message>
--- a/src/eric7/i18n/eric7_tr.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_tr.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56317,6 +56317,16 @@
       <source>commented code lines should be removed</source>
       <translation type="unfinished" />
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>
--- a/src/eric7/i18n/eric7_zh_CN.ts	Sun Feb 16 15:06:29 2025 +0100
+++ b/src/eric7/i18n/eric7_zh_CN.ts	Mon Feb 17 16:28:25 2025 +0100
@@ -56282,6 +56282,16 @@
       <source>commented code lines should be removed</source>
       <translation type="unfinished" />
     </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="640" />
+      <source>matching a default value should raise a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
+    <message>
+      <location filename="../Plugins/CheckerPlugins/CodeStyleChecker/Miscellaneous/translations.py" line="644" />
+      <source>matching a default value should not contain a `return` statement before raising a `ValueError` exception</source>
+      <translation type="unfinished" />
+    </message>
   </context>
   <context>
     <name>MouseClickDialog</name>

eric ide

mercurial