1import pathlib
2import re
3import sys
4from distutils.command.build_ext import build_ext
5from distutils.errors import CCompilerError, DistutilsExecError, DistutilsPlatformError
6
7from setuptools import Extension, setup
8
9if sys.version_info < (3, 6):
10    raise RuntimeError("aiohttp 3.7+ requires Python 3.6+")
11
12here = pathlib.Path(__file__).parent
13
14
15if (here / ".git").exists() and not (here / "vendor/http-parser/README.md").exists():
16    print("Install submodules when building from git clone", file=sys.stderr)
17    print("Hint:", file=sys.stderr)
18    print("  git submodule update --init", file=sys.stderr)
19    sys.exit(2)
20
21
22# NOTE: makefile cythonizes all Cython modules
23
24extensions = [
25    Extension("aiohttp._websocket", ["aiohttp/_websocket.c"]),
26    Extension(
27        "aiohttp._http_parser",
28        [
29            "aiohttp/_http_parser.c",
30            "vendor/http-parser/http_parser.c",
31            "aiohttp/_find_header.c",
32        ],
33        define_macros=[("HTTP_PARSER_STRICT", 0)],
34    ),
35    Extension("aiohttp._frozenlist", ["aiohttp/_frozenlist.c"]),
36    Extension("aiohttp._helpers", ["aiohttp/_helpers.c"]),
37    Extension("aiohttp._http_writer", ["aiohttp/_http_writer.c"]),
38]
39
40
41class BuildFailed(Exception):
42    pass
43
44
45class ve_build_ext(build_ext):
46    # This class allows C extension building to fail.
47
48    def run(self):
49        try:
50            build_ext.run(self)
51        except (DistutilsPlatformError, FileNotFoundError):
52            raise BuildFailed()
53
54    def build_extension(self, ext):
55        try:
56            build_ext.build_extension(self, ext)
57        except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError):
58            raise BuildFailed()
59
60
61txt = (here / "aiohttp" / "__init__.py").read_text("utf-8")
62try:
63    version = re.findall(r'^__version__ = "([^"]+)"\r?$', txt, re.M)[0]
64except IndexError:
65    raise RuntimeError("Unable to determine version.")
66
67install_requires = [
68    "attrs>=17.3.0",
69    "chardet>=2.0,<5.0",
70    "multidict>=4.5,<7.0",
71    "async_timeout>=3.0,<4.0",
72    "yarl>=1.0,<2.0",
73    'idna-ssl>=1.0; python_version<"3.7"',
74    "typing_extensions>=3.6.5",
75]
76
77
78def read(f):
79    return (here / f).read_text("utf-8").strip()
80
81
82NEEDS_PYTEST = {"pytest", "test"}.intersection(sys.argv)
83pytest_runner = ["pytest-runner"] if NEEDS_PYTEST else []
84
85tests_require = [
86    "pytest",
87    "gunicorn",
88    "pytest-timeout",
89    "async-generator",
90    "pytest-xdist",
91]
92
93
94args = dict(
95    name="aiohttp",
96    version=version,
97    description="Async http client/server framework (asyncio)",
98    long_description="\n\n".join((read("README.rst"), read("CHANGES.rst"))),
99    classifiers=[
100        "License :: OSI Approved :: Apache Software License",
101        "Intended Audience :: Developers",
102        "Programming Language :: Python",
103        "Programming Language :: Python :: 3",
104        "Programming Language :: Python :: 3.6",
105        "Programming Language :: Python :: 3.7",
106        "Programming Language :: Python :: 3.8",
107        "Programming Language :: Python :: 3.9",
108        "Development Status :: 5 - Production/Stable",
109        "Operating System :: POSIX",
110        "Operating System :: MacOS :: MacOS X",
111        "Operating System :: Microsoft :: Windows",
112        "Topic :: Internet :: WWW/HTTP",
113        "Framework :: AsyncIO",
114    ],
115    author="Nikolay Kim",
116    author_email="fafhrd91@gmail.com",
117    maintainer=", ".join(
118        (
119            "Nikolay Kim <fafhrd91@gmail.com>",
120            "Andrew Svetlov <andrew.svetlov@gmail.com>",
121        )
122    ),
123    maintainer_email="aio-libs@googlegroups.com",
124    url="https://github.com/aio-libs/aiohttp",
125    project_urls={
126        "Chat: Gitter": "https://gitter.im/aio-libs/Lobby",
127        "CI: Azure Pipelines": "https://dev.azure.com/aio-libs/aiohttp/_build",
128        "Coverage: codecov": "https://codecov.io/github/aio-libs/aiohttp",
129        "Docs: RTD": "https://docs.aiohttp.org",
130        "GitHub: issues": "https://github.com/aio-libs/aiohttp/issues",
131        "GitHub: repo": "https://github.com/aio-libs/aiohttp",
132    },
133    license="Apache 2",
134    packages=["aiohttp"],
135    python_requires=">=3.6",
136    install_requires=install_requires,
137    extras_require={
138        "speedups": [
139            "aiodns",
140            "brotlipy",
141            "cchardet",
142        ],
143    },
144    tests_require=tests_require,
145    setup_requires=pytest_runner,
146    include_package_data=True,
147    ext_modules=extensions,
148    cmdclass=dict(build_ext=ve_build_ext),
149)
150
151try:
152    setup(**args)
153except BuildFailed:
154    print("************************************************************")
155    print("Cannot compile C accelerator module, use pure python version")
156    print("************************************************************")
157    del args["ext_modules"]
158    del args["cmdclass"]
159    setup(**args)
160