Merge pull request #20263 from joefarebrother/python-qual-exceptions

Python: Modernize the Unreachable Except Block query
This commit is contained in:
Joe Farebrother
2025-09-22 09:42:09 +01:00
committed by GitHub
11 changed files with 894 additions and 22 deletions

View File

@@ -0,0 +1,738 @@
# process-builtin-exceptions 0.0.1; Python 3.11.0rc2
extensions:
- addsTo:
extensible: typeModel
pack: codeql/python-all
data:
- - builtins.PendingDeprecationWarning~Subclass
- builtins.PendingDeprecationWarning
- ''
- - builtins.Warning~Subclass
- builtins.PendingDeprecationWarning
- ''
- - builtins.Exception~Subclass
- builtins.PendingDeprecationWarning
- ''
- - builtins.BaseException~Subclass
- builtins.PendingDeprecationWarning
- ''
- - builtins.UnicodeWarning~Subclass
- builtins.UnicodeWarning
- ''
- - builtins.Warning~Subclass
- builtins.UnicodeWarning
- ''
- - builtins.Exception~Subclass
- builtins.UnicodeWarning
- ''
- - builtins.BaseException~Subclass
- builtins.UnicodeWarning
- ''
- - builtins.StopAsyncIteration~Subclass
- builtins.StopAsyncIteration
- ''
- - builtins.Exception~Subclass
- builtins.StopAsyncIteration
- ''
- - builtins.BaseException~Subclass
- builtins.StopAsyncIteration
- ''
- - builtins.KeyboardInterrupt~Subclass
- builtins.KeyboardInterrupt
- ''
- - builtins.BaseException~Subclass
- builtins.KeyboardInterrupt
- ''
- - builtins.ConnectionError~Subclass
- builtins.ConnectionError
- ''
- - builtins.OSError~Subclass
- builtins.ConnectionError
- ''
- - builtins.Exception~Subclass
- builtins.ConnectionError
- ''
- - builtins.BaseException~Subclass
- builtins.ConnectionError
- ''
- - builtins.ConnectionResetError~Subclass
- builtins.ConnectionResetError
- ''
- - builtins.ConnectionError~Subclass
- builtins.ConnectionResetError
- ''
- - builtins.OSError~Subclass
- builtins.ConnectionResetError
- ''
- - builtins.Exception~Subclass
- builtins.ConnectionResetError
- ''
- - builtins.BaseException~Subclass
- builtins.ConnectionResetError
- ''
- - builtins.InterruptedError~Subclass
- builtins.InterruptedError
- ''
- - builtins.OSError~Subclass
- builtins.InterruptedError
- ''
- - builtins.Exception~Subclass
- builtins.InterruptedError
- ''
- - builtins.BaseException~Subclass
- builtins.InterruptedError
- ''
- - builtins.RuntimeError~Subclass
- builtins.RuntimeError
- ''
- - builtins.Exception~Subclass
- builtins.RuntimeError
- ''
- - builtins.BaseException~Subclass
- builtins.RuntimeError
- ''
- - builtins.AttributeError~Subclass
- builtins.AttributeError
- ''
- - builtins.Exception~Subclass
- builtins.AttributeError
- ''
- - builtins.BaseException~Subclass
- builtins.AttributeError
- ''
- - builtins.IndexError~Subclass
- builtins.IndexError
- ''
- - builtins.LookupError~Subclass
- builtins.IndexError
- ''
- - builtins.Exception~Subclass
- builtins.IndexError
- ''
- - builtins.BaseException~Subclass
- builtins.IndexError
- ''
- - builtins.UnicodeDecodeError~Subclass
- builtins.UnicodeDecodeError
- ''
- - builtins.UnicodeError~Subclass
- builtins.UnicodeDecodeError
- ''
- - builtins.ValueError~Subclass
- builtins.UnicodeDecodeError
- ''
- - builtins.Exception~Subclass
- builtins.UnicodeDecodeError
- ''
- - builtins.BaseException~Subclass
- builtins.UnicodeDecodeError
- ''
- - builtins.ExceptionGroup~Subclass
- builtins.ExceptionGroup
- ''
- - builtins.BaseExceptionGroup~Subclass
- builtins.ExceptionGroup
- ''
- - builtins.Exception~Subclass
- builtins.ExceptionGroup
- ''
- - builtins.BaseException~Subclass
- builtins.ExceptionGroup
- ''
- - builtins.OverflowError~Subclass
- builtins.OverflowError
- ''
- - builtins.ArithmeticError~Subclass
- builtins.OverflowError
- ''
- - builtins.Exception~Subclass
- builtins.OverflowError
- ''
- - builtins.BaseException~Subclass
- builtins.OverflowError
- ''
- - builtins.BufferError~Subclass
- builtins.BufferError
- ''
- - builtins.Exception~Subclass
- builtins.BufferError
- ''
- - builtins.BaseException~Subclass
- builtins.BufferError
- ''
- - builtins.SyntaxWarning~Subclass
- builtins.SyntaxWarning
- ''
- - builtins.Warning~Subclass
- builtins.SyntaxWarning
- ''
- - builtins.Exception~Subclass
- builtins.SyntaxWarning
- ''
- - builtins.BaseException~Subclass
- builtins.SyntaxWarning
- ''
- - builtins.BytesWarning~Subclass
- builtins.BytesWarning
- ''
- - builtins.Warning~Subclass
- builtins.BytesWarning
- ''
- - builtins.Exception~Subclass
- builtins.BytesWarning
- ''
- - builtins.BaseException~Subclass
- builtins.BytesWarning
- ''
- - builtins.StopIteration~Subclass
- builtins.StopIteration
- ''
- - builtins.Exception~Subclass
- builtins.StopIteration
- ''
- - builtins.BaseException~Subclass
- builtins.StopIteration
- ''
- - builtins.ImportError~Subclass
- builtins.ImportError
- ''
- - builtins.Exception~Subclass
- builtins.ImportError
- ''
- - builtins.BaseException~Subclass
- builtins.ImportError
- ''
- - builtins.ChildProcessError~Subclass
- builtins.ChildProcessError
- ''
- - builtins.OSError~Subclass
- builtins.ChildProcessError
- ''
- - builtins.Exception~Subclass
- builtins.ChildProcessError
- ''
- - builtins.BaseException~Subclass
- builtins.ChildProcessError
- ''
- - builtins.FileExistsError~Subclass
- builtins.FileExistsError
- ''
- - builtins.OSError~Subclass
- builtins.FileExistsError
- ''
- - builtins.Exception~Subclass
- builtins.FileExistsError
- ''
- - builtins.BaseException~Subclass
- builtins.FileExistsError
- ''
- - builtins.PermissionError~Subclass
- builtins.PermissionError
- ''
- - builtins.OSError~Subclass
- builtins.PermissionError
- ''
- - builtins.Exception~Subclass
- builtins.PermissionError
- ''
- - builtins.BaseException~Subclass
- builtins.PermissionError
- ''
- - builtins.RecursionError~Subclass
- builtins.RecursionError
- ''
- - builtins.RuntimeError~Subclass
- builtins.RecursionError
- ''
- - builtins.Exception~Subclass
- builtins.RecursionError
- ''
- - builtins.BaseException~Subclass
- builtins.RecursionError
- ''
- - builtins.SyntaxError~Subclass
- builtins.SyntaxError
- ''
- - builtins.Exception~Subclass
- builtins.SyntaxError
- ''
- - builtins.BaseException~Subclass
- builtins.SyntaxError
- ''
- - builtins.KeyError~Subclass
- builtins.KeyError
- ''
- - builtins.LookupError~Subclass
- builtins.KeyError
- ''
- - builtins.Exception~Subclass
- builtins.KeyError
- ''
- - builtins.BaseException~Subclass
- builtins.KeyError
- ''
- - builtins.UnicodeTranslateError~Subclass
- builtins.UnicodeTranslateError
- ''
- - builtins.UnicodeError~Subclass
- builtins.UnicodeTranslateError
- ''
- - builtins.ValueError~Subclass
- builtins.UnicodeTranslateError
- ''
- - builtins.Exception~Subclass
- builtins.UnicodeTranslateError
- ''
- - builtins.BaseException~Subclass
- builtins.UnicodeTranslateError
- ''
- - builtins.ZeroDivisionError~Subclass
- builtins.ZeroDivisionError
- ''
- - builtins.ArithmeticError~Subclass
- builtins.ZeroDivisionError
- ''
- - builtins.Exception~Subclass
- builtins.ZeroDivisionError
- ''
- - builtins.BaseException~Subclass
- builtins.ZeroDivisionError
- ''
- - builtins.Warning~Subclass
- builtins.Warning
- ''
- - builtins.Exception~Subclass
- builtins.Warning
- ''
- - builtins.BaseException~Subclass
- builtins.Warning
- ''
- - builtins.RuntimeWarning~Subclass
- builtins.RuntimeWarning
- ''
- - builtins.Warning~Subclass
- builtins.RuntimeWarning
- ''
- - builtins.Exception~Subclass
- builtins.RuntimeWarning
- ''
- - builtins.BaseException~Subclass
- builtins.RuntimeWarning
- ''
- - builtins.EncodingWarning~Subclass
- builtins.EncodingWarning
- ''
- - builtins.Warning~Subclass
- builtins.EncodingWarning
- ''
- - builtins.Exception~Subclass
- builtins.EncodingWarning
- ''
- - builtins.BaseException~Subclass
- builtins.EncodingWarning
- ''
- - builtins.BaseException~Subclass
- builtins.BaseException
- ''
- - builtins.GeneratorExit~Subclass
- builtins.GeneratorExit
- ''
- - builtins.BaseException~Subclass
- builtins.GeneratorExit
- ''
- - builtins.ModuleNotFoundError~Subclass
- builtins.ModuleNotFoundError
- ''
- - builtins.ImportError~Subclass
- builtins.ModuleNotFoundError
- ''
- - builtins.Exception~Subclass
- builtins.ModuleNotFoundError
- ''
- - builtins.BaseException~Subclass
- builtins.ModuleNotFoundError
- ''
- - builtins.BrokenPipeError~Subclass
- builtins.BrokenPipeError
- ''
- - builtins.ConnectionError~Subclass
- builtins.BrokenPipeError
- ''
- - builtins.OSError~Subclass
- builtins.BrokenPipeError
- ''
- - builtins.Exception~Subclass
- builtins.BrokenPipeError
- ''
- - builtins.BaseException~Subclass
- builtins.BrokenPipeError
- ''
- - builtins.FileNotFoundError~Subclass
- builtins.FileNotFoundError
- ''
- - builtins.OSError~Subclass
- builtins.FileNotFoundError
- ''
- - builtins.Exception~Subclass
- builtins.FileNotFoundError
- ''
- - builtins.BaseException~Subclass
- builtins.FileNotFoundError
- ''
- - builtins.ProcessLookupError~Subclass
- builtins.ProcessLookupError
- ''
- - builtins.OSError~Subclass
- builtins.ProcessLookupError
- ''
- - builtins.Exception~Subclass
- builtins.ProcessLookupError
- ''
- - builtins.BaseException~Subclass
- builtins.ProcessLookupError
- ''
- - builtins.NotImplementedError~Subclass
- builtins.NotImplementedError
- ''
- - builtins.RuntimeError~Subclass
- builtins.NotImplementedError
- ''
- - builtins.Exception~Subclass
- builtins.NotImplementedError
- ''
- - builtins.BaseException~Subclass
- builtins.NotImplementedError
- ''
- - builtins.IndentationError~Subclass
- builtins.IndentationError
- ''
- - builtins.SyntaxError~Subclass
- builtins.IndentationError
- ''
- - builtins.Exception~Subclass
- builtins.IndentationError
- ''
- - builtins.BaseException~Subclass
- builtins.IndentationError
- ''
- - builtins.ValueError~Subclass
- builtins.ValueError
- ''
- - builtins.Exception~Subclass
- builtins.ValueError
- ''
- - builtins.BaseException~Subclass
- builtins.ValueError
- ''
- - builtins.AssertionError~Subclass
- builtins.AssertionError
- ''
- - builtins.Exception~Subclass
- builtins.AssertionError
- ''
- - builtins.BaseException~Subclass
- builtins.AssertionError
- ''
- - builtins.SystemError~Subclass
- builtins.SystemError
- ''
- - builtins.Exception~Subclass
- builtins.SystemError
- ''
- - builtins.BaseException~Subclass
- builtins.SystemError
- ''
- - builtins.UserWarning~Subclass
- builtins.UserWarning
- ''
- - builtins.Warning~Subclass
- builtins.UserWarning
- ''
- - builtins.Exception~Subclass
- builtins.UserWarning
- ''
- - builtins.BaseException~Subclass
- builtins.UserWarning
- ''
- - builtins.FutureWarning~Subclass
- builtins.FutureWarning
- ''
- - builtins.Warning~Subclass
- builtins.FutureWarning
- ''
- - builtins.Exception~Subclass
- builtins.FutureWarning
- ''
- - builtins.BaseException~Subclass
- builtins.FutureWarning
- ''
- - builtins.Exception~Subclass
- builtins.Exception
- ''
- - builtins.BaseException~Subclass
- builtins.Exception
- ''
- - builtins.ResourceWarning~Subclass
- builtins.ResourceWarning
- ''
- - builtins.Warning~Subclass
- builtins.ResourceWarning
- ''
- - builtins.Exception~Subclass
- builtins.ResourceWarning
- ''
- - builtins.BaseException~Subclass
- builtins.ResourceWarning
- ''
- - builtins.SystemExit~Subclass
- builtins.SystemExit
- ''
- - builtins.BaseException~Subclass
- builtins.SystemExit
- ''
- - builtins.OSError~Subclass
- builtins.OSError
- ''
- - builtins.Exception~Subclass
- builtins.OSError
- ''
- - builtins.BaseException~Subclass
- builtins.OSError
- ''
- - builtins.ConnectionAbortedError~Subclass
- builtins.ConnectionAbortedError
- ''
- - builtins.ConnectionError~Subclass
- builtins.ConnectionAbortedError
- ''
- - builtins.OSError~Subclass
- builtins.ConnectionAbortedError
- ''
- - builtins.Exception~Subclass
- builtins.ConnectionAbortedError
- ''
- - builtins.BaseException~Subclass
- builtins.ConnectionAbortedError
- ''
- - builtins.IsADirectoryError~Subclass
- builtins.IsADirectoryError
- ''
- - builtins.OSError~Subclass
- builtins.IsADirectoryError
- ''
- - builtins.Exception~Subclass
- builtins.IsADirectoryError
- ''
- - builtins.BaseException~Subclass
- builtins.IsADirectoryError
- ''
- - builtins.TimeoutError~Subclass
- builtins.TimeoutError
- ''
- - builtins.OSError~Subclass
- builtins.TimeoutError
- ''
- - builtins.Exception~Subclass
- builtins.TimeoutError
- ''
- - builtins.BaseException~Subclass
- builtins.TimeoutError
- ''
- - builtins.NameError~Subclass
- builtins.NameError
- ''
- - builtins.Exception~Subclass
- builtins.NameError
- ''
- - builtins.BaseException~Subclass
- builtins.NameError
- ''
- - builtins.TabError~Subclass
- builtins.TabError
- ''
- - builtins.IndentationError~Subclass
- builtins.TabError
- ''
- - builtins.SyntaxError~Subclass
- builtins.TabError
- ''
- - builtins.Exception~Subclass
- builtins.TabError
- ''
- - builtins.BaseException~Subclass
- builtins.TabError
- ''
- - builtins.UnicodeError~Subclass
- builtins.UnicodeError
- ''
- - builtins.ValueError~Subclass
- builtins.UnicodeError
- ''
- - builtins.Exception~Subclass
- builtins.UnicodeError
- ''
- - builtins.BaseException~Subclass
- builtins.UnicodeError
- ''
- - builtins.ArithmeticError~Subclass
- builtins.ArithmeticError
- ''
- - builtins.Exception~Subclass
- builtins.ArithmeticError
- ''
- - builtins.BaseException~Subclass
- builtins.ArithmeticError
- ''
- - builtins.ReferenceError~Subclass
- builtins.ReferenceError
- ''
- - builtins.Exception~Subclass
- builtins.ReferenceError
- ''
- - builtins.BaseException~Subclass
- builtins.ReferenceError
- ''
- - builtins.DeprecationWarning~Subclass
- builtins.DeprecationWarning
- ''
- - builtins.Warning~Subclass
- builtins.DeprecationWarning
- ''
- - builtins.Exception~Subclass
- builtins.DeprecationWarning
- ''
- - builtins.BaseException~Subclass
- builtins.DeprecationWarning
- ''
- - builtins.ImportWarning~Subclass
- builtins.ImportWarning
- ''
- - builtins.Warning~Subclass
- builtins.ImportWarning
- ''
- - builtins.Exception~Subclass
- builtins.ImportWarning
- ''
- - builtins.BaseException~Subclass
- builtins.ImportWarning
- ''
- - builtins.TypeError~Subclass
- builtins.TypeError
- ''
- - builtins.Exception~Subclass
- builtins.TypeError
- ''
- - builtins.BaseException~Subclass
- builtins.TypeError
- ''
- - builtins.BaseExceptionGroup~Subclass
- builtins.BaseExceptionGroup
- ''
- - builtins.BaseException~Subclass
- builtins.BaseExceptionGroup
- ''
- - builtins.BlockingIOError~Subclass
- builtins.BlockingIOError
- ''
- - builtins.OSError~Subclass
- builtins.BlockingIOError
- ''
- - builtins.Exception~Subclass
- builtins.BlockingIOError
- ''
- - builtins.BaseException~Subclass
- builtins.BlockingIOError
- ''
- - builtins.ConnectionRefusedError~Subclass
- builtins.ConnectionRefusedError
- ''
- - builtins.ConnectionError~Subclass
- builtins.ConnectionRefusedError
- ''
- - builtins.OSError~Subclass
- builtins.ConnectionRefusedError
- ''
- - builtins.Exception~Subclass
- builtins.ConnectionRefusedError
- ''
- - builtins.BaseException~Subclass
- builtins.ConnectionRefusedError
- ''
- - builtins.NotADirectoryError~Subclass
- builtins.NotADirectoryError
- ''
- - builtins.OSError~Subclass
- builtins.NotADirectoryError
- ''
- - builtins.Exception~Subclass
- builtins.NotADirectoryError
- ''
- - builtins.BaseException~Subclass
- builtins.NotADirectoryError
- ''
- - builtins.EOFError~Subclass
- builtins.EOFError
- ''
- - builtins.Exception~Subclass
- builtins.EOFError
- ''
- - builtins.BaseException~Subclass
- builtins.EOFError
- ''
- - builtins.UnboundLocalError~Subclass
- builtins.UnboundLocalError
- ''
- - builtins.NameError~Subclass
- builtins.UnboundLocalError
- ''
- - builtins.Exception~Subclass
- builtins.UnboundLocalError
- ''
- - builtins.BaseException~Subclass
- builtins.UnboundLocalError
- ''
- - builtins.LookupError~Subclass
- builtins.LookupError
- ''
- - builtins.Exception~Subclass
- builtins.LookupError
- ''
- - builtins.BaseException~Subclass
- builtins.LookupError
- ''
- - builtins.UnicodeEncodeError~Subclass
- builtins.UnicodeEncodeError
- ''
- - builtins.UnicodeError~Subclass
- builtins.UnicodeEncodeError
- ''
- - builtins.ValueError~Subclass
- builtins.UnicodeEncodeError
- ''
- - builtins.Exception~Subclass
- builtins.UnicodeEncodeError
- ''
- - builtins.BaseException~Subclass
- builtins.UnicodeEncodeError
- ''
- - builtins.FloatingPointError~Subclass
- builtins.FloatingPointError
- ''
- - builtins.ArithmeticError~Subclass
- builtins.FloatingPointError
- ''
- - builtins.Exception~Subclass
- builtins.FloatingPointError
- ''
- - builtins.BaseException~Subclass
- builtins.FloatingPointError
- ''
- - builtins.MemoryError~Subclass
- builtins.MemoryError
- ''
- - builtins.Exception~Subclass
- builtins.MemoryError
- ''
- - builtins.BaseException~Subclass
- builtins.MemoryError
- ''

View File

@@ -25,11 +25,11 @@ is a super class of <code>Error</code>.
<p>Reorganize the <code>except</code> blocks so that the more specific <code>except</code> <p>Reorganize the <code>except</code> blocks so that the more specific <code>except</code>
is defined first. Alternatively, if the more specific <code>except</code> block is is defined first. Alternatively, if the more specific <code>except</code> block is
no longer required then it should be deleted.</p> no longer required, then it should be deleted.</p>
</recommendation> </recommendation>
<example> <example>
<p>In this example the <code>except Exception:</code> will handle <code>AttributeError</code> preventing the <p>In the following example, the <code>except Exception:</code> will handle <code>AttributeError</code> preventing the
subsequent handler from ever executing.</p> subsequent handler from ever executing.</p>
<sample src="IncorrectExceptOrder.py" /> <sample src="IncorrectExceptOrder.py" />
@@ -37,8 +37,8 @@ subsequent handler from ever executing.</p>
</example> </example>
<references> <references>
<li>Python Language Reference: <a href="http://docs.python.org/2.7/reference/compound_stmts.html#try">The try statement</a>, <li>Python Language Reference: <a href="http://docs.python.org/3/reference/compound_stmts.html#try">The try statement</a>,
<a href="http://docs.python.org/2.7/reference/executionmodel.html#exceptions">Exceptions</a>.</li> <a href="http://docs.python.org/3/reference/executionmodel.html#exceptions">Exceptions</a>.</li>
</references> </references>

View File

@@ -1,5 +1,5 @@
/** /**
* @name Unreachable 'except' block * @name Unreachable `except` block
* @description Handling general exceptions before specific exceptions means that the specific * @description Handling general exceptions before specific exceptions means that the specific
* handlers are never executed. * handlers are never executed.
* @kind problem * @kind problem
@@ -14,22 +14,95 @@
*/ */
import python import python
import semmle.python.dataflow.new.internal.DataFlowDispatch
import semmle.python.ApiGraphs
import semmle.python.frameworks.data.internal.ApiGraphModels
predicate incorrect_except_order(ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2) { predicate builtinException(string name) {
typeModel("builtins.BaseException~Subclass", "builtins." + name, "")
}
predicate builtinExceptionSubclass(string base, string sub) {
typeModel("builtins." + base + "~Subclass", "builtins." + sub, "")
}
newtype TExceptType =
TClass(Class c) or
TBuiltin(string name) { builtinException(name) }
class ExceptType extends TExceptType {
Class asClass() { this = TClass(result) }
string asBuiltinName() { this = TBuiltin(result) }
predicate isBuiltin() { this = TBuiltin(_) }
string getName() {
result = this.asClass().getName()
or
result = this.asBuiltinName()
}
string toString() { result = this.getName() }
DataFlow::Node getAUse() {
result = classTracker(this.asClass())
or
API::builtin(this.asBuiltinName()).asSource().flowsTo(result)
}
ExceptType getADirectSuperclass() {
result.asClass() = getADirectSuperclass(this.asClass())
or
result.isBuiltin() and
result.getAUse().asExpr() = this.asClass().getABase()
or
builtinExceptionSubclass(result.asBuiltinName(), this.asBuiltinName()) and
this != result
}
/**
* Holds if this element is at the specified location.
* The location spans column `startColumn` of line `startLine` to
* column `endColumn` of line `endLine` in file `filepath`.
* For more information, see
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filePath, int startLine, int startColumn, int endLine, int endColumn
) {
this.asClass()
.getLocation()
.hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn)
or
this.isBuiltin() and
filePath = "" and
startLine = 0 and
startColumn = 0 and
endLine = 0 and
endColumn = 0
}
}
predicate incorrectExceptOrder(ExceptStmt ex1, ExceptType cls1, ExceptStmt ex2, ExceptType cls2) {
exists(int i, int j, Try t | exists(int i, int j, Try t |
ex1 = t.getHandler(i) and ex1 = t.getHandler(i) and
ex2 = t.getHandler(j) and ex2 = t.getHandler(j) and
i < j and i < j and
cls1 = except_class(ex1) and cls1 = exceptClass(ex1) and
cls2 = except_class(ex2) and cls2 = exceptClass(ex2) and
cls1 = cls2.getASuperType() cls1 = cls2.getADirectSuperclass*()
) )
} }
ClassValue except_class(ExceptStmt ex) { ex.getType().pointsTo(result) } ExceptType exceptClass(ExceptStmt ex) { ex.getType() = result.getAUse().asExpr() }
from ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2 from ExceptStmt ex1, ExceptType cls1, ExceptStmt ex2, ExceptType cls2, string msg
where incorrect_except_order(ex1, cls1, ex2, cls2) where
select ex2, incorrectExceptOrder(ex1, cls1, ex2, cls2) and
"Except block for $@ is unreachable; the more general $@ for $@ will always be executed in preference.", if cls1 = cls2
cls2, cls2.getName(), ex1, "except block", cls1, cls1.getName() then msg = "This except block handling $@ is unreachable; as $@ also handles $@."
else
msg =
"This except block handling $@ is unreachable; as $@ for the more general $@ always subsumes it."
select ex2, msg, cls2, cls2.getName(), ex1, "this except block", cls1, cls1.getName()

View File

@@ -0,0 +1,31 @@
from shared_subclass_functions import wrap_in_template
import sys
import yaml
from pathlib import Path
py_version = sys.version.split()[0]
VERSION = f"process-builtin-exceptions 0.0.1; Python {py_version}"
builtins_model_path = Path(__file__).parent.parent.parent.parent / "lib/semmle/python/frameworks/builtins.model.yml"
def write_data(data, path: Path):
f = path.open("w+")
f.write(f"# {VERSION}\n")
yaml.dump(data, indent=2, stream=f, Dumper=yaml.CDumper)
builtin_names = dir(__builtins__)
builtin_dict = {x: getattr(__builtins__,x) for x in builtin_names}
builtin_exceptions = {v for v in builtin_dict.values() if type(v) is type and issubclass(v, BaseException)}
data = []
for sub in builtin_exceptions:
for base in sub.__mro__:
if issubclass(base, BaseException):
basename = base.__name__
subname = sub.__name__
row = [f"builtins.{basename}~Subclass", f"builtins.{subname}", ""]
data.append(row)
write_data(wrap_in_template(data), builtins_model_path)

View File

@@ -1,2 +1,2 @@
| exceptions_test.py:7:5:7:11 | ExceptStmt | Except block directly handles BaseException. | | exceptions_test.py:7:5:7:11 | ExceptStmt | Except block directly handles BaseException. |
| exceptions_test.py:71:5:71:25 | ExceptStmt | Except block directly handles BaseException. | | exceptions_test.py:97:5:97:25 | ExceptStmt | Except block directly handles BaseException. |

View File

@@ -1,2 +1,5 @@
| exceptions_test.py:7:5:7:11 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. | | exceptions_test.py:7:5:7:11 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. |
| exceptions_test.py:13:5:13:21 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. | | exceptions_test.py:13:5:13:21 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. |
| exceptions_test.py:72:1:72:18 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. |
| exceptions_test.py:85:1:85:17 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. |
| exceptions_test.py:89:1:89:17 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. |

View File

@@ -1,4 +1,4 @@
| exceptions_test.py:51:5:51:25 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:33:1:33:28 | ControlFlowNode for ClassExpr | class 'NotException1' | | exceptions_test.py:51:5:51:25 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:33:1:33:28 | ControlFlowNode for ClassExpr | class 'NotException1' |
| exceptions_test.py:54:5:54:25 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:36:1:36:28 | ControlFlowNode for ClassExpr | class 'NotException2' | | exceptions_test.py:54:5:54:25 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:36:1:36:28 | ControlFlowNode for ClassExpr | class 'NotException2' |
| exceptions_test.py:112:5:112:22 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:107:12:107:14 | ControlFlowNode for FloatLiteral | instance of 'float' | | exceptions_test.py:138:5:138:22 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:133:12:133:14 | ControlFlowNode for FloatLiteral | instance of 'float' |
| pypy_test.py:14:5:14:14 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | pypy_test.py:14:12:14:13 | ControlFlowNode for IntegerLiteral | instance of 'int' | | pypy_test.py:14:5:14:14 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | pypy_test.py:14:12:14:13 | ControlFlowNode for IntegerLiteral | instance of 'int' |

View File

@@ -1 +1 @@
| exceptions_test.py:64:1:64:22 | ExceptStmt | Except block for $@ is unreachable; the more general $@ for $@ will always be executed in preference. | file://:0:0:0:0 | builtin-class AttributeError | AttributeError | exceptions_test.py:62:1:62:17 | ExceptStmt | except block | file://:0:0:0:0 | builtin-class Exception | Exception | | exceptions_test.py:64:1:64:22 | ExceptStmt | This except block handling $@ is unreachable; as $@ for the more general $@ always subsumes it. | file://:0:0:0:0 | AttributeError | AttributeError | exceptions_test.py:62:1:62:17 | ExceptStmt | this except block | file://:0:0:0:0 | Exception | Exception |

View File

@@ -1 +1,2 @@
Exceptions/IncorrectExceptOrder.ql query: Exceptions/IncorrectExceptOrder.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,2 +1,2 @@
| exceptions_test.py:170:11:170:24 | NotImplemented | NotImplemented is not an Exception. Did you mean NotImplementedError? | | exceptions_test.py:196:11:196:24 | NotImplemented | NotImplemented is not an Exception. Did you mean NotImplementedError? |
| exceptions_test.py:173:11:173:26 | NotImplemented() | NotImplemented is not an Exception. Did you mean NotImplementedError? | | exceptions_test.py:199:11:199:26 | NotImplemented() | NotImplemented is not an Exception. Did you mean NotImplementedError? |

View File

@@ -61,8 +61,34 @@ try:
val.attr val.attr
except Exception: except Exception:
print (2) print (2)
except AttributeError: except AttributeError: # $Alert[py/unreachable-except]
print (3) print (3)
class MyExc(ValueError):
pass
try:
pass
except ValueError:
pass
except MyExc: # $MISSING:Alert[py/unreachable-except] # Missing due to dataflow limitiation preventing MyExc from being tracked here.
pass
class MyBaseExc(Exception):
pass
class MySubExc(MyBaseExc):
pass
try:
pass
except MyBaseExc:
pass
except MySubExc: # $MISSING:Alert[py/unreachable-except] # Missing due to dataflow limitation preventing MyExc from being tracked here.
pass
except Exception:
pass
#Catch BaseException #Catch BaseException
def catch_base_exception(): def catch_base_exception():