setup   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 7
eloc 106
dl 0
loc 164
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A BinaryDistribution.has_ext_modules() 0 2 1
A OptionalBuildExt._unavailable() 0 15 1
A OptionalBuildExt.run() 0 8 3

1 Function

Rating   Name   Duplication   Size   Complexity  
A read() 0 3 2
1
#!/usr/bin/env python
2
import os
3
import re
4
from pathlib import Path
5
6
from setuptools import Extension
7
from setuptools import find_packages
8
from setuptools import setup
9
from setuptools.command.build_ext import build_ext
10
from setuptools.dist import Distribution
11
12
try:
13
    # Allow installing package without any Cython available. This
14
    # assumes you are going to include the .c files in your sdist.
15
    import Cython
16
except ImportError:
17
    Cython = None
18
19
# Enable code coverage for C code: we cannot use CFLAGS=-coverage in tox.ini, since that may mess with compiling
20
# dependencies (e.g. numpy). Therefore, we set SETUPPY_CFLAGS=-coverage in tox.ini and copy it to CFLAGS here (after
21
# deps have been safely installed).
22
if "TOX_ENV_NAME" in os.environ and os.environ.get("SETUPPY_EXT_COVERAGE") == "yes":
23
    CFLAGS = os.environ["CFLAGS"] = "-DCYTHON_TRACE=1"
24
    LFLAGS = os.environ["LFLAGS"] = ""
25
else:
26
    CFLAGS = ""
27
    LFLAGS = ""
28
29
30
class OptionalBuildExt(build_ext):
31
    """
32
    Allow the building of C extensions to fail.
33
    """
34
35
    def run(self):
36
        try:
37
            if os.environ.get("SETUPPY_FORCE_PURE"):
38
                raise Exception("C extensions disabled (SETUPPY_FORCE_PURE)!")
39
            super().run()
40
        except Exception as e:
41
            self._unavailable(e)
42
            self.extensions = []  # avoid copying missing files (it would fail).
43
44
    def _unavailable(self, e):
45
        print("*" * 80)
46
        print(
47
            """WARNING:
48
49
    An optional code optimization (C extension) could not be compiled.
50
51
    Optimizations for this package will not be available!
52
            """
53
        )
54
55
        print("CAUSE:")
56
        print("")
57
        print("    " + repr(e))
58
        print("*" * 80)
59
60
61
class BinaryDistribution(Distribution):
62
    """
63
    Distribution which almost always forces a binary package with platform name
64
    """
65
66
    def has_ext_modules(self):
67
        return super().has_ext_modules() or not os.environ.get("SETUPPY_ALLOW_PURE")
68
69
70
def read(*names, **kwargs):
71
    with Path(__file__).parent.joinpath(*names).open(encoding=kwargs.get("encoding", "utf8")) as fh:
72
        return fh.read()
73
74
75
setup(
76
    name="nameless",
77
    use_scm_version={
78
        "local_scheme": "dirty-tag",
79
        "write_to": "src/nameless/_version.py",
80
        "fallback_version": "1.0.0",
81
    },
82
    license="BSD-2-Clause",
83
    description="An example package. Generated with cookiecutter-pylibrary.",
84
    long_description="{}\n{}".format(
85
        re.compile("^.. start-badges.*^.. end-badges", re.M | re.S).sub("", read("README.rst")),
86
        re.sub(":[a-z]+:`~?(.*?)`", r"``\1``", read("CHANGELOG.rst")),
87
    ),
88
    author="Ionel Cristian Mărieș",
89
    author_email="[email protected]",
90
    url="https://github.com/ionelmc/python-nameless",
91
    packages=find_packages("src"),
92
    package_dir={"": "src"},
93
    py_modules=[path.stem for path in Path("src").glob("*.py")],
94
    include_package_data=True,
95
    zip_safe=False,
96
    classifiers=[
97
        # complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers
98
        "Development Status :: 5 - Production/Stable",
99
        "Intended Audience :: Developers",
100
        "License :: OSI Approved :: BSD License",
101
        "Operating System :: Unix",
102
        "Operating System :: POSIX",
103
        "Operating System :: Microsoft :: Windows",
104
        "Programming Language :: Python",
105
        "Programming Language :: Python :: 3",
106
        "Programming Language :: Python :: 3 :: Only",
107
        "Programming Language :: Python :: 3.8",
108
        "Programming Language :: Python :: 3.9",
109
        "Programming Language :: Python :: 3.10",
110
        "Programming Language :: Python :: 3.11",
111
        "Programming Language :: Python :: 3.12",
112
        "Programming Language :: Python :: Implementation :: CPython",
113
        "Programming Language :: Python :: Implementation :: PyPy",
114
        # uncomment if you test on these interpreters:
115
        # "Programming Language :: Python :: Implementation :: IronPython",
116
        # "Programming Language :: Python :: Implementation :: Jython",
117
        # "Programming Language :: Python :: Implementation :: Stackless",
118
        "Topic :: Utilities",
119
    ],
120
    project_urls={
121
        "Documentation": "https://python-nameless.readthedocs.io/",
122
        "Changelog": "https://python-nameless.readthedocs.io/en/latest/changelog.html",
123
        "Issue Tracker": "https://github.com/ionelmc/python-nameless/issues",
124
    },
125
    keywords=[
126
        # eg: "keyword1", "keyword2", "keyword3",
127
    ],
128
    python_requires=">=3.8",
129
    install_requires=[
130
        # eg: "aspectlib==1.1.1", "six>=1.7",
131
    ],
132
    extras_require={
133
        # eg:
134
        #   "rst": ["docutils>=0.11"],
135
        #   ":python_version=="2.6"": ["argparse"],
136
    },
137
    setup_requires=(
138
        [
139
            "setuptools_scm>=3.3.1",
140
            "cython",
141
        ]
142
        if Cython
143
        else [
144
            "setuptools_scm>=3.3.1",
145
        ]
146
    ),
147
    entry_points={
148
        "console_scripts": [
149
            "nameless = nameless.cli:run",
150
        ]
151
    },
152
    cmdclass={"build_ext": OptionalBuildExt},
153
    ext_modules=[
154
        Extension(
155
            str(path.relative_to("src").with_suffix("")).replace(os.sep, "."),
156
            sources=[str(path)],
157
            extra_compile_args=CFLAGS.split(),
158
            extra_link_args=LFLAGS.split(),
159
            include_dirs=[str(path.parent)],
160
        )
161
        for path in Path("src").glob("**/*.pyx" if Cython else "**/*.c")
162
    ],
163
    distclass=BinaryDistribution,
164
)
165