Skip to content

Commit 95153c1

Browse files
Add some more details to the documentation
1 parent 90bf45a commit 95153c1

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

python/ql/src/Classes/InitCallsSubclass/InitCallsSubclassMethod.qhelp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
<p>
77
When initializing an instance of the class in the class' <code>__init__</code> method, calls tha are made using the instance may receive an instance of the class that is not
88
yet fully initialized. When a method called in an initializer is overridden in a subclass, the subclass method receives the instance
9-
in a potentially unexpected state, which may lead to runtime errors from accessing uninitialized fields, and generally makes the code
10-
more difficult to maintain.
9+
in a potentially unexpected state. Fields that would be initialized after the call, including potentially in the subclass' <code>__init__</code> method,
10+
will not be initialized. This may lead to runtime errors, as well as make the code more difficult to maintain, as future changes may not
11+
be aware of which fields would not be initialized.
1112
</p>
1213

1314
</overview>
@@ -16,14 +17,19 @@ more difficult to maintain.
1617
<p>If possible, refactor the initializer method such that initialization is complete before calling any overridden methods.
1718
For helper methods used as part of initialization, avoid overriding them, and instead call any additional logic required
1819
in the subclass' <code>__init__</code> method.
19-
</p><p>
20-
If calling an overridden method is required, consider marking it as an internal method (by using an <code>_</code> prefix) to
21-
discourage external users of the library from overriding it and observing partially initialized state.
20+
</p>
21+
<p>
22+
If the overridden method does not depend on the instance <code>self</code>, and only on its class, consider making it a <code>@classmethod</code> or <code>@staticmethod</code> instead.
23+
</p>
24+
<p>
25+
If calling an overridden method is absolutely required, consider marking it as an internal method (by using an <code>_</code> prefix) to
26+
discourage external users of the library from overriding it and observing partially initialized state, and ensure that the fact it is called during initialization
27+
is mentioned in the documentation.
2228
</p>
2329

2430
</recommendation>
2531
<example>
26-
<p>In the following case, the `__init__` method of `Super` calls the `set_up` method that is overriden by `Sub`.
32+
<p>In the following case, the <code>__init__</code> method of <code>Super</code> calls the <code>set_up</code> method that is overridden by <code>Sub</code>.
2733
This results in `Sun.set_up` being called with a partially initialized instance of `Super` which may be unexpected. </p>
2834
<sample src="examples/InitCallsSubclassMethodBad.py" />
2935
<p>In the following case, the initialization methods are separate between the superclass and the subclass.</p>
@@ -35,7 +41,7 @@ This results in `Sun.set_up` being called with a partially initialized instance
3541
<li>CERT Secure Coding: <a href="https://www.securecoding.cert.org/confluence/display/java/MET05-J.+Ensure+that+constructors+do+not+call+overridable+methods">
3642
Rule MET05-J</a>. Reference discusses Java but is applicable to object oriented programming in many languages.</li>
3743
<li>StackOverflow: <a href="https://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors">Overridable method calls in constructors</a>.</li>
38-
44+
<li>Python documentation: <a href="https://docs.python.org/3/library/functions.html#classmethod">@classmethod</a>.</li>
3945

4046

4147
</references>

0 commit comments

Comments
 (0)