Back to index

python-biopython  1.60
setup.py
Go to the documentation of this file.
00001 """Distutils based setup script for Biopython.
00002 
00003 This uses Distutils (http://python.org/sigs/distutils-sig/) the standard
00004 python mechanism for installing packages. For the easiest installation
00005 just type the command:
00006 
00007 python setup.py install
00008 
00009 For more in-depth instructions, see the installation section of the
00010 Biopython manual, linked to from:
00011 
00012 http://biopython.org/wiki/Documentation
00013 
00014 Or for more details about the options available from distutils, look at
00015 the 'Installing Python Modules' distutils documentation, available from:
00016 
00017 http://python.org/sigs/distutils-sig/doc/
00018 
00019 Or, if all else fails, feel free to write to the sign up to the Biopython
00020 mailing list and ask for help.  See:
00021 
00022 http://biopython.org/wiki/Mailing_lists
00023 """
00024 import sys
00025 import os
00026 import shutil
00027 
00028 def is_pypy():
00029     import platform
00030     try:
00031         if platform.python_implementation()=='PyPy':
00032             return True
00033     except AttributeError:
00034         #New in Python 2.6, not in Jython yet either
00035         pass
00036     return False
00037 
00038 def get_yes_or_no(question, default):
00039     if default:
00040         option_str = "(Y/n)"
00041         default_str = 'y'
00042     else:
00043         option_str = "(y/N)"
00044         default_str = 'n'
00045 
00046     while True:
00047         print ("%s %s:" % (question, option_str))
00048         if sys.version_info[0] == 3:
00049             response = input().lower()
00050         else:
00051             response = raw_input().lower()
00052         if not response:
00053             response = default_str
00054         if response[0] in ['y', 'n']:
00055             break
00056         print ("Please answer y or n.")
00057     return response[0] == 'y'
00058 
00059 # Make sure I have the right Python version.
00060 if sys.version_info[:2] < (2, 5):
00061     print ("Biopython requires Python 2.5 or better (but not Python 3 " \
00062           + "yet).  Python %d.%d detected" % sys.version_info[:2])
00063     sys.exit(-1)
00064 elif sys.version_info[0] == 3:
00065     print("WARNING - Biopython does not yet officially support Python 3")
00066     import do2to3
00067     python3_source = "build/py%i.%i" % sys.version_info[:2]
00068     if "clean" in sys.argv:
00069         if os.path.isdir(python3_source):
00070             shutil.rmtree(python3_source)
00071         del python3_source #so we don't try to change to it below
00072     else:
00073         if not os.path.isdir("build"):
00074             os.mkdir("build")
00075         do2to3.main(".", python3_source)
00076 
00077 # use setuptools, falling back on core modules if not found
00078 try:
00079     from setuptools import setup, Command
00080     from setuptools.command.install import install
00081     from setuptools.command.build_py import build_py
00082     from setuptools.command.build_ext import build_ext
00083     from setuptools.extension import Extension
00084     _SETUPTOOLS = True
00085 except ImportError:
00086     from distutils.core import setup
00087     from distutils.core import Command
00088     from distutils.command.install import install
00089     from distutils.command.build_py import build_py
00090     from distutils.command.build_ext import build_ext
00091     from distutils.extension import Extension
00092     _SETUPTOOLS = False
00093 
00094 _CHECKED = None
00095 def check_dependencies_once():
00096     # Call check_dependencies, but cache the result for subsequent
00097     # calls.
00098     global _CHECKED
00099     if _CHECKED is None:
00100         _CHECKED = check_dependencies()
00101     return _CHECKED
00102 
00103 def get_install_requires():
00104     install_requires = []
00105     # skip this with distutils (otherwise get a warning)
00106     if not _SETUPTOOLS:
00107         return []
00108     # skip this with jython and pypy
00109     if os.name=="java" or is_pypy():
00110         return []
00111     # check for easy_install and pip
00112     is_automated = False
00113     # easy_install: --dist-dir option passed
00114     try:
00115         dist_dir_i = sys.argv.index("--dist-dir")
00116     except ValueError:
00117         dist_dir_i = None
00118     if dist_dir_i is not None:
00119         dist_dir = sys.argv[dist_dir_i+1]
00120         if "egg-dist-tmp" in dist_dir:
00121             is_automated = True
00122     # pip -- calls from python directly with "-c"
00123     if sys.argv in [["-c", "develop", "--no-deps"],
00124                     ["--no-deps", "-c", "develop"],
00125                     ["-c", "egg_info"]]:
00126         is_automated = True
00127     if is_automated:
00128         global _CHECKED
00129         if _CHECKED is None: _CHECKED = True
00130         install_requires.append("numpy >= 1.5.1")
00131     return install_requires
00132 
00133 def check_dependencies():
00134     """Return whether the installation should continue."""
00135     # There should be some way for the user to tell specify not to
00136     # check dependencies.  For example, it probably should not if
00137     # the user specified "-q".  However, I'm not sure where
00138     # distutils stores that information.  Also, install has a
00139     # --force option that gets saved in self.user_options.  It
00140     # means overwrite previous installations.  If the user has
00141     # forced an installation, should we also ignore dependencies?
00142 
00143     # We only check for NumPy, as this is a compile time dependency
00144     if is_Numpy_installed() : return True
00145 
00146     if os.name=='java':
00147         return True #NumPy is not avaliable for Jython (for now)
00148     if is_pypy():
00149         return True #Full NumPy not available for PyPy (for now)
00150 
00151     print ("""
00152 Numerical Python (NumPy) is not installed.
00153 
00154 This package is required for many Biopython features.  Please install
00155 it before you install Biopython. You can install Biopython anyway, but
00156 anything dependent on NumPy will not work. If you do this, and later
00157 install NumPy, you should then re-install Biopython.
00158 
00159 You can find NumPy at http://numpy.scipy.org
00160 """)
00161     # exit automatically if running as part of some script
00162     # (e.g. PyPM, ActiveState's Python Package Manager)
00163     if not sys.stdout.isatty() :
00164         sys.exit(-1)
00165     # We can ask the user
00166     return get_yes_or_no("Do you want to continue this installation?", False)
00167 
00168 class install_biopython(install):
00169     """Override the standard install to check for dependencies.
00170 
00171     This will just run the normal install, and then print warning messages
00172     if packages are missing.
00173 
00174     """
00175     # Adds support for the single-version-externally-managed flag
00176     # which is present in setuptools but not distutils. pip requires it.
00177     # In setuptools this forces installation the "old way" which we
00178     # only support here, so we just make it a no-op.
00179     user_options = install.user_options + [
00180         ('single-version-externally-managed', None,
00181             "used by system package builders to create 'flat' eggs"),
00182     ]
00183     boolean_options = install.boolean_options + [
00184         'single-version-externally-managed',
00185     ]
00186     def initialize_options(self):
00187         install.initialize_options(self)
00188         self.single_version_externally_managed = None
00189 
00190     def run(self):
00191         if check_dependencies_once():
00192             # Run the normal install.
00193             install.run(self)
00194 
00195 class build_py_biopython(build_py):
00196     def run(self):
00197         if not check_dependencies_once():
00198             return
00199         # Add software that requires Numpy to be installed.
00200         if is_Numpy_installed():
00201             self.packages.extend(NUMPY_PACKAGES)
00202         build_py.run(self)
00203 
00204 
00205 class build_ext_biopython(build_ext):
00206     def run(self):
00207         if not check_dependencies_once():
00208             return
00209         build_ext.run(self)
00210 
00211 
00212 class test_biopython(Command):
00213     """Run all of the tests for the package.
00214 
00215     This is a automatic test run class to make distutils kind of act like
00216     perl. With this you can do:
00217 
00218     python setup.py build
00219     python setup.py install
00220     python setup.py test
00221     
00222     """
00223     description = "Automatically run the test suite for Biopython."
00224     user_options = []
00225 
00226     def initialize_options(self):
00227         pass
00228 
00229     def finalize_options(self):
00230         pass
00231 
00232     def run(self):
00233         this_dir = os.getcwd()
00234 
00235         # change to the test dir and run the tests
00236         os.chdir("Tests")
00237         sys.path.insert(0, '')
00238         import run_tests   
00239         run_tests.main([])
00240 
00241         # change back to the current directory
00242         os.chdir(this_dir)
00243 
00244 def can_import(module_name):
00245     """can_import(module_name) -> module or None"""
00246     try:
00247         return __import__(module_name)
00248     except ImportError:
00249         return None
00250 
00251 def is_Numpy_installed():
00252     if is_pypy():
00253         return False
00254     return bool(can_import("numpy"))
00255 
00256 # --- set up the packages we are going to install
00257 # standard biopython packages
00258 PACKAGES = [
00259     'Bio',
00260     'Bio.Align',
00261     'Bio.Align.Applications',
00262     'Bio.AlignIO',
00263     'Bio.Alphabet',
00264     'Bio.Application',
00265     'Bio.Blast',
00266     'Bio.CAPS',
00267     'Bio.Compass',
00268     'Bio.Crystal',
00269     'Bio.Data',
00270     'Bio.Emboss',
00271     'Bio.Entrez',
00272     'Bio.ExPASy',
00273     'Bio.FSSP',
00274     'Bio.GA',
00275     'Bio.GA.Crossover',
00276     'Bio.GA.Mutation',
00277     'Bio.GA.Repair',
00278     'Bio.GA.Selection',
00279     'Bio.GenBank',
00280     'Bio.Geo',
00281     'Bio.Graphics',
00282     'Bio.Graphics.GenomeDiagram',
00283     'Bio.HMM',
00284     'Bio.KEGG',
00285     'Bio.KEGG.Compound',
00286     'Bio.KEGG.Enzyme',
00287     'Bio.KEGG.Map',
00288     'Bio.Medline',
00289     'Bio.Motif',
00290     'Bio.Motif.Parsers',
00291     'Bio.Motif.Applications',
00292     'Bio.NeuralNetwork',
00293     'Bio.NeuralNetwork.BackPropagation',
00294     'Bio.NeuralNetwork.Gene',
00295     'Bio.Nexus',
00296     'Bio.NMR',
00297     'Bio.Pathway',
00298     'Bio.Pathway.Rep',
00299     'Bio.PDB',
00300     'Bio.PDB.mmCIF',
00301     'Bio.PopGen',
00302     'Bio.PopGen.Async',
00303     'Bio.PopGen.FDist',
00304     'Bio.PopGen.GenePop',
00305     'Bio.PopGen.SimCoal',
00306     'Bio.Restriction',
00307     'Bio.Restriction._Update',
00308     'Bio.SCOP',
00309     'Bio.SeqIO',
00310     'Bio.SeqUtils',
00311     'Bio.Sequencing',
00312     'Bio.Sequencing.Applications',
00313     'Bio.Statistics',
00314     'Bio.SubsMat',
00315     'Bio.SVDSuperimposer',
00316     'Bio.SwissProt',
00317     'Bio.TogoWS',
00318     'Bio.Phylo',
00319     'Bio.Phylo.Applications',
00320     'Bio.Phylo.PAML',
00321     'Bio.UniGene',
00322     'Bio.Wise',
00323     #Other top level packages,
00324     'BioSQL',
00325     ]
00326 
00327 # packages that require Numeric Python
00328 NUMPY_PACKAGES = [
00329     'Bio.Affy',
00330     'Bio.Cluster',
00331     'Bio.KDTree',
00332 ]
00333 
00334 if os.name == 'java' :
00335     # Jython doesn't support C extensions
00336     EXTENSIONS = []
00337 elif is_pypy():
00338     # Skip C extensions for now
00339     EXTENSIONS = []
00340 elif sys.version_info[0] == 3:
00341     # TODO - Must update our C extensions for Python 3
00342     EXTENSIONS = [
00343     Extension('Bio.cpairwise2',
00344               ['Bio/cpairwise2module.c'],
00345               include_dirs=["Bio"]
00346               ),
00347     Extension('Bio.Nexus.cnexus',
00348               ['Bio/Nexus/cnexus.c']
00349               ),
00350     ]
00351 else :
00352     EXTENSIONS = [
00353     Extension('Bio.cpairwise2',
00354               ['Bio/cpairwise2module.c'],
00355               include_dirs=["Bio"]
00356               ),
00357     Extension('Bio.trie',
00358               ['Bio/triemodule.c',
00359                'Bio/trie.c'],
00360               include_dirs=["Bio"]
00361               ),
00362     Extension('Bio.PDB.mmCIF.MMCIFlex',
00363              ['Bio/PDB/mmCIF/lex.yy.c',
00364               'Bio/PDB/mmCIF/MMCIFlexmodule.c'],
00365              include_dirs=["Bio"],
00366              ),
00367     Extension('Bio.Nexus.cnexus',
00368               ['Bio/Nexus/cnexus.c']
00369               ),
00370     ]
00371 
00372 #Add extensions that requires NumPy to build
00373 if is_Numpy_installed():
00374     import numpy
00375     numpy_include_dir = numpy.get_include()
00376     EXTENSIONS.append(
00377         Extension('Bio.Cluster.cluster',
00378                   ['Bio/Cluster/clustermodule.c',
00379                    'Bio/Cluster/cluster.c'],
00380                   include_dirs=[numpy_include_dir],
00381                   ))
00382     EXTENSIONS.append(
00383         Extension('Bio.KDTree._CKDTree',
00384                   ["Bio/KDTree/KDTree.c",
00385                    "Bio/KDTree/KDTreemodule.c"],
00386                   include_dirs=[numpy_include_dir],
00387                   ))
00388     EXTENSIONS.append(
00389         Extension('Bio.Motif._pwm',
00390                   ["Bio/Motif/_pwm.c"],
00391                   include_dirs=[numpy_include_dir],
00392                   ))
00393 
00394 
00395 #We now define the Biopython version number in Bio/__init__.py
00396 #Here we can't use "import Bio" then "Bio.__version__" as that would
00397 #tell us the version of Biopython already installed (if any).
00398 __version__ = "Undefined"
00399 for line in open('Bio/__init__.py'):
00400     if (line.startswith('__version__')):
00401         exec(line.strip())
00402 
00403 #Simple trick to use the 2to3 converted source under Python 3,
00404 #change the current directory before/after running setup.
00405 #Note as a side effect there will be a build folder underneath
00406 #the python3_source folder.
00407 old_path = os.getcwd()
00408 try:
00409     src_path = python3_source
00410 except NameError:
00411     src_path = os.path.dirname(os.path.abspath(sys.argv[0]))
00412 os.chdir(src_path)
00413 sys.path.insert(0, src_path)
00414 
00415 setup_args = {
00416     "name" : 'biopython',
00417     "version" : __version__,
00418     "author" : 'The Biopython Consortium',
00419     "author_email" : 'biopython@biopython.org',
00420     "url" : 'http://www.biopython.org/',
00421     "description" : 'Freely available tools for computational molecular biology.',
00422     "download_url" : 'http://biopython.org/DIST/',
00423     "cmdclass" : {
00424         "install" : install_biopython,
00425         "build_py" : build_py_biopython,
00426         "build_ext" : build_ext_biopython,
00427         "test" : test_biopython,
00428         },
00429     "packages" : PACKAGES,
00430     "ext_modules" : EXTENSIONS,
00431     "package_data" : {
00432         'Bio.Entrez': ['DTDs/*.dtd', 'DTDs/*.ent', 'DTDs/*.mod'],
00433         'Bio.PopGen': ['SimCoal/data/*.par'],
00434          },
00435    }
00436 
00437 if _SETUPTOOLS:
00438     setup_args["install_requires"] = get_install_requires()
00439 
00440 try:
00441     setup(**setup_args)
00442 finally:
00443     del sys.path[0]
00444     os.chdir(old_path)