Parsing a python file to find classes with certain label
<p>I have a python file with many classes in it. The file looks something like that:</p>

<pre><code>some code, functions and stuff...
class A():
     some code...
@label
class B(A):
     some code...
@label
class C(A):
    some code...
class D(A):
    some code...
some extra code...
</code></pre>

<p>What I want to do is to make a list of all the classes that has the @label before their declaration, i.e in this example: [B,C]. (That will happen in another file, if it matters)</p>

<p>What I tried so far is parsing the file like it was a regular text file (with read() and stuff), but what I get is a list of the classes name and not the classes themselves, i.e  (['B','C']) and I don't know what to do next. I would really hope there's a more elegant way. My next step, after I get that classes list, is to activate for each of the classes a certain function they all have. That's why the name of the class isn't enough for me. </p>

<p>You have two options:</p>

<ul>
<li><p>use the <a href="https://docs.python.org/3/library/tokenize.html" rel="nofollow"><code>tokenize</code> module</a> to look out for <code>token.OP</code> tokens with the value <code>@</code>, followed by <code>token.NAME</code> tokens for <code>label</code> and, after a newline token, <code>class</code>. This is the most light-weight.</p></li>
<li><p>use the <a href="https://docs.python.org/3/library/ast.html" rel="nofollow"><code>ast</code> module</a> to parse the source into a tree, then use the <code>ast.walk()</code> function, looking for <code>ast.ClassDef</code> objects. If the object has a <code>ast.Name</code> object with <code>id == 'label'</code> in the <code>decorator_list</code> attribute, you can record the <code>name</code> attribute.</p></li>
</ul>

<p>The latter is probably easiest:</p>

<pre><code>import ast

def labelled_classnames(source):
    module = ast.parse(source)
    for node in ast.walk(module):
        if not isinstance(node, ast.ClassDef):
            continue
        if any(isinstance(n, ast.Name) and n.id == 'label' 
               for n in node.decorator_list):
            yield node.name
</code></pre>

<p>Demo:</p>

<pre><code>&gt;&gt;&gt; demosource = '''
... class A():
...     pass
...
... @label
... class B(A):
...     pass
...
... @label
... class C(A):
...     pass
...
... class D(A):
...     pass
... '''
&gt;&gt;&gt; list(labelled_classnames(demosource))
['B', 'C']
</code></pre>

python class parsing