ANN: cssutils 0.9.5rc2

Christof Hoeke cthedot at
Mon Jul 14 22:34:33 CEST 2008

what is it
A Python package to parse and build CSS Cascading Style Sheets. (Not a 
renderer  though!)

main changes
There has been a **major change** in this release which may affect your 
program and may require some rewriting... There is a workaround (see 
below) but please take care. The second major change in this release is 
a quite noticable performance improvement which was more or less a side 
effect of a bugfix...

0.9.5rc2 080714
     - **API CHANGE/BUGFIX (major)**:

         Upto 0.9.5rc1 any sheet resulting from parsing via any 
``parse*`` function or ``CSSParser(raiseExceptions=False)`` (which also 
was and is the default) resulted in the library simply logging any later 
exceptions and not raising them. Until now the global setting of 
``cssutils.log.raiseExceptions=True`` (the default) was overwritten with 
the value of the CSSParser ``raiseExceptions`` setting which normally is 
``False`` any time a ``cssutils.parse*`` function or 
``CSSParser.parse*`` method was used. 0.9.5rc2 fixes this.

         until 0.9.5rc1::

             >>> # parsing does not raise errors
             >>> s = cssutils.parseString('$') # empty but CSSStyleSheet 

             >>> # using DOM methods does **not raise either** but should:
             >>> s.cssText = '$' # just logs:
             ERROR   CSSStyleRule: No start { of style declaration 
found: u'$' [1:2: ]

         from 0.9.5rc2::

             >>> # parsing STILL does not raise errors
             >>> s = cssutils.parseString('$') # empty but CSSStyleSheet 

             >>> # using DOM methods **does raise now though**
             >>> s.cssText = '$' # raises:
             xml.dom.SyntaxErr: CSSStyleRule: No start { of style 
declaration found: u'$' [1:1: $]

         To use the old but false behaviour add the following line at 
the start to your program::

             >>> cssutils.log.raiseExceptions = False # normally True

         **This should only be done in specific cases** as normal 
raising of exceptions in methods or functions with the CSS DOM is the 
expected behaviour. **This setting may also be removed in the future so 
use with care.**

     - **BUGFIX**: Parsing of @rules like ``@mediaall ...`` does not 
result in ``@media all ...`` anymore (so not a ``CSSMediaRule``) but 
parses as  ``@mediaall`` so a ``CSSUnknownRule``. The specification is 
not too clear here but it seems this is the way to go. To help finding 
typos like this probably is, for any found CSSUnknownRule (an unknown 
@rule) a WARNING is emitted now (but never an exception raised). These 
typos will most likely happen like e.g. ``@mediaall``, ``@importurl()``, 
``@namespaceprefix"uri"`` or ``@pagename:left``.

     - **BUGFIX**: Parsing of unicode escapes like ``\\abc`` followed by 
CR/LF this is now correctly combined as only a single whitespace character.

     - **BUGFIX**: Adding a malformed ``stylesheets.MediaQuery`` to a 
``stylesheets.MediaList`` does fail now, e.g.::

             >>> # invalid malformed medialist (missing comma):
             >>> sheet = cssutils.parseString('@media tv INVALID {a 
{top: 0;}}')
             ERROR   MediaQuery: Unexpected syntax. [1:11: INVALID]
             ERROR   MediaList: Invalid MediaQuery:  tv INVALID
             >>> # the actual rule exists but has default empty content, 
this may be
             changed later as it can be seen as a bug itself
             >>> sheet.cssRules[0]
             >>> sheet.cssText

             >>> # BUT: Unknown media type but as it is valid does parse:
             >>> sheet = cssutils.parseString('@media tv, UNKNOWN {a 
{top: 0;}}')
             WARNING MediaQuery: Unknown media type "UNKNOWN".
             >>> sheet.cssRules[0]
             cssutils.css.CSSMediaRule(mediaText=u'tv, UNKNOWN')
             >>> sheet.cssText
             '@media tv, UNKNOWN {\n    a {\n        top: 0\n        }\n 

     - **BUGFIX**: References to ``MediaList`` in ``CSSImportRule`` and 
``CSSMediaRule`` are kept now properly.

     - BUGFIX: Deleting a ``MediaQuery`` item from a ``MediaList`` does 
use the libs logging/raising settings instead of always raising

     - **IMPROVEMENT**: Parsing performance has been improved (by about 
25%, tested with a basic CSS of about 50 lines, so may not be 
representative but this release definitely is faster ;). The following 
changes have been done which should not impact any actual stylesheet:

         + A ``BOM`` token is recognized at the start of a stylesheet 
only (may be swallowed by the CSS codec anyway).
         + A ``BOM`` token is not counted in the line/col reporting 
anymore so the following token has a line and col of 1 now
         + Tests for tokenizing with css2productions has been removed 
but this is never used in the library anyway

     CSSValue, CSSValueList, and CSSPrimitiveValue and the relevant 
methods/properties Property.cssValue and 
CSSStyleDeclaration.getPropertyCSSValue are more or less DEPRECATED and 
will probably be replaced with interfaces defined in CSSOM. For now use 
the properties and methods that handle values as simple strings, e.g. 
``Property.value``. As the aforementioned classes are not hardly that 
useful anyway this should not be a big problem but please beware if you 
use or have used them.

     If you think this a bad idea please let me know!

cssutils is published under the LGPL version 3 or later, see

If you have other licensing needs please let me know.

For download options see

cssutils needs Python 2.4 or higher (tested with Python 2.5.2 on Vista only)

Bug reports (via Google code), comments, etc are very much appreciated! 


More information about the Python-announce-list mailing list