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):