Skip to content

Commit 8a44f51

Browse files
committed
Bring headings more into line with content models
1 parent 8ab4ceb commit 8a44f51

6 files changed

Lines changed: 66 additions & 71 deletions

File tree

docs/language/learn-ql/python/control-flow.rst

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ An annotated flow graph:
3131

3232
The simplest use of the ``ControlFlowNode`` and ``AstNode`` classes is to find unreachable code. There is one ``ControlFlowNode`` per path through any ``AstNode`` and any ``AstNode`` that is unreachable has no paths flowing through it. Therefore, any ``AstNode`` without a corresponding ``ControlFlowNode`` is unreachable.
3333

34-
**Unreachable AST nodes**
34+
Example finding unreachable AST nodes
35+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3536

3637
.. code-block:: ql
3738
@@ -43,7 +44,8 @@ The simplest use of the ``ControlFlowNode`` and ``AstNode`` classes is to find u
4344
4445
➤ `See this in the query console <https://lgtm.com/query/669220024/>`__. The demo projects on LGTM.com all have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements:
4546

46-
**Unreachable statements**
47+
Example finding unreachable statements
48+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4749

4850
.. code-block:: ql
4951
@@ -60,8 +62,8 @@ The ``BasicBlock`` class
6062

6163
The ``BasicBlock`` class represents a `basic block <http://en.wikipedia.org/wiki/Basic_block>`__ of control flow nodes. The ``BasicBlock`` class is not that useful for writing queries directly, but is very useful for building complex analyses, such as data flow. The reason it is useful is that it shares many of the interesting properties of control flow nodes, such as what can reach what and what `dominates <http://en.wikipedia.org/wiki/Dominator_%28graph_theory%29>`__ what, but there are fewer basic blocks than control flow nodes - resulting in queries that are faster and use less memory.
6264

63-
Example: Finding mutually exclusive basic blocks
64-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65+
Example finding mutually exclusive basic blocks
66+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6567

6668
Suppose we have the following Python code:
6769

@@ -92,7 +94,8 @@ However, by that definition, two basic blocks are mutually exclusive if they are
9294
9395
Combining these conditions we get:
9496

95-
**Mutually exclusive blocks within the same function**
97+
Example finding mutually exclusive blocks within the same function
98+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9699

97100
.. code-block:: ql
98101

docs/language/learn-ql/python/functions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Functions in Python
33

44
Functions are key building blocks of Python code bases. You can find functions and identify calls to them using syntactic classes from the standard CodeQL library.
55

6-
This example uses the standard CodeQL class ``Function`` (see :doc:`Introducing the Python libraries <introduce-libraries-python>`).
6+
These examples use the standard CodeQL class `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__. For more information, see :doc:`Introducing the Python libraries <introduce-libraries-python>`.
77

88
Finding all functions called "get..."
99
-------------------------------------

docs/language/learn-ql/python/introduce-libraries-python.rst

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ CodeQL library for Python
33

44
Overview of the extensive library you use to analyze databases generated from Python code bases. This library uses classes with abstractions and predicates to present the data in an object-oriented form. This abstraction makes it easier for you to write queries.
55

6-
.. code-block:: ql
6+
About the CodeQL library for Python
7+
-----------------------------------
78

8-
import python
9+
The CodeQL library for each programming language is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``python.qll`` imports all the core Python library modules, so you can include the complete library by beginning your query with:
910

10-
The rest of this tutorial summarizes the contents of the standard libraries for Python. We recommend that you read this and then work through the practical examples in the tutorials shown at the end of the page.
11+
.. code-block:: ql
1112
12-
Overview of the library
13-
-----------------------
13+
import python
1414
1515
The CodeQL library for Python incorporates a large number of classes. Each class corresponds either to one kind of entity in Python source code or to an entity that can be derived from the source code using static analysis. These classes can be divided into four categories:
1616

@@ -20,16 +20,16 @@ The CodeQL library for Python incorporates a large number of classes. Each class
2020
- **Taint tracking** - classes that represent the source, sinks and kinds of taint used to implement taint-tracking queries.
2121

2222
Syntactic classes
23-
~~~~~~~~~~~~~~~~~
23+
-----------------
2424

25-
This part of the library represents the Python source code. The ``Module``, ``Class``, and ``Function`` classes correspond to Python modules, classes, and functions respectively, collectively these are known as ``Scope`` classes. Each ``Scope`` contains a list of statements each of which is represented by a subclass of the class ``Stmt``. Statements themselves can contain other statements or expressions which are represented by subclasses of ``Expr``. Finally, there are a few additional classes for the parts of more complex expressions such as list comprehensions. Collectively these classes are subclasses of ``AstNode`` and form an `Abstract syntax tree <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ (AST). The root of each AST is a ``Module``.
25+
This part of the library represents the Python source code. The ``Module``, ``Class``, and ``Function`` classes correspond to Python modules, classes, and functions respectively, collectively these are known as ``Scope`` classes. Each ``Scope`` contains a list of statements each of which is represented by a subclass of the class ``Stmt``. Statements themselves can contain other statements or expressions which are represented by subclasses of ``Expr``. Finally, there are a few additional classes for the parts of more complex expressions such as list comprehensions. Collectively these classes are subclasses of ``AstNode`` and form an Abstract syntax tree (AST). The root of each AST is a ``Module``. For more information, see `Abstract syntax tree <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__.
2626

27-
`Symbolic information <http://en.wikipedia.org/wiki/Symbol_table>`__ is attached to the AST in the form of variables (represented by the class ``Variable``).
27+
Symbolic information is attached to the AST in the form of variables (represented by the class ``Variable``). For more information, see `Symbolic information <http://en.wikipedia.org/wiki/Symbol_table>`__.
2828

2929
Scope
3030
^^^^^
3131

32-
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class, and function are represented by the three CodeQL classes (`Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``.
32+
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class, and function are represented by the three CodeQL classes (`Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``).
3333

3434
- ``Scope``
3535

@@ -153,8 +153,8 @@ Both forms are equivalent. Using the positive expression, the whole query looks
153153
154154
➤ `See this in the query console <https://lgtm.com/query/690010036/>`__. Many projects include pass-only ``except`` blocks.
155155

156-
Summary
157-
^^^^^^^
156+
Summary of syntactic classes
157+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
158158

159159
The most commonly used standard classes in the syntactic part of the library are organized as follows:
160160

@@ -237,11 +237,14 @@ Other
237237
- ``Comment`` – A comment
238238

239239
Control flow classes
240-
~~~~~~~~~~~~~~~~~~~~
240+
--------------------
241241

242242
This part of the library represents the control flow graph of each ``Scope`` (classes, functions, and modules). Each ``Scope`` contains a graph of ``ControlFlowNode`` elements. Each scope has a single entry point and at least one (potentially many) exit points. To speed up control and data flow analysis, control flow nodes are grouped into `basic blocks <http://en.wikipedia.org/wiki/Basic_block>`__.
243243

244-
As an example, we might want to find the longest sequence of code without any branches. A ``BasicBlock`` is, by definition, a sequence of code without any branches, so we just need to find the longest ``BasicBlock``.
244+
Example
245+
^^^^^^^
246+
247+
If we want to find the longest sequence of code without any branches, we need to consider control flow. A ``BasicBlock`` is, by definition, a sequence of code without any branches, so we just need to find the longest ``BasicBlock``.
245248

246249
First of all we introduce a simple predicate ``bb_length()`` which relates ``BasicBlock``\ s to their length.
247250

@@ -289,7 +292,12 @@ The classes in the control-flow part of the library are:
289292
Type-inference classes
290293
----------------------
291294

292-
The CodeQL library for Python also supplies some classes for accessing the inferred types of values. The classes ``Value`` and ``ClassValue`` allow you to query the possible classes that an expression may have at runtime. For example, which ``ClassValue``\ s are iterable can be determined using the query:
295+
The CodeQL library for Python also supplies some classes for accessing the inferred types of values. The classes ``Value`` and ``ClassValue`` allow you to query the possible classes that an expression may have at runtime.
296+
297+
Example
298+
^^^^^^^
299+
300+
For example, which ``ClassValue``\ s are iterable can be determined using the query:
293301

294302
**Find iterable "ClassValue"s**
295303

@@ -304,15 +312,15 @@ The CodeQL library for Python also supplies some classes for accessing the infer
304312
➤ `See this in the query console <https://lgtm.com/query/5151030165280978402/>`__ This query returns a list of classes for the projects analyzed. If you want to include the results for `builtin classes <http://docs.python.org/library/stdtypes.html>`__, which do not have any Python source code, show the non-source results.
305313

306314
Summary
307-
~~~~~~~
315+
^^^^^^^
308316

309317
- `Value <https://help.semmle.com/qldoc/python/semmle/python/objects/ObjectAPI.qll/type.ObjectAPI$Value.html>`__
310318

311319
- ``ClassValue``
312320
- ``CallableValue``
313321
- ``ModuleValue``
314322

315-
These classes are explained in more detail in :doc:`Tutorial: Points-to analysis and type inference <pointsto-type-infer>`.
323+
For more information about these classes, see :doc:`Pointer analysis and type inference in Python <pointsto-type-infer>`.
316324

317325
Taint-tracking classes
318326
----------------------
@@ -321,12 +329,12 @@ The CodeQL library for Python also supplies classes to specify taint-tracking an
321329

322330

323331
Summary
324-
~~~~~~~
332+
^^^^^^^
325333

326334
- `TaintKind <https://help.semmle.com/qldoc/python/semmle/python/dataflow/TaintTracking.qll/type.TaintTracking$TaintKind.html>`__
327335
- `Configuration <https://help.semmle.com/qldoc/python/semmle/python/dataflow/Configuration.qll/type.Configuration$TaintTracking$Configuration.html>`__
328336

329-
These classes are explained in more detail in :doc:`Tutorial: Taint tracking and data flow analysis in Python <taint-tracking>`.
337+
For more information about these classes, see :doc:`Analyzing data flow and tracking tainted data in Python <taint-tracking>`.
330338

331339

332340
Further reading

docs/language/learn-ql/python/pointsto-type-infer.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Pointer analysis and type inference in Python
33

44
At run time, each Python expression has a value with an associated type. You can learn how an expression behaves at run time using type-inference classes from the standard CodeQL library.
55

6+
67
This topic contains worked examples of how to write queries using the standard CodeQL library classes for Python type inference.
78

89
The ``Value`` class
@@ -11,7 +12,7 @@ The ``Value`` class
1112
The ``Value`` class and its subclasses ``FunctionValue``, ``ClassValue``, and ``ModuleValue`` represent the values an expression may hold at runtime.
1213

1314
Summary
14-
~~~~~~~
15+
^^^^^^^
1516

1617
Class hierarchy for ``Value``:
1718

docs/language/learn-ql/python/statements-expressions.rst

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,11 @@ Here is the full class hierarchy:
3939
- ``While`` – A ``while`` statement
4040
- ``With`` – A ``with`` statement
4141

42-
Example: Finding redundant 'global' statements
43-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42+
Example finding redundant 'global' statements
43+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4444

4545
The ``global`` statement in Python declares a variable with a global (module-level) scope, when it would otherwise be local. Using the ``global`` statement outside a class or function is redundant as the variable is already global.
4646

47-
**Finding redundant global statements**
48-
4947
.. code-block:: ql
5048
5149
import python
@@ -58,23 +56,19 @@ The ``global`` statement in Python declares a variable with a global (module-lev
5856

5957
The line: ``g.getScope() instanceof Module`` ensures that the ``Scope`` of ``Global g`` is a ``Module``, rather than a class or function.
6058

61-
Example: Finding 'if' statements with redundant branches
62-
--------------------------------------------------------
59+
Example finding 'if' statements with redundant branches
60+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6361

6462
An ``if`` statement where one branch is composed of just ``pass`` statements could be simplified by negating the condition and dropping the ``else`` clause.
6563

66-
**An 'if' statement that could be simplified**
67-
6864
.. code-block:: python
6965
7066
if cond():
7167
pass
7268
else:
7369
do_something
7470
75-
To find statements like this we can run the following query:
76-
77-
**Find 'if' statements with empty branches**
71+
To find statements like this that could be simplified we can write a query.
7872

7973
.. code-block:: ql
8074
@@ -133,8 +127,8 @@ Each kind of Python expression has its own class. Here is the full class hierarc
133127
- ``Yield`` – A ``yield`` expression
134128
- ``YieldFrom`` – A ``yield from`` expression (Python 3.3+)
135129

136-
Example: Finding comparisons to integer or string literals using 'is'
137-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130+
Example finding comparisons to integer or string literals using 'is'
131+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
138132

139133
Python implementations commonly cache small integers and single character strings, which means that comparisons such as the following often work correctly, but this is not guaranteed and we might want to check for them.
140134

@@ -143,9 +137,7 @@ Python implementations commonly cache small integers and single character string
143137
x is 10
144138
x is "A"
145139
146-
We can check for these as follows:
147-
148-
**Find comparisons to integer or string literals using** ``is``
140+
We can check for these using a query.
149141

150142
.. code-block:: ql
151143
@@ -166,15 +158,11 @@ The clause ``cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal`` che
166158

167159
We have to use ``cmp.getOp(0)`` and ``cmp.getComparator(0)``\ as there is no ``cmp.getOp()`` or ``cmp.getComparator()``. The reason for this is that a ``Compare`` expression can have multiple operators. For example, the expression ``3 < x < 7`` has two operators and two comparators. You use ``cmp.getComparator(0)`` to get the first comparator (in this example the ``3``) and ``cmp.getComparator(1)`` to get the second comparator (in this example the ``7``).
168160

169-
Example: Duplicates in dictionary literals
170-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
161+
Example finding duplicates in dictionary literals
162+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171163

172164
If there are duplicate keys in a Python dictionary, then the second key will overwrite the first, which is almost certainly a mistake. We can find these duplicates with CodeQL, but the query is more complex than previous examples and will require us to write a ``predicate`` as a helper.
173165

174-
Here is the query:
175-
176-
**Find duplicate dictionary keys**
177-
178166
.. code-block:: ql
179167
180168
import python
@@ -206,12 +194,10 @@ is equivalent to
206194
207195
The short version is usually used as this is easier to read.
208196

209-
Example: Finding Java-style getters
210-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
211-
212-
Returning to the example from :doc:`Tutorial: Functions <functions>`, the query identified all methods with a single line of code and a name starting with ``get``:
197+
Example finding Java-style getters
198+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
213199

214-
**Basic: Find Java-style getters**
200+
Returning to the example from :doc:`Tutorial: Functions <functions>`, the query identified all methods with a single line of code and a name starting with ``get``.
215201

216202
.. code-block:: ql
217203
@@ -222,9 +208,7 @@ Returning to the example from :doc:`Tutorial: Functions <functions>`, the query
222208
and count(f.getAStmt()) = 1
223209
select f, "This function is (probably) a getter."
224210
225-
This basic query can be improved by checking that the one line of code is of the form ``return self.attr``
226-
227-
**Improved: Find Java-style getters**
211+
This basic query can be improved by checking that the one line of code is a Java-style getter of the form ``return self.attr``.
228212

229213
.. code-block:: ql
230214
@@ -238,21 +222,17 @@ This basic query can be improved by checking that the one line of code is of the
238222
239223
➤ `See this in the query console <https://lgtm.com/query/669220054/>`__. Of the demo projects on LGTM.com, only the *openstack/nova* project has examples of functions that appear to be Java-style getters.
240224

241-
In this query, the condition:
242-
243225
.. code-block:: ql
244226
245227
ret = f.getStmt(0) and ret.getValue() = attr
246228
247-
checks that the first line in the method is a return statement and that the expression returned (``ret.getValue()``) is an ``Attribute`` expression. Note that the equality ``ret.getValue() = attr`` means that ``ret.getValue()`` is restricted to ``Attribute``\ s, since ``attr`` is an ``Attribute``.
248-
249-
The condition:
229+
This condition checks that the first line in the method is a return statement and that the expression returned (``ret.getValue()``) is an ``Attribute`` expression. Note that the equality ``ret.getValue() = attr`` means that ``ret.getValue()`` is restricted to ``Attribute``\ s, since ``attr`` is an ``Attribute``.
250230

251231
.. code-block:: ql
252232
253233
attr.getObject() = self and self.getId() = "self"
254234
255-
checks that the value of the attribute (the expression to the left of the dot in ``value.attr``) is an access to a variable called ``"self"``.
235+
This condition checks that the value of the attribute (the expression to the left of the dot in ``value.attr``) is an access to a variable called ``"self"``.
256236

257237
Class and function definitions
258238
------------------------------

0 commit comments

Comments
 (0)