Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt pep517 + try compile with cython #1709

Merged
merged 14 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
[build-system]
build-backend = "setuptools.build_meta"
requires = [
"setuptools>=47",
"wheel",
"cython; python_implementation == 'CPython'", # Skip cython when using pypy
CaselIT marked this conversation as resolved.
Show resolved Hide resolved
]

[tool.towncrier]
package = "falcon"
package_dir = ""
Expand Down
67 changes: 67 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,70 @@
[metadata]
name = falcon
version = attr: falcon.__version__
description = An unladen web framework for building APIs and app backends.
long_description_content_type = text/x-rst
url = https://falconframework.org
author = Kurt Griffiths
author_email = mail@kgriffs.com
license = Apache 2.0
license_file = LICENSE
classifiers =
Development Status :: 5 - Production/Stable
Environment :: Web Environment
Natural Language :: English
Intended Audience :: Developers
Intended Audience :: System Administrators
License :: OSI Approved :: Apache Software License
Operating System :: MacOS :: MacOS X
Operating System :: Microsoft :: Windows
Operating System :: POSIX
Topic :: Internet :: WWW/HTTP :: WSGI
Topic :: Software Development :: Libraries :: Application Frameworks
Programming Language :: Python
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
CaselIT marked this conversation as resolved.
Show resolved Hide resolved
keywords =
asgi
wsgi
web
api
framework
rest
http
cloud
project_urls =
Documentation=https://falcon.readthedocs.io/en/stable/
Issue Tracker=https://github.com/falconry/falcon

[options]
zip_safe = False
include_package_data = True
packages = find:
python_requires = >=3.5
install_requires =
tests_require =
testtools
requests
pyyaml
pytest
pytest-runner

[options.packages.find]
exclude =
examples
tests

[options.entry_points]
console_scripts =
falcon-bench = falcon.cmd.bench:main
falcon-inspect-app = falcon.cmd.inspect_app:main
falcon-print-routes = falcon.cmd.inspect_app:route_main

[egg_info]
# TODO replace
tag_build = dev1
Expand Down
146 changes: 80 additions & 66 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import glob
import importlib
import io
import os
from os import path
import re
import sys

from setuptools import Extension, find_packages, setup
from setuptools import Extension, setup

MYDIR = path.abspath(os.path.dirname(__file__))

VERSION = importlib.import_module('falcon.version')
VERSION = VERSION.__version__

REQUIRES = []

try:
sys.pypy_version_info
PYPY = True
Expand All @@ -30,7 +24,39 @@
except ImportError:
CYTHON = False

if CYTHON:

class BuildFailed(Exception):
pass


def get_cython_options():
# from sqlalchemy setup.py
from distutils.errors import CCompilerError, DistutilsExecError, DistutilsPlatformError
ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
if sys.platform == 'win32':
# Work around issue https://github.com/pypa/setuptools/issues/1902
ext_errors += (IOError, TypeError)

class ve_build_ext(build_ext):
# This class allows Cython building to fail.

def run(self):
try:
super().run()
except DistutilsPlatformError:
raise BuildFailed()

def build_extension(self, ext):
try:
super().build_extension(ext)
except ext_errors as e:
raise BuildFailed() from e
except ValueError as e:
# this can happen on Windows 64 bit, see Python issue 7511
if "'path'" in str(e):
raise BuildFailed() from e
raise

def list_modules(dirname, pattern):
filenames = glob.glob(path.join(dirname, pattern))

Expand Down Expand Up @@ -92,11 +118,8 @@ def list_modules(dirname, pattern):
for ext_mod in ext_modules:
ext_mod.cython_directives = {'language_level': '3'}

cmdclass = {'build_ext': build_ext}

else:
cmdclass = {}
ext_modules = []
cmdclass = {'build_ext': ve_build_ext}
return cmdclass, ext_modules


def load_description():
Expand Down Expand Up @@ -134,56 +157,47 @@ def load_description():
return ''.join(description_lines)


setup(
name='falcon',
version=VERSION,
description='An unladen web framework for building APIs and app backends.',
long_description=load_description(),
long_description_content_type='text/x-rst',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Natural Language :: English',
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: Apache Software License',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Operating System :: POSIX :: Linux',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: WSGI',
# 'Topic :: Internet :: WWW/HTTP :: ASGI',
'Topic :: Software Development :: Libraries :: Application Frameworks',
'Programming Language :: Python',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Cython',
],
keywords='wsgi web api framework rest http cloud',
author='Kurt Griffiths',
author_email='mail@kgriffs.com',
url='https://falconframework.org',
license='Apache 2.0',
packages=find_packages(exclude=['examples', 'tests']),
include_package_data=True,
zip_safe=False,
python_requires='>=3.5',
install_requires=REQUIRES,
cmdclass=cmdclass,
ext_modules=ext_modules,
tests_require=['testtools', 'requests', 'pyyaml', 'pytest', 'pytest-runner'],
entry_points={
'console_scripts': [
'falcon-bench = falcon.cmd.bench:main',
'falcon-inspect-app = falcon.cmd.inspect_app:main',
'falcon-print-routes = falcon.cmd.inspect_app:route_main',
]
}
)
def run_setup(CYTHON):
if CYTHON:
cmdclass, ext_modules = get_cython_options()
else:
cmdclass, ext_modules = {}, []

setup(
long_description=load_description(),
cmdclass=cmdclass,
ext_modules=ext_modules,
)


def status_msgs(*msgs):
print('*' * 75, *msgs, '*' * 75, sep='\n')


if not CYTHON:
run_setup(False)
if not PYPY:
status_msgs('Cython compilation not supported in this environment')
elif os.environ.get('DISABLE_FALCON_CYTHON'):
run_setup(False)
status_msgs(
'DISABLE_FALCON_CYTHON is set, skipping cython compilation.',
'Pure-Python build succeeded.',
)
else:
try:
run_setup(True)
except BuildFailed as exc:
status_msgs(
exc.__cause__,
'Cython compilation could not be completed, speedups are not enabled.',
'Failure information, if any, is above.',
'Retrying the build without the C extension now.'
)

run_setup(False)

status_msgs(
'Cython compilation could not be completed, speedups are not enabled.',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this message be repeated twice in the case pure Python build succeeds?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider that this is only visible if the verbose flag is passed (aka almost no-one)
This is what is printed:

    building 'falcon.api_helpers' extension
    ***************************************************************************
    Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
    Cython compilation could not be completed, speedups are not enabled.
    Failure information, if any, is above.
    Retrying the build without the C extension now.
    ***************************************************************************
    running develop
    running egg_info
    writing falcon.egg-info\PKG-INFO
    writing dependency_links to falcon.egg-info\dependency_links.txt
    writing entry points to falcon.egg-info\entry_points.txt
    writing top-level names to falcon.egg-info\top_level.txt
    warning: the 'license_file' option is deprecated, use 'license_files' instead
    adding license file 'LICENSE' (matched pattern 'LICENSE')
    reading manifest file 'falcon.egg-info\SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    writing manifest file 'falcon.egg-info\SOURCES.txt'
    running build_ext
    Creating c:\users\cfede\miniconda3\envs\falcon\lib\site-packages\falcon.egg-link (link to .)
    Adding falcon 3.0.2.dev1 to easy-install.pth file
    Installing falcon-bench-script.py script to C:\Users\cfede\miniconda3\envs\falcon\Scripts
    Installing falcon-bench.exe script to C:\Users\cfede\miniconda3\envs\falcon\Scripts
    Installing falcon-inspect-app-script.py script to C:\Users\cfede\miniconda3\envs\falcon\Scripts
    Installing falcon-inspect-app.exe script to C:\Users\cfede\miniconda3\envs\falcon\Scripts
    Installing falcon-print-routes-script.py script to C:\Users\cfede\miniconda3\envs\falcon\Scripts
    Installing falcon-print-routes.exe script to C:\Users\cfede\miniconda3\envs\falcon\Scripts

    Installed c:\users\cfede\dev\github\falcon
    ***************************************************************************
    Cython compilation could not be completed, speedups are not enabled.
    Pure-Python build succeeded.
    ***************************************************************************
Successfully installed falcon

I think in makes sense, maybe we could invert the working:

    Pure-Python build succeeded.
    Cython compilation could not be completed, speedups are not enabled.

'Pure-Python build succeeded.'
)
5 changes: 4 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ envlist = py38,
setenv =
PIP_CONFIG_FILE={toxinidir}/pip.conf
PYTHONASYNCIODEBUG=1
DISABLE_FALCON_CYTHON=Y
CaselIT marked this conversation as resolved.
Show resolved Hide resolved
deps = -r{toxinidir}/requirements/tests
commands = {toxinidir}/tools/clean.sh {toxinidir}/falcon
pytest tests []
Expand Down Expand Up @@ -132,10 +133,10 @@ commands = {toxinidir}/tools/clean.sh {toxinidir}/falcon

[with-cython]
deps = -r{toxinidir}/requirements/tests
cython
setenv =
PIP_CONFIG_FILE={toxinidir}/pip.conf
FALCON_CYTHON=Y
CaselIT marked this conversation as resolved.
Show resolved Hide resolved
DISABLE_FALCON_CYTHON=
FALCON_ASGI_WRAP_NON_COROUTINES=Y
FALCON_TESTING_SESSION=Y
PYTHONASYNCIODEBUG=1
Expand Down Expand Up @@ -183,6 +184,7 @@ commands = {[with-cython]commands}

[testenv:wsgi_servers]
install_command = {[with-cython]install_command}
setenv = {[with-cython]setenv}
deps = {[with-cython]deps}
gunicorn
meinheld
Expand Down Expand Up @@ -449,6 +451,7 @@ setenv =
PYTHONNOUSERSITE=1
FALCON_ASGI_WRAP_NON_COROUTINES=Y
FALCON_TESTING_SESSION=Y
DISABLE_FALCON_CYTHON=Y
commands =
pip uninstall --yes falcon
pip install --find-links {toxinidir}/dist --no-index --ignore-installed falcon
Expand Down