--- a/conf.py Thu Apr 02 20:54:37 2009 +0300
+++ b/conf.py Thu Apr 02 21:11:01 2009 +0300
@@ -9,6 +9,22 @@
An object that can be written to a ConfFile, as multiple lines of text.
"""
+ def __init__ (self, comments=None) :
+ """
+ Initialize with the given list of comments. Comments that are None should be ignore.
+ """
+
+ # init the comments list
+ self.comments = comments or []
+
+ def add_comment (self, comment) :
+ """
+ Add a comment to be rendered in the output.
+ """
+
+ # add it
+ self.comments.append(comment)
+
def fmt_lines (self) :
"""
Yield a series of lines to be output in the file
--- a/dhcp_conf.py Thu Apr 02 20:54:37 2009 +0300
+++ b/dhcp_conf.py Thu Apr 02 21:11:01 2009 +0300
@@ -6,12 +6,24 @@
import itertools
-class Comment (conf.ConfObject) :
+class Object (conf.ConfObject) :
+ """
+ Our version of ConfObject
+ """
+
+ def _fmt_comments (self) :
+ """
+ Format our comment lines
+ """
+
+ for comment in self.comments :
+ if comment is not None :
+ yield "# %s" % (comment, )
+
+
+class Comment (Object) :
"""
A comment, is, well, a comment :)
-
- Currently, comments are only one line, and look like the following:
- "#" <comment>
"""
def __init__ (self, comment) :
@@ -19,18 +31,18 @@
@param comment the comment string
"""
- self.comment = comment
+ Object.__init__(self, [comment])
def fmt_lines (self) :
"""
Yield a single line with the comment
"""
- yield "# %s" % (self.comment, )
+ return self._fmt_comments()
-class Section (conf.ConfObject) :
+class _Section (Object) :
"""
- A section holds a list of params and a list of decls
+ Base implementation of Section, but doesn't format comments in output (inheriting class can define how that happens)
"""
def __init__ (self, params=None, decls=None, comment=None) :
@@ -39,10 +51,11 @@
If a comment is given, then it will be formatted before the section's stuff
"""
+
+ Object.__init__(self, [comment])
self.params = params or []
self.decls = decls or []
- self.comment = comment
def add_param (self, param) :
"""
@@ -66,23 +79,11 @@
for decl in decls :
self.add_decl(decl)
- def _fmt_comment (self) :
- """
- Format our comment line
- """
-
- return "# %s" % (self.comment, )
-
-
def fmt_lines (self) :
"""
Format all of our params and decls, in that order
"""
- # comment?
- if self.comment :
- yield self._fmt_comment()
-
# then output each content line
for stmt in itertools.chain(self.params, self.decls) :
# skip Nones
@@ -92,6 +93,24 @@
for line in stmt.fmt_lines() :
yield line
+class Section (_Section) :
+ """
+ A section holds a list of params and a list of decls, plus some comments at the beginning of the section
+ """
+
+ def fmt_lines (self) :
+ """
+ Format all of our comments, and then super
+ """
+
+ # comments
+ for line in self._fmt_comments() :
+ yield line
+
+ # section stuff
+ for line in _Section.fmt_lines(self) :
+ yield line
+
class ConfFile (Section, conf.File) :
DEFAULT_NAME = "dhcpd.conf"
DEFAULT_PATH = "/etc/dhcp3/dhcpd.conf"
@@ -104,16 +123,22 @@
conf.File.__init__(self, name, path)
Section.__init__(self, params, decls)
-class Statement (conf.ConfObject) :
+class Statement (Object) :
"""
A statement is a single line in the config file
"""
- def __init__ (self, name, *args) :
+ def __init__ (self, name, *args, **kwargs) :
"""
Arguments given as None will be ignored.
+
+ A comment can be given as a keyword argument
"""
+ if kwargs : assert len(kwargs) == 1 and 'comment' in kwargs
+
+ Object.__init__(self, [kwargs.get('comment')])
+
self.name = name
self.args = [arg for arg in args if arg is not None]
@@ -186,10 +211,15 @@
"""
Yields a single ;-terminated line
"""
-
+
+ # comments
+ for line in self._fmt_comments() :
+ yield line
+
+ # the line
yield "%s;" % self._fmt_data()
-class Declaration (Section, Statement) :
+class Declaration (_Section, Statement) :
"""
A declaration begins like a statement (with name and args), but then contains a curly-braces-delimited block
that acts like a Section.
@@ -200,26 +230,30 @@
"""
- def __init__ (self, name, args=[], params=None, decls=None) :
+ def __init__ (self, name, args=[], params=None, decls=None, comment=None) :
"""
The name/args will be formatted as in Statement, but params should be an iterable of Parameters, and decls
an iterable of Declarations.
"""
# init the statement bit
- Section.__init__(self, params, decls)
- Statement.__init__(self, name, *args)
+ _Section.__init__(self, params, decls)
+ Statement.__init__(self, name, *args, **dict(comment=comment))
def fmt_lines (self) :
"""
Yields a header line, a series of indented body lines, and the footer line
"""
+ # comments
+ for line in self._fmt_comments() :
+ yield line
+
# the header to open the block
yield "%s {" % self._fmt_data()
# then output the section stuff, indented
- for line in Section.fmt_lines(self) :
+ for line in _Section.fmt_lines(self) :
yield "\t%s" % line
# and then close the block
--- a/test_dhcp.py Thu Apr 02 20:54:37 2009 +0300
+++ b/test_dhcp.py Thu Apr 02 21:11:01 2009 +0300
@@ -53,6 +53,7 @@
def test_parameter (self) :
self.assert_obj(dhcpc.Parameter("param0", "this", 13, "that"), [ "param0 this 13 that;" ])
+ self.assert_obj(dhcpc.Parameter("param1", comment="testing"), [ "# testing", "param1;" ])
def test_declaration (self) :
self.assert_obj(dhcpc.Declaration("decl0", ["arg0", "arg1"], [
@@ -62,8 +63,8 @@
dhcpc.Declaration("decl0.0", params=[
dhcpc.Parameter("param0.0.1", "value")
])
- ]), [
-
+ ], comment="foo"), [
+ "# foo",
"decl0 arg0 arg1 {",
"\tparam0;",
"\tdecl0.0 {",