lxml 3.0 final released - efficient XML and HTML processing with Python

Stefan Behnel stefan_ml at behnel.de
Wed Oct 10 07:18:53 CEST 2012


Hi everyone,

it's been a while since the last stable release series appeared, so I'm
proud to announce the final release of lxml 3.0.

http://lxml.de/

http://pypi.python.org/pypi/lxml/3.0

In short, lxml is the most feature-rich and easy-to-use library for
processing XML and HTML in the Python language. It's also very fast, in
case you're interested in that. It runs on Python 2.4 - 3.3.

The 3.0 release features initial support for PyPy and a new tree API for
DTDs (by Walter Dörwald), as well as some major cleanups in the code base.
The lxml.cssselect package was moved into a separate PyPI project nicely
extended and maintained by Simon Sapin.

Originally, this release was targeted as lxml 2.4, but some major
improvements as well as a couple of potentially incompatible changes make
"3.0" appear more appropriate.

This release was built using Cython 0.17.1. Development on lxml's sources
now requires this version. Note that the build no longer uses Cython, even
if it is installed. Recompilation of the sources has to be requested
explicitly with the setup.py option "--with-cython".

If you are interested in commercial support or customisations for the lxml
package, please contact me directly.

Have fun,

Stefan


3.0 (2012-10-08)
================

Features added
--------------

Bugs fixed
----------

* End-of-file handling was incorrect in iterparse() when reading from
  a low-level C file stream and failed in libxml2 2.9.0 due to its
  improved consistency checks.

Other changes
-------------

* The build no longer uses Cython by default unless the generated C files
  are missing.  To use Cython, pass the option "--with-cython".  To ignore
  the fatal build error when Cython is required but not available (e.g. to
  run special setup.py commands that do not actually run a build), pass
  "--without-cython".


3.0beta1 (2012-09-26)
=====================

Features added
--------------

* Python level access to (optional) libxml2 memory debugging features
  to simplify debugging of memory leaks etc.

Bugs fixed
----------

* Fix a memory leak in XPath by switching to Cython 0.17.1.

* Some tests were adapted to work with PyPy.

Other changes
-------------

* The code was adapted to work with the upcoming libxml2 2.9.0 release.


3.0alpha2 (2012-08-23)
======================

Features added
--------------

* The .iter() method of elements now accepts tag arguments like "{*}name"
  to search for elements with a given local name in any namespace.  With
  this addition, all combinations of wildcards now work as expected:
  "{ns}name", "{}name", "{*}name", "{ns}*", "{}*" and "{*}*".  Note that
  "name" is equivalent to "{}name", but "*" is "{*}*".  The same change
  applies to the .getiterator(), .itersiblings(), .iterancestors(),
  .iterdescendants(), .iterchildren() and .itertext() methods,  the
  strip_attributes(), strip_elements() and strip_tags() functions as well
  as the iterparse() function.

* C14N allows specifying the inclusive prefixes to be promoted to
  top-level during exclusive serialisation.

Bugs fixed
----------

* Passing long Unicode strings into the feed() parser interface failed to
  read the entire string.

Other changes
-------------


3.0alpha1 (2012-07-31)
======================

Features added
--------------

* Initial support for building in PyPy (through cpyext).

* DTD objects gained an API that allows read access to their
  declarations.

* xpathgrep.py gained support for parsing line-by-line (e.g.
  from grep output) and for surrounding the output with a new root
  tag.

* E-factory in lxml.builder accepts subtypes of known data
  types (such as string subtypes) when building elements around them.

* Tree iteration and iterparse() with a selective tag
  argument supports passing a set of tags.  Tree nodes will be
  returned by the iterators if they match any of the tags.

Bugs fixed
----------

* The .find*() methods in lxml.objectify no longer use XPath
  internally, which makes them faster in many cases (especially when
  short circuiting after a single or couple of elements) and fixes
  some behavioural differences compared to lxml.etree.  Note that
  this means that they no longer support arbitrary XPath expressions
  but only the subset that the ElementPath language supports.
  The previous implementation was also redundant with the normal
  XPath support, which can be used as a replacement.

* el.find('*') could accidentally return a comment or processing
  instruction that happened to be in the wrong spot.  (Same for the
  other .find*() methods.)

* The error logging is less intrusive and avoids a global setup where
  possible.

* Fixed undefined names in html5lib parser.

* xpathgrep.py did not work in Python 3.

* Element.attrib.update() did not accept an attrib of
  another Element as parameter.

* For subtypes of ElementBase that make the .text or .tail
  properties immutable (as in objectify, for example), inserting text
  when creating Elements through the E-Factory feature of the class
  constructor would fail with an exception, stating that the text
  cannot be modified.

Other changes
--------------

* The code base was overhauled to properly use 'const' where the API
  of libxml2 and libxslt requests it.  This also has an impact on the
  public C-API of lxml itself, as defined in etreepublic.pxd, as
  well as the provided declarations in the lxml/includes/ directory.
  Code that uses these declarations may have to be adapted.  On the
  plus side, this fixes several C compiler warnings, also for user
  code, thus making it easier to spot real problems again.

* The functionality of "lxml.cssselect" was moved into a separate PyPI
  package called "cssselect".  To continue using it, you must install
  that package separately.  The "lxml.cssselect" module is still
  available and provides the same interface, provided the "cssselect"
  package can be imported at runtime.

* Element attributes passed in as an attrib dict or as keyword
  arguments are now sorted by (namespaced) name before being created
  to make their order predictable for serialisation and iteration.
  Note that adding or deleting attributes afterwards does not take
  that order into account, i.e. setting a new attribute appends it
  after the existing ones.

* Several classes that are for internal use only were removed
  from the lxml.etree module dict:
  _InputDocument, _ResolverRegistry, _ResolverContext, _BaseContext,
  _ExsltRegExp, _IterparseContext, _TempStore, _ExceptionContext,
  __ContentOnlyElement, _AttribIterator, _NamespaceRegistry,
  _ClassNamespaceRegistry, _FunctionNamespaceRegistry,
  _XPathFunctionNamespaceRegistry, _ParserDictionaryContext,
  _FileReaderContext, _ParserContext, _PythonSaxParserTarget,
  _TargetParserContext, _ReadOnlyProxy, _ReadOnlyPIProxy,
  _ReadOnlyEntityProxy, _ReadOnlyElementProxy, _OpaqueNodeWrapper,
  _OpaqueDocumentWrapper, _ModifyContentOnlyProxy,
  _ModifyContentOnlyPIProxy, _ModifyContentOnlyEntityProxy,
  _AppendOnlyElementProxy, _SaxParserContext, _FilelikeWriter,
  _ParserSchemaValidationContext, _XPathContext,
  _XSLTResolverContext, _XSLTContext, _XSLTQuotedStringParam

* Several internal classes can no longer be inherited from:
  _InputDocument, _ResolverRegistry, _ExsltRegExp, _ElementUnicodeResult,
  _IterparseContext, _TempStore, _AttribIterator, _ClassNamespaceRegistry,
  _XPathFunctionNamespaceRegistry, _ParserDictionaryContext,
  _FileReaderContext, _PythonSaxParserTarget, _TargetParserContext,
  _ReadOnlyPIProxy, _ReadOnlyEntityProxy, _OpaqueDocumentWrapper,
  _ModifyContentOnlyPIProxy, _ModifyContentOnlyEntityProxy,
  _AppendOnlyElementProxy, _FilelikeWriter, _ParserSchemaValidationContext,
  _XPathContext, _XSLTResolverContext, _XSLTContext,
  _XSLTQuotedStringParam, _XSLTResultTree, _XSLTProcessingInstruction


More information about the Python-announce-list mailing list