You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: python/ql/src/Functions/IncorrectRaiseInSpecialMethod.qhelp
+19-21Lines changed: 19 additions & 21 deletions
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ When the expression <code>a + b</code> is evaluated the Python virtual machine w
9
9
is not implemented it will call <code>type(b).__radd__(b, a)</code>.</p>
10
10
<p>
11
11
Since the virtual machine calls these special methods for common expressions, users of the class will expect these operations to raise standard exceptions.
12
-
For example, users would expect that the expression <code>a.b</code> might raise an <code>AttributeError</code>
12
+
For example, users would expect that the expression <code>a.b</code> may raise an <code>AttributeError</code>
13
13
if the object <code>a</code> does not have an attribute <code>b</code>.
14
14
If a <code>KeyError</code> were raised instead,
15
15
then this would be unexpected and may break code that expected an <code>AttributeError</code>, but not a <code>KeyError</code>.
@@ -20,50 +20,48 @@ Therefore, if a method is unable to perform the expected operation then its resp
<li>Arithmetic operations, <code>a + b</code> (<code>__add__</code>): Do not raise an exception, return <code>NotImplemented</code> instead.</li>
25
+
<li>Indexing, <code>a[b]</code> (<code>__getitem__</code>): Raise <code>KeyError</code> or <code>IndexError</code>.</li>
26
+
<li>Hashing, <code>hash(a)</code> (<code>__hash__</code>): Should not raise an exception. Use <code>__hash__ = None</code> to indicate that an object is unhashable rather than raising an exception.</li>
27
+
<li>Equality methods, <code>a == b</code> (<code>__eq__</code>): Never raise an exception, always return <code>True</code> or <code>False</code>.</li>
28
+
<li>Ordering comparison methods, <code>a < b</code> (<code>__lt__</code>): Raise a <code>TypeError</code> if the objects cannot be ordered.</li>
29
29
<li>Most others: Ideally, do not implement the method at all, otherwise raise <code>TypeError</code> to indicate that the operation is unsupported.</li>
30
30
</ul>
31
31
32
32
</overview>
33
33
<recommendation>
34
-
<p>If the method is meant to be abstract, then declare it so using the <code>@abstractmethod</code> decorator.
34
+
<p>If the method is intended to be abstract, then declare it so using the <code>@abstractmethod</code> decorator.
35
35
Otherwise, either remove the method or ensure that the method raises an exception of the correct type.
36
36
</p>
37
37
38
38
</recommendation>
39
39
<example>
40
40
41
41
<p>
42
-
This example shows two unhashable classes. The first class is unhashable in a non-standard way which may cause maintenance problems.
43
-
The second, corrected, class uses the standard idiom for unhashable classes.
42
+
In the following example, the <code>__add__</code> method of <code>A</code> raises a <code>TypeError</code> if <code>other</code> is of the wrong type.
43
+
However, it should return <code>NotImplemented</code> instead of rising an exception, to allow other classes to support adding to <code>A</code>.
In this example, the first class is implicitly abstract; the <code>__add__</code> method is unimplemented,
48
-
presumably with the expectation that it will be implemented by sub-classes.
49
-
The second class makes this explicit with an <code>@abstractmethod</code> decoration on the unimplemented <code>__add__</code> method.
48
+
In the following example, the <code>__getitem__</code> method of <code>C</code> raises a <code>ValueError</code>, rather than a <code>KeyError</code> or <code>IndexError</code> as expected.
0 commit comments