From scoder at codespeak.net Wed Nov 1 12:54:44 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 1 Nov 2006 12:54:44 +0100 (CET)
Subject: [Lxml-checkins] r34004 - lxml/trunk
Message-ID: <20061101115444.EBED910060@code0.codespeak.net>
Author: scoder
Date: Wed Nov 1 12:54:43 2006
New Revision: 34004
Modified:
lxml/trunk/setup.py
Log:
download URL
Modified: lxml/trunk/setup.py
==============================================================================
--- lxml/trunk/setup.py (original)
+++ lxml/trunk/setup.py Wed Nov 1 12:54:43 2006
@@ -185,6 +185,7 @@
maintainer="lxml dev team",
maintainer_email="lxml-dev at codespeak.net",
url="http://codespeak.net/lxml",
+ download_url="http://cheeseshop.python.org/packages/source/l/lxml/lxml-%s.tar.gz" % version,
description="Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.",
From scoder at codespeak.net Wed Nov 1 12:55:30 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 1 Nov 2006 12:55:30 +0100 (CET)
Subject: [Lxml-checkins] r34005 - lxml/branch/lxml-1.1
Message-ID: <20061101115530.3693810060@code0.codespeak.net>
Author: scoder
Date: Wed Nov 1 12:55:29 2006
New Revision: 34005
Modified:
lxml/branch/lxml-1.1/setup.py
Log:
download URL
Modified: lxml/branch/lxml-1.1/setup.py
==============================================================================
--- lxml/branch/lxml-1.1/setup.py (original)
+++ lxml/branch/lxml-1.1/setup.py Wed Nov 1 12:55:29 2006
@@ -185,6 +185,7 @@
maintainer="lxml dev team",
maintainer_email="lxml-dev at codespeak.net",
url="http://codespeak.net/lxml",
+ download_url="http://cheeseshop.python.org/packages/source/l/lxml/lxml-%s.tar.gz" % version,
description="Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.",
From scoder at codespeak.net Wed Nov 1 15:30:20 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 1 Nov 2006 15:30:20 +0100 (CET)
Subject: [Lxml-checkins] r34028 - lxml/trunk/src/lxml/tests
Message-ID: <20061101143020.3151F10077@code0.codespeak.net>
Author: scoder
Date: Wed Nov 1 15:30:18 2006
New Revision: 34028
Modified:
lxml/trunk/src/lxml/tests/test_xslt.py
Log:
disabled XSLT test for missing parameter for now, doesn't seem to be reliable
Modified: lxml/trunk/src/lxml/tests/test_xslt.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_xslt.py (original)
+++ lxml/trunk/src/lxml/tests/test_xslt.py Wed Nov 1 15:30:18 2006
@@ -205,7 +205,8 @@
''',
st.tostring(res))
- def test_xslt_parameter_missing(self):
+ def _test_xslt_parameter_missing(self):
+ # DISABLED - NOT RELIABLE?
# apply() without needed parameter will lead to XSLTApplyError
tree = self.parse('BC')
style = self.parse('''\
From scoder at codespeak.net Wed Nov 1 15:30:42 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 1 Nov 2006 15:30:42 +0100 (CET)
Subject: [Lxml-checkins] r34029 - lxml/branch/lxml-1.1/src/lxml/tests
Message-ID: <20061101143042.70C2610077@code0.codespeak.net>
Author: scoder
Date: Wed Nov 1 15:30:41 2006
New Revision: 34029
Modified:
lxml/branch/lxml-1.1/src/lxml/tests/test_xslt.py
Log:
disabled XSLT test for missing parameter for now, doesn't seem to be reliable
Modified: lxml/branch/lxml-1.1/src/lxml/tests/test_xslt.py
==============================================================================
--- lxml/branch/lxml-1.1/src/lxml/tests/test_xslt.py (original)
+++ lxml/branch/lxml-1.1/src/lxml/tests/test_xslt.py Wed Nov 1 15:30:41 2006
@@ -205,7 +205,8 @@
''',
st.tostring(res))
- def test_xslt_parameter_missing(self):
+ def _test_xslt_parameter_missing(self):
+ # DISABLED - NOT RELIABLE?
# apply() without needed parameter will lead to XSLTApplyError
tree = self.parse('BC')
style = self.parse('''\
From scoder at codespeak.net Wed Nov 1 15:46:30 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 1 Nov 2006 15:46:30 +0100 (CET)
Subject: [Lxml-checkins] r34031 - lxml/trunk/src/lxml
Message-ID: <20061101144630.C63C110063@code0.codespeak.net>
Author: scoder
Date: Wed Nov 1 15:46:29 2006
New Revision: 34031
Modified:
lxml/trunk/src/lxml/etree.pyx
Log:
likely more tolerant way to parse libxml2 version
Modified: lxml/trunk/src/lxml/etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/etree.pyx (original)
+++ lxml/trunk/src/lxml/etree.pyx Wed Nov 1 15:46:29 2006
@@ -149,8 +149,9 @@
cdef int _LIBXML_VERSION_INT
try:
- _LIBXML_VERSION_INT = int((tree.xmlParserVersion).split('-')[0])
+ _LIBXML_VERSION_INT = int(re.match('[0-9]+', tree.xmlParserVersion).group(0))
except Exception:
+ print "Unknown libxml2 version:", tree.xmlParserVersion
_LIBXML_VERSION_INT = 0
LIBXML_VERSION = __unpackIntVersion(_LIBXML_VERSION_INT)
From scoder at codespeak.net Wed Nov 1 15:46:54 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 1 Nov 2006 15:46:54 +0100 (CET)
Subject: [Lxml-checkins] r34032 - lxml/branch/lxml-1.1/src/lxml
Message-ID: <20061101144654.A905410063@code0.codespeak.net>
Author: scoder
Date: Wed Nov 1 15:46:53 2006
New Revision: 34032
Modified:
lxml/branch/lxml-1.1/src/lxml/etree.pyx
Log:
likely more tolerant way to parse libxml2 version
Modified: lxml/branch/lxml-1.1/src/lxml/etree.pyx
==============================================================================
--- lxml/branch/lxml-1.1/src/lxml/etree.pyx (original)
+++ lxml/branch/lxml-1.1/src/lxml/etree.pyx Wed Nov 1 15:46:53 2006
@@ -149,8 +149,9 @@
cdef int _LIBXML_VERSION_INT
try:
- _LIBXML_VERSION_INT = int((tree.xmlParserVersion).split('-')[0])
+ _LIBXML_VERSION_INT = int(re.match('[0-9]+', tree.xmlParserVersion).group(0))
except Exception:
+ print "Unknown libxml2 version:", tree.xmlParserVersion
_LIBXML_VERSION_INT = 0
LIBXML_VERSION = __unpackIntVersion(_LIBXML_VERSION_INT)
From scoder at codespeak.net Thu Nov 2 20:54:46 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Thu, 2 Nov 2006 20:54:46 +0100 (CET)
Subject: [Lxml-checkins] r34075 - lxml/trunk/src/lxml
Message-ID: <20061102195446.7320710072@code0.codespeak.net>
Author: scoder
Date: Thu Nov 2 20:54:44 2006
New Revision: 34075
Modified:
lxml/trunk/src/lxml/xslt.pxi
Log:
small optimisations
Modified: lxml/trunk/src/lxml/xslt.pxi
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxi (original)
+++ lxml/trunk/src/lxml/xslt.pxi Thu Nov 2 20:54:44 2006
@@ -450,7 +450,7 @@
return _xsltResultTreeFactory(result_doc, self, profile_doc)
def apply(self, _input, profile_run=False, **_kw):
- return self.__call__(_input, profile_run, **_kw)
+ return self(_input, profile_run, **_kw)
def tostring(self, _ElementTree result_tree):
"""Save result doc to string based on stylesheet output method.
@@ -507,7 +507,7 @@
"""Return an ElementTree with profiling data for the stylesheet run.
"""
def __get__(self):
- cdef _Element root
+ cdef object root
if self._profile is None:
return None
root = self._profile.getroot()
From scoder at codespeak.net Sun Nov 5 14:31:04 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Sun, 5 Nov 2006 14:31:04 +0100 (CET)
Subject: [Lxml-checkins] r34237 - lxml/trunk/doc
Message-ID: <20061105133104.3E93710079@code0.codespeak.net>
Author: scoder
Date: Sun Nov 5 14:31:02 2006
New Revision: 34237
Modified:
lxml/trunk/doc/FAQ.txt
Log:
FAQ entry on binary distributions
Modified: lxml/trunk/doc/FAQ.txt
==============================================================================
--- lxml/trunk/doc/FAQ.txt (original)
+++ lxml/trunk/doc/FAQ.txt Sun Nov 5 14:31:02 2006
@@ -12,8 +12,10 @@
1 General Questions
1.1 Is there a tutorial?
1.2 Where can I find more documentation about lxml?
- 1.3 Why is my application so slow?
- 1.4 Why do I get errors about missing UCS4 symbols when installing lxml?
+ 1.3 Where are the Windows binaries?
+ 1.4 What is the difference between lxml.etree and lxml.objectify?
+ 1.5 Why is my application so slow?
+ 1.6 Why do I get errors about missing UCS4 symbols when installing lxml?
2 Bugs
2.1 My application crashes! Why does lxml.etree do that?
2.2 I think I have found a bug in lxml. What should I do?
@@ -30,9 +32,6 @@
5.2 Why doesn't ``findall()`` support full XPath expressions?
5.3 How can I find out which namespace prefixes are used in a document?
5.4 How can I specify a default namespace for XPath expressions?
- 6 lxml.objectify
- 6.1 What is the difference between lxml.etree and lxml.objectify?
- 6.2 Is there a way to speed up frequent element access?
General Questions
@@ -64,6 +63,32 @@
.. _`the web page`: http://codespeak.net/lxml/#documentation
+Where are the Windows binaries?
+-------------------------------
+
+Short answer: If you want to contribute a binary build, we are happy to put it
+up on the Cheeseshop.
+
+Long answer: Two of the bigger problems with the Windows system are the lack
+of a pre-installed standard compiler and the missing package management. Both
+make it non-trivial to build lxml on this platform. We are trying hard to
+make lxml as platform-independent as possible and it is regularly tested on
+Windows systems. However, we currently cannot provide Windows binaries
+distributions ourselves.
+
+From time to time, users of different environments kindly contribute binary
+builds of lxml, most frequently for Windows or Mac-OS X. We put these on the
+Cheeseshop to make it as easy as possible for others to use lxml on their
+platform.
+
+If there is not currently a binary distribution of the most recent lxml
+release for your platform available from the Cheeseshop, please look through
+the older versions to see if they provide a binary build. This is done by
+appending the version number to the cheeseshop URL, e.g.:
+
+ http://cheeseshop.python.org/pypi/lxml/1.1.2
+
+
What is the difference between lxml.etree and lxml.objectify?
-------------------------------------------------------------
From scoder at codespeak.net Sun Nov 5 14:31:36 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Sun, 5 Nov 2006 14:31:36 +0100 (CET)
Subject: [Lxml-checkins] r34238 - lxml/branch/lxml-1.1/doc
Message-ID: <20061105133136.D1A051007D@code0.codespeak.net>
Author: scoder
Date: Sun Nov 5 14:31:35 2006
New Revision: 34238
Modified:
lxml/branch/lxml-1.1/doc/FAQ.txt
Log:
FAQ entry on binary distributions
Modified: lxml/branch/lxml-1.1/doc/FAQ.txt
==============================================================================
--- lxml/branch/lxml-1.1/doc/FAQ.txt (original)
+++ lxml/branch/lxml-1.1/doc/FAQ.txt Sun Nov 5 14:31:35 2006
@@ -12,8 +12,10 @@
1 General Questions
1.1 Is there a tutorial?
1.2 Where can I find more documentation about lxml?
- 1.3 Why is my application so slow?
- 1.4 Why do I get errors about missing UCS4 symbols when installing lxml?
+ 1.3 Where are the Windows binaries?
+ 1.4 What is the difference between lxml.etree and lxml.objectify?
+ 1.5 Why is my application so slow?
+ 1.6 Why do I get errors about missing UCS4 symbols when installing lxml?
2 Bugs
2.1 My application crashes! Why does lxml.etree do that?
2.2 I think I have found a bug in lxml. What should I do?
@@ -30,9 +32,6 @@
5.2 Why doesn't ``findall()`` support full XPath expressions?
5.3 How can I find out which namespace prefixes are used in a document?
5.4 How can I specify a default namespace for XPath expressions?
- 6 lxml.objectify
- 6.1 What is the difference between lxml.etree and lxml.objectify?
- 6.2 Is there a way to speed up frequent element access?
General Questions
@@ -64,6 +63,32 @@
.. _`the web page`: http://codespeak.net/lxml/#documentation
+Where are the Windows binaries?
+-------------------------------
+
+Short answer: If you want to contribute a binary build, we are happy to put it
+up on the Cheeseshop.
+
+Long answer: Two of the bigger problems with the Windows system are the lack
+of a pre-installed standard compiler and the missing package management. Both
+make it non-trivial to build lxml on this platform. We are trying hard to
+make lxml as platform-independent as possible and it is regularly tested on
+Windows systems. However, we currently cannot provide Windows binaries
+distributions ourselves.
+
+From time to time, users of different environments kindly contribute binary
+builds of lxml, most frequently for Windows or Mac-OS X. We put these on the
+Cheeseshop to make it as easy as possible for others to use lxml on their
+platform.
+
+If there is not currently a binary distribution of the most recent lxml
+release for your platform available from the Cheeseshop, please look through
+the older versions to see if they provide a binary build. This is done by
+appending the version number to the cheeseshop URL, e.g.:
+
+ http://cheeseshop.python.org/pypi/lxml/1.1.2
+
+
What is the difference between lxml.etree and lxml.objectify?
-------------------------------------------------------------
From scoder at codespeak.net Tue Nov 21 08:51:24 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Tue, 21 Nov 2006 08:51:24 +0100 (CET)
Subject: [Lxml-checkins] r34818 - lxml/trunk
Message-ID: <20061121075124.1C66C1006F@code0.codespeak.net>
Author: scoder
Date: Tue Nov 21 08:51:21 2006
New Revision: 34818
Modified:
lxml/trunk/setup.py
Log:
better handling of -lxslt -> -lexslt addition
Modified: lxml/trunk/setup.py
==============================================================================
--- lxml/trunk/setup.py (original)
+++ lxml/trunk/setup.py Tue Nov 21 08:51:21 2006
@@ -56,6 +56,18 @@
wf, rf, ef = os.popen3(cmd)
return rf.read().split()
+def add_libexslt(lib_flags):
+ if '-lxslt' in lib_flags:
+ xslt, exslt = '-lxslt', '-lexslt'
+ else:
+ xslt, exslt = 'xslt', 'exslt'
+ for i, libname in enumerate(lib_flags):
+ if exslt in libname:
+ return
+ if xslt in libname:
+ lib_flags.insert(i, libname.replace(xslt, exslt))
+ return
+
def fix_alphabeta(version, alphabeta):
if '.'+alphabeta in version:
return version
@@ -116,13 +128,7 @@
else:
cflags = flags('xslt-config --cflags')
xslt_libs = flags('xslt-config --libs')
- # compile also against libexslt!
- for i, libname in enumerate(xslt_libs):
- if 'exslt' in libname:
- break
- if 'xslt' in libname:
- xslt_libs.insert(i, libname.replace('xslt', 'exslt'))
- break
+ add_libexslt(xslt_libs) # compile also against libexslt!
if '--rpath' in sys.argv:
# compile with --rpath under gcc
From faassen at codespeak.net Wed Nov 22 15:20:58 2006
From: faassen at codespeak.net (faassen at codespeak.net)
Date: Wed, 22 Nov 2006 15:20:58 +0100 (CET)
Subject: [Lxml-checkins] r34860 - in lxml/trunk: . doc
Message-ID: <20061122142058.CE92210061@code0.codespeak.net>
Author: faassen
Date: Wed Nov 22 15:20:56 2006
New Revision: 34860
Added:
lxml/trunk/setupinfo.py
lxml/trunk/versioninfo.py
Modified:
lxml/trunk/doc/build.txt
lxml/trunk/setup.py
Log:
Refactored setup.py into multiple files to be more readable and hackable.
Modified: lxml/trunk/doc/build.txt
==============================================================================
--- lxml/trunk/doc/build.txt (original)
+++ lxml/trunk/doc/build.txt Wed Nov 22 15:20:56 2006
@@ -186,38 +186,29 @@
zlib-1.2.3.win32/
zlib-1.2.3.win32.zip
-Go to the lxml-1.0.0 directory and edit the file ``setup.py``. There should
+Go to the lxml directory and edit the file ``setup.py``. There should
be a section near the top that looks like this::
- def setupStaticBuild():
- cflags = [
- ]
- xslt_libs = [
- ]
- result = (cflags, xslt_libs)
- # return result
- raise NotImplementedError, \
- "Static build not configured, see doc/build.txt"
+ STATIC_LIBS = []
+ STATIC_CFLAGS = []
Change this section to something like this, but take care to use the correct
version numbers::
- def setupStaticBuild():
- cflags = [
- "-I..\\libxml2-2.6.23.win32\\include ",
- "-I..\\libxslt-1.1.15.win32\\include",
- "-I..\\zlib-1.2.3.win32\\include",
- "-I..\\iconv-1.9.1.win32\\include"
- ]
- xslt_libs = [
+ STATIC_LIBS = [
"..\\libxml2-2.6.23.win32\\lib\\libxml2_a.lib",
"..\\libxslt-1.1.15.win32\\lib\\libxslt_a.lib",
"..\\libxslt-1.1.15.win32\\lib\\libexslt_a.lib",
"..\\zlib-1.2.3.win32\\lib\\zlib.lib",
"..\\iconv-1.9.1.win32\\lib\\iconv_a.lib"
]
- result = (cflags, xslt_libs)
- return result
+
+ STATIC_CFLAGS = [
+ "-I..\\libxml2-2.6.23.win32\\include ",
+ "-I..\\libxslt-1.1.15.win32\\include",
+ "-I..\\zlib-1.2.3.win32\\include",
+ "-I..\\iconv-1.9.1.win32\\include"
+ ]
The ``_a`` part of the library names means that we are linking statically
against the named library files. If you want to use dynamic libraries, you
Modified: lxml/trunk/setup.py
==============================================================================
--- lxml/trunk/setup.py (original)
+++ lxml/trunk/setup.py Wed Nov 22 15:20:56 2006
@@ -1,201 +1,31 @@
-import sys, os, os.path, re
-
-EXT_MODULES = [
- ("etree", "lxml.etree"),
- ("objectify", "lxml.objectify")
- ]
-
-setup_args = {}
-ext_args = {}
-DEFINES = []
-
-try:
- from setuptools import setup
- from setuptools.extension import Extension
- # prevent setuptools from making local etree.so copies:
- setup_args['zip_safe'] = False
-except ImportError:
- from distutils.core import setup
- from distutils.extension import Extension
-
-# This is called if the '--static' option is passed
-def setupStaticBuild():
- "See doc/build.txt to make this work."
- cflags = [
- ]
- xslt_libs = [
- ]
- result = (cflags, xslt_libs)
- # return result
- raise NotImplementedError, \
- "Static build not configured, see doc/build.txt"
-
-# This is called if the '--rpath' option is passed
-def setupRpathBuild(xslt_libs, ext_args):
- libdirs = []
- libs = []
- libflags = []
- rpathdirs = []
- for option in xslt_libs:
- content = option[2:]
- if option.startswith('-L'):
- if not content.startswith('/usr'):
- rpathdirs.append(content)
- libdirs.append(content)
- elif option.startswith('-l'):
- libs.append(content)
- else:
- libflags.append(option)
-
- ext_args['libraries'] = libs
- ext_args['library_dirs'] = libdirs
- ext_args['extra_link_args'] = libflags
- ext_args['runtime_library_dirs'] = rpathdirs
-
-def flags(cmd):
- wf, rf, ef = os.popen3(cmd)
- return rf.read().split()
-
-def add_libexslt(lib_flags):
- if '-lxslt' in lib_flags:
- xslt, exslt = '-lxslt', '-lexslt'
- else:
- xslt, exslt = 'xslt', 'exslt'
- for i, libname in enumerate(lib_flags):
- if exslt in libname:
- return
- if xslt in libname:
- lib_flags.insert(i, libname.replace(xslt, exslt))
- return
-
-def fix_alphabeta(version, alphabeta):
- if '.'+alphabeta in version:
- return version
- return version.replace(alphabeta, '.'+alphabeta)
-
-# determine version number and create lxml-version.h
-
-src_dir = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))
-version = open(os.path.join(src_dir, 'version.txt')).read().strip()
-branch_version = version[:3]
-
-try:
- svn_entries = open(os.path.join(src_dir, '.svn', 'entries')).read()
-except IOError:
- svn_version = version
-else:
- revision = re.search(']*name=""[^>]*revision="([^"]+)"',
- svn_entries).group(1)
- svn_version = version + '-' + revision
-
-if 'dev' in version:
- svn_version = fix_alphabeta(svn_version, 'dev')
- dev_status = 'Development Status :: 3 - Alpha'
-elif 'alpha' in version:
- svn_version = fix_alphabeta(svn_version, 'alpha')
- dev_status = 'Development Status :: 3 - Alpha'
-elif 'beta' in version:
- svn_version = fix_alphabeta(svn_version, 'beta')
- dev_status = 'Development Status :: 4 - Beta'
-else:
- dev_status = 'Development Status :: 5 - Production/Stable'
-
-version_h = open(os.path.join(src_dir, 'src', 'lxml', 'lxml-version.h'), 'w')
-version_h.write('''\
-#ifndef LXML_VERSION_STRING
-#define LXML_VERSION_STRING "%s"
-#endif
-''' % svn_version)
-version_h.close()
-
+from setuptools import setup
+import versioninfo
+import setupinfo
+
+# override these and pass --static for a static build. See
+# doc/build.txt for more information. If you do not pass --static
+# changing this will have no effect.
+STATIC_LIBS = []
+STATIC_CFLAGS = []
+
+# create lxml-version.h file
+svn_version = versioninfo.svn_version()
+versioninfo.create_version_h(svn_version)
print "Building lxml version", svn_version
-# setup etree extension building
-
-try:
- from Pyrex.Distutils import build_ext as build_pyx
- source_extension = ".pyx"
- setup_args['cmdclass'] = {'build_ext' : build_pyx}
-except ImportError:
- print "*NOTE*: Trying to build without Pyrex, needs pre-generated 'src/lxml/etree.c' !"
- source_extension = ".c"
-
-if '--static' in sys.argv:
- # use the static setup as configured in setupStaticBuild
- sys.argv.remove('--static')
- cflags, xslt_libs = setupStaticBuild()
- ext_args['extra_link_args'] = xslt_libs
-else:
- cflags = flags('xslt-config --cflags')
- xslt_libs = flags('xslt-config --libs')
- add_libexslt(xslt_libs) # compile also against libexslt!
-
- if '--rpath' in sys.argv:
- # compile with --rpath under gcc
- sys.argv.remove('--rpath')
- setupRpathBuild(xslt_libs, ext_args)
- else:
- ext_args['extra_link_args'] = xslt_libs
-
-try:
- sys.argv.remove('--without-assert')
- DEFINES.append( ('PYREX_WITHOUT_ASSERTIONS', None) )
-except ValueError:
- pass
-
-if '--debug-gcc' in sys.argv:
- sys.argv.remove('--debug-gcc')
- cflags.append('-g2')
-
-ext_modules = []
-
-for module, package in EXT_MODULES:
- ext_modules.append(
- Extension(
- package,
- sources = ["src/lxml/" + module + source_extension],
- extra_compile_args = ['-w'] + cflags,
- define_macros = DEFINES,
- **ext_args
- ))
-
-# setup ChangeLog entry
-
-changelog_text = ""
-try:
- changelog = open(os.path.join(src_dir, "CHANGES.txt"), 'r')
-except:
- print "*NOTE*: couldn't open CHANGES.txt !"
-else:
- changelog_lines = []
- for line in changelog:
- if line.startswith('====='):
- if len(changelog_lines) > 1:
- break
- if changelog_lines:
- changelog_lines.append(line)
- elif line.startswith(version):
- changelog_lines.append(line)
-
- if changelog_lines:
- changelog_text = ''.join(changelog_lines[:-1])
-
- changelog.close()
-
-
setup(
name = "lxml",
- version = version,
+ version = versioninfo.version(),
author="lxml dev team",
author_email="lxml-dev at codespeak.net",
maintainer="lxml dev team",
maintainer_email="lxml-dev at codespeak.net",
url="http://codespeak.net/lxml",
- download_url="http://cheeseshop.python.org/packages/source/l/lxml/lxml-%s.tar.gz" % version,
+ download_url="http://cheeseshop.python.org/packages/source/l/lxml/lxml-%s.tar.gz" % versioninfo.version(),
description="Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.",
- long_description="""\
+ long_description=(("""\
lxml is a Pythonic binding for the libxml2 and libxslt libraries. It provides
safe and convenient access to these libraries using the ElementTree API.
@@ -213,10 +43,10 @@
version from
http://codespeak.net/svn/lxml/branch/lxml-%(branch_version)s#egg=lxml-%(branch_version)sbugfix
-""" % {"branch_version":branch_version} + changelog_text,
-
+""" % { "branch_version" : versioninfo.branch_version() }) +
+ versioninfo.changes()),
classifiers = [
- dev_status,
+ versioninfo.dev_status(),
'Intended Audience :: Developers',
'Intended Audience :: Information Technology',
'License :: OSI Approved :: BSD License',
@@ -229,6 +59,7 @@
package_dir = {'': 'src'},
packages = ['lxml'],
- ext_modules = ext_modules,
- **setup_args
+ zip_safe = False,
+ ext_modules = setupinfo.ext_modules(STATIC_LIBS, STATIC_CFLAGS),
+ **setupinfo.extra_setup_args()
)
Added: lxml/trunk/setupinfo.py
==============================================================================
--- (empty file)
+++ lxml/trunk/setupinfo.py Wed Nov 22 15:20:56 2006
@@ -0,0 +1,123 @@
+import sys, os
+from setuptools.extension import Extension
+
+try:
+ from Pyrex.Distutils import build_ext as build_pyx
+ PYREX_INSTALLED = True
+except ImportError:
+ PYREX_INSTALLED = False
+
+EXT_MODULES = [
+ ("etree", "lxml.etree"),
+ ("objectify", "lxml.objectify")
+ ]
+
+def ext_modules(static_libs, static_cflags):
+ if PYREX_INSTALLED:
+ source_extension = ".pyx"
+ else:
+ print ("NOTE: Trying to build without Pyrex, pre-generated "
+ "'src/lxml/etree.c' needs to be available.")
+ source_extension = ".c"
+
+ result = []
+ _ext_args = ext_args(static_libs)
+ _cflags = cflags(static_cflags)
+ _define_macros = define_macros()
+ for module, package in EXT_MODULES:
+ result.append(
+ Extension(
+ package,
+ sources = ["src/lxml/" + module + source_extension],
+ extra_compile_args = ['-w'] + _cflags,
+ define_macros = _define_macros,
+ **_ext_args
+ ))
+ return result
+
+def extra_setup_args():
+ result = {}
+ if PYREX_INSTALLED:
+ result['cmdclass'] = {'build_ext': build_pyx}
+ return result
+
+def cflags(static_cflags):
+ if OPTION_STATIC:
+ assert static_cflags, "Static build not configured, see doc/build.txt"
+ result = static_cflags
+ else:
+ result = flags('xslt-config --cflags')
+ if OPTION_DEBUG_GCC:
+ result.append('-g2')
+ return result
+
+def define_macros():
+ if OPTION_WITHOUT_ASSERT:
+ return [('PYREX_WITHOUT_ASSERTIONS', None)]
+ return []
+
+def ext_args(static_libs):
+ if OPTION_STATIC:
+ assert static_libs, "Static build not configured, see doc/build.txt"
+ return {'extra_link_args': static_libs}
+
+ xslt_libs = flags('xslt-config --libs')
+ add_libexslt(xslt_libs)
+
+ if OPTION_RPATH:
+ return ext_args_rpath(xslt_libs)
+ else:
+ return {'extra_link_args': xslt_libs}
+
+def flags(cmd):
+ wf, rf, ef = os.popen3(cmd)
+ return rf.read().split()
+
+def add_libexslt(lib_flags):
+ if '-lxslt' in lib_flags:
+ xslt, exslt = '-lxslt', '-lexslt'
+ else:
+ xslt, exslt = 'xslt', 'exslt'
+ for i, libname in enumerate(lib_flags):
+ if exslt in libname:
+ return
+ if xslt in libname:
+ lib_flags.insert(i, libname.replace(xslt, exslt))
+ return
+
+def ext_args_rpath(xslt_libs):
+ library_dirs = []
+ libraries = []
+ extra_link_args = []
+ runtime_library_dirs = []
+
+ for option in xslt_libs:
+ content = option[2:]
+ if option.startswith('-L'):
+ if not content.startswith('/usr'):
+ runtime_library_dirs.append(content)
+ library_dirs.append(content)
+ elif option.startswith('-l'):
+ libraries.append(content)
+ else:
+ extra_link_args.append(option)
+
+ return {
+ 'libraries': libraries,
+ 'library_dirs': library_dirs,
+ 'extra_link_args': extra_link_args,
+ 'runtime_library_dirs': runtime_library_dirs,
+ }
+
+def has_option(name):
+ try:
+ sys.argv.remove('--%s' % name)
+ return True
+ except ValueError:
+ return False
+
+# pick up any commandline options
+OPTION_WITHOUT_ASSERT = has_option('without-assert')
+OPTION_STATIC = has_option('static')
+OPTION_DEBUG_GCC = has_option('debug-gcc')
+OPTION_RPATH = has_option('rpath')
Added: lxml/trunk/versioninfo.py
==============================================================================
--- (empty file)
+++ lxml/trunk/versioninfo.py Wed Nov 22 15:20:56 2006
@@ -0,0 +1,76 @@
+import os, sys, re
+
+def version():
+ return open(os.path.join(get_src_dir(), 'version.txt')).read().strip()
+
+def branch_version():
+ return version()[:3]
+
+def svn_version():
+ _version = version()
+ try:
+ svn_entries = open(
+ os.path.join(get_src_dir(), '.svn', 'entries')).read()
+ revision = re.search(']*name=""[^>]*revision="([^"]+)"',
+ svn_entries).group(1)
+ result = _version + '-' + revision
+ except IOError:
+ result = _version
+
+ if 'dev' in _version:
+ result = fix_alphabeta(result, 'dev')
+ elif 'alpha' in _version:
+ result = fix_alphabeta(result, 'alpha')
+ if 'beta' in _version:
+ result = fix_alphabeta(result, 'beta')
+
+ return result
+
+def dev_status():
+ _version = version()
+ if 'dev' in _version:
+ return 'Development Status :: 3 - Alpha'
+ elif 'alpha' in _version:
+ return 'Development Status :: 3 - Alpha'
+ elif 'beta' in _version:
+ return 'Development Status :: 4 - Beta'
+ else:
+ return 'Development Status :: 5 - Production/Stable'
+
+def changes():
+ """Extract part of changelog pertaining to version.
+ """
+ _version = version()
+ f = open(os.path.join(get_src_dir(), "CHANGES.txt"), 'r')
+ lines = []
+ for line in f:
+ if line.startswith('====='):
+ if len(lines) > 1:
+ break
+ if lines:
+ lines.append(line)
+ elif line.startswith(_version):
+ lines.append(line)
+ f.close()
+ return ''.join(lines[:-1])
+
+def create_version_h(svn_version):
+ """Create lxml-version.h
+ """
+ version_h = open(
+ os.path.join(get_src_dir(), 'src', 'lxml', 'lxml-version.h'),
+ 'w')
+ version_h.write('''\
+#ifndef LXML_VERSION_STRING
+#define LXML_VERSION_STRING "%s"
+#endif
+''' % svn_version)
+ version_h.close()
+
+def get_src_dir():
+ return os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))
+
+def fix_alphabeta(version, alphabeta):
+ if ('.' + alphabeta) in version:
+ return version
+ return version.replace(alphabeta, '.' + alphabeta)
From scoder at codespeak.net Wed Nov 22 15:51:59 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 22 Nov 2006 15:51:59 +0100 (CET)
Subject: [Lxml-checkins] r34862 - lxml/trunk
Message-ID: <20061122145159.9879010064@code0.codespeak.net>
Author: scoder
Date: Wed Nov 22 15:51:57 2006
New Revision: 34862
Modified:
lxml/trunk/versioninfo.py
Log:
small fix to prevent version() from repeatedly reading version.txt
Modified: lxml/trunk/versioninfo.py
==============================================================================
--- lxml/trunk/versioninfo.py (original)
+++ lxml/trunk/versioninfo.py Wed Nov 22 15:51:57 2006
@@ -1,7 +1,12 @@
import os, sys, re
+__LXML_VERSION = None
+
def version():
- return open(os.path.join(get_src_dir(), 'version.txt')).read().strip()
+ global __LXML_VERSION
+ if __LXML_VERSION is None:
+ __LXML_VERSION = open(os.path.join(get_src_dir(), 'version.txt')).read().strip()
+ return __LXML_VERSION
def branch_version():
return version()[:3]
From faassen at codespeak.net Wed Nov 22 17:25:47 2006
From: faassen at codespeak.net (faassen at codespeak.net)
Date: Wed, 22 Nov 2006 17:25:47 +0100 (CET)
Subject: [Lxml-checkins] r34864 - lxml/trunk
Message-ID: <20061122162547.ACDD510064@code0.codespeak.net>
Author: faassen
Date: Wed Nov 22 17:25:44 2006
New Revision: 34864
Modified:
lxml/trunk/CHANGES.txt
lxml/trunk/setupinfo.py
Log:
Rename --rpath to --auto-rpath and add some notes to CHANGES.txt
Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt (original)
+++ lxml/trunk/CHANGES.txt Wed Nov 22 17:25:44 2006
@@ -2,6 +2,19 @@
lxml changelog
==============
+under development
+=================
+
+Features added
+--------------
+
+* setup.py has been refactored for greater readability and flexibility.
+
+* --rpath flag to setup.py to induce automatic linking-in of dynamic library
+ runtime search paths has been renamed to --auto-rpath. This makes it
+ possible to pass an --rpath directly to distutils; previously this was being
+ shadowed.
+
1.1.2 (2006-10-30)
==================
Modified: lxml/trunk/setupinfo.py
==============================================================================
--- lxml/trunk/setupinfo.py (original)
+++ lxml/trunk/setupinfo.py Wed Nov 22 17:25:44 2006
@@ -64,7 +64,7 @@
xslt_libs = flags('xslt-config --libs')
add_libexslt(xslt_libs)
- if OPTION_RPATH:
+ if OPTION_AUTO_RPATH:
return ext_args_rpath(xslt_libs)
else:
return {'extra_link_args': xslt_libs}
@@ -120,4 +120,4 @@
OPTION_WITHOUT_ASSERT = has_option('without-assert')
OPTION_STATIC = has_option('static')
OPTION_DEBUG_GCC = has_option('debug-gcc')
-OPTION_RPATH = has_option('rpath')
+OPTION_AUTO_RPATH = has_option('auto-rpath')
From scoder at codespeak.net Wed Nov 22 18:05:32 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 22 Nov 2006 18:05:32 +0100 (CET)
Subject: [Lxml-checkins] r34865 - lxml/trunk/doc
Message-ID: <20061122170532.3888610064@code0.codespeak.net>
Author: scoder
Date: Wed Nov 22 18:05:29 2006
New Revision: 34865
Modified:
lxml/trunk/doc/build.txt
Log:
some cleanup, dependency on setuptools
Modified: lxml/trunk/doc/build.txt
==============================================================================
--- lxml/trunk/doc/build.txt (original)
+++ lxml/trunk/doc/build.txt Wed Nov 22 18:05:29 2006
@@ -2,7 +2,11 @@
=============================
To build lxml from source, you need libxml2 and libxslt properly installed,
-including header files (possibly shipped in -dev packages).
+including header files (possibly shipped in -dev packages). The build process
+also requires setuptools_.
+
+.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools
+
Pyrex
-----
@@ -64,10 +68,10 @@
.. _`browse the repository through the web`: http://codespeak.net/svn/lxml
-The distutils approach
+The setuptools approach
----------------------
-Usually, building lxml is done through distutils. Do a Subversion checkout
+Usually, building lxml is done through setuptools. Do a Subversion checkout
(or download the source tar-ball and unpack it) and then type::
python setup.py build
@@ -147,6 +151,7 @@
cheeseshop entry. If not, you can just make an egg with bdist_egg and
mail it to the lxml maintainer.
+
Static linking on Windows
-------------------------
@@ -216,7 +221,7 @@
notes, you might have to add the standard Windows library ``wsock32.dll`` to
the above list of libraries to make ``lxml.objectify`` compile.
-.. _`Ashish Kulkarni`:
+.. _`Ashish Kulkarni`: http://codespeak.net/pipermail/lxml-dev/2006-September/001893.html
Now you should be able to pass the ``--static`` option to setup.py and
everything should work well. Try calling::
From scoder at codespeak.net Wed Nov 22 18:32:06 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 22 Nov 2006 18:32:06 +0100 (CET)
Subject: [Lxml-checkins] r34869 - lxml/trunk
Message-ID: <20061122173206.9AEEF10064@code0.codespeak.net>
Author: scoder
Date: Wed Nov 22 18:32:03 2006
New Revision: 34869
Added:
lxml/trunk/ez_setup.py
Modified:
lxml/trunk/setup.py
Log:
added ez_setup.py to support building even when setuptools must be downloaded first
Added: lxml/trunk/ez_setup.py
==============================================================================
--- (empty file)
+++ lxml/trunk/ez_setup.py Wed Nov 22 18:32:03 2006
@@ -0,0 +1,222 @@
+#!python
+"""Bootstrap setuptools installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+ from ez_setup import use_setuptools
+ use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import sys
+DEFAULT_VERSION = "0.6c3"
+DEFAULT_URL = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+
+md5_data = {
+ 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
+ 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
+ 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
+ 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
+ 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
+ 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
+ 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
+ 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
+ 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
+ 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+ 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
+ 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
+ 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
+ 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
+ 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
+}
+
+import sys, os
+
+def _validate_md5(egg_name, data):
+ if egg_name in md5_data:
+ from md5 import md5
+ digest = md5(data).hexdigest()
+ if digest != md5_data[egg_name]:
+ print >>sys.stderr, (
+ "md5 validation of %s failed! (Possible download problem?)"
+ % egg_name
+ )
+ sys.exit(2)
+ return data
+
+
+def use_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ download_delay=15
+):
+ """Automatically find/download setuptools and make it available on sys.path
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end with
+ a '/'). `to_dir` is the directory where setuptools will be downloaded, if
+ it is not already available. If `download_delay` is specified, it should
+ be the number of seconds that will be paused before initiating a download,
+ should one be required. If an older version of setuptools is installed,
+ this routine will print a message to ``sys.stderr`` and raise SystemExit in
+ an attempt to abort the calling script.
+ """
+ try:
+ import setuptools
+ if setuptools.__version__ == '0.0.1':
+ print >>sys.stderr, (
+ "You have an obsolete version of setuptools installed. Please\n"
+ "remove it from your system entirely before rerunning this script."
+ )
+ sys.exit(2)
+ except ImportError:
+ egg = download_setuptools(version, download_base, to_dir, download_delay)
+ sys.path.insert(0, egg)
+ import setuptools; setuptools.bootstrap_install_from = egg
+
+ import pkg_resources
+ try:
+ pkg_resources.require("setuptools>="+version)
+
+ except pkg_resources.VersionConflict, e:
+ # XXX could we install in a subprocess here?
+ print >>sys.stderr, (
+ "The required version of setuptools (>=%s) is not available, and\n"
+ "can't be installed while this script is running. Please install\n"
+ " a more recent version first.\n\n(Currently using %r)"
+ ) % (version, e.args[0])
+ sys.exit(2)
+
+def download_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ delay = 15
+):
+ """Download setuptools from a specified location and return its filename
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end
+ with a '/'). `to_dir` is the directory where the egg will be downloaded.
+ `delay` is the number of seconds to pause before an actual download attempt.
+ """
+ import urllib2, shutil
+ egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
+ url = download_base + egg_name
+ saveto = os.path.join(to_dir, egg_name)
+ src = dst = None
+ if not os.path.exists(saveto): # Avoid repeated downloads
+ try:
+ from distutils import log
+ if delay:
+ log.warn("""
+---------------------------------------------------------------------------
+This script requires setuptools version %s to run (even to display
+help). I will attempt to download it for you (from
+%s), but
+you may need to enable firewall access for this script first.
+I will start the download in %d seconds.
+
+(Note: if this machine does not have network access, please obtain the file
+
+ %s
+
+and place it in this directory before rerunning this script.)
+---------------------------------------------------------------------------""",
+ version, download_base, delay, url
+ ); from time import sleep; sleep(delay)
+ log.warn("Downloading %s", url)
+ src = urllib2.urlopen(url)
+ # Read/write all in one block, so we don't create a corrupt file
+ # if the download is interrupted.
+ data = _validate_md5(egg_name, src.read())
+ dst = open(saveto,"wb"); dst.write(data)
+ finally:
+ if src: src.close()
+ if dst: dst.close()
+ return os.path.realpath(saveto)
+
+def main(argv, version=DEFAULT_VERSION):
+ """Install or upgrade setuptools and EasyInstall"""
+
+ try:
+ import setuptools
+ except ImportError:
+ egg = None
+ try:
+ egg = download_setuptools(version, delay=0)
+ sys.path.insert(0,egg)
+ from setuptools.command.easy_install import main
+ return main(list(argv)+[egg]) # we're done here
+ finally:
+ if egg and os.path.exists(egg):
+ os.unlink(egg)
+ else:
+ if setuptools.__version__ == '0.0.1':
+ # tell the user to uninstall obsolete version
+ use_setuptools(version)
+
+ req = "setuptools>="+version
+ import pkg_resources
+ try:
+ pkg_resources.require(req)
+ except pkg_resources.VersionConflict:
+ try:
+ from setuptools.command.easy_install import main
+ except ImportError:
+ from easy_install import main
+ main(list(argv)+[download_setuptools(delay=0)])
+ sys.exit(0) # try to force an exit
+ else:
+ if argv:
+ from setuptools.command.easy_install import main
+ main(argv)
+ else:
+ print "Setuptools version",version,"or greater has been installed."
+ print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
+
+
+
+def update_md5(filenames):
+ """Update our built-in md5 registry"""
+
+ import re
+ from md5 import md5
+
+ for name in filenames:
+ base = os.path.basename(name)
+ f = open(name,'rb')
+ md5_data[base] = md5(f.read()).hexdigest()
+ f.close()
+
+ data = [" %r: %r,\n" % it for it in md5_data.items()]
+ data.sort()
+ repl = "".join(data)
+
+ import inspect
+ srcfile = inspect.getsourcefile(sys.modules[__name__])
+ f = open(srcfile, 'rb'); src = f.read(); f.close()
+
+ match = re.search("\nmd5_data = {\n([^}]+)}", src)
+ if not match:
+ print >>sys.stderr, "Internal error!"
+ sys.exit(2)
+
+ src = src[:match.start(1)] + repl + src[match.end(1):]
+ f = open(srcfile,'w')
+ f.write(src)
+ f.close()
+
+
+if __name__=='__main__':
+ if len(sys.argv)>2 and sys.argv[1]=='--md5update':
+ update_md5(sys.argv[2:])
+ else:
+ main(sys.argv[1:])
+
+
+
+
+
Modified: lxml/trunk/setup.py
==============================================================================
--- lxml/trunk/setup.py (original)
+++ lxml/trunk/setup.py Wed Nov 22 18:32:03 2006
@@ -1,3 +1,6 @@
+from ez_setup import use_setuptools
+use_setuptools()
+
from setuptools import setup
import versioninfo
import setupinfo
From scoder at codespeak.net Wed Nov 22 18:36:22 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Wed, 22 Nov 2006 18:36:22 +0100 (CET)
Subject: [Lxml-checkins] r34870 - lxml/trunk
Message-ID: <20061122173622.9CBED1006C@code0.codespeak.net>
Author: scoder
Date: Wed Nov 22 18:36:21 2006
New Revision: 34870
Modified:
lxml/trunk/setup.py
Log:
do not require setuptools 0.6 to be installed
Modified: lxml/trunk/setup.py
==============================================================================
--- lxml/trunk/setup.py (original)
+++ lxml/trunk/setup.py Wed Nov 22 18:36:21 2006
@@ -1,5 +1,5 @@
from ez_setup import use_setuptools
-use_setuptools()
+use_setuptools(version="0.5")
from setuptools import setup
import versioninfo
From faassen at codespeak.net Wed Nov 22 19:03:00 2006
From: faassen at codespeak.net (faassen at codespeak.net)
Date: Wed, 22 Nov 2006 19:03:00 +0100 (CET)
Subject: [Lxml-checkins] r34873 - lxml/trunk
Message-ID: <20061122180300.3AA8E10071@code0.codespeak.net>
Author: faassen
Date: Wed Nov 22 19:02:59 2006
New Revision: 34873
Modified:
lxml/trunk/setup.py
lxml/trunk/setupinfo.py
Log:
Refactor further:
* explicitly list libraries to list in. I don't extract them from
xslt-config right now, but we could change this if we wanted.
* explicitly have a library_dirs and a include_dirs, to use more of the
distutils machinery and less of our own custom hackery.
* put the directory setup.py is in on the python path so that
it can import setupinfo and versioninfo even when it's called from
another directory
Modified: lxml/trunk/setup.py
==============================================================================
--- lxml/trunk/setup.py (original)
+++ lxml/trunk/setup.py Wed Nov 22 19:02:59 2006
@@ -2,13 +2,21 @@
use_setuptools(version="0.5")
from setuptools import setup
+import sys, os
+
+# need to insert this to python path so we're sure we can import
+# versioninfo and setupinfo even if we start setup.py from another
+# location (such as a buildout)
+sys.path.insert(0, os.path.dirname(__file__))
+
import versioninfo
import setupinfo
# override these and pass --static for a static build. See
# doc/build.txt for more information. If you do not pass --static
# changing this will have no effect.
-STATIC_LIBS = []
+STATIC_INCLUDE_DIRS = []
+STATIC_LIBRARY_DIRS = []
STATIC_CFLAGS = []
# create lxml-version.h file
@@ -63,6 +71,7 @@
package_dir = {'': 'src'},
packages = ['lxml'],
zip_safe = False,
- ext_modules = setupinfo.ext_modules(STATIC_LIBS, STATIC_CFLAGS),
+ ext_modules = setupinfo.ext_modules(
+ STATIC_INCLUDE_DIRS, STATIC_LIBRARY_DIRS, STATIC_CFLAGS),
**setupinfo.extra_setup_args()
)
Modified: lxml/trunk/setupinfo.py
==============================================================================
--- lxml/trunk/setupinfo.py (original)
+++ lxml/trunk/setupinfo.py Wed Nov 22 19:02:59 2006
@@ -12,7 +12,7 @@
("objectify", "lxml.objectify")
]
-def ext_modules(static_libs, static_cflags):
+def ext_modules(static_include_dirs, static_library_dirs, static_cflags):
if PYREX_INSTALLED:
source_extension = ".pyx"
else:
@@ -20,10 +20,17 @@
"'src/lxml/etree.c' needs to be available.")
source_extension = ".c"
- result = []
- _ext_args = ext_args(static_libs)
+ _include_dirs = include_dirs(static_include_dirs)
+ _library_dirs = library_dirs(static_library_dirs)
_cflags = cflags(static_cflags)
_define_macros = define_macros()
+
+ if OPTION_AUTO_RPATH:
+ runtime_library_dirs = _library_dirs
+ else:
+ runtime_library_dirs = []
+
+ result = []
for module, package in EXT_MODULES:
result.append(
Extension(
@@ -31,7 +38,10 @@
sources = ["src/lxml/" + module + source_extension],
extra_compile_args = ['-w'] + _cflags,
define_macros = _define_macros,
- **_ext_args
+ include_dirs = _include_dirs,
+ library_dirs = _library_dirs,
+ runtime_library_dirs = runtime_library_dirs,
+ libraries=['xslt', 'exslt', 'xml2', 'z', 'm'],
))
return result
@@ -41,74 +51,56 @@
result['cmdclass'] = {'build_ext': build_pyx}
return result
-def cflags(static_cflags):
+def library_dirs(static_library_dirs):
if OPTION_STATIC:
- assert static_cflags, "Static build not configured, see doc/build.txt"
- result = static_cflags
- else:
- result = flags('xslt-config --cflags')
+ assert static_library_dirs, "Static build not configured, see doc/build.txt"
+ return static_library_dirs
+ # filter them from xslt-config --libs
+ result = []
+ possible_library_dirs = flags('xslt-config --libs')
+ for possible_library_dir in possible_library_dirs:
+ if possible_library_dir.startswith('-L'):
+ result.append(possible_library_dir[2:])
+ return result
+
+def include_dirs(static_include_dirs):
+ if OPTION_STATIC:
+ assert static_include_dirs, "Static build not configured, see doc/build.txt"
+ return static_include_dirs
+ # filter them from xslt-config --cflags
+ result = []
+ possible_include_dirs = flags('xslt-config --cflags')
+ for possible_include_dir in possible_include_dirs:
+ if possible_include_dir.startswith('-I'):
+ result.append(possible_include_dir[2:])
+ return result
+
+def cflags(static_cflags):
+ result = []
if OPTION_DEBUG_GCC:
result.append('-g2')
+
+ if OPTION_STATIC:
+ assert static_cflags, "Static build not configured, see doc/build.txt"
+ result.extend(static_cflags)
+ return result
+
+ # anything from xslt-config --cflags that doesn't start with -I
+ possible_cflags = flags('xslt-config --cflags')
+ for possible_cflag in possible_cflags:
+ if not possible_cflag.startswith('-I'):
+ result.append(possible_cflag)
return result
def define_macros():
if OPTION_WITHOUT_ASSERT:
return [('PYREX_WITHOUT_ASSERTIONS', None)]
return []
-
-def ext_args(static_libs):
- if OPTION_STATIC:
- assert static_libs, "Static build not configured, see doc/build.txt"
- return {'extra_link_args': static_libs}
-
- xslt_libs = flags('xslt-config --libs')
- add_libexslt(xslt_libs)
-
- if OPTION_AUTO_RPATH:
- return ext_args_rpath(xslt_libs)
- else:
- return {'extra_link_args': xslt_libs}
def flags(cmd):
wf, rf, ef = os.popen3(cmd)
return rf.read().split()
-def add_libexslt(lib_flags):
- if '-lxslt' in lib_flags:
- xslt, exslt = '-lxslt', '-lexslt'
- else:
- xslt, exslt = 'xslt', 'exslt'
- for i, libname in enumerate(lib_flags):
- if exslt in libname:
- return
- if xslt in libname:
- lib_flags.insert(i, libname.replace(xslt, exslt))
- return
-
-def ext_args_rpath(xslt_libs):
- library_dirs = []
- libraries = []
- extra_link_args = []
- runtime_library_dirs = []
-
- for option in xslt_libs:
- content = option[2:]
- if option.startswith('-L'):
- if not content.startswith('/usr'):
- runtime_library_dirs.append(content)
- library_dirs.append(content)
- elif option.startswith('-l'):
- libraries.append(content)
- else:
- extra_link_args.append(option)
-
- return {
- 'libraries': libraries,
- 'library_dirs': library_dirs,
- 'extra_link_args': extra_link_args,
- 'runtime_library_dirs': runtime_library_dirs,
- }
-
def has_option(name):
try:
sys.argv.remove('--%s' % name)
From scoder at codespeak.net Mon Nov 27 11:49:01 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Mon, 27 Nov 2006 11:49:01 +0100 (CET)
Subject: [Lxml-checkins] r35023 - in lxml/trunk/src: . lxml/tests
Message-ID: <20061127104901.E218B10077@code0.codespeak.net>
Author: scoder
Date: Mon Nov 27 11:48:59 2006
New Revision: 35023
Added:
lxml/trunk/src/local_doctest.py
- copied unchanged from r35022, lxml/tag/lxml-1.0/src/doctest.py
Modified:
lxml/trunk/src/lxml/tests/common_imports.py
Log:
use custom doctest.py under Py2.3
Modified: lxml/trunk/src/lxml/tests/common_imports.py
==============================================================================
--- lxml/trunk/src/lxml/tests/common_imports.py (original)
+++ lxml/trunk/src/lxml/tests/common_imports.py Mon Nov 27 11:48:59 2006
@@ -13,6 +13,17 @@
except ImportError:
ElementTree = None
+try:
+ import doctest
+ # check if the system version has everything we need
+ doctest.DocFileSuite
+ doctest.NORMALIZE_WHITESPACE
+ doctest.ELLIPSIS
+except (ImportError, AttributeError):
+ # we need our own version to make it work (Python 2.3?)
+ import lxml.local_doctest as doctest
+
+
class HelperTestCase(unittest.TestCase):
def parse(self, text):
f = StringIO(text)
From scoder at codespeak.net Mon Nov 27 12:10:07 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Mon, 27 Nov 2006 12:10:07 +0100 (CET)
Subject: [Lxml-checkins] r35024 - lxml/trunk/src/lxml/tests
Message-ID: <20061127111007.BF60610077@code0.codespeak.net>
Author: scoder
Date: Mon Nov 27 12:09:58 2006
New Revision: 35024
Modified:
lxml/trunk/src/lxml/tests/test_etree.py
lxml/trunk/src/lxml/tests/test_nsclasses.py
lxml/trunk/src/lxml/tests/test_objectify.py
lxml/trunk/src/lxml/tests/test_sax.py
lxml/trunk/src/lxml/tests/test_xslt.py
Log:
import doctest module from common_imports
Modified: lxml/trunk/src/lxml/tests/test_etree.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_etree.py (original)
+++ lxml/trunk/src/lxml/tests/test_etree.py Mon Nov 27 12:09:58 2006
@@ -8,10 +8,10 @@
"""
-import unittest, doctest, copy, sys
+import unittest, copy, sys
from common_imports import etree, StringIO, HelperTestCase, fileInTestDir
-from common_imports import SillyFileLike, canonicalize
+from common_imports import SillyFileLike, canonicalize, doctest
print
print "TESTED VERSION:"
Modified: lxml/trunk/src/lxml/tests/test_nsclasses.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_nsclasses.py (original)
+++ lxml/trunk/src/lxml/tests/test_nsclasses.py Mon Nov 27 12:09:58 2006
@@ -5,9 +5,9 @@
namespace registry mechanism
"""
-import unittest, doctest
+import unittest
-from common_imports import etree, HelperTestCase
+from common_imports import etree, HelperTestCase, doctest
class ETreeNamespaceClassesTestCase(HelperTestCase):
assertFalse = HelperTestCase.failIf
Modified: lxml/trunk/src/lxml/tests/test_objectify.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_objectify.py (original)
+++ lxml/trunk/src/lxml/tests/test_objectify.py Mon Nov 27 12:09:58 2006
@@ -8,10 +8,10 @@
"""
-import unittest, doctest, operator
+import unittest, operator
from common_imports import etree, StringIO, HelperTestCase, fileInTestDir
-from common_imports import SillyFileLike, canonicalize
+from common_imports import SillyFileLike, canonicalize, doctest
from lxml import objectify
Modified: lxml/trunk/src/lxml/tests/test_sax.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_sax.py (original)
+++ lxml/trunk/src/lxml/tests/test_sax.py Mon Nov 27 12:09:58 2006
@@ -4,10 +4,10 @@
Test cases related to SAX I/O
"""
-import unittest, doctest
+import unittest
from StringIO import StringIO
-from common_imports import HelperTestCase
+from common_imports import HelperTestCase, doctest
from lxml import sax
from xml.dom import pulldom
Modified: lxml/trunk/src/lxml/tests/test_xslt.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_xslt.py (original)
+++ lxml/trunk/src/lxml/tests/test_xslt.py Mon Nov 27 12:09:58 2006
@@ -4,9 +4,10 @@
Test cases related to XSLT processing
"""
-import unittest, doctest
+import unittest
from common_imports import etree, StringIO, HelperTestCase, fileInTestDir
+from common_imports import doctest
class ETreeXSLTTestCase(HelperTestCase):
"""XPath tests etree"""
From scoder at codespeak.net Mon Nov 27 12:13:25 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Mon, 27 Nov 2006 12:13:25 +0100 (CET)
Subject: [Lxml-checkins] r35025 - lxml/trunk/src/lxml/tests
Message-ID: <20061127111325.86EA210077@code0.codespeak.net>
Author: scoder
Date: Mon Nov 27 12:13:24 2006
New Revision: 35025
Modified:
lxml/trunk/src/lxml/tests/test_etree.py
Log:
provide fallback for calls to sorted() under Py2.3
Modified: lxml/trunk/src/lxml/tests/test_etree.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_etree.py (original)
+++ lxml/trunk/src/lxml/tests/test_etree.py Mon Nov 27 12:13:24 2006
@@ -23,6 +23,15 @@
print " libxslt compiled: ", etree.LIBXSLT_COMPILED_VERSION
print
+try:
+ sorted(())
+except NameError:
+ # Python 2.3
+ def sorted(seq):
+ seq = list(seq)
+ seq.sort()
+ return seq
+
class ETreeOnlyTestCase(HelperTestCase):
"""Tests only for etree, not ElementTree"""
etree = etree
From scoder at codespeak.net Tue Nov 28 13:46:47 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Tue, 28 Nov 2006 13:46:47 +0100 (CET)
Subject: [Lxml-checkins] r35079 - lxml/trunk/src/lxml
Message-ID: <20061128124647.EBCD81009B@code0.codespeak.net>
Author: scoder
Date: Tue Nov 28 13:46:46 2006
New Revision: 35079
Modified:
lxml/trunk/src/lxml/etree_defs.h
Log:
switch off threading under Python 2.3
Modified: lxml/trunk/src/lxml/etree_defs.h
==============================================================================
--- lxml/trunk/src/lxml/etree_defs.h (original)
+++ lxml/trunk/src/lxml/etree_defs.h Tue Nov 28 13:46:46 2006
@@ -16,6 +16,14 @@
#endif
#endif
+/* Threading can crash under Python 2.3 */
+#if PY_VERSION_HEX < 0x02040000
+ #define PyEval_SaveThread() (NULL)
+ #define PyEval_RestoreThread(state)
+ #define PyGILState_Ensure() (PyGILState_UNLOCKED)
+ #define PyGILState_Release(state)
+#endif
+
/* libxml2 version specific setup */
#include "libxml/xmlversion.h"
#if LIBXML_VERSION < 20621
From scoder at codespeak.net Tue Nov 28 14:01:01 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Tue, 28 Nov 2006 14:01:01 +0100 (CET)
Subject: [Lxml-checkins] r35082 - lxml/trunk/src/lxml
Message-ID: <20061128130101.E5C641008D@code0.codespeak.net>
Author: scoder
Date: Tue Nov 28 14:01:00 2006
New Revision: 35082
Modified:
lxml/trunk/src/lxml/etree_defs.h
Log:
enable switching off threading at compile time
Modified: lxml/trunk/src/lxml/etree_defs.h
==============================================================================
--- lxml/trunk/src/lxml/etree_defs.h (original)
+++ lxml/trunk/src/lxml/etree_defs.h Tue Nov 28 14:01:00 2006
@@ -18,6 +18,12 @@
/* Threading can crash under Python 2.3 */
#if PY_VERSION_HEX < 0x02040000
+#ifndef WITHOUT_THREADING
+ #define WITHOUT_THREADING
+#endif
+#endif
+
+#ifdef WITHOUT_THREADING
#define PyEval_SaveThread() (NULL)
#define PyEval_RestoreThread(state)
#define PyGILState_Ensure() (PyGILState_UNLOCKED)
From scoder at codespeak.net Tue Nov 28 15:36:30 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Tue, 28 Nov 2006 15:36:30 +0100 (CET)
Subject: [Lxml-checkins] r35084 - lxml/trunk
Message-ID: <20061128143630.E5CAF1006F@code0.codespeak.net>
Author: scoder
Date: Tue Nov 28 15:36:28 2006
New Revision: 35084
Modified:
lxml/trunk/versioninfo.py
Log:
patch by Sidnei da Silva: make parsing the SVN release work with SVN 1.4
Modified: lxml/trunk/versioninfo.py
==============================================================================
--- lxml/trunk/versioninfo.py (original)
+++ lxml/trunk/versioninfo.py Tue Nov 28 15:36:28 2006
@@ -13,14 +13,45 @@
def svn_version():
_version = version()
- try:
- svn_entries = open(
- os.path.join(get_src_dir(), '.svn', 'entries')).read()
- revision = re.search(']*name=""[^>]*revision="([^"]+)"',
- svn_entries).group(1)
- result = _version + '-' + revision
- except IOError:
- result = _version
+ src_dir = get_src_dir()
+
+ revision = 0
+ base_url = None
+ urlre = re.compile('url="([^"]+)"')
+ revre = re.compile('committed-rev="(\d+)"')
+
+ for base, dirs, files in os.walk(src_dir):
+ if '.svn' not in dirs:
+ dirs[:] = []
+ continue # no sense walking uncontrolled subdirs
+ dirs.remove('.svn')
+ f = open(os.path.join(base, '.svn', 'entries'))
+ data = f.read()
+ f.close()
+
+ if data.startswith('8'):
+ del data[0] # get rid of the '8'
+ data = map(str.splitlines, data.split('\n\x0c\n'))
+ dirurl = data[0][3]
+ localrev = max([int(d[9]) for d in data if len(d)>9 and d[9]])
+ elif data.startswith('
Author: scoder
Date: Tue Nov 28 17:17:17 2006
New Revision: 35086
Modified:
lxml/trunk/versioninfo.py
Log:
fix: remove leading '8' from SVN entries data
Modified: lxml/trunk/versioninfo.py
==============================================================================
--- lxml/trunk/versioninfo.py (original)
+++ lxml/trunk/versioninfo.py Tue Nov 28 17:17:17 2006
@@ -30,7 +30,7 @@
f.close()
if data.startswith('8'):
- del data[0] # get rid of the '8'
+ data = data[1:] # get rid of the '8'
data = map(str.splitlines, data.split('\n\x0c\n'))
dirurl = data[0][3]
localrev = max([int(d[9]) for d in data if len(d)>9 and d[9]])
From scoder at codespeak.net Tue Nov 28 17:19:32 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Tue, 28 Nov 2006 17:19:32 +0100 (CET)
Subject: [Lxml-checkins] r35087 - lxml/trunk
Message-ID: <20061128161932.C4BF210083@code0.codespeak.net>
Author: scoder
Date: Tue Nov 28 17:19:31 2006
New Revision: 35087
Modified:
lxml/trunk/versioninfo.py
Log:
reverted to original implementation by Sidnei
Modified: lxml/trunk/versioninfo.py
==============================================================================
--- lxml/trunk/versioninfo.py (original)
+++ lxml/trunk/versioninfo.py Tue Nov 28 17:19:31 2006
@@ -30,8 +30,8 @@
f.close()
if data.startswith('8'):
- data = data[1:] # get rid of the '8'
data = map(str.splitlines, data.split('\n\x0c\n'))
+ del data[0][0] # get rid of the '8'
dirurl = data[0][3]
localrev = max([int(d[9]) for d in data if len(d)>9 and d[9]])
elif data.startswith('
Author: scoder
Date: Tue Nov 28 17:53:54 2006
New Revision: 35089
Modified:
lxml/trunk/setupinfo.py
Log:
patch by Sidney da Silva: support passing compiler flags in env vars
Modified: lxml/trunk/setupinfo.py
==============================================================================
--- lxml/trunk/setupinfo.py (original)
+++ lxml/trunk/setupinfo.py Tue Nov 28 17:53:54 2006
@@ -12,6 +12,16 @@
("objectify", "lxml.objectify")
]
+
+env_map = {'win32':{'INCLUDE': 'INCLUDE',
+ 'LIBRARY': 'LIB',
+ 'CFLAGS' : 'CFLAGS'},
+ }.get(sys.platform, {})
+
+def env_var(name):
+ value = os.getenv(env_map.get(name), '')
+ return value.split(os.pathsep)
+
def ext_modules(static_include_dirs, static_library_dirs, static_cflags):
if PYREX_INSTALLED:
source_extension = ".pyx"
@@ -24,6 +34,7 @@
_library_dirs = library_dirs(static_library_dirs)
_cflags = cflags(static_cflags)
_define_macros = define_macros()
+ _libraries = libraries()
if OPTION_AUTO_RPATH:
runtime_library_dirs = _library_dirs
@@ -41,7 +52,7 @@
include_dirs = _include_dirs,
library_dirs = _library_dirs,
runtime_library_dirs = runtime_library_dirs,
- libraries=['xslt', 'exslt', 'xml2', 'z', 'm'],
+ libraries = _libraries,
))
return result
@@ -51,8 +62,22 @@
result['cmdclass'] = {'build_ext': build_pyx}
return result
+def libraries():
+ if sys.platform in ('win32',):
+ libs = ['libxslt', 'libexslt', 'libxml2', 'iconv']
+ else:
+ libs = ['xslt', 'exslt', 'xml2', 'z', 'm']
+ if OPTION_STATIC:
+ if sys.platform in ('win32',):
+ libs = ['%s_a' % lib for lib in libs]
+ if sys.platform in ('win32',):
+ libs.extend(['zlib', 'WS2_32'])
+ return libs
+
def library_dirs(static_library_dirs):
if OPTION_STATIC:
+ if not static_library_dirs:
+ static_library_dirs = env_var('LIBRARY')
assert static_library_dirs, "Static build not configured, see doc/build.txt"
return static_library_dirs
# filter them from xslt-config --libs
@@ -65,6 +90,8 @@
def include_dirs(static_include_dirs):
if OPTION_STATIC:
+ if not static_include_dirs:
+ static_include_dirs = env_var('INCLUDE')
assert static_include_dirs, "Static build not configured, see doc/build.txt"
return static_include_dirs
# filter them from xslt-config --cflags
@@ -81,6 +108,8 @@
result.append('-g2')
if OPTION_STATIC:
+ if not static_cflags:
+ static_cflags = env_var('CFLAGS')
assert static_cflags, "Static build not configured, see doc/build.txt"
result.extend(static_cflags)
return result
@@ -93,9 +122,10 @@
return result
def define_macros():
+ macros = []
if OPTION_WITHOUT_ASSERT:
- return [('PYREX_WITHOUT_ASSERTIONS', None)]
- return []
+ macros.append(('PYREX_WITHOUT_ASSERTIONS', None))
+ return macros
def flags(cmd):
wf, rf, ef = os.popen3(cmd)
@@ -110,6 +140,7 @@
# pick up any commandline options
OPTION_WITHOUT_ASSERT = has_option('without-assert')
+OPTION_WITHOUT_THREADING = has_option('without-threading')
OPTION_STATIC = has_option('static')
OPTION_DEBUG_GCC = has_option('debug-gcc')
OPTION_AUTO_RPATH = has_option('auto-rpath')
From scoder at codespeak.net Tue Nov 28 17:54:52 2006
From: scoder at codespeak.net (scoder at codespeak.net)
Date: Tue, 28 Nov 2006 17:54:52 +0100 (CET)
Subject: [Lxml-checkins] r35090 - lxml/trunk
Message-ID: <20061128165452.B36D710080@code0.codespeak.net>
Author: scoder
Date: Tue Nov 28 17:54:51 2006
New Revision: 35090
Modified:
lxml/trunk/setupinfo.py
Log:
support building without threading by passing --without-threading option
Modified: lxml/trunk/setupinfo.py
==============================================================================
--- lxml/trunk/setupinfo.py (original)
+++ lxml/trunk/setupinfo.py Tue Nov 28 17:54:51 2006
@@ -125,6 +125,8 @@
macros = []
if OPTION_WITHOUT_ASSERT:
macros.append(('PYREX_WITHOUT_ASSERTIONS', None))
+ if OPTION_WITHOUT_THREADING:
+ macros.append(('WITHOUT_THREADING', None))
return macros
def flags(cmd):
From faassen at codespeak.net Thu Nov 30 18:10:14 2006
From: faassen at codespeak.net (faassen at codespeak.net)
Date: Thu, 30 Nov 2006 18:10:14 +0100 (CET)
Subject: [Lxml-checkins] r35175 - lxml/trunk/src/lxml/tests
Message-ID: <20061130171014.01E341007F@code0.codespeak.net>
Author: faassen
Date: Thu Nov 30 18:10:13 2006
New Revision: 35175
Modified:
lxml/trunk/src/lxml/tests/common_imports.py
Log:
Import local_doctest from the right location.
Modified: lxml/trunk/src/lxml/tests/common_imports.py
==============================================================================
--- lxml/trunk/src/lxml/tests/common_imports.py (original)
+++ lxml/trunk/src/lxml/tests/common_imports.py Thu Nov 30 18:10:13 2006
@@ -21,7 +21,7 @@
doctest.ELLIPSIS
except (ImportError, AttributeError):
# we need our own version to make it work (Python 2.3?)
- import lxml.local_doctest as doctest
+ import local_doctest as doctest
class HelperTestCase(unittest.TestCase):