Code Documentation

Slicing

The definition of slicing is split into forward and backwards slicing: using both methods together and we get a full slice. Currently only forward slicing is implemented which returns all line numbers depending on the current line number.

Slicing Forward

Given a simple program:

>>> program = u"""
... def main():
...     foo = 1
...     bar = 1
...     baz = foo + bar
...     print(baz)
...
... if __name__ == "__main__":
...     main()
... """

To see which lines depend on line 3, use the slice_string() method:

>>> from programslice import slice_string
>>> slice_string('foo', 3, 4, program, 'myprogram')
['foo,3,4', 'foo,5,10', 'baz,5,4', 'baz,6,10']

Shebangs and Encoding declarations

Sometimes programs use encoding declarations, which need to removed before the program can be parsed. The slicing will not cause an error:

>>> encprogram = u'#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n{program}'.format(program=program)
>>> ignored = slice_string('bar', 4, 4, encprogram, 'myprogram')
>>> encprogram = u'#!/usr/bin/env python\n#\n# vim: set fileencoding=utf-8 :\n{program}'.format(program=program)
>>> ignored = slice_string('baz', 5, 4, encprogram, 'myprogram')

Text Output

Instead of returning line numbers, we can filter the buffer as well. The slice_string function can be given a custom formatter class. It defaults to LineFormatter to just render the line numbers:

>>> from programslice.formatter import TextOutputFormatter
>>> result = slice_string('bar', 4, 4, program, 'myprogram', formatter=TextOutputFormatter)
>>> print('\n'.join(result))    
    bar = 1
    baz = foo + bar
    print(baz)

Utility Functions

programslice.command_slice_file()[source]

Command line utility which can slice a given file and return the depending lines.

programslice.get_formatter_klass(name)[source]

Returns the slice result formatter given by it’s name.

programslice.slice_string(varname, currentline, offset, source, filename, formatter=<class 'programslice.formatter.VimOutPutFormatter'>)[source]

Slices the given source code from the given currentline.

Parameters:
  • varname (str) – The variable name to slice from.
  • currentline (int) – A line from which to start the slicing.
  • offset (int) – The position offset of the variable.
  • source (str) – The source code to parse.
  • filename (str) – filename of the given source code.
  • formatter (class) – Formatter class to format the slice result. Defaults to VimOutPutFormatter which only outputs the line numbers.

Deprecated since version 0.3.

Parameters:invert (bool) – Invert the result and return lines which don’t depend on the currentline. Defaults to False.

Graph

Note: The reason for a self implemented graph and edge is not to be smarter, since there are better modules available for this. It is an educational project for me.

class programslice.graph.Edge(name, ln, column)[source]
synopsis

Representing the edge of a graph.

class programslice.graph.Graph(name='')[source]
synopsis

A graph which represents a function visited by a programslice.visitor. The edges of this graph are the line numbers of the parsed function.

Parameters:name (string) – A name identifying this graph (e.g. function X)
add(edge)[source]

Adds a new edge with the given parameters to the graph.

Return type:Edge
get(edge, default=[])[source]

Returns all referenced edges from the given edge an empty list otherwise.

class programslice.graph.Slice(graph)[source]

A simple search over a graph, starting from an edge.

Parameters:graph (Graph) – The graph to slice
slice_forward(edge)[source]

A forward slice starting at the given edge. A match is when Edge.lineno == lineno and Edge.name == name.

Parameters:edge (Edge) – An edge.
Return type:list of edges

Visitor

class programslice.visitor.LineDependencyVisitor[source]

A visitor which creates a data dependency graph.

Note

Read and Written variables are currently kept track of in a dictionary for each. This may cause wrong results when building the graph. Furthermore, we might want to create a data flow graph and a control flow graph.

connect_by_lineno(node)[source]

Connect reads and writes also by line number.

We can not only connect by name, but also by line number. That ensures, that we connect the variables which are read, to assigned ones in the current line.

Example:

v = a + b
connect_by_name()[source]

Here we are connecting all variables which are stored with the variables which are read.

For example:

>>> v = 1
>>> b = 1
>>> c = v

writes: v, c
reads: v
visitor visits: v (store) → b (store) → c (store) → v (read)

In order to produce a graph such that: v → v → c we need to check if we can find a read variable which now is written to. Just using the line number is not good enough, because written variables may appear at the end of the function/method, not in the next line.

visit_FunctionDef(node)[source]

Visits function and resets writes and reads in order to prevent that current function variables are overwritten.

Note: This currently just resets writes and reads which is used to build the dependency graph. But it should set the writes and reads in such a way, so that we can slice over function boundaries.

visit_Name(node)[source]

Use the name and context in order to distinguish between variables written and read.

Once the variable is read, we tie up dependencies by line number and name.

Formatter

class programslice.formatter.LineFormatter(slice_result, source)[source]

A base formatter which outputs a list of linenumbers on call.

Parameters:
  • slice_result (list) – The slice result which should be a list of line numbers.
  • source (str) – The parsed source code as a string.

TODO: No checking in place wether source is a unicode object or str.

>>> from programslice.graph import Edge
>>> slice_result = [Edge('foo', 12, 3), Edge('bar', 13, 3)]
>>> formatter = LineFormatter(slice_result, '')
>>> formatter()
[12, 13]
class programslice.formatter.TextOutputFormatter(slice_result, source)[source]

Returns a list of source code lines based on the given slice result line numbers.

class programslice.formatter.VimOutPutFormatter(slice_result, source)[source]

Returns slice output information parsable by vim.

This class is different to the Line formatter in that it outputs additional detail from the edges.

Table Of Contents

Previous topic

Commandline API

Next topic

CHANGES

This Page