~ubuntu-branches/ubuntu/hardy/psycopg2/hardy

« back to all changes in this revision

Viewing changes to setup.py

  • Committer: Bazaar Package Importer
  • Author(s): Fabio Tranchitella
  • Date: 2006-08-09 10:28:30 UTC
  • Revision ID: james.westby@ubuntu.com-20060809102830-grac1dsp24uyqfp4
Tags: upstream-2.0.4
ImportĀ upstreamĀ versionĀ 2.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# setup.py - distutils packaging
 
2
#
 
3
# Copyright (C) 2003-2004 Federico Di Gregorio  <fog@debian.org>
 
4
#
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by the
 
7
# Free Software Foundation; either version 2, or (at your option) any later
 
8
# version.
 
9
#
 
10
# This program is distributed in the hope that it will be useful, but
 
11
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
 
12
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
13
# for more details.
 
14
 
 
15
"""Python-PostgreSQL Database Adapter
 
16
 
 
17
psycopg is a PostgreSQL database adapter for the Python programming
 
18
language. This is version 2, a complete rewrite of the original code to
 
19
provide new-style classes for connection and cursor objects and other sweet
 
20
candies. Like the original, psycopg 2 was written with the aim of being
 
21
very small and fast, and stable as a rock.
 
22
 
 
23
psycopg is different from the other database adapter because it was
 
24
designed for heavily multi-threaded applications that create and destroy
 
25
lots of cursors and make a conspicuous number of concurrent INSERTs or
 
26
UPDATEs. psycopg 2 also provide full asycronous operations for the really
 
27
brave programmer.
 
28
"""
 
29
 
 
30
classifiers = """\
 
31
Development Status :: 4 - Beta
 
32
Intended Audience :: Developers
 
33
License :: OSI Approved :: GNU General Public License (GPL)
 
34
License :: OSI Approved :: Zope Public License
 
35
Programming Language :: Python
 
36
Programming Language :: C
 
37
Programming Language :: SQL
 
38
Topic :: Database
 
39
Topic :: Database :: Front-Ends
 
40
Topic :: Software Development
 
41
Topic :: Software Development :: Libraries :: Python Modules
 
42
Operating System :: Microsoft :: Windows
 
43
Operating System :: Unix
 
44
"""
 
45
 
 
46
import os
 
47
import sys
 
48
import popen2
 
49
from distutils.core import setup, Extension
 
50
from distutils.errors import DistutilsFileError
 
51
from distutils.command.build_ext import build_ext
 
52
from distutils.sysconfig import get_python_inc
 
53
from distutils.ccompiler import get_default_compiler
 
54
 
 
55
PSYCOPG_VERSION = '2.0.4'
 
56
version_flags   = []
 
57
 
 
58
# to work around older distutil limitations
 
59
if sys.version < '2.2.3':
 
60
    from distutils.dist import DistributionMetadata
 
61
    DistributionMetadata.classifiers = None
 
62
    DistributionMetadata.download_url = None
 
63
 
 
64
def get_pg_config(kind, pg_config="pg_config"):
 
65
    p = popen2.popen3(pg_config + " --" + kind)
 
66
    r = p[0].readline().strip()
 
67
    if not r:
 
68
        raise Warning(p[2].readline())
 
69
    return r
 
70
    
 
71
class psycopg_build_ext(build_ext):
 
72
    """Conditionally complement the setup.cfg options file.
 
73
    
 
74
    This class configures the include_dirs, libray_dirs, libraries
 
75
    options as required by the system. Most of the configuration happens
 
76
    in finalize_options() method.
 
77
    
 
78
    If you want to set up the build step for a peculiar platform, add a
 
79
    method finalize_PLAT(), where PLAT matches your sys.platform.
 
80
    """
 
81
    user_options = build_ext.user_options[:]
 
82
    user_options.extend([
 
83
        ('use-pydatetime', None,
 
84
         "Use Python datatime objects for date and time representation."),    
 
85
        ('pg-config=', None,
 
86
          "The name of the pg_config binary and/or full path to find it"),
 
87
        ('use-decimal', None,
 
88
         "Use Decimal type even on Python 2.3 if the module is provided."),
 
89
    ])
 
90
    
 
91
    boolean_options = build_ext.boolean_options[:]
 
92
    boolean_options.extend(('use-pydatetime', 'use-decimal'))
 
93
    
 
94
    DEFAULT_PG_CONFIG = "pg_config"
 
95
    
 
96
    def initialize_options(self):
 
97
        build_ext.initialize_options(self)
 
98
        self.use_pydatetime = 1
 
99
        self.use_pg_dll = 1
 
100
        self.pgdir = None
 
101
        self.pg_config = self.DEFAULT_PG_CONFIG
 
102
        self.mx_include_dir = None
 
103
    
 
104
    def get_compiler(self):
 
105
        """Return the c compiler to compile extensions.
 
106
 
 
107
        If a compiler was not explicitely set (on the command line, for
 
108
        example), fall back on the default compiler.
 
109
        """
 
110
        return self.compiler or get_default_compiler()
 
111
 
 
112
    def get_pg_config(self, kind):
 
113
        return get_pg_config(kind, self.pg_config)
 
114
 
 
115
    def build_extensions(self):
 
116
        # Linking against this library causes psycopg2 to crash 
 
117
        # on Python >= 2.4. Maybe related to strdup calls, cfr.
 
118
        # http://mail.python.org/pipermail/distutils-sig/2005-April/004433.html
 
119
        if self.get_compiler().compiler_type == "mingw32" \
 
120
            and 'msvcr71' in self.compiler.dll_libraries:
 
121
            self.compiler.dll_libraries.remove('msvcr71')
 
122
 
 
123
        build_ext.build_extensions(self)
 
124
        
 
125
    def finalize_win32(self):
 
126
        """Finalize build system configuration on win32 platform."""
 
127
        self.libraries.append("ws2_32")
 
128
        self.libraries.append("advapi32")
 
129
        if self.get_compiler() == "msvc":
 
130
            # MSVC requires an explicit "libpq"
 
131
            self.libraries.remove("pq")
 
132
            self.libraries.append("libpq")
 
133
            self.libraries.append("shfolder")
 
134
            for path in self.library_dirs: 
 
135
                if os.path.isfile(os.path.join(path, "ms", "libpq.lib")): 
 
136
                    self.library_dirs.append(os.path.join(path, "ms")) 
 
137
                    break
 
138
 
 
139
    def finalize_darwin(self):
 
140
        """Finalize build system configuration on darwin platform."""
 
141
        self.libraries.append('ssl')
 
142
        self.libraries.append('crypto')
 
143
        
 
144
    def finalize_options(self):
 
145
        """Complete the build system configuation."""
 
146
        build_ext.finalize_options(self)
 
147
 
 
148
        self.include_dirs.append(".")        
 
149
        self.libraries.append("pq")
 
150
        
 
151
        try:
 
152
            self.library_dirs.append(self.get_pg_config("libdir"))
 
153
            self.include_dirs.append(self.get_pg_config("includedir"))
 
154
            self.include_dirs.append(self.get_pg_config("includedir-server"))
 
155
            try:
 
156
                # Here we take a conservative approach: we suppose that
 
157
                # *at least* PostgreSQL 7.4 is available (this is the only
 
158
                # 7.x series supported by psycopg 2)
 
159
                pgversion = self.get_pg_config("version").split()[1]
 
160
                pgmajor, pgminor, pgpatch = pgversion.split('.')
 
161
            except:
 
162
                pgmajor, pgminor, pgpatch = 7, 4, 0
 
163
            define_macros.append(("PG_MAJOR_VERSION", pgmajor))
 
164
            define_macros.append(("PG_MINOR_VERSION", pgminor))
 
165
            define_macros.append(("PG_PATCH_VERSION", pgpatch))
 
166
        except Warning, w:
 
167
            if self.pg_config == self.DEFAULT_PG_CONFIG:
 
168
                sys.stderr.write("Warning: %s" % str(w))
 
169
            else:
 
170
                sys.stderr.write("Error: %s" % str(w))
 
171
                sys.exit(1)
 
172
            
 
173
        if hasattr(self, "finalize_" + sys.platform):
 
174
            getattr(self, "finalize_" + sys.platform)()
 
175
            
 
176
# let's start with macro definitions (the ones not already in setup.cfg)
 
177
define_macros = []
 
178
include_dirs = []
 
179
 
 
180
# python version
 
181
define_macros.append(('PY_MAJOR_VERSION', str(sys.version_info[0])))
 
182
define_macros.append(('PY_MINOR_VERSION', str(sys.version_info[1])))
 
183
 
 
184
# some macros related to python versions and features
 
185
if sys.version_info[0] >= 2 and sys.version_info[1] >= 3:
 
186
    define_macros.append(('HAVE_PYBOOL','1'))
 
187
    
 
188
# gather information to build the extension module
 
189
ext = [] ; data_files = []
 
190
 
 
191
# sources
 
192
 
 
193
sources = [
 
194
    'psycopgmodule.c', 'pqpath.c',  'typecast.c',
 
195
    'microprotocols.c', 'microprotocols_proto.c', 
 
196
    'connection_type.c', 'connection_int.c', 'cursor_type.c', 'cursor_int.c',
 
197
    'adapter_qstring.c', 'adapter_pboolean.c', 'adapter_binary.c',
 
198
    'adapter_asis.c', 'adapter_list.c']
 
199
 
 
200
from ConfigParser import ConfigParser
 
201
parser = ConfigParser()
 
202
parser.read('setup.cfg')
 
203
 
 
204
# Choose if to use Decimal type
 
205
use_decimal = int(parser.get('build_ext', 'use_decimal'))
 
206
if sys.version_info[0] >= 2 and (
 
207
    sys.version_info[1] >= 4 or (sys.version_info[1] == 3 and use_decimal)):
 
208
    define_macros.append(('HAVE_DECIMAL','1'))
 
209
    version_flags.append('dec')
 
210
 
 
211
# Choose a datetime module
 
212
have_pydatetime = False
 
213
have_mxdatetime = False
 
214
use_pydatetime  = int(parser.get('build_ext', 'use_pydatetime'))
 
215
 
 
216
# check for mx package
 
217
if parser.has_option('build_ext', 'mx_include_dir'):
 
218
    mxincludedir = parser.get('build_ext', 'mx_include_dir')
 
219
else:
 
220
    mxincludedir = os.path.join(get_python_inc(plat_specific=1), "mx")
 
221
if os.path.exists(mxincludedir):
 
222
    include_dirs.append(mxincludedir)
 
223
    define_macros.append(('HAVE_MXDATETIME','1'))
 
224
    sources.append('adapter_mxdatetime.c')
 
225
    have_mxdatetime = True
 
226
    version_flags.append('mx')
 
227
 
 
228
# check for python datetime package
 
229
if os.path.exists(os.path.join(get_python_inc(plat_specific=1),"datetime.h")):
 
230
    define_macros.append(('HAVE_PYDATETIME','1'))
 
231
    sources.append('adapter_datetime.c')
 
232
    have_pydatetime = True
 
233
    version_flags.append('dt')
 
234
    
 
235
# now decide which package will be the default for date/time typecasts
 
236
if have_pydatetime and use_pydatetime \
 
237
       or have_pydatetime and not have_mxdatetime:
 
238
    define_macros.append(('PSYCOPG_DEFAULT_PYDATETIME','1'))
 
239
elif have_mxdatetime:
 
240
    define_macros.append(('PSYCOPG_DEFAULT_MXDATETIME','1'))
 
241
else:
 
242
    def e(msg):
 
243
        sys.stderr.write("error: " + msg + "\n")
 
244
    e("psycopg requires a datetime module:")
 
245
    e("    mx.DateTime module not found")
 
246
    e("    python datetime module not found")
 
247
    e("Note that psycopg needs the module headers and not just the module")
 
248
    e("itself. If you installed Python or mx.DateTime from a binary package")
 
249
    e("you probably need to install its companion -dev or -devel package.")
 
250
    sys.exit(1)
 
251
 
 
252
# generate a nice version string to avoid confusion when users report bugs
 
253
for have in parser.get('build_ext', 'define').split(','):
 
254
    if have == 'PSYCOPG_EXTENSIONS':
 
255
        version_flags.append('ext')
 
256
    elif have == 'HAVE_PQPROTOCOL3':
 
257
        version_flags.append('pq3')
 
258
if version_flags:
 
259
    PSYCOPG_VERSION_EX = PSYCOPG_VERSION + " (%s)" % ' '.join(version_flags)
 
260
else:
 
261
    PSYCOPG_VERSION_EX = PSYCOPG_VERSION
 
262
    
 
263
if sys.platform != 'win32':
 
264
    define_macros.append(('PSYCOPG_VERSION', '"'+PSYCOPG_VERSION_EX+'"'))
 
265
else:
 
266
    define_macros.append(('PSYCOPG_VERSION', '\\"'+PSYCOPG_VERSION_EX+'\\"'))
 
267
 
 
268
# build the extension
 
269
 
 
270
sources = map(lambda x: os.path.join('psycopg', x), sources)
 
271
 
 
272
ext.append(Extension("psycopg2._psycopg", sources,
 
273
                     define_macros=define_macros,
 
274
                     include_dirs=include_dirs,
 
275
                     undef_macros=[]))
 
276
 
 
277
setup(name="psycopg2",
 
278
      version=PSYCOPG_VERSION,
 
279
      maintainer="Federico Di Gregorio",
 
280
      maintainer_email="fog@initd.org",
 
281
      author="Federico Di Gregorio",
 
282
      author_email="fog@initd.org",
 
283
      url="http://initd.org/tracker/psycopg",
 
284
      download_url = "http://initd.org/pub/software/psycopg2",
 
285
      license="GPL with exceptions or ZPL",
 
286
      platforms = ["any"],
 
287
      description=__doc__.split("\n")[0],
 
288
      long_description="\n".join(__doc__.split("\n")[2:]),
 
289
      classifiers=filter(None, classifiers.split("\n")),
 
290
      data_files=data_files,
 
291
      package_dir={'psycopg2':'lib'},
 
292
      packages=['psycopg2'],
 
293
      cmdclass={ 'build_ext': psycopg_build_ext },
 
294
      ext_modules=ext)