32
34
file round tripper*. Its main feature is that it is very easy to use, with a
33
35
straightforward programmer's interface and a simple syntax for config files.
34
36
It has lots of other features though :
36
.. sidebar:: ConfigObj in Bazaar
38
**ConfigObj** is now used as the config file parser for `Bazaar <http://bazaar-vcs.org>`_.
40
Bazaar is *the* Python distributed {acro;VCS;Version Control System}.
41
ConfigObj is used to read ``bazaar.conf`` and ``branches.conf``.
43
Other projects that use **ConfigObj** include :
45
* `Planet Plus <http://planetplus.python-hosting.com/>`_
47
A new web application version of `Planet <http://www.planetplanet.org/>`_,
50
* `NeuroImaging in Python <http://projects.scipy.org/neuroimaging/ni/wiki>`_
52
BrainSTAT is a project with the ultimate goal to produce a
53
platform-independent python environment for the analysis of brain
56
* `Gruik <http://www.tracos.org/gruik/wiki>`_
58
Gruik is a free software network packet sniffer.
60
38
* Nested sections (subsections), to any level
62
40
* Multiple line values
70
48
* All comments in the file are preserved
71
49
* The order of keys/sections is preserved
72
50
* No external dependencies
73
* Full unicode support.
51
* Full Unicode support
52
* A powerful ``unrepr`` mode for storing basic datatypes
75
ConfigObj 4 is a complete rewrite of ConfigObj. ConfigObj now has a barrage [#]_
76
of doctests built into it, testing almost every feature. Run ``python configobj.py -v``
77
to see them in action. Despite the tests, ConfigObj 4 is smaller than version 3
78
and has no external dependencies.
54
ConfigObj has a barrage of doctests [#]_ built into it, testing almost every
55
feature. Run ``python configobj_test.py -v`` to see them in action.
80
57
For support and bug reports please use the ConfigObj `Mailing List`_.
84
ConfigObj provides a convenient API for storing all sorts of data, not just
85
config files. There is an article on using `ConfigObj for Data Persistence`_.
87
The code from that article is available as ConfigPersist.py_.
89
60
.. _ConfigObj for Data Persistence: http://www.voidspace.org.uk/python/articles/configobj_for_data_persistence.shtml
90
61
.. _ConfigPersist.py: http://www.voidspace.org.uk/python/configpersist.html
135
106
various other useful modules, and is required by many of the `Voidspace Python
112
It is sometimes possible to get the latest *development version* of ConfigObj
113
from the `Subversion Repository <http://svn.pythonutils.python-hosting.com/trunk/pythonutils/>`_.
138
115
.. _configobj.py: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=configobj.py
139
.. _configobj.zip: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=configobj-4.2.0.zip
116
.. _configobj.zip: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=configobj-4.4.0.zip
140
117
.. _validate.py: http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=validate.py
141
118
.. _API Docs: http://www.voidspace.org.uk/python/configobj-api/
142
119
.. _this document:
143
120
.. _configobj homepage: http://www.voidspace.org.uk/python/configobj.html
144
.. _Subversion Repository: http://svn.rest2web.python-hosting.com/branches/configobj4
145
121
.. _Sourceforge: http://sourceforge.net/projects/configobj
146
122
.. _EpyDoc: http://epydoc.sourceforge.net
147
123
.. _pythonutils: http://www.voidspace.org.uk/python/pythonutils.html
148
124
.. _Voidspace Python Projects: http://www.voidspace.org.uk/python
128
ConfigObj in the Real World
129
===========================
131
Projects that use **ConfigObj** include :
133
* `Bazaar <http://bazaar-ng.org>`_.
135
Bazaar is a Python distributed {acro;VCS;Version Control System}.
136
ConfigObj is used to read ``bazaar.conf`` and ``branches.conf``.
138
* `Turbogears <http://www.turbogears.org/>`_
140
Turbogears is a web application framework.
142
* `Chandler <http://chandler.osafoundation.org/>`_
144
A Python and `wxPython <http://www.wxpython.org>`_
145
{acro;PIM;Personal Information Manager}, being developed by the
146
`OSAFoundation <http://www.osafoundation.org/>`_.
148
* `CryptoBox <https://systemausfall.org/trac/cryptobox/wiki/CryptoBox/en>`_
150
A very interesting looking Debian based Live-CD which supports storing
151
data using an encrypted harddisk; usable even by non technical users.
153
* `Simple64 <http://ubuntuforums.org/showthread.php?t=266290>`_
155
A Ubuntu tool which provides a GUI to install a host of applications.
157
* `Debian-cd-ng <http://wiki.debian.org/debian-cd-ng>`_
159
*Debian-cd-ng* recommends ConfigObj for parsing the Debian-cd configuration files.
161
* `NeuroImaging in Python <http://projects.scipy.org/neuroimaging/ni/wiki>`_
163
BrainSTAT is a project with the ultimate goal to produce a
164
platform-independent python environment for the analysis of brain
167
* `Gruik <http://www.tracos.org/gruik/wiki>`_
169
Gruik is a free software network packet sniffer.
410
431
non-string value [#]_ will raise a ``TypeError`` (no type conversion is
411
432
done by validation).
413
* 'indent_type': ``' '``
434
* 'indent_type': ``' '``
415
Indentation is not significant; it can however be present in the output
416
config. Allowable values are: ``''`` (no indentation), ``' '`` (indentation
417
with spaces, fixed at four per level), or ``'\t'`` (indentation with tabs,
436
Indentation is not significant; it can however be present in the input and
437
output config. Any combination of tabs and spaces may be used: the string
438
will be repeated for each level of indentation. Typical values are: ``''``
439
(no indentation), ``' '`` (indentation with four spaces, the default),
440
``'\t'`` (indentation with one tab).
420
442
If this option is not specified, and the ConfigObj is initialised with a
421
443
dictionary, the indentation used in the output is the default one, that is,
424
446
If this option is not specified, and the ConfigObj is initialised with a
425
447
list of lines or a file, the indentation used in the first indented line is
584
If your ConfigObj is only comprised of basic data types, then you can use
585
a function from the ConfigPersist.py_ module to auto-generate your
588
See `ConfigObj for Data Persistence`_.
619
The system of configspecs can seem confusing at first, but is actually
620
quite simple and powerful. For a concrete example of how to use it, you may
621
find this blog entry helpful :
622
`Transforming Values with ConfigObj <http://www.voidspace.org.uk/python/weblog/arch_d7_2006_03_04.shtml#e257>`_.
624
There is also a module to assist in auto-generating configspecs called
625
ConfigPersist.py_. Its use is explained in `ConfigObj for Data Persistence`_.
627
The ``copy`` parameter fills in missing values from the configspec (default
628
values), *without* marking the values as defaults. It also causes comments to
629
be copied from the configspec into the config file. This allows you to use a
630
configspec to create default config files. (Normally default values aren't
631
written out by the ``write`` method.)
633
As of ConfigObj 4.3.0 you can also pass in a ConfigObj instance as your
634
configspec. This is especially useful if you need to specify the encoding of
635
your configspec file. When you read your configspec file, you *must* specify
636
``list_values=False``.
641
from configobj import ConfigObj
642
configspec = ConfigObj(configspecfilename, encoding='UTF8',
644
config = ConfigObj(filename, configspec=configspec)
760
As discussed in `Mentioning Default Values`_, you can use a configspec to
761
supply default values. These are marked in the ConfigObj instance as defaults,
762
and *not* written out by the ``write`` mode. This means that your users only
763
need to supply values that are different from the defaults.
765
This can be inconvenient if you *do* want to write out the default values,
766
for example to write out a default config file.
768
If you set ``copy=True`` when you call validate, then no values are marked as
769
defaults. In addition, all comments from the configspec are copied into
770
your ConfigObj instance. You can then call ``write`` to create your config
773
There is a limitation with this. In order to allow `String Interpolation`_ to work
774
within configspecs, ``DEFAULT`` sections are not processed by
775
validation; even in copy mode.
1410
1517
cfg.walk(transform, call_on_sections=True)
1412
{'CLIENT1key1': 'CLIENT1value1', 'CLIENT1key2': 'CLIENT1value2',
1519
ConfigObj({'CLIENT1key1': 'CLIENT1value1', 'CLIENT1key2': 'CLIENT1value2',
1413
1520
'CLIENT1key3': 'CLIENT1value3',
1414
1521
'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1',
1415
1522
'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'},
1416
1523
'CLIENT1section2': {'CLIENT1key1': 'CLIENT1value1',
1417
1524
'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3',
1418
1525
'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1',
1419
'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'}}}
1526
'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'}}})
1489
1600
If ``raise_errors=False`` (the default) then parsing will continue to the
1490
1601
end and *all* errors will be collected.
1492
In the second case a ``ConfigObjError`` is raised after parsing has stopped.
1493
The error raised has a ``config`` attribute, which is the parts of the
1494
ConfigObj that parsed successfully. It also has an attribute ``errors``, which
1495
is a list of *all* the errors raised. Each entry in the list is an instance of
1496
the appropriate error type. Each one has the following attributes (useful for
1497
delivering a sensible error message to your user) :
1603
If ``raise_errors`` is False and multiple errors are found a ``ConfigObjError``
1604
is raised. The error raised has a ``config`` attribute, which is the parts of
1605
the ConfigObj that parsed successfully. It also has an attribute ``errors``,
1606
which is a list of *all* the errors raised. Each entry in the list is an
1607
instance of the appropriate error type. Each one has the following attributes
1608
(useful for delivering a sensible error message to your user) :
1499
1610
* ``line``: the original line that caused the error.
1670
1811
sub-sections. Defaults work in the normal way in repeated sections.
1817
Because you can specify default values in your configspec, you can use
1818
ConfigObj to write out default config files for your application.
1820
However, normally values supplied from a default in a configspec are *not*
1821
written out by the ``write`` method.
1823
To do this, you need to specify ``copy=True`` when you call validate. As well
1824
as not marking values as default, all the comments in the configspec file
1825
will be copied into your ConfigObj instance.
1830
from configobj import ConfigObj
1831
from validate import Validator
1833
config = ConfigObj(configspec='default.ini')
1834
config.filename = 'new_default.ini'
1835
config.validate(vdt, copy=True)
1673
1839
Validation and Interpolation
1674
1840
----------------------------
1906
Many config files from other applications allow empty values. As of version
1907
4.3.0, ConfigObj will read these as an empty string.
1909
A new option/attribute has been added (``write_empty_values``) to allow
1910
ConfigObj to write empty strings as empty values.
1915
from configobj import ConfigObj
1920
config = ConfigObj(cfg)
1922
ConfigObj({'key': '', 'key2': ''})
1924
config.write_empty_values = True
1925
for line in config.write():
1935
The ``unrepr`` option allows you to store and retrieve the basic Python
1936
data-types using config files. It has to use a slightly different syntax to
1937
normal ConfigObj files. Unsurprisingly it uses Python syntax.
1939
This means that lists are different (they are surrounded by square brackets),
1940
and strings *must* be quoted.
1942
The types that ``unrepr`` can work with are :
1944
| strings, lists tuples
1946
| dictionaries, integers, floats
1947
| longs and complex numbers
1949
You can't store classes, types or instances.
1951
``unrepr`` uses ``repr(object)`` to write out values, so it currently *doesn't*
1952
check that you are writing valid objects. If you attempt to read an unsupported
1953
value, ConfigObj will raise a ``configobj.UnknownType`` exception.
1955
Values that are triple quoted cased. The triple quotes are removed *before*
1956
converting. This means that you can use triple quotes to write dictionaries
1957
over several lines in your config files. They won't be written like this
1960
If you are writing config files by hand, for use with ``unrepr``, you should
1961
be aware of the following differences from normal ConfigObj syntax :
1963
| List : ``['A List', 'With', 'Strings']``
1964
| Strings : ``"Must be quoted."``
1965
| Backslash : ``"The backslash must be escaped \\"``
1967
These all follow normal Python syntax.
1969
In unrepr mode *inline comments* are not saved. This is because lines are
1970
parsed using the `compiler package <http://docs.python.org/lib/compiler.html>`_
1971
which discards comments.
1973
String Interpolation
1974
====================
1740
1976
ConfigObj allows string interpolation *similar* to the way ``ConfigParser``
1742
You specify a value to be substituted by including ``%(name)s`` in the value.
1744
Interpolation checks first the 'DEFAULT' sub-section of the current section to
1745
see if ``name`` is the key to a value. ('name' is case sensitive).
1747
If it doesn't find it, next it checks the 'DEFAULT' section of the parent
1748
section, last it checks the 'DEFAULT' section of the main section.
1750
If the value specified isn't found then a ``MissingInterpolationOption`` error
1751
is raised (a subclass of ``ConfigObjError``).
1977
or ``string.Template`` work. The value of the ``interpolation`` attribute
1978
determines which style of interpolation you want to use. Valid values are
1979
"ConfigParser" or "Template" (case-insensitive, so "configparser" and
1980
"template" will also work). For backwards compatibility reasons, the value
1981
``True`` is also a valid value for the ``interpolation`` attribute, and
1982
will select ``ConfigParser``-style interpolation. At some undetermined point
1983
in the future, that default *may* change to ``Template``-style interpolation.
1985
For ``ConfigParser``-style interpolation, you specify a value to be
1986
substituted by including ``%(name)s`` in the value.
1988
For ``Template``-style interpolation, you specify a value to be substituted
1989
by including ``${cl}name{cr}`` in the value. Alternately, if 'name' is a valid
1990
Python identifier (i.e., is composed of nothing but alphanumeric characters,
1991
plus the underscore character), then the braces are optional and the value
1992
can be written as ``$name``.
1994
Note that ``ConfigParser``-style interpolation and ``Template``-style
1995
interpolation are mutually exclusive; you cannot have a configuration file
1996
that's a mix of one or the other. Pick one and stick to it. ``Template``-style
1997
interpolation is simpler to read and write by hand, and is recommended if
1998
you don't have a particular reason to use ``ConfigParser``-style.
2000
Interpolation checks first the current section to see if ``name`` is the key
2001
to a value. ('name' is case sensitive).
2003
If it doesn't find it, next it checks the 'DEFAULT' sub-section of the current
2006
If it still doesn't find it, it moves on to check the parent section and the
2007
parent section's 'DEFAULT' subsection, and so on all the way up to the main
2010
If the value specified isn't found in any of these locations, then a
2011
``MissingInterpolationOption`` error is raised (a subclass of
2012
``ConfigObjError``).
1753
2014
If it is found then the returned value is also checked for substitutions. This
1754
2015
allows you to make up compound values (for example directory paths) that use
1755
2016
more than one default value. It also means it's possible to create circular
1756
references. If after ten replacements there are still values to substitute, an
1757
``InterpolationDepthError`` is raised.
2017
references. If there are any circular references which would cause an infinite
2018
interpolation loop, an ``InterpolationLoopError`` is raised.
1759
2020
Both of these errors are subclasses of ``InterpolationError``, which is a
1760
2021
subclass of ``ConfigObjError``.
2017
Fix any bugs (and resolvable issues).
2019
Do an example for the 'walk' which removes uniform indentation in multiline
2022
When initialising a section from a ConfigObj *or* an ``OrderedDictionary``
2023
we could preserve ordering.
2025
Add an *odict* method which returns an ``OrderedDictionary``.
2278
Better support for configuration from multiple files, including tracking
2279
*where* the original file came from and writing changes to the correct
2282
Make ``newline`` an option (as well as an attribute) ?
2284
``UTF16`` encoded files, when returned as a list of lines, will have the
2285
BOM at the start of every line. Should this be removed from all but the
2288
Option to set warning type for unicode decode ? (Defaults to strict).
2290
A method to optionally remove uniform indentation from multiline values.
2291
(do as an example of using ``walk`` - along with string-escape)
2293
Should the results dictionary from validate be an ordered dictionary if
2294
`odict <http://www.voidspace.org.uk/python/odict.html>`_ is available ?
2296
Implement some of the sequence methods (which include slicing) from the
2299
Preserve line numbers of values (and possibly the original text of each value).
2033
2307
Please file any bug reports to `Michael Foord`_ or the **ConfigObj**
2034
2308
`Mailing List`_.
2036
You can't have a keyword with the same name as a section (in the same section).
2037
They are both dictionary keys, so they would overlap.
2039
Interpolation checks first the 'DEFAULT' sub-section of the current section,
2040
next it checks the 'DEFAULT' section of the parent section, last it checks the
2041
'DEFAULT' section of the main section.
2310
There is currently no way to specify the encoding of a configspec file.
2312
When using ``copy`` mode for validation, it won't copy ``DEFAULT``
2313
sections. This is so that you *can* use interpolation in configspec
2316
``validate`` doesn't report *extra* values or sections.
2318
You can't have a keyword with the same name as a section (in the same
2319
section). They are both dictionary keys - so they would overlap.
2321
ConfigObj doesn't quote and unquote values if ``list_values=False``.
2322
This means that leading or trailing whitespace in values will be lost when
2323
writing. (Unless you manually quote).
2325
Interpolation checks first the current section, then the 'DEFAULT' subsection
2326
of the current section, before moving on to the current section's parent and
2043
2329
Logically a 'DEFAULT' section should apply to all subsections of the *same
2044
parent*: this means that checking the 'DEFAULT' sub-section in the *current
2045
section* is not necessarily logical ?
2047
Does it matter that we don't support the ':' divider, which is supported by
2050
String interpolation and validation don't play well together. See
2051
`Validation and Interpolation`_.
2053
Validation is no longer done on the 'DEFAULT' section (on the root level). This
2054
allows interpolation from within your configspec - but also prevents you
2055
validating the 'DEFAULT' section.
2330
parent* - this means that checking the 'DEFAULT' subsection in the
2331
*current section* is not necessarily logical ?
2333
Does it matter that we don't support the ':' divider, which is supported
2334
by ``ConfigParser`` ?
2336
String interpolation and validation don't play well together. When
2337
validation changes type it sets the value. This will correctly fetch the
2338
value using interpolation - but then overwrite the interpolation reference.
2339
If the value is unchanged by validation (it's a string) - but other types
2061
2346
This is an abbreviated changelog showing the major releases up to version 4.
2062
2347
From version 4 it lists all releases and changes. *More* data on individual
2063
changes may be found in the source code.
2348
changes may be found in the source code or the CHANGELOG file.
2351
2007/02/04 - Version 4.4.0
2352
--------------------------
2354
Official release of 4.4.0
2357
2006/12/17 - Version 4.3.3-alpha4
2358
---------------------------------
2362
Allowed arbitrary indentation in the ``indent_type`` parameter, removed the
2363
``NUM_INDENT_SPACES`` and ``MAX_INTERPOL_DEPTH`` (a leftover) constants,
2364
added indentation tests (including another docutils workaround, sigh), updated
2369
Made the import of ``compiler`` conditional so that ``ConfigObj`` can be used
2370
with `IronPython <http://www.codeplex.com/IronPython>`_.
2373
2006/12/17 - Version 4.3.3-alpha3
2374
---------------------------------
2378
Added a missing ``self.`` in the _handle_comment method and a related test,
2379
per Sourceforge bug #1523975.
2382
2006/12/09 - Version 4.3.3-alpha2
2383
---------------------------------
2387
Changed interpolation search strategy, based on this patch by Robin Munn:
2388
http://sourceforge.net/mailarchive/message.php?msg_id=17125993
2391
2006/12/09 - Version 4.3.3-alpha1
2392
---------------------------------
2396
Added Template-style interpolation, with tests, based on this patch by
2397
Robin Munn: http://sourceforge.net/mailarchive/message.php?msg_id=17125991
2398
(awful archives, bad Sourceforge, bad).
2401
2006/06/04 - Version 4.3.2
2402
--------------------------
2404
Changed error handling, if parsing finds a single error then that error will
2405
be re-raised. That error will still have an ``errors`` and a ``config``
2408
Fixed bug where '\n' terminated files could be truncated.
2410
Bugfix in ``unrepr`` mode, it couldn't handle '#' in values. (Thanks to
2411
Philippe Normand for the report.)
2413
As a consequence of this fix, ConfigObj doesn't now keep inline comments in
2414
``unrepr`` mode. This is because the parser in the `compiler package`_
2415
doesn't keep comments. {sm;:-)}
2417
Error messages are now more useful. They tell you the number of parsing errors
2418
and the line number of the first error. (In the case of multiple errors.)
2420
Line numbers in exceptions now start at 1, not 0.
2422
Errors in ``unrepr`` mode are now handled the same way as in the normal mode.
2423
The errors stored will be an ``UnreprError``.
2426
2006/04/29 - Version 4.3.1
2427
--------------------------
2429
Added ``validate.py`` back into ``configobj.zip``. (Thanks to Stewart
2432
Updated to `validate.py`_ 0.2.2.
2434
Preserve tuples when calling the ``dict`` method. (Thanks to Gustavo Niemeyer.)
2436
Changed ``__repr__`` to return a string that contains ``ConfigObj({ ... })``.
2438
Change so that an options dictionary isn't modified by passing it to ConfigObj.
2439
(Thanks to Artarious.)
2441
Added ability to handle negative integers in ``unrepr``. (Thanks to Kevin
2445
2006/03/24 - Version 4.3.0
2446
--------------------------
2448
Moved the tests and the CHANGELOG (etc) into a separate file. This has reduced
2449
the size of ``configobj.py`` by about 40%.
2451
Added the ``unrepr`` mode to reading and writing config files. Thanks to Kevin
2452
Dangoor for this suggestion.
2454
Empty values are now valid syntax. They are read as an empty string ``''``.
2455
(``key =``, or ``key = # comment``.)
2457
``validate`` now honours the order of the configspec.
2459
Added the ``copy`` mode to validate. Thanks to Louis Cordier for this
2462
Fixed bug where files written on windows could be given ``'\r\r\n'`` line
2465
Fixed bug where last occurring comment line could be interpreted as the
2466
final comment if the last line isn't terminated.
2468
Fixed bug where nested list values would be flattened when ``write`` is
2469
called. Now sub-lists have a string representation written instead.
2471
Deprecated ``encode`` and ``decode`` methods instead.
2473
You can now pass in a ConfigObj instance as a configspec (remember to read
2474
the configspec file using ``list_values=False``).
2476
Sorted footnotes in the docs.
2065
2479
2006/02/16 - Version 4.2.0
2066
2480
--------------------------
2294
2710
ConfigObj originated in a set of functions for reading config files in the
2295
atlantibots_ project. The original functions were written by Rob McNeur...
2711
`atlantibots <http://www.voidspace.org.uk/atlantibots/>`_ project. The original
2712
functions were written by Rob McNeur.
2297
.. _atlantibots: http://www.voidspace.org.uk/atlantibots
2304
.. [#] 253 of them, at the time of writing.
2720
.. [#] 315 of them, at the time of writing.
2306
2722
.. [#] And if you discover any bugs, let us know. We'll fix them quickly.
2308
2724
.. [#] If you specify a filename that doesn't exist, ConfigObj will assume you
2309
2725
are creating a new one. See the *create_empty* and *file_error* options_.
2311
.. [#] They can be byte strings ('ordinary' strings) or Unicode.
2727
.. [#] They can be byte strings (*ordinary* strings) or Unicode.
2729
.. [#] Except we don't support the RFC822 style line continuations, nor ':' as
2313
2732
.. [#] This is a change in ConfigObj 4.2.0. Note that ConfigObj doesn't call
2314
2733
the seek method of any file like object you pass in. You may want to call
2315
2734
``file_object.seek(0)`` yourself, first.
2317
.. [#] Except we don't support the RFC822 style line continuations, nor ':' as
2320
.. [#] For a file object that will depend what mode it was opened with. You
2321
can read *and* write to a ``StringIO`` instance, but not always to a
2322
``cStringIO`` instance.
2324
2736
.. [#] A side effect of this is that it enables you to copy a ConfigObj :
2371
2780
<div align="center">
2372
<a href="http://sourceforge.net/donate/index.php?group_id=123265">
2373
<img src="http://images.sourceforge.net/images/project-support.jpg" width="88" height="32" border="0" alt="Support This Project" />
2375
<a href="http://sourceforge.net">
2376
<img src="http://sourceforge.net/sflogo.php?group_id=123265&type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" />
2379
<a href="http://www.python.org">
2380
<img src="images/powered_by_python.jpg" width="602" height="186" border="0" />
2382
<a href="http://www.opensource.org">
2383
<img src="images/osi-certified-120x100.gif" width="120" height="100" border="0" />
2384
<br /><strong>Certified Open Source</strong>
2387
<script type="text/javascript" language="JavaScript">var site="s16atlantibots"</script>
2388
<script type="text/javascript" language="JavaScript1.2" src="http://s16.sitemeter.com/js/counter.js?site=s16atlantibots"></script>
2390
<a href="http://s16.sitemeter.com/stats.asp?site=s16atlantibots">
2391
<img src="http://s16.sitemeter.com/meter.asp?site=s16atlantibots" alt="Site Meter" border=0 />
2782
<a href="http://www.python.org">
2783
<img src="images/new_python.gif" width="100" height="103" border="0"
2784
alt="Powered by Python" />
2786
<a href="http://sourceforge.net">
2787
<img src="http://sourceforge.net/sflogo.php?group_id=123265&type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" />
2789
<a href="http://www.opensource.org">
2790
<img src="images/osi-certified-120x100.gif" width="120" height="100" border="0"
2791
alt="Certified Open Source"/>
2795
<a href="http://www.voidspace.org.uk/python/index.shtml">
2796
<img src="images/pythonbanner.gif" width="468" height="60"
2797
alt="Python on Voidspace" border="0" />
2801
<a href="http://sourceforge.net/donate/index.php?group_id=123265">
2802
<img src="http://images.sourceforge.net/images/project-support.jpg" width="88" height="32" border="0" alt="Support This Project" />
2806
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
2808
<script type="text/javascript">
2809
_uacct = "UA-203625-1";
2396
2816
.. _listquote: http://www.voidspace.org.uk/python/modules.shtml#listquote