mirror of
https://github.com/hohn/codeql-info.git
synced 2025-12-16 20:53:04 +01:00
493 lines
47 KiB
HTML
493 lines
47 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html lang="en" data-content_root="../">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
||
<title>CodeQL library for Python — CodeQL</title>
|
||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css?v=93459777" />
|
||
<script src="../_static/documentation_options.js?v=5929fcd5"></script>
|
||
<script src="../_static/doctools.js?v=888ff710"></script>
|
||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||
<link rel="icon" href="../_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="next" title="Analyzing data flow in Python" href="analyzing-data-flow-in-python.html" />
|
||
<link rel="prev" title="Basic query for Python code" href="basic-query-for-python-code.html" />
|
||
|
||
<title>CodeQL docs</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/primer.css" type="text/css" />
|
||
|
||
|
||
</head><body>
|
||
<header class="Header">
|
||
<div class="Header-item--full">
|
||
<a href="https://codeql.github.com/docs" class="Header-link f2 d-flex flex-items-center">
|
||
<!-- <%= octicon "mark-github", class: "mr-2", height: 32 %> -->
|
||
<svg height="32" class="octicon octicon-mark-github mr-2" viewBox="0 0 16 16" version="1.1" width="32"
|
||
aria-hidden="true">
|
||
<path fill-rule="evenodd"
|
||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z">
|
||
</path>
|
||
</svg>
|
||
<span class="hide-sm">CodeQL documentation</span>
|
||
</a>
|
||
</div>
|
||
<div class="Header-item hide-sm hide-md">
|
||
<script src="https://addsearch.com/js/?key=93b4d287e2fc079a4089412b669785d5&categories=!0xhelp.semmle.com,0xcodeql.github.com,1xdocs,1xcodeql-standard-libraries,1xcodeql-query-help"></script>
|
||
</div>
|
||
<div class="Header-item">
|
||
|
||
<details class="dropdown details-reset details-overlay d-inline-block">
|
||
<summary class="btn bg-gray-dark text-white border" aria-haspopup="true">
|
||
CodeQL resources
|
||
<div class="dropdown-caret"></div>
|
||
</summary>
|
||
|
||
<ul class="dropdown-menu dropdown-menu-se dropdown-menu-dark">
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-overview">CodeQL overview</a></li>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
CodeQL tools
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-for-visual-studio-code">CodeQL for VS Code</a>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-cli">CodeQL CLI</a>
|
||
</li>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
CodeQL guides
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/writing-codeql-queries">Writing CodeQL queries</a></li>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-language-guides">CodeQL language guides</a>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
Reference docs
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/docs/ql-language-reference/">QL language
|
||
reference</a>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-standard-libraries">CodeQL
|
||
standard-libraries</a>
|
||
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-query-help">CodeQL
|
||
query help</a>
|
||
<li class="dropdown-divider" role="separator"></li>
|
||
<div class="dropdown-header">
|
||
Source files
|
||
</div>
|
||
<li><a class="dropdown-item" href="https://github.com/github/codeql">CodeQL repository</a>
|
||
</ul>
|
||
</details>
|
||
|
||
</div>
|
||
|
||
</header>
|
||
<main class="bg-gray-light clearfix">
|
||
<nav class="SideNav position-sticky top-0 col-lg-3 col-md-3 float-left p-4 hide-sm hide-md overflow-y-auto">
|
||
|
||
<ul class="current">
|
||
<li class="toctree-l1"><a class="reference internal" href="../codeql-overview/index.html">CodeQL overview</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../codeql-for-visual-studio-code/index.html">CodeQL for Visual Studio Code</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../codeql-cli/index.html">CodeQL CLI</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../writing-codeql-queries/index.html">Writing CodeQL queries</a></li>
|
||
<li class="toctree-l1 current"><a class="reference internal" href="index.html">CodeQL language guides</a><ul class="current">
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-cpp.html">CodeQL for C and C++</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-csharp.html">CodeQL for C#</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-go.html">CodeQL for Go</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-java.html">CodeQL for Java</a></li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-javascript.html">CodeQL for JavaScript</a></li>
|
||
<li class="toctree-l2 current"><a class="reference internal" href="codeql-for-python.html">CodeQL for Python</a><ul class="current">
|
||
<li class="toctree-l3"><a class="reference internal" href="basic-query-for-python-code.html">Basic query for Python code</a></li>
|
||
<li class="toctree-l3 current"><a class="current reference internal" href="#">CodeQL library for Python</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="analyzing-data-flow-in-python.html">Analyzing data flow in Python</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="using-api-graphs-in-python.html">Using API graphs in Python</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="functions-in-python.html">Functions in Python</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="expressions-and-statements-in-python.html">Expressions and statements in Python</a></li>
|
||
<li class="toctree-l3"><a class="reference internal" href="analyzing-control-flow-in-python.html">Analyzing control flow in Python</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toctree-l2"><a class="reference internal" href="codeql-for-ruby.html">CodeQL for Ruby</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toctree-l1"><a class="reference internal" href="../ql-language-reference/index.html">QL language reference</a></li>
|
||
</ul>
|
||
|
||
|
||
</nav>
|
||
|
||
|
||
<div class="body col-sm-12 col-md-9 col-lg-9 float-left border-left">
|
||
|
||
<div class="hide-lg hide-xl px-4 pt-4">
|
||
|
||
<div class="related" role="navigation" aria-label="related navigation">
|
||
<ul>
|
||
<li class="nav-item nav-item-0"><a href="../contents.html">CodeQL</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="index.html"
|
||
>CodeQL language guides</a> »</li>
|
||
<li class="nav-item nav-item-2"><a href="codeql-for-python.html"
|
||
accesskey="U">CodeQL for Python</a> »</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<article class="p-4 col-lg-10 col-md-10 col-sm-12">
|
||
|
||
<section id="codeql-library-for-python">
|
||
<span id="id1"></span><h1>CodeQL library for Python<a class="headerlink" href="#codeql-library-for-python" title="Link to this heading">¶</a></h1>
|
||
<p>When you need to analyze a Python program, you can make use of the large collection of classes in the CodeQL library for Python.</p>
|
||
<section id="about-the-codeql-library-for-python">
|
||
<h2>About the CodeQL library for Python<a class="headerlink" href="#about-the-codeql-library-for-python" title="Link to this heading">¶</a></h2>
|
||
<p>The CodeQL library for each programming language uses classes with abstractions and predicates to present data in an object-oriented form.</p>
|
||
<p>Each CodeQL library is implemented as a set of QL modules, that is, files with the extension <code class="docutils literal notranslate"><span class="pre">.qll</span></code>. The module <code class="docutils literal notranslate"><span class="pre">python.qll</span></code> imports all the core Python library modules, so you can include the complete library by beginning your query with:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
|
||
</pre></div>
|
||
</div>
|
||
<p>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:</p>
|
||
<ul class="simple">
|
||
<li><p><strong>Syntactic</strong> - classes that represent entities in the Python source code.</p></li>
|
||
<li><p><strong>Control flow</strong> - classes that represent entities from the control flow graphs.</p></li>
|
||
<li><p><strong>Data flow</strong> - classes that represent entities from the data flow graphs.</p></li>
|
||
<li><p><strong>API graphs</strong> - classes that represent entities from the API graphs.</p></li>
|
||
</ul>
|
||
<p>The first two categories are described below.
|
||
For a description of data flow and associated classes, see “<a class="reference internal" href="analyzing-data-flow-in-python.html"><span class="doc">Analyzing data flow in Python</span></a>”.
|
||
For a description of API graphs and their use, see “<a class="reference internal" href="using-api-graphs-in-python.html"><span class="doc">Using API graphs in Python</span></a>.”</p>
|
||
</section>
|
||
<section id="syntactic-classes">
|
||
<h2>Syntactic classes<a class="headerlink" href="#syntactic-classes" title="Link to this heading">¶</a></h2>
|
||
<p>This part of the library represents the Python source code. The <code class="docutils literal notranslate"><span class="pre">Module</span></code>, <code class="docutils literal notranslate"><span class="pre">Class</span></code>, and <code class="docutils literal notranslate"><span class="pre">Function</span></code> classes correspond to Python modules, classes, and functions respectively, collectively these are known as <code class="docutils literal notranslate"><span class="pre">Scope</span></code> classes. Each <code class="docutils literal notranslate"><span class="pre">Scope</span></code> contains a list of statements each of which is represented by a subclass of the class <code class="docutils literal notranslate"><span class="pre">Stmt</span></code>. Statements themselves can contain other statements or expressions which are represented by subclasses of <code class="docutils literal notranslate"><span class="pre">Expr</span></code>. Finally, there are a few additional classes for the parts of more complex expressions such as list comprehensions. Collectively these classes are subclasses of <code class="docutils literal notranslate"><span class="pre">AstNode</span></code> and form an Abstract syntax tree (AST). The root of each AST is a <code class="docutils literal notranslate"><span class="pre">Module</span></code>. Symbolic information is attached to the AST in the form of variables (represented by the class <code class="docutils literal notranslate"><span class="pre">Variable</span></code>). For more information, see <a class="reference external" href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">Abstract syntax tree</a> and <a class="reference external" href="https://en.wikipedia.org/wiki/Symbol_table">Symbolic information</a> on Wikipedia.</p>
|
||
<section id="scope">
|
||
<h3>Scope<a class="headerlink" href="#scope" title="Link to this heading">¶</a></h3>
|
||
<p>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 <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Module.qll/type.Module$Module.html">Module</a>, <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Class.qll/type.Class$Class.html">Class</a> and <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Function.qll/type.Function$Function.html">Function</a> which are all subclasses of <code class="docutils literal notranslate"><span class="pre">Scope</span></code>.</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Scope</span></code></p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Module</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Class</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Function</span></code></p></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>All scopes are basically a list of statements, although <code class="docutils literal notranslate"><span class="pre">Scope</span></code> classes have additional attributes such as names. For example, the following query finds all functions whose scope (the scope in which they are declared) is also a function:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
|
||
|
||
from Function f
|
||
where f.getScope() instanceof Function
|
||
select f
|
||
</pre></div>
|
||
</div>
|
||
<p>➤ <a class="reference external" href="https://lgtm.com/query/665620040/">See this in the query console on LGTM.com</a>. Many projects have nested functions.</p>
|
||
</section>
|
||
<section id="statement">
|
||
<h3>Statement<a class="headerlink" href="#statement" title="Link to this heading">¶</a></h3>
|
||
<p>A statement is represented by the <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Stmts.qll/type.Stmts$Stmt.html">Stmt</a> class which has about 20 subclasses representing the various kinds of statements, such as the <code class="docutils literal notranslate"><span class="pre">Pass</span></code> statement, the <code class="docutils literal notranslate"><span class="pre">Return</span></code> statement or the <code class="docutils literal notranslate"><span class="pre">For</span></code> statement. Statements are usually made up of parts. The most common of these is the expression, represented by the <code class="docutils literal notranslate"><span class="pre">Expr</span></code> class. For example, take the following Python <code class="docutils literal notranslate"><span class="pre">for</span></code> statement:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">var</span> <span class="ow">in</span> <span class="n">seq</span><span class="p">:</span>
|
||
<span class="k">pass</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="mi">0</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Stmts.qll/type.Stmts$For.html">For</a> class representing the <code class="docutils literal notranslate"><span class="pre">for</span></code> statement has a number of member predicates to access its parts:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">getTarget()</span></code> returns the <code class="docutils literal notranslate"><span class="pre">Expr</span></code> representing the variable <code class="docutils literal notranslate"><span class="pre">var</span></code>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">getIter()</span></code> returns the <code class="docutils literal notranslate"><span class="pre">Expr</span></code> resenting the variable <code class="docutils literal notranslate"><span class="pre">seq</span></code>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">getBody()</span></code> returns the statement list body.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">getStmt(0)</span></code> returns the pass <code class="docutils literal notranslate"><span class="pre">Stmt</span></code>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">getOrElse()</span></code> returns the <code class="docutils literal notranslate"><span class="pre">StmtList</span></code> containing the return statement.</p></li>
|
||
</ul>
|
||
</section>
|
||
<section id="expression">
|
||
<h3>Expression<a class="headerlink" href="#expression" title="Link to this heading">¶</a></h3>
|
||
<p>Most statements are made up of expressions. The <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Exprs.qll/type.Exprs$Expr.html">Expr</a> class is the superclass of all expression classes, of which there are about 30 including calls, comprehensions, tuples, lists and arithmetic operations. For example, the Python expression <code class="docutils literal notranslate"><span class="pre">a+2</span></code> is represented by the <code class="docutils literal notranslate"><span class="pre">BinaryExpr</span></code> class:</p>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">getLeft()</span></code> returns the <code class="docutils literal notranslate"><span class="pre">Expr</span></code> representing the <code class="docutils literal notranslate"><span class="pre">a</span></code>.</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">getRight()</span></code> returns the <code class="docutils literal notranslate"><span class="pre">Expr</span></code> representing the <code class="docutils literal notranslate"><span class="pre">2</span></code>.</p></li>
|
||
</ul>
|
||
<p>As an example, to find expressions of the form <code class="docutils literal notranslate"><span class="pre">a+2</span></code> where the left is a simple name and the right is a numeric constant we can use the following query:</p>
|
||
<p><strong>Finding expressions of the form “a+2”</strong></p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
|
||
|
||
from BinaryExpr bin
|
||
where bin.getLeft() instanceof Name and bin.getRight() instanceof Num
|
||
select bin
|
||
</pre></div>
|
||
</div>
|
||
<p>➤ <a class="reference external" href="https://lgtm.com/query/669950026/">See this in the query console on LGTM.com</a>. Many projects include examples of this pattern.</p>
|
||
</section>
|
||
<section id="variable">
|
||
<h3>Variable<a class="headerlink" href="#variable" title="Link to this heading">¶</a></h3>
|
||
<p>Variables are represented by the <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Variables.qll/type.Variables$Variable.html">Variable</a> class in the CodeQL library. There are two subclasses, <code class="docutils literal notranslate"><span class="pre">LocalVariable</span></code> for function-level and class-level variables and <code class="docutils literal notranslate"><span class="pre">GlobalVariable</span></code> for module-level variables.</p>
|
||
</section>
|
||
<section id="other-source-code-elements">
|
||
<h3>Other source code elements<a class="headerlink" href="#other-source-code-elements" title="Link to this heading">¶</a></h3>
|
||
<p>Although the meaning of the program is encoded by the syntactic elements, <code class="docutils literal notranslate"><span class="pre">Scope</span></code>, <code class="docutils literal notranslate"><span class="pre">Stmt</span></code> and <code class="docutils literal notranslate"><span class="pre">Expr</span></code> there are some parts of the source code not covered by the abstract syntax tree. The most useful of these is the <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Comment.qll/type.Comment$Comment.html">Comment</a> class which describes comments in the source code.</p>
|
||
</section>
|
||
<section id="examples">
|
||
<h3>Examples<a class="headerlink" href="#examples" title="Link to this heading">¶</a></h3>
|
||
<p>Each syntactic element in Python source is recorded in the CodeQL database. These can be queried via the corresponding class. Let us start with a couple of simple examples.</p>
|
||
<section id="finding-all-finally-blocks">
|
||
<h4>1. Finding all <code class="docutils literal notranslate"><span class="pre">finally</span></code> blocks<a class="headerlink" href="#finding-all-finally-blocks" title="Link to this heading">¶</a></h4>
|
||
<p>For our first example, we can find all <code class="docutils literal notranslate"><span class="pre">finally</span></code> blocks by using the <code class="docutils literal notranslate"><span class="pre">Try</span></code> class:</p>
|
||
<p><strong>Find all</strong> <code class="docutils literal notranslate"><span class="pre">finally</span></code> <strong>blocks</strong></p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
|
||
|
||
from Try t
|
||
select t.getFinalbody()
|
||
</pre></div>
|
||
</div>
|
||
<p>➤ <a class="reference external" href="https://lgtm.com/query/659662193/">See this in the query console on LGTM.com</a>. Many projects include examples of this pattern.</p>
|
||
</section>
|
||
<section id="finding-except-blocks-that-do-nothing">
|
||
<h4>2. Finding <code class="docutils literal notranslate"><span class="pre">except</span></code> blocks that do nothing<a class="headerlink" href="#finding-except-blocks-that-do-nothing" title="Link to this heading">¶</a></h4>
|
||
<p>For our second example, we can use a simplified version of a query from the standard query set. We look for all <code class="docutils literal notranslate"><span class="pre">except</span></code> blocks that do nothing.</p>
|
||
<p>A block that does nothing is one that contains no statements except <code class="docutils literal notranslate"><span class="pre">pass</span></code> statements. We can encode this as:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>not exists(Stmt s | s = ex.getAStmt() | not s instanceof Pass)
|
||
</pre></div>
|
||
</div>
|
||
<p>where <code class="docutils literal notranslate"><span class="pre">ex</span></code> is an <code class="docutils literal notranslate"><span class="pre">ExceptStmt</span></code> and <code class="docutils literal notranslate"><span class="pre">Pass</span></code> is the class representing <code class="docutils literal notranslate"><span class="pre">pass</span></code> statements. Instead of using the double negative, “<strong>no</strong> <em>statements that are</em> <strong>not</strong> <em>pass statements”</em>, this can also be expressed positively, <em>“all statements must be pass statements.”</em> The positive form is expressed using the <code class="docutils literal notranslate"><span class="pre">forall</span></code> quantifier:</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>forall(Stmt s | s = ex.getAStmt() | s instanceof Pass)
|
||
</pre></div>
|
||
</div>
|
||
<p>Both forms are equivalent. Using the positive expression, the whole query looks like this:</p>
|
||
<p><strong>Find pass-only</strong> <code class="docutils literal notranslate"><span class="pre">except</span></code> <strong>blocks</strong></p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
|
||
|
||
from ExceptStmt ex
|
||
where forall(Stmt s | s = ex.getAStmt() | s instanceof Pass)
|
||
select ex
|
||
</pre></div>
|
||
</div>
|
||
<p>➤ <a class="reference external" href="https://lgtm.com/query/690010036/">See this in the query console on LGTM.com</a>. Many projects include pass-only <code class="docutils literal notranslate"><span class="pre">except</span></code> blocks.</p>
|
||
</section>
|
||
</section>
|
||
<section id="summary">
|
||
<h3>Summary<a class="headerlink" href="#summary" title="Link to this heading">¶</a></h3>
|
||
<p>The most commonly used standard classes in the syntactic part of the library are organized as follows:</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">Module</span></code>, <code class="docutils literal notranslate"><span class="pre">Class</span></code>, <code class="docutils literal notranslate"><span class="pre">Function</span></code>, <code class="docutils literal notranslate"><span class="pre">Stmt</span></code>, and <code class="docutils literal notranslate"><span class="pre">Expr</span></code> - they are all subclasses of <a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/AstExtended.qll/type.AstExtended$AstNode.html">AstNode</a>.</p>
|
||
<section id="abstract-syntax-tree">
|
||
<h4>Abstract syntax tree<a class="headerlink" href="#abstract-syntax-tree" title="Link to this heading">¶</a></h4>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">AstNode</span></code></p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Module</span></code> – A Python module</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Class</span></code> – The body of a class definition</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Function</span></code> – The body of a function definition</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Stmt</span></code> – A statement</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Assert</span></code> – An <code class="docutils literal notranslate"><span class="pre">assert</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Assign</span></code> – An assignment</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">AssignStmt</span></code> – An assignment statement, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">y</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">ClassDef</span></code> – A class definition statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">FunctionDef</span></code> – A function definition statement</p></li>
|
||
</ul>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">AugAssign</span></code> – An augmented assignment, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">+=</span> <span class="pre">y</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Break</span></code> – A <code class="docutils literal notranslate"><span class="pre">break</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Continue</span></code> – A <code class="docutils literal notranslate"><span class="pre">continue</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Delete</span></code> – A <code class="docutils literal notranslate"><span class="pre">del</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">ExceptStmt</span></code> – The <code class="docutils literal notranslate"><span class="pre">except</span></code> part of a <code class="docutils literal notranslate"><span class="pre">try</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Exec</span></code> – An exec statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">For</span></code> – A <code class="docutils literal notranslate"><span class="pre">for</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">If</span></code> – An <code class="docutils literal notranslate"><span class="pre">if</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Pass</span></code> – A <code class="docutils literal notranslate"><span class="pre">pass</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Print</span></code> – A <code class="docutils literal notranslate"><span class="pre">print</span></code> statement (Python 2 only)</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Raise</span></code> – A raise statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Return</span></code> – A <code class="docutils literal notranslate"><span class="pre">return</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Try</span></code> – A <code class="docutils literal notranslate"><span class="pre">try</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">While</span></code> – A <code class="docutils literal notranslate"><span class="pre">while</span></code> statement</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">With</span></code> – A <code class="docutils literal notranslate"><span class="pre">with</span></code> statement</p></li>
|
||
</ul>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Expr</span></code> – An expression</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Attribute</span></code> – An attribute, <code class="docutils literal notranslate"><span class="pre">obj.attr</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Call</span></code> – A function call, <code class="docutils literal notranslate"><span class="pre">f(arg)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">IfExp</span></code> – A conditional expression, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">if</span> <span class="pre">cond</span> <span class="pre">else</span> <span class="pre">y</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Lambda</span> <span class="pre">–</span> <span class="pre">A</span> <span class="pre">lambda</span> <span class="pre">expression</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Yield</span></code> – A <code class="docutils literal notranslate"><span class="pre">yield</span></code> expression</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Bytes</span></code> – A bytes literal, <code class="docutils literal notranslate"><span class="pre">b"x"</span></code> or (in Python 2) <code class="docutils literal notranslate"><span class="pre">"x"</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Unicode</span></code> – A unicode literal, <code class="docutils literal notranslate"><span class="pre">u"x"</span></code> or (in Python 3) <code class="docutils literal notranslate"><span class="pre">"x"</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Num</span></code> – A numeric literal, <code class="docutils literal notranslate"><span class="pre">3</span></code> or <code class="docutils literal notranslate"><span class="pre">4.2</span></code></p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">IntegerLiteral</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">FloatLiteral</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">ImaginaryLiteral</span></code></p></li>
|
||
</ul>
|
||
</li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Dict</span></code> – A dictionary literal, <code class="docutils literal notranslate"><span class="pre">{'a':</span> <span class="pre">2}</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Set</span></code> – A set literal, <code class="docutils literal notranslate"><span class="pre">{'a',</span> <span class="pre">'b'}</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">List</span></code> – A list literal, <code class="docutils literal notranslate"><span class="pre">['a',</span> <span class="pre">'b']</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Tuple</span></code> – A tuple literal, <code class="docutils literal notranslate"><span class="pre">('a',</span> <span class="pre">'b')</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">DictComp</span></code> – A dictionary comprehension, <code class="docutils literal notranslate"><span class="pre">{k:</span> <span class="pre">v</span> <span class="pre">for</span> <span class="pre">...}</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">SetComp</span></code> – A set comprehension, <code class="docutils literal notranslate"><span class="pre">{x</span> <span class="pre">for</span> <span class="pre">...}</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">ListComp</span></code> – A list comprehension, <code class="docutils literal notranslate"><span class="pre">[x</span> <span class="pre">for</span> <span class="pre">...]</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">GenExpr</span></code> – A generator expression, <code class="docutils literal notranslate"><span class="pre">(x</span> <span class="pre">for</span> <span class="pre">...)</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Subscript</span></code> – A subscript operation, <code class="docutils literal notranslate"><span class="pre">seq[index]</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Name</span></code> – A reference to a variable, <code class="docutils literal notranslate"><span class="pre">var</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">UnaryExpr</span></code> – A unary operation, <code class="docutils literal notranslate"><span class="pre">-x</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">BinaryExpr</span></code> – A binary operation, <code class="docutils literal notranslate"><span class="pre">x+y</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Compare</span></code> – A comparison operation, <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre"><</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">10</span></code></p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">BoolExpr</span></code> – Short circuit logical operations, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">and</span> <span class="pre">y</span></code>, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">or</span> <span class="pre">y</span></code></p></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="variables">
|
||
<h4>Variables<a class="headerlink" href="#variables" title="Link to this heading">¶</a></h4>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Variable</span></code> – A variable</p>
|
||
<ul>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">LocalVariable</span></code> – A variable local to a function or a class</p></li>
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">GlobalVariable</span></code> – A module level variable</p></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section id="other">
|
||
<h4>Other<a class="headerlink" href="#other" title="Link to this heading">¶</a></h4>
|
||
<ul class="simple">
|
||
<li><p><code class="docutils literal notranslate"><span class="pre">Comment</span></code> – A comment</p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
</section>
|
||
<section id="control-flow-classes">
|
||
<h2>Control flow classes<a class="headerlink" href="#control-flow-classes" title="Link to this heading">¶</a></h2>
|
||
<p>This part of the library represents the control flow graph of each <code class="docutils literal notranslate"><span class="pre">Scope</span></code> (classes, functions, and modules). Each <code class="docutils literal notranslate"><span class="pre">Scope</span></code> contains a graph of <code class="docutils literal notranslate"><span class="pre">ControlFlowNode</span></code> 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. For more information, see <a class="reference external" href="https://en.wikipedia.org/wiki/Basic_block">Basic block</a> on Wikipedia.</p>
|
||
<section id="example">
|
||
<h3>Example<a class="headerlink" href="#example" title="Link to this heading">¶</a></h3>
|
||
<p>If we want to find the longest sequence of code without any branches, we need to consider control flow. A <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code> is, by definition, a sequence of code without any branches, so we just need to find the longest <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code>.</p>
|
||
<p>First of all we introduce a simple predicate <code class="docutils literal notranslate"><span class="pre">bb_length()</span></code> which relates <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code>s to their length.</p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>int bb_length(BasicBlock b) {
|
||
result = max(int i | exists(b.getNode(i))) + 1
|
||
}
|
||
</pre></div>
|
||
</div>
|
||
<p>Each <code class="docutils literal notranslate"><span class="pre">ControlFlowNode</span></code> within a <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code> is numbered consecutively, starting from zero, therefore the length of a <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code> is equal to one more than the largest index within that <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code>.</p>
|
||
<p>Using this predicate we can select the longest <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code> by selecting the <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code> whose length is equal to the maximum length of any <code class="docutils literal notranslate"><span class="pre">BasicBlock</span></code>:</p>
|
||
<p><strong>Find the longest sequence of code without branches</strong></p>
|
||
<div class="highlight-ql notranslate"><div class="highlight"><pre><span></span>import python
|
||
|
||
int bb_length(BasicBlock b) {
|
||
result = max(int i | exists(b.getNode(i)) | i) + 1
|
||
}
|
||
|
||
from BasicBlock b
|
||
where bb_length(b) = max(bb_length(_))
|
||
select b
|
||
</pre></div>
|
||
</div>
|
||
<p>➤ <a class="reference external" href="https://lgtm.com/query/666730036/">See this in the query console on LGTM.com</a>. When we ran it on the LGTM.com demo projects, the <em>openstack/nova</em> and <em>ytdl-org/youtube-dl</em> projects both contained source code results for this query.</p>
|
||
<blockquote class="pull-quote">
|
||
<div><p>Note</p>
|
||
<p>The special underscore variable <code class="docutils literal notranslate"><span class="pre">_</span></code> means any value; so <code class="docutils literal notranslate"><span class="pre">bb_length(_)</span></code> is the length of any block.</p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="id2">
|
||
<h3>Summary<a class="headerlink" href="#id2" title="Link to this heading">¶</a></h3>
|
||
<p>The classes in the control-flow part of the library are:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Flow.qll/type.Flow$ControlFlowNode.html">ControlFlowNode</a> – A control-flow node. There is a one-to-many relation between AST nodes and control-flow nodes.</p></li>
|
||
<li><p><a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/semmle/python/Flow.qll/type.Flow$BasicBlock.html">BasicBlock</a> – A non branching list of control-flow nodes.</p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
<section id="further-reading">
|
||
<h2>Further reading<a class="headerlink" href="#further-reading" title="Link to this heading">¶</a></h2>
|
||
<ul class="simple">
|
||
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/python/ql/src">CodeQL queries for Python</a></p></li>
|
||
<li><p><a class="reference external" href="https://github.com/github/codeql/tree/main/python/ql/examples">Example queries for Python</a></p></li>
|
||
<li><p><a class="reference external" href="https://codeql.github.com/codeql-standard-libraries/python/">CodeQL library reference for Python</a></p></li>
|
||
</ul>
|
||
<ul class="simple">
|
||
<li><p>“<a class="reference internal" href="../ql-language-reference/index.html#ql-language-reference"><span class="std std-ref">QL language reference</span></a>”</p></li>
|
||
<li><p>“<a class="reference internal" href="../codeql-overview/codeql-tools.html#codeql-tools"><span class="std std-ref">CodeQL tools</span></a>”</p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
</article>
|
||
|
||
<!-- GitHub footer, with links to terms and privacy statement -->
|
||
<div class="px-3 px-md-6 f6 py-4 d-sm-flex flex-justify-between flex-row-reverse flex-items-center border-top">
|
||
<ul class="list-style-none d-flex flex-items-center mb-3 mb-sm-0 lh-condensed-ultra">
|
||
<li class="mr-3">
|
||
<a href="https://twitter.com/github" title="GitHub on Twitter" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 273.5 222.3" class="d-block" height="18">
|
||
<path
|
||
d="M273.5 26.3a109.77 109.77 0 0 1-32.2 8.8 56.07 56.07 0 0 0 24.7-31 113.39 113.39 0 0 1-35.7 13.6 56.1 56.1 0 0 0-97 38.4 54 54 0 0 0 1.5 12.8A159.68 159.68 0 0 1 19.1 10.3a56.12 56.12 0 0 0 17.4 74.9 56.06 56.06 0 0 1-25.4-7v.7a56.11 56.11 0 0 0 45 55 55.65 55.65 0 0 1-14.8 2 62.39 62.39 0 0 1-10.6-1 56.24 56.24 0 0 0 52.4 39 112.87 112.87 0 0 1-69.7 24 119 119 0 0 1-13.4-.8 158.83 158.83 0 0 0 86 25.2c103.2 0 159.6-85.5 159.6-159.6 0-2.4-.1-4.9-.2-7.3a114.25 114.25 0 0 0 28.1-29.1"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li class="mr-3">
|
||
<a href="https://www.facebook.com/GitHub" title="GitHub on Facebook" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.3 15.4" class="d-block" height="18">
|
||
<path
|
||
d="M14.5 0H.8a.88.88 0 0 0-.8.9v13.6a.88.88 0 0 0 .8.9h7.3v-6h-2V7.1h2V5.4a2.87 2.87 0 0 1 2.5-3.1h.5a10.87 10.87 0 0 1 1.8.1v2.1h-1.3c-1 0-1.1.5-1.1 1.1v1.5h2.3l-.3 2.3h-2v5.9h3.9a.88.88 0 0 0 .9-.8V.8a.86.86 0 0 0-.8-.8z"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li class="mr-3">
|
||
<a href="https://www.youtube.com/github" title="GitHub on YouTube" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.17 13.6" class="d-block" height="16">
|
||
<path
|
||
d="M18.77 2.13A2.4 2.4 0 0 0 17.09.42C15.59 0 9.58 0 9.58 0a57.55 57.55 0 0 0-7.5.4A2.49 2.49 0 0 0 .39 2.13 26.27 26.27 0 0 0 0 6.8a26.15 26.15 0 0 0 .39 4.67 2.43 2.43 0 0 0 1.69 1.71c1.52.42 7.5.42 7.5.42a57.69 57.69 0 0 0 7.51-.4 2.4 2.4 0 0 0 1.68-1.71 25.63 25.63 0 0 0 .4-4.67 24 24 0 0 0-.4-4.69zM7.67 9.71V3.89l5 2.91z"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li class="mr-3 flex-self-start">
|
||
<a href="https://www.linkedin.com/company/github" title="GitHub on Linkedin" style="color: #959da5;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" class="d-block" height="18">
|
||
<path
|
||
d="M3.94 2A2 2 0 1 1 2 0a2 2 0 0 1 1.94 2zM4 5.48H0V18h4zm6.32 0H6.34V18h3.94v-6.57c0-3.66 4.77-4 4.77 0V18H19v-7.93c0-6.17-7.06-5.94-8.72-2.91z"
|
||
fill="currentColor"></path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="https://github.com/github" title="GitHub's organization" style="color: #959da5;">
|
||
<svg version="1.1" width="20" height="20" viewBox="0 0 16 16" class="octicon octicon-mark-github"
|
||
aria-hidden="true">
|
||
<path fill-rule="evenodd"
|
||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z">
|
||
</path>
|
||
</svg>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
<ul class="list-style-none d-flex text-gray">
|
||
<li class="mr-3">©
|
||
<script type="text/javascript">document.write(new Date().getFullYear());</script> GitHub, Inc.</li>
|
||
<li class="mr-3"><a
|
||
href="https://docs.github.com/github/site-policy/github-terms-of-service"
|
||
class="link-gray">Terms </a></li>
|
||
<li><a href="https://docs.github.com/github/site-policy/github-privacy-statement"
|
||
class="link-gray">Privacy </a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<script type="text/javascript">
|
||
$(document).ready(function () {
|
||
$(".toggle > *").hide();
|
||
$(".toggle .name").show();
|
||
$(".toggle .name").click(function () {
|
||
$(this).parent().children().not(".name").toggle(400);
|
||
$(this).parent().children(".name").toggleClass("open");
|
||
})
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html> |