# HG changeset patch
# User Julien Cristau <julien.cristau@logilab.fr>
# Date 1432768408 -7200
# Thu May 28 01:13:28 2015 +0200
# Node ID d9762b5a4604f3616c7f8501a29fd0878e8e1a88
# Parent 5b44acfd687b253fe5ca76ed3cf0356c0842aeba
[pkg] Use setuptools
Move sources to a 'rql' subdirectory, drop the NO_SETUPTOOLS code path
(essentially rewriting all of setup.py). This avoids a conflict between
our parser.py and the stdlib when running setup.py. Closes #278637.
# User Julien Cristau <julien.cristau@logilab.fr>
# Date 1432768408 -7200
# Thu May 28 01:13:28 2015 +0200
# Node ID d9762b5a4604f3616c7f8501a29fd0878e8e1a88
# Parent 5b44acfd687b253fe5ca76ed3cf0356c0842aeba
[pkg] Use setuptools
Move sources to a 'rql' subdirectory, drop the NO_SETUPTOOLS code path
(essentially rewriting all of setup.py). This avoids a conflict between
our parser.py and the stdlib when running setup.py. Closes #278637.
@@ -58,19 +58,19 @@
1 return ((a<<16)+(b<<8)+c) 2 3 GECODE_VERSION = encode_version(*gecode_version()) 4 5 if sys.platform != 'win32': 6 - ext_modules = [Extension('rql_solve', 7 - ['gecode_solver.cpp'], 8 + ext_modules = [Extension('rql.rql_solve', 9 + ['rql/gecode_solver.cpp'], 10 libraries=['gecodeint', 'gecodekernel', 'gecodesearch',], 11 extra_compile_args=['-DGE_VERSION=%s' % GECODE_VERSION], 12 ) 13 ] 14 else: 15 - ext_modules = [ Extension('rql_solve', 16 - ['gecode_solver.cpp'], 17 + ext_modules = [ Extension('rql.rql_solve', 18 + ['rql/gecode_solver.cpp'], 19 libraries=['GecodeInt-3-3-1-r-x86', 20 'GecodeKernel-3-3-1-r-x86', 21 'GecodeSearch-3-3-1-r-x86', 22 'GecodeSupport-3-3-1-r-x86', 23 ],
@@ -83,6 +83,7 @@
24 'logilab-common >= 0.47.0', 25 'logilab-database >= 1.6.0', 26 'yapps >= 2.2.0', # XXX to ensure we don't use the broken pypi version 27 'logilab-constraint >= 0.5.0', # fallback if the gecode compiled module is missing 28 'six >= 1.4.0', 29 + 'setuptools', 30 ]
@@ -16,22 +16,25 @@
31 # You should have received a copy of the GNU Lesser General Public License along 32 # with rql. If not, see <http://www.gnu.org/licenses/>. 33 """RQL library (implementation independant).""" 34 __docformat__ = "restructuredtext en" 35 36 -from rql.__pkginfo__ import version as __version__ 37 from math import log 38 39 import sys 40 import threading 41 42 +import pkg_resources 43 from six import StringIO 44 45 from rql._exceptions import * 46 47 + 48 +__version__ = pkg_resources.get_distribution('rql').version 49 #REQUIRED_TYPES = ['String', 'Float', 'Int', 'Boolean', 'Date'] 50 51 + 52 class RQLHelper(object): 53 """Helper class for RQL handling 54 55 give access to methods for : 56 - parsing RQL strings
@@ -17,208 +17,42 @@
57 # 58 # You should have received a copy of the GNU Lesser General Public License along 59 # with rql. If not, see <http://www.gnu.org/licenses/>. 60 """Generic Setup script, takes package info from __pkginfo__.py file. 61 """ 62 -__docformat__ = "restructuredtext en" 63 - 64 -import os 65 -import sys 66 -import shutil 67 -from os.path import isdir, exists, join, walk 68 69 -try: 70 - if os.environ.get('NO_SETUPTOOLS'): 71 - raise ImportError() 72 - from setuptools import setup 73 - from setuptools.command import install_lib, build_ext 74 - USE_SETUPTOOLS = 1 75 -except ImportError: 76 - from distutils.core import setup 77 - from distutils.command import install_lib, build_ext 78 - USE_SETUPTOOLS = 0 79 - 80 +from setuptools import setup, find_packages 81 +from io import open 82 +from os import path 83 84 -sys.modules.pop('__pkginfo__', None) 85 -# import required features 86 -from __pkginfo__ import modname, version, license, description, long_desc, \ 87 - web, author, author_email 88 -# import optional features 89 -import __pkginfo__ 90 -distname = getattr(__pkginfo__, 'distname', modname) 91 -scripts = getattr(__pkginfo__, 'scripts', []) 92 -data_files = getattr(__pkginfo__, 'data_files', None) 93 -subpackage_of = getattr(__pkginfo__, 'subpackage_of', None) 94 -include_dirs = getattr(__pkginfo__, 'include_dirs', []) 95 -ext_modules = getattr(__pkginfo__, 'ext_modules', None) 96 -install_requires = getattr(__pkginfo__, 'install_requires', None) 97 -dependency_links = getattr(__pkginfo__, 'dependency_links', []) 98 +here = path.abspath(path.dirname(__file__)) 99 100 -STD_BLACKLIST = ('CVS', '.svn', '.hg', 'debian', 'dist', 'build') 101 - 102 -IGNORED_EXTENSIONS = ('.pyc', '.pyo', '.elc', '~') 103 - 104 - 105 +pkginfo = {} 106 +with open(path.join(here, '__pkginfo__.py')) as f: 107 + exec(f.read(), pkginfo) 108 109 -def ensure_scripts(linux_scripts): 110 - """ 111 - Creates the proper script names required for each platform 112 - (taken from 4Suite) 113 - """ 114 - from distutils import util 115 - if util.get_platform()[:3] == 'win': 116 - scripts_ = [script + '.bat' for script in linux_scripts] 117 - else: 118 - scripts_ = linux_scripts 119 - return scripts_ 120 - 121 +# Get the long description from the relevant file 122 +with open(path.join(here, 'README'), encoding='utf-8') as f: 123 + long_description = f.read() 124 125 -def get_packages(directory, prefix): 126 - """return a list of subpackages for the given directory 127 - """ 128 - result = [] 129 - for package in os.listdir(directory): 130 - absfile = join(directory, package) 131 - if isdir(absfile): 132 - if exists(join(absfile, '__init__.py')) or \ 133 - package in ('test', 'tests'): 134 - if prefix: 135 - result.append('%s.%s' % (prefix, package)) 136 - else: 137 - result.append(package) 138 - result += get_packages(absfile, result[-1]) 139 - return result 140 +kwargs = {} 141 +if 'subpackage_of' in pkginfo: 142 + kwargs['namespace_packages'] = [pkginfo['subpackage_of']], 143 144 -def export(from_dir, to_dir, 145 - blacklist=STD_BLACKLIST, 146 - ignore_ext=IGNORED_EXTENSIONS, 147 - verbose=True): 148 - """make a mirror of from_dir in to_dir, omitting directories and files 149 - listed in the black list 150 - """ 151 - def make_mirror(arg, directory, fnames): 152 - """walk handler""" 153 - for norecurs in blacklist: 154 - try: 155 - fnames.remove(norecurs) 156 - except ValueError: 157 - pass 158 - for filename in fnames: 159 - # don't include binary files 160 - if filename[-4:] in ignore_ext: 161 - continue 162 - if filename[-1] == '~': 163 - continue 164 - src = join(directory, filename) 165 - dest = to_dir + src[len(from_dir):] 166 - if verbose: 167 - print >> sys.stderr, src, '->', dest 168 - if os.path.isdir(src): 169 - if not exists(dest): 170 - os.mkdir(dest) 171 - else: 172 - if exists(dest): 173 - os.remove(dest) 174 - shutil.copy2(src, dest) 175 - try: 176 - os.mkdir(to_dir) 177 - except OSError as ex: 178 - # file exists ? 179 - import errno 180 - if ex.errno != errno.EEXIST: 181 - raise 182 - walk(from_dir, make_mirror, None) 183 - 184 - 185 -EMPTY_FILE = '''"""generated file, don\'t modify or your data will be lost""" 186 -try: 187 - __import__('pkg_resources').declare_namespace(__name__) 188 -except ImportError: 189 - pass 190 -''' 191 - 192 -class MyInstallLib(install_lib.install_lib): 193 - """extend install_lib command to handle package __init__.py and 194 - include_dirs variable if necessary 195 - """ 196 - def run(self): 197 - """overridden from install_lib class""" 198 - install_lib.install_lib.run(self) 199 - # create Products.__init__.py if needed 200 - if subpackage_of: 201 - product_init = join(self.install_dir, subpackage_of, '__init__.py') 202 - if not exists(product_init): 203 - self.announce('creating %s' % product_init) 204 - stream = open(product_init, 'w') 205 - stream.write(EMPTY_FILE) 206 - stream.close() 207 - # manually install included directories if any 208 - if include_dirs: 209 - if subpackage_of: 210 - base = join(subpackage_of, modname) 211 - else: 212 - base = modname 213 - for directory in include_dirs: 214 - dest = join(self.install_dir, base, directory) 215 - export(directory, dest, verbose=False) 216 - 217 -if os.environ.get('RQL_FORCE_GECODE'): 218 - MyBuildExt = build_ext.build_ext 219 -else: 220 - class MyBuildExt(build_ext.build_ext): 221 - """Extend build_ext command to pass through compilation error. 222 - In fact, if gecode extension fail, rql will use logilab.constraint 223 - """ 224 - def run(self): 225 - try: 226 - build_ext.build_ext.run(self) 227 - except Exception: 228 - import traceback 229 - traceback.print_exc() 230 - sys.stderr.write('================================\n' 231 - 'The compilation of the gecode C extension failed. ' 232 - 'rql will use logilab.constraint which is a pure ' 233 - 'python implementation. ' 234 - 'Please note that the C extension run faster. ' 235 - 'So, install a compiler then install rql again with' 236 - ' the "force" option for better performance.\n' 237 - '================================\n') 238 - 239 -def install(**kwargs): 240 - """setup entry point""" 241 - if USE_SETUPTOOLS: 242 - if '--force-manifest' in sys.argv: 243 - sys.argv.remove('--force-manifest') 244 - # install-layout option was introduced in 2.5.3-1~exp1 245 - elif sys.version_info < (2, 5, 4) and '--install-layout=deb' in sys.argv: 246 - sys.argv.remove('--install-layout=deb') 247 - if subpackage_of: 248 - package = subpackage_of + '.' + modname 249 - kwargs['package_dir'] = {package : '.'} 250 - packages = [package] + get_packages(os.getcwd(), package) 251 - if USE_SETUPTOOLS: 252 - kwargs['namespace_packages'] = [subpackage_of] 253 - else: 254 - kwargs['package_dir'] = {modname : '.'} 255 - packages = [modname] + get_packages(os.getcwd(), modname) 256 - if USE_SETUPTOOLS and install_requires: 257 - kwargs['install_requires'] = install_requires 258 - kwargs['dependency_links'] = dependency_links 259 - kwargs['packages'] = packages 260 - return setup(name = distname, 261 - version = version, 262 - license = license, 263 - description = description, 264 - long_description = long_desc, 265 - author = author, 266 - author_email = author_email, 267 - url = web, 268 - scripts = ensure_scripts(scripts), 269 - data_files = data_files, 270 - ext_modules = ext_modules, 271 - cmdclass = {'install_lib': MyInstallLib, 272 - 'build_ext':MyBuildExt}, 273 - **kwargs 274 - ) 275 - 276 -if __name__ == '__main__' : 277 - install() 278 +setup( 279 + name=pkginfo.get('distname', pkginfo['modname']), 280 + version=pkginfo['version'], 281 + description=pkginfo['description'], 282 + long_description=long_description, 283 + url=pkginfo['web'], 284 + author=pkginfo['author'], 285 + author_email=pkginfo['author_email'], 286 + license=pkginfo['license'], 287 + # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 288 + classifiers=pkginfo.get('classifiers', []), 289 + packages=find_packages(exclude=['contrib', 'docs', 'test*']), 290 + install_requires=pkginfo.get('install_requires'), 291 + tests_require=pkginfo.get('tests_require'), 292 + scripts=pkginfo.get('scripts', []), 293 + ext_modules=pkginfo.get('ext_modules'), 294 + **kwargs 295 +)