File: setup.py

package info (click to toggle)
cu2qu 1.6.5-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 872 kB
  • sloc: python: 2,169; makefile: 6
file content (241 lines) | stat: -rw-r--r-- 8,728 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# Copyright 2015 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from setuptools import setup, find_packages, Extension
from setuptools.command.build_ext import build_ext as _build_ext
from setuptools.command.sdist import sdist as _sdist
import pkg_resources
from distutils import log
import sys
import os
import re
from io import open


needs_pytest = {'pytest', 'test'}.intersection(sys.argv)
pytest_runner = ['pytest_runner'] if needs_pytest else []
needs_wheel = {'bdist_wheel'}.intersection(sys.argv)
wheel = ['wheel'] if needs_wheel else []

# Check if minimum required Cython is available.
# For consistency, we require the same as our vendored Cython.Shadow module
cymod = "Lib/cu2qu/cython.py"
cython_version_re = re.compile('__version__ = ["\']([0-9][0-9\w\.]+)["\']')
with open(cymod, "r", encoding="utf-8") as fp:
    for line in fp:
        m = cython_version_re.match(line)
        if m:
            cython_min_version = m.group(1)
            break
    else:
        sys.exit("error: failed to parse cython version in '%s'" % cymod)

required_cython = "cython >= %s" % cython_min_version
try:
    pkg_resources.require(required_cython)
except pkg_resources.ResolutionError:
    has_cython = False
else:
    has_cython = True

# First, check if the CU2QU_WITH_CYTHON environment variable is set.
# Values "1", "true" or "yes" mean that Cython is required and will be used
# to regenerate the *.c sources from which the native extension is built;
# "0", "false" or "no" mean that Cython is not required and no extension
# module will be compiled (i.e. the wheel is pure-python and universal).
# If the variable is not set, then the pre-generated *.c sources that
# are included in the sdist package will be used to try build the extension.
# However, if any error occurs during compilation (e.g. the host
# machine doesn't have the required compiler toolchain installed), the
# installation proceeds without the compiled extensions, but will only have
# the pure-python module.
env_with_cython = os.environ.get("CU2QU_WITH_CYTHON")
with_cython = (
    True if env_with_cython in {"1", "true", "yes"}
    else False if env_with_cython in {"0", "false", "no"}
    else None
)

# command line options --with-cython and --without-cython are also supported.
# They override the environment variable
opt_with_cython = {'--with-cython'}.intersection(sys.argv)
opt_without_cython = {'--without-cython'}.intersection(sys.argv)
if opt_with_cython and opt_without_cython:
    sys.exit(
        "error: the options '--with-cython' and '--without-cython' are "
        "mutually exclusive"
    )
elif opt_with_cython:
    sys.argv.remove("--with-cython")
    with_cython = True
elif opt_without_cython:
    sys.argv.remove("--without-cython")
    with_cython = False


class cython_build_ext(_build_ext):
    """Compile *.pyx source files to *.c using cythonize if Cython is
    installed, else use the pre-generated *.c sources.
    """

    def finalize_options(self):
        if with_cython:
            if not has_cython:
                from distutils.errors import DistutilsSetupError

                raise DistutilsSetupError(
                    "%s is required when using --with-cython" % required_cython
                )

            from Cython.Build import cythonize

            # optionally enable line tracing for test coverage support
            linetrace = os.environ.get("CYTHON_TRACE") == "1"

            self.distribution.ext_modules[:] = cythonize(
                self.distribution.ext_modules,
                force=linetrace or self.force,
                annotate=os.environ.get("CYTHON_ANNOTATE") == "1",
                quiet=not self.verbose,
                compiler_directives={
                    "linetrace": linetrace,
                    "language_level": 3,
                    "embedsignature": True,
                },
            )
        else:
            # replace *.py/.pyx sources with their pre-generated *.c versions
            for ext in self.distribution.ext_modules:
                ext.sources = [re.sub("\.pyx?$", ".c", n) for n in ext.sources]

        _build_ext.finalize_options(self)

    def build_extensions(self):
        if not has_cython:
            log.info(
                "%s is not installed. Pre-generated *.c sources will be "
                "will be used to build the extensions." % required_cython
            )

        try:
            _build_ext.build_extensions(self)
        except Exception as e:
            if with_cython:
                raise
            from distutils.errors import DistutilsModuleError

            # optional compilation failed: we delete 'ext_modules' and make sure
            # the generated wheel is 'pure'
            del self.distribution.ext_modules[:]
            try:
                bdist_wheel = self.get_finalized_command("bdist_wheel")
            except DistutilsModuleError:
                # 'bdist_wheel' command not available as wheel is not installed
                pass
            else:
                bdist_wheel.root_is_pure = True
            log.error('error: building extensions failed: %s' % e)

    def get_source_files(self):
        filenames = _build_ext.get_source_files(self)

        # include pre-generated *.c sources inside sdist, but only if cython is
        # installed (and hence they will be updated upon making the sdist)
        if has_cython:
            for ext in self.extensions:
                filenames.extend(
                    [re.sub("\.pyx?$", ".c", n) for n in ext.sources]
                )
        return filenames


class cython_sdist(_sdist):
    """ Run 'cythonize' on *.pyx sources to ensure the *.c files included
    in the source distribution are up-to-date.
    """

    def run(self):
        if with_cython and not has_cython:
            from distutils.errors import DistutilsSetupError

            raise DistutilsSetupError(
                "%s is required when creating sdist --with-cython"
                % required_cython
            )

        if has_cython:
            from Cython.Build import cythonize

            cythonize(
                self.distribution.ext_modules,
                force=True,  # always regenerate *.c sources
                quiet=not self.verbose,
                compiler_directives={
                    "language_level": 3,
                    "embedsignature": True
                },
            )

        _sdist.run(self)


# don't build extensions if user explicitly requested --without-cython
if with_cython is False:
    extensions = []
else:
    extensions = [
        Extension("cu2qu.cu2qu", ["Lib/cu2qu/cu2qu.py"]),
    ]

with open('README.rst', 'r') as f:
    long_description = f.read()

setup(
    name='cu2qu',
    use_scm_version={"write_to": "Lib/cu2qu/_version.py"},
    description='Cubic-to-quadratic bezier curve conversion',
    author="James Godfrey-Kittle, Behdad Esfahbod",
    author_email="jamesgk@google.com",
    url="https://github.com/googlei18n",
    license="Apache License, Version 2.0",
    long_description=long_description,
    packages=find_packages('Lib'),
    package_dir={'': 'Lib'},
    ext_modules=extensions,
    include_package_data=True,
    setup_requires=pytest_runner + wheel + ["setuptools_scm"],
    tests_require=[
        'pytest>=2.8',
    ],
    install_requires=[
        "fonttools[ufo] >= 3.32.0",
    ],
    extras_require={"cli": ["defcon >= 0.6.0"]},
    entry_points={"console_scripts": ["cu2qu = cu2qu.cli:main [cli]"]},
    classifiers=[
        'Development Status :: 4 - Beta',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: Apache Software License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 3',
        'Topic :: Scientific/Engineering :: Mathematics',
        'Topic :: Multimedia :: Graphics :: Graphics Conversion',
        'Topic :: Multimedia :: Graphics :: Editors :: Vector-Based',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ],
    cmdclass={"build_ext": cython_build_ext, "sdist": cython_sdist},
)