File: setup.py

package info (click to toggle)
openbabel 3.1.1%2Bdfsg-12
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 259,676 kB
  • sloc: cpp: 361,956; python: 11,640; ansic: 6,470; perl: 6,010; pascal: 793; php: 529; sh: 226; xml: 97; ruby: 64; makefile: 44; java: 23
file content (150 lines) | stat: -rw-r--r-- 6,245 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python
import os
import re
import subprocess
import sys
from distutils.command.build import build
from distutils.command.sdist import sdist
from distutils.errors import DistutilsExecError
from distutils.version import StrictVersion
from setuptools.command.build_ext import build_ext
from setuptools.command.install import install
from setuptools import setup, Extension


# Path to the directory that contains this setup.py file.
base_dir = os.path.abspath(os.path.dirname(__file__))


def find_version():
    """Extract the current version of these python bindings from the __init__.py file."""
    try:
        with open(os.path.join(base_dir, 'openbabel', '__init__.py')) as fp:
            for line in fp:
                version_match = re.match(r'^__version__ = "(.+?)"$', line)
                if version_match:
                    return version_match.group(1)
            raise Exception('Could not find version string in openbabel/__init__.py.')
    except IOError:
        raise Exception('Could not find openbabel/__init__.py.')


def pkgconfig(package, option):
    """Wrapper around pkg-config command line tool."""
    try:
        return subprocess.check_output(['pkg-config', option, package],
                                       universal_newlines=True).strip()
    except subprocess.CalledProcessError:
        raise Exception('Failed to run pkg-config')


def locate_ob():
    """Try use pkgconfig to locate Open Babel, otherwise guess default location."""
    try:
        # Warn if the (major, minor) version of the installed OB doesn't match these python bindings
        py_ver = StrictVersion(find_version())
        py_major_ver, py_minor_ver = py_ver.version[:2]
        pcfile = 'openbabel-{}'.format(py_major_ver)
        ob_ver = StrictVersion(pkgconfig(pcfile, '--modversion'))
        if not ob_ver.version[:2] == py_ver.version[:2]:
            print('Warning: Open Babel {}.{}.x is required. Your version ({}) may not be compatible.'
                  .format(py_major_ver, py_minor_ver, ob_ver))
        include_dirs = pkgconfig(pcfile, '--variable=pkgincludedir')
        library_dirs = pkgconfig(pcfile, '--variable=libdir')
        print('Open Babel location automatically determined by pkg-config:')
    except Exception as e:
        print('Warning: %s.\nGuessing Open Babel location:' % e)
        include_dirs = '/usr/local/include/openbabel3'
        library_dirs = '/usr/local/lib'
    return include_dirs, library_dirs


class CustomBuild(build):
    """Ensure build_ext runs first in build command."""
    def run(self):
        self.run_command('build_ext')
        build.run(self)


class CustomInstall(install):
    """Ensure build_ext runs first in install command."""
    def run(self):
        self.run_command('build_ext')
        install.run(self)


class CustomSdist(sdist):
    """Add swig interface files into distribution from parent directory."""
    def make_release_tree(self, base_dir, files):
        sdist.make_release_tree(self, base_dir, files)
        link = 'hard' if hasattr(os, 'link') else None
        pkg_dir = os.path.join(base_dir, 'openbabel')
        self.copy_file(os.path.join('..', 'stereo.i'), pkg_dir, link=link)
        self.copy_file(os.path.join('..', 'openbabel-python.i'), pkg_dir, link=link)


class CustomBuildExt(build_ext):
    """Custom build_ext to set SWIG options and print a better error message."""
    def finalize_options(self):
        # Setting include_dirs, library_dirs, swig_opts here instead of in Extension constructor allows them to be
        # overridden using -I and -L command line options to python setup.py build_ext.
        build_ext.finalize_options(self)
        self.ob_include_dir, self.ob_library_dir = locate_ob()
        self.include_dirs.append(self.ob_include_dir)
        self.library_dirs.append(self.ob_library_dir)
        self.swig_opts = ['-c++', '-small', '-O', '-templatereduce', '-naturalvar']
        self.swig_opts += ['-I%s' % i for i in self.include_dirs]
        print('- include_dirs: %s\n- library_dirs: %s' % (self.include_dirs, self.library_dirs))

    def swig_sources(self, sources, extension):
        try:
            return build_ext.swig_sources(self, sources, extension)
        except DistutilsExecError:
            print('\nError: SWIG failed. Is Open Babel installed?',
                  'You may need to manually specify the location of Open Babel include and library directories. '
                  'For example:',
                  '  python setup.py build_ext -I{} -L{}'.format(self.ob_include_dir, self.ob_library_dir),
                  '  python setup.py install',
                  sep='\n')
            sys.exit(1)


obextension = Extension(
    'openbabel._openbabel', [os.path.join('openbabel', 'openbabel-python.i')], libraries=['openbabel']
)


setup(
    name='openbabel',
    version=find_version(),
    author='Noel O\'Boyle',
    author_email='openbabel-discuss@lists.sourceforge.net',
    license='GPL-2.0',
    url='http://openbabel.org/',
    description='Python interface to the Open Babel chemistry library',
    long_description=open(os.path.join(base_dir, 'README.rst')).read(),
    zip_safe=False,
    cmdclass={'build': CustomBuild, 'build_ext': CustomBuildExt, 'install': CustomInstall, 'sdist': CustomSdist},
    packages=['openbabel'],
    ext_modules=[obextension],
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Environment :: Console',
        'Environment :: Other Environment',
        'Intended Audience :: Education',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: GNU General Public License (GPL)',
        'Natural Language :: English',
        'Operating System :: MacOS :: MacOS X',
        'Operating System :: Microsoft :: Windows',
        'Operating System :: OS Independent',
        'Operating System :: POSIX',
        'Operating System :: POSIX :: Linux',
        'Operating System :: Unix',
        'Programming Language :: C++',
        'Programming Language :: Python',
        'Topic :: Scientific/Engineering :: Bio-Informatics',
        'Topic :: Scientific/Engineering :: Chemistry',
        'Topic :: Software Development :: Libraries'
    ]
)