1
# setup.py - distutils packaging
3
# Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
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
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
15
"""Python-PostgreSQL Database Adapter
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.
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
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
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
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
55
PSYCOPG_VERSION = '2.0.4'
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
64
def get_pg_config(kind, pg_config="pg_config"):
65
p = popen2.popen3(pg_config + " --" + kind)
66
r = p[0].readline().strip()
68
raise Warning(p[2].readline())
71
class psycopg_build_ext(build_ext):
72
"""Conditionally complement the setup.cfg options file.
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.
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.
81
user_options = build_ext.user_options[:]
83
('use-pydatetime', None,
84
"Use Python datatime objects for date and time representation."),
86
"The name of the pg_config binary and/or full path to find it"),
88
"Use Decimal type even on Python 2.3 if the module is provided."),
91
boolean_options = build_ext.boolean_options[:]
92
boolean_options.extend(('use-pydatetime', 'use-decimal'))
94
DEFAULT_PG_CONFIG = "pg_config"
96
def initialize_options(self):
97
build_ext.initialize_options(self)
98
self.use_pydatetime = 1
101
self.pg_config = self.DEFAULT_PG_CONFIG
102
self.mx_include_dir = None
104
def get_compiler(self):
105
"""Return the c compiler to compile extensions.
107
If a compiler was not explicitely set (on the command line, for
108
example), fall back on the default compiler.
110
return self.compiler or get_default_compiler()
112
def get_pg_config(self, kind):
113
return get_pg_config(kind, self.pg_config)
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')
123
build_ext.build_extensions(self)
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"))
139
def finalize_darwin(self):
140
"""Finalize build system configuration on darwin platform."""
141
self.libraries.append('ssl')
142
self.libraries.append('crypto')
144
def finalize_options(self):
145
"""Complete the build system configuation."""
146
build_ext.finalize_options(self)
148
self.include_dirs.append(".")
149
self.libraries.append("pq")
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"))
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('.')
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))
167
if self.pg_config == self.DEFAULT_PG_CONFIG:
168
sys.stderr.write("Warning: %s" % str(w))
170
sys.stderr.write("Error: %s" % str(w))
173
if hasattr(self, "finalize_" + sys.platform):
174
getattr(self, "finalize_" + sys.platform)()
176
# let's start with macro definitions (the ones not already in setup.cfg)
181
define_macros.append(('PY_MAJOR_VERSION', str(sys.version_info[0])))
182
define_macros.append(('PY_MINOR_VERSION', str(sys.version_info[1])))
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'))
188
# gather information to build the extension module
189
ext = [] ; data_files = []
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']
200
from ConfigParser import ConfigParser
201
parser = ConfigParser()
202
parser.read('setup.cfg')
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')
211
# Choose a datetime module
212
have_pydatetime = False
213
have_mxdatetime = False
214
use_pydatetime = int(parser.get('build_ext', 'use_pydatetime'))
216
# check for mx package
217
if parser.has_option('build_ext', 'mx_include_dir'):
218
mxincludedir = parser.get('build_ext', 'mx_include_dir')
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')
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')
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'))
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.")
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')
259
PSYCOPG_VERSION_EX = PSYCOPG_VERSION + " (%s)" % ' '.join(version_flags)
261
PSYCOPG_VERSION_EX = PSYCOPG_VERSION
263
if sys.platform != 'win32':
264
define_macros.append(('PSYCOPG_VERSION', '"'+PSYCOPG_VERSION_EX+'"'))
266
define_macros.append(('PSYCOPG_VERSION', '\\"'+PSYCOPG_VERSION_EX+'\\"'))
268
# build the extension
270
sources = map(lambda x: os.path.join('psycopg', x), sources)
272
ext.append(Extension("psycopg2._psycopg", sources,
273
define_macros=define_macros,
274
include_dirs=include_dirs,
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",
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 },