SourceBuilder is a simple way to write (Python) code using Python code.
Say you want to generate stub class definitions for two Python classes
named Foo
and Bar
. This can be achieved using the following code:
>>> from sourcebuilder import PySourceBuilder >>> klasses = ['Foo', 'Bar'] >>> sb = PySourceBuilder() >>> for klass in klasses: ... with sb.block('class {0}(object)'.format(klass):, 2): ... sb.docstring('TODO: Document {0}'.format(klass)) ... with sb.block('def __init__(self):'): ... sb.writeln('pass') ... >>> source = sb.end() >>> print source class Foo(object): """TODO: Document Foo""" def __init__(self): pass class Bar(object): """TODO: Document Bar""" def __init__(self): pass
There's also the generic SourceBuilder. It doesn't come with the block context manager or docstring method, but it's a starting point for writing your own custom SourceBuilder implementation.
The following example shows how to use the generic SourceBuilder to generate (nearly) the same code as the previous example (sans docstrings):
>>> from sourcebuilder import SourceBuilder >>> sb = SourceBuilder() >>> for klass in klasses: ... sb.writeln() ... sb.writeln('class {0}(object):'.format(klass)) ... with sb.indent: ... sb.writeln('def __init__(self):') ... with sb.indent: ... sb.writeln('pass') ... sb.writeln() ... >>> source = sb.end()
Create a SourceBuilder instance and write code to it to line by line. Currently there's a generic SourceBuilder and a PySourceBuilder.
Initialize a SourceBuilder, indent_with
is set to 4 spaces by default.
Write code at the current indentation level.
Write a line at the current indentation level. If no code is given only a newline is written.
Get the generated source and resets the indent level.
Decrease the current indentation level. Should only be used if the indent context manager is not used.
Raises a DedentException
if decreasing indentation level is not possible.
Discard generated source and memory buffer and resets the indent level.
Convenience method for use with contextlib.closing
.
Calls self.truncate()
.
The code is indented with 4 spaces each level by default. This can be
changed by setting indent_with
on initialization:
>>> sb = SourceBuilder(indent_with='\t')
By using the indent
context manager each line gets correctly indented
and the input indentation will resemble the output:
>>> sb = SourceBuilder() >>> sb.writeln() >>> sb.writeln('def hello_world():') >>> with sb.indent: ... sb.writeln('print \'Hello World\'') ... ... >>> sb.writeln() >>> sb.writeln('hello_world()') >>> source = sb.end() >>> print source def hello_world(): print 'Hello World' hello_world()
If for some reason context managers can't be used indent
also works
as a method. Combined with the dedent
method code indentation levels
can be controlled manually.:
>>> sb = SourceBuilder() >>> sb.writeln() >>> sb.writeln('def hello_world():') >>> sb.indent() >>> sb.writeln('print \'Hello World\'') >>> sb.dedent() >>> sb.writeln() >>> sb.writeln('hello_world()') >>> source = sb.end() >>> print source def hello_world(): print 'Hello World' hello_world()
It's not advised to use sb.indent
in with
statements in combination
with calls to sb.dedent()
or sb.indent()
.
PySourceBuilder inherits from the generic SourceBuilder and adds some Python specific methods and context managers.
A context manager for block structures. It's a generic way to start a control structure (if, try, while, for etc.) or a class, function or method definition.
The given code
will be printed preceded by 0 or more blank lines,
controlled by the lines_before
parameter. An indent context is
then started.
Example:
sb = PySourceBuilder() >>> >>> with sb.block('class Hello(object):', 2): ... with sb.block('def __init__(self, what=\'World\'):', 1): ... sb.writeln('pass') ... >>> print sb.end() class Hello(object): def __init__(self, what='World'): pass
Write a docstring. The given doc
is surrounded by triple double
quotes ("""). This can be changed by passing a different delimiter
(e.g. triple single quotes).
The docstring is formatted to not run past 72 characters per line (including
indentation). This can be changed by passing a different width
parameter.
SourceBuilder has 100% test coverage and passes all its tests in Python 2.5, 2.6 and 2.7.
This project was started on Sat Mar 31 2012 by Jaap Roes.
It is in part inspired by 'A Python Code Generator' by Fredrik Lundh, Mar 1998