Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 327 lines (232 sloc) 11.294 kb
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
1 #!/usr/bin/python
2
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
3 import sys, os, re, platform
eb54575 @mkleehammer Issue 80: setup.py uses setuptools if available to allow building eggs
authored
4 from os.path import exists, abspath, dirname, join, isdir
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
5 from ConfigParser import SafeConfigParser
eb54575 @mkleehammer Issue 80: setup.py uses setuptools if available to allow building eggs
authored
6
7 try:
8 # Allow use of setuptools so eggs can be built.
b4cf762 @mkleehammer Issue 167: Import of setuptools incorrect
authored
9 from setuptools import setup, Command
eb54575 @mkleehammer Issue 80: setup.py uses setuptools if available to allow building eggs
authored
10 except ImportError:
11 from distutils.core import setup, Command
12
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
13 from distutils.extension import Extension
14 from distutils.errors import *
15
16 OFFICIAL_BUILD = 9999
17
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
18
e82cb43 Added version command to setup.py
Michael Kleehammer authored
19 class VersionCommand(Command):
f89886e @mkleehammer Added description to setup version command
authored
20
a42975a @mkleehammer Ported setup tags command from v31 branch.
authored
21 description = "prints the pyodbc version, determined from git"
f89886e @mkleehammer Added description to setup version command
authored
22
e82cb43 Added version command to setup.py
Michael Kleehammer authored
23 user_options = []
24
25 def initialize_options(self):
26 self.verbose = 0
27
28 def finalize_options(self):
29 pass
30
31 def run(self):
32 version_str, version = get_version()
33 print version_str
34
35
a42975a @mkleehammer Ported setup tags command from v31 branch.
authored
36 class TagsCommand(Command):
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
37
a42975a @mkleehammer Ported setup tags command from v31 branch.
authored
38 description = 'runs etags'
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
39
a42975a @mkleehammer Ported setup tags command from v31 branch.
authored
40 user_options = []
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
41
a42975a @mkleehammer Ported setup tags command from v31 branch.
authored
42 def initialize_options(self):
43 pass
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
44
a42975a @mkleehammer Ported setup tags command from v31 branch.
authored
45 def finalize_options(self):
46 pass
47
48 def run(self):
49 # Windows versions of etag do not seem to expand wildcards (which Unix shells normally do for Unix utilities),
50 # so find all of the files ourselves.
51 files = [ join('src', f) for f in os.listdir('src') if f.endswith(('.h', '.cpp')) ]
52 cmd = 'etags %s' % ' '.join(files)
53 return os.system(cmd)
54
55
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
56
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
57 def main():
58
59 version_str, version = get_version()
60
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
61 settings = get_compiler_settings(version_str)
04d8111 @mkleehammer Added SQL Server 2008 date/time extensions support. Now caches conne…
authored
62
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
63 files = [ abspath(join('src', f)) for f in os.listdir('src') if f.endswith('.cpp') ]
523aed0 @mkleehammer Issue 91: decimal fix; Completely reworked parameters; added leakcheck
authored
64
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
65 if exists('MANIFEST'):
66 os.remove('MANIFEST')
67
9b7799f @mkleehammer Issue 182: Installer crash on Windows 7 due to UAC
authored
68 options = {}
69 if sys.hexversion >= 0x02060000:
70 options['bdist_wininst'] = {'user_access_control' : 'auto'}
71
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
72 setup (name = "pyodbc",
73 version = version_str,
74 description = "DB API Module for ODBC",
75
76 long_description = ('A Python DB API 2 module for ODBC. This project provides an up-to-date, '
77 'convenient interface to ODBC using native data types like datetime and decimal.'),
78
79 maintainer = "Michael Kleehammer",
80 maintainer_email = "michael@kleehammer.com",
81
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
82 ext_modules = [Extension('pyodbc', files, **settings)],
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
83
9b7799f @mkleehammer Issue 182: Installer crash on Windows 7 due to UAC
authored
84 options = options,
85
1567234 eliminate gcc write-strings warnings; caused by Python declarations -…
Michael Kleehammer authored
86 classifiers = ['Development Status :: 5 - Production/Stable',
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
87 'Intended Audience :: Developers',
88 'Intended Audience :: System Administrators',
89 'License :: OSI Approved :: MIT License',
90 'Operating System :: Microsoft :: Windows',
91 'Operating System :: POSIX',
92 'Programming Language :: Python',
93 'Topic :: Database',
1567234 eliminate gcc write-strings warnings; caused by Python declarations -…
Michael Kleehammer authored
94 ],
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
95
47138be @mkleehammer Updated metadata to point to Google code hosting
authored
96 url = 'http://code.google.com/p/pyodbc',
e82cb43 Added version command to setup.py
Michael Kleehammer authored
97 download_url = 'http://code.google.com/p/pyodbc/downloads/list',
a42975a @mkleehammer Ported setup tags command from v31 branch.
authored
98 cmdclass = { 'version' : VersionCommand,
99 'tags' : TagsCommand })
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
100
101
04d8111 @mkleehammer Added SQL Server 2008 date/time extensions support. Now caches conne…
authored
102
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
103 def get_compiler_settings(version_str):
104
105 settings = { 'libraries': [],
106 'define_macros' : [ ('PYODBC_VERSION', version_str) ] }
107
108 # This isn't the best or right way to do this, but I don't see how someone is supposed to sanely subclass the build
109 # command.
110 for option in ['assert', 'trace', 'leak-check']:
111 try:
112 sys.argv.remove('--%s' % option)
113 settings['define_macros'].append(('PYODBC_%s' % option.replace('-', '_'), 1))
114 except ValueError:
115 pass
116
117 if os.name == 'nt':
3c7a9e7 @mkleehammer Cleaned up compiler warnings
authored
118 settings['extra_compile_args'] = ['/Wall',
119 '/wd4668',
120 '/wd4820',
121 '/wd4711', # function selected for automatic inline expansion
122 '/wd4100', # unreferenced formal parameter
123 '/wd4127', # "conditional expression is constant" testing compilation constants
124 '/wd4191', # casts to PYCFunction, perhaps the extra parameters should be added
125 ]
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
126 settings['libraries'].append('odbc32')
eeede2f @mkleehammer Added pyodbc.drivers() for Windows builds.
authored
127 settings['libraries'].append('advapi32')
9dd144f @mkleehammer Added pyodbc.conf for preprocessor-time access to sizeof(SQLWCHAR)
authored
128
129 elif os.environ.get("OS", '').lower().startswith('windows'):
130 # Windows Cygwin (posix on windows)
131 # OS name not windows, but still on Windows
132 settings['libraries'].append('odbc32')
133
134 elif sys.platform == 'darwin':
135 # OS/X now ships with iODBC.
136 settings['libraries'].append('iodbc')
137
138 else:
139 # Other posix-like: Linux, Solaris, etc.
140
141 # Python functions take a lot of 'char *' that really should be const. gcc complains about this *a lot*
142 settings['extra_compile_args'] = ['-Wno-write-strings']
143
144 # What is the proper way to detect iODBC, MyODBC, unixODBC, etc.?
145 settings['libraries'].append('odbc')
146
147 get_config(settings, version_str)
148
149 return settings
150
151
152 def get_config(settings, version_str):
153 """
154 Adds configuration macros from pyodbc.conf to the compiler settings dictionary.
155
156 If pyodbc.conf does not exist, it will compile and run the pyodbcconf utility.
157
158 This is similar to what autoconf provides, but only uses the infrastructure provided by Python, which is important
159 for building on *nix and Windows.
160 """
161 filename = 'pyodbc.conf'
162
163 # If the file exists, make sure that the version in it is the same as the version we are compiling. Otherwise we
164 # might have added configuration items that aren't there.
165 if exists(filename):
166 try:
167 config = SafeConfigParser()
168 config.read(filename)
169
170 if (not config.has_option('define_macros', 'pyodbc_version') or
171 config.get('define_macros', 'pyodbc_version') != version_str):
172 print 'Recreating pyodbc.conf for new version'
173 os.remove(filename)
174
175 except:
176 config = None
177 # Assume the file has been corrupted. Delete and recreate
178 print 'Unable to read %s. Recreating' % filename
179 os.remove(filename)
180
181 if not exists('pyodbc.conf'):
182 # Doesn't exist, so build the pyodbcconf module and use it.
183
184 oldargv = sys.argv
185 sys.argv = [ oldargv[0], 'build' ]
186
187 setup(name="pyodbcconf",
188 ext_modules = [ Extension('pyodbcconf',
189 [join('utils', 'pyodbcconf', 'pyodbcconf.cpp')],
190 **settings) ])
191
192 sys.argv = oldargv
193
194 add_to_path()
195
196 import pyodbcconf
197 pyodbcconf.configure()
198
199 config = SafeConfigParser()
200 config.read(filename)
201
202 for section in config.sections():
203 for key, value in config.items(section):
204 settings[section].append( (key.upper(), value) )
205
206
207
208 def add_to_path():
209 """
210 Prepends the build directory to the path so pyodbcconf can be imported without installing it.
211 """
212 # Now run the utility
213
214 import imp
215 library_exts = [ t[0] for t in imp.get_suffixes() if t[-1] == imp.C_EXTENSION ]
216 library_names = [ 'pyodbcconf%s' % ext for ext in library_exts ]
217
218 # Only go into directories that match our version number.
219
220 dir_suffix = '-%s.%s' % (sys.version_info[0], sys.version_info[1])
221
222 build = join(dirname(abspath(__file__)), 'build')
223
224 for top, dirs, files in os.walk(build):
225 dirs = [ d for d in dirs if d.endswith(dir_suffix) ]
226 for name in library_names:
227 if name in files:
228 sys.path.insert(0, top)
229 return
230
231 raise SystemExit('Did not find pyodbcconf')
232
233
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
234 def get_version():
235 """
236 Returns the version of the product as (description, [major,minor,micro,beta]).
237
238 If the release is official, `beta` will be 9999 (OFFICIAL_BUILD).
239
240 1. If in a git repository, use the latest tag (git describe).
241 2. If in an unzipped source directory (from setup.py sdist),
242 read the version from the PKG-INFO file.
243 3. Use 2.1.0.0 and complain a lot.
244 """
245 # My goal is to (1) provide accurate tags for official releases but (2) not have to manage tags for every test
246 # release.
247 #
248 # Official versions are tagged using 3 numbers: major, minor, micro. A build of a tagged version should produce
249 # the version using just these pieces, such as 2.1.4.
250 #
251 # Unofficial versions are "working towards" the next version. So the next unofficial build after 2.1.4 would be a
252 # beta for 2.1.5. Using 'git describe' we can find out how many changes have been made after 2.1.4 and we'll use
253 # this count as the beta id (beta1, beta2, etc.)
254 #
c8c8fe1 fixed pyodbc.version for non-beta releases
Michael Kleehammer authored
255 # Since the 4 numbers are put into the Windows DLL, we want to make sure the beta versions sort *before* the
256 # official, so we set the official build number to 9999, but we don't show it.
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
257
258 name = None # branch/feature name. Should be None for official builds.
259 numbers = None # The 4 integers that make up the version.
260
261 # If this is a source release the version will have already been assigned and be in the PKG-INFO file.
262
263 name, numbers = _get_version_pkginfo()
264
265 # If not a source release, we should be in a git repository. Look for the latest tag.
266
267 if not numbers:
268 name, numbers = _get_version_git()
269
270 if not numbers:
271 print 'WARNING: Unable to determine version. Using 2.1.0.0'
272 name, numbers = '2.1.0-unsupported', [2,1,0,0]
273
274 return name, numbers
275
276
277 def _get_version_pkginfo():
278 filename = join(dirname(abspath(__file__)), 'PKG-INFO')
279 if exists(filename):
280 re_ver = re.compile(r'^Version: \s+ (\d+)\.(\d+)\.(\d+) (?: -beta(\d+))?', re.VERBOSE)
281 for line in open(filename):
282 match = re_ver.search(line)
283 if match:
284 name = line.split(':', 1)[1].strip()
9ff5342 @mkleehammer Issue 95: "beta0" added when building from source distribution.
authored
285 numbers = [int(n or 0) for n in match.groups()[:3]]
286 numbers.append(int(match.group(4) or OFFICIAL_BUILD)) # don't use 0 as a default for build
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
287 return name, numbers
288
289 return None, None
290
291
292 def _get_version_git():
9ff5342 @mkleehammer Issue 95: "beta0" added when building from source distribution.
authored
293 n, result = getoutput('git describe --tags --match 2.*')
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
294 if n:
295 print 'WARNING: git describe failed with: %s %s' % (n, result)
296 return None, None
297
298 match = re.match(r'(\d+).(\d+).(\d+) (?: -(\d+)-g[0-9a-z]+)?', result, re.VERBOSE)
299 if not match:
300 return None, None
301
1567234 eliminate gcc write-strings warnings; caused by Python declarations -…
Michael Kleehammer authored
302 numbers = [int(n or OFFICIAL_BUILD) for n in match.groups()]
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
303 if numbers[-1] == OFFICIAL_BUILD:
304 name = '%s.%s.%s' % tuple(numbers[:3])
305 if numbers[-1] != OFFICIAL_BUILD:
306 # This is a beta of the next micro release, so increment the micro number to reflect this.
307 numbers[-2] += 1
691b6ba @mkleehammer Reworked Unicode; changed version format; more Py_ssize_t
authored
308 name = '%s.%s.%s-beta%02d' % tuple(numbers)
309
310 n, result = getoutput('git branch')
311 branch = re.search(r'\* (\w+)', result).group(1)
312 if branch != 'master' and not re.match('^v\d+$', branch):
313 name = branch + '-' + name
314
c3f6b46 @mkleehammer Import from Subversion 2.0.63; reworked versioning
authored
315 return name, numbers
316
317
318
319 def getoutput(cmd):
320 pipe = os.popen(cmd, 'r')
321 text = pipe.read().rstrip('\n')
322 status = pipe.close() or 0
323 return status, text
324
325 if __name__ == '__main__':
326 main()
Something went wrong with that request. Please try again.