WIP [pkg] Use setuptools

TODO:

  • build gecode extension
authorRémi Cardona <remi.cardona@free.fr>
changesetd8abe60fb3fe
branchdefault
phasedraft
hiddenyes
parent revision#37eb5bac804a fixup setup.py
child revision<not specified>
files modified by this revision
__init__.py
__pkginfo__.py
_exceptions.py
analyze.py
base.py
compare.py
editextensions.py
gecode_solver.cpp
interfaces.py
nodes.py
parser.g
parser.py
parser_main.py
pygments_ext.py
rql/__init__.py
rql/_exceptions.py
rql/analyze.py
rql/base.py
rql/compare.py
rql/editextensions.py
rql/gecode_solver.cpp
rql/interfaces.py
rql/nodes.py
rql/parser.g
rql/parser.py
rql/parser_main.py
rql/pygments_ext.py
rql/rqlgen.py
rql/stcheck.py
rql/stmts.py
rql/undo.py
rql/utils.py
rqlgen.py
setup.py
stcheck.py
stmts.py
undo.py
utils.py
# HG changeset patch
# User Rémi Cardona <remi.cardona@free.fr>
# Date 1432768408 -7200
# Thu May 28 01:13:28 2015 +0200
# Node ID d8abe60fb3feeefa758f6a14f18174a7cfe2936a
# Parent 37eb5bac804a5224969c56029f092fda7c567322
WIP [pkg] Use setuptools

TODO:

- build gecode extension

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