setup.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import os
  2. import re
  3. import sys
  4. import fnmatch
  5. # for command line options and supported environment variables, please
  6. # see the end of 'setupinfo.py'
  7. if sys.version_info < (2, 6) or sys.version_info[:2] in [(3, 0), (3, 1)]:
  8. print("This lxml version requires Python 2.6, 2.7, 3.2 or later.")
  9. sys.exit(1)
  10. try:
  11. from setuptools import setup
  12. except ImportError:
  13. from distutils.core import setup
  14. import versioninfo
  15. import setupinfo
  16. # override these and pass --static for a static build. See
  17. # doc/build.txt for more information. If you do not pass --static
  18. # changing this will have no effect.
  19. STATIC_INCLUDE_DIRS = []
  20. STATIC_LIBRARY_DIRS = []
  21. STATIC_CFLAGS = []
  22. STATIC_BINARIES = []
  23. # create lxml-version.h file
  24. svn_version = versioninfo.svn_version()
  25. versioninfo.create_version_h(svn_version)
  26. print("Building lxml version %s." % svn_version)
  27. OPTION_RUN_TESTS = setupinfo.has_option('run-tests')
  28. branch_link = """
  29. After an official release of a new stable series, bug fixes may become
  30. available at
  31. https://github.com/lxml/lxml/tree/lxml-%(branch_version)s .
  32. Running ``easy_install lxml==%(branch_version)sbugfix`` will install
  33. the unreleased branch state from
  34. https://github.com/lxml/lxml/tarball/lxml-%(branch_version)s#egg=lxml-%(branch_version)sbugfix
  35. as soon as a maintenance branch has been established. Note that this
  36. requires Cython to be installed at an appropriate version for the build.
  37. """
  38. if versioninfo.is_pre_release():
  39. branch_link = ""
  40. extra_options = {}
  41. if 'setuptools' in sys.modules:
  42. extra_options['zip_safe'] = False
  43. try:
  44. import pkg_resources
  45. except ImportError:
  46. pass
  47. else:
  48. f = open("requirements.txt", "r")
  49. try:
  50. deps = [str(req) for req in pkg_resources.parse_requirements(f)]
  51. finally:
  52. f.close()
  53. extra_options['extras_require'] = {
  54. 'source': deps,
  55. 'cssselect': 'cssselect>=0.7',
  56. 'html5': 'html5lib',
  57. 'htmlsoup': 'BeautifulSoup4',
  58. }
  59. extra_options.update(setupinfo.extra_setup_args())
  60. extra_options['package_data'] = {
  61. 'lxml': [
  62. 'lxml.etree.h',
  63. 'lxml.etree_api.h',
  64. ],
  65. 'lxml.includes': [
  66. '*.pxd', '*.h'
  67. ],
  68. 'lxml.isoschematron': [
  69. 'resources/rng/iso-schematron.rng',
  70. 'resources/xsl/*.xsl',
  71. 'resources/xsl/iso-schematron-xslt1/*.xsl',
  72. 'resources/xsl/iso-schematron-xslt1/readme.txt'
  73. ],
  74. }
  75. extra_options['package_dir'] = {
  76. '': 'src'
  77. }
  78. extra_options['packages'] = [
  79. 'lxml', 'lxml.includes', 'lxml.html', 'lxml.isoschematron'
  80. ]
  81. def setup_extra_options():
  82. is_interesting_package = re.compile('^(libxml|libxslt|libexslt)$').match
  83. def extract_files(directories, pattern='*'):
  84. def get_files(root, dir_path, files):
  85. return [ (root, dir_path, filename)
  86. for filename in fnmatch.filter(files, pattern) ]
  87. file_list = []
  88. for dir_path in directories:
  89. dir_path = os.path.realpath(dir_path)
  90. for root, dirs, files in os.walk(dir_path):
  91. rel_dir = root[len(dir_path)+1:]
  92. if is_interesting_package(rel_dir):
  93. file_list.extend(get_files(root, rel_dir, files))
  94. return file_list
  95. def build_packages(files):
  96. packages = {}
  97. seen = set()
  98. for root_path, rel_path, filename in files:
  99. if filename in seen:
  100. # libxml2/libxslt header filenames are unique
  101. continue
  102. seen.add(filename)
  103. package_path = '.'.join(rel_path.split(os.sep))
  104. if package_path in packages:
  105. root, package_files = packages[package_path]
  106. if root != root_path:
  107. print("conflicting directories found for include package '%s': %s and %s"
  108. % (package_path, root_path, root))
  109. continue
  110. else:
  111. package_files = []
  112. packages[package_path] = (root_path, package_files)
  113. package_files.append(filename)
  114. return packages
  115. # Copy Global Extra Options
  116. extra_opts = dict(extra_options)
  117. # Build ext modules
  118. ext_modules = setupinfo.ext_modules(
  119. STATIC_INCLUDE_DIRS, STATIC_LIBRARY_DIRS,
  120. STATIC_CFLAGS, STATIC_BINARIES)
  121. extra_opts['ext_modules'] = ext_modules
  122. packages = extra_opts.get('packages', list())
  123. package_dir = extra_opts.get('package_dir', dict())
  124. package_data = extra_opts.get('package_data', dict())
  125. # Add lxml.include with (lxml, libxslt headers...)
  126. # python setup.py build --static --static-deps install
  127. # python setup.py bdist_wininst --static
  128. if setupinfo.OPTION_STATIC:
  129. include_dirs = [] # keep them in order
  130. for extension in ext_modules:
  131. for inc_dir in extension.include_dirs:
  132. if inc_dir not in include_dirs:
  133. include_dirs.append(inc_dir)
  134. header_packages = build_packages(extract_files(include_dirs))
  135. for package_path, (root_path, filenames) in header_packages.items():
  136. if package_path:
  137. package = 'lxml.includes.' + package_path
  138. packages.append(package)
  139. else:
  140. package = 'lxml.includes'
  141. package_data[package] = filenames
  142. package_dir[package] = root_path
  143. return extra_opts
  144. setup(
  145. name = "lxml",
  146. version = versioninfo.version(),
  147. author="lxml dev team",
  148. author_email="lxml-dev@lxml.de",
  149. maintainer="lxml dev team",
  150. maintainer_email="lxml-dev@lxml.de",
  151. url="http://lxml.de/",
  152. download_url="http://pypi.python.org/packages/source/l/lxml/lxml-%s.tar.gz" % versioninfo.version(),
  153. bugtrack_url="https://bugs.launchpad.net/lxml",
  154. description="Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.",
  155. long_description=((("""\
  156. lxml is a Pythonic, mature binding for the libxml2 and libxslt libraries. It
  157. provides safe and convenient access to these libraries using the ElementTree
  158. API.
  159. It extends the ElementTree API significantly to offer support for XPath,
  160. RelaxNG, XML Schema, XSLT, C14N and much more.
  161. To contact the project, go to the `project home page
  162. <http://lxml.de/>`_ or see our bug tracker at
  163. https://launchpad.net/lxml
  164. In case you want to use the current in-development version of lxml,
  165. you can get it from the github repository at
  166. https://github.com/lxml/lxml . Note that this requires Cython to
  167. build the sources, see the build instructions on the project home
  168. page. To the same end, running ``easy_install lxml==dev`` will
  169. install lxml from
  170. https://github.com/lxml/lxml/tarball/master#egg=lxml-dev if you have
  171. an appropriate version of Cython installed.
  172. """ + branch_link) % { "branch_version" : versioninfo.branch_version() }) +
  173. versioninfo.changes()),
  174. classifiers = [
  175. versioninfo.dev_status(),
  176. 'Intended Audience :: Developers',
  177. 'Intended Audience :: Information Technology',
  178. 'License :: OSI Approved :: BSD License',
  179. 'Programming Language :: Cython',
  180. 'Programming Language :: Python :: 2',
  181. 'Programming Language :: Python :: 2.6',
  182. 'Programming Language :: Python :: 2.7',
  183. 'Programming Language :: Python :: 3',
  184. 'Programming Language :: Python :: 3.2',
  185. 'Programming Language :: Python :: 3.3',
  186. 'Programming Language :: Python :: 3.4',
  187. 'Programming Language :: C',
  188. 'Operating System :: OS Independent',
  189. 'Topic :: Text Processing :: Markup :: HTML',
  190. 'Topic :: Text Processing :: Markup :: XML',
  191. 'Topic :: Software Development :: Libraries :: Python Modules'
  192. ],
  193. **setup_extra_options()
  194. )
  195. if OPTION_RUN_TESTS:
  196. print("Running tests.")
  197. import test
  198. sys.exit( test.main(sys.argv[:1]) )