diff --git a/.travis.yml b/.travis.yml index 773c4e5e8..80ff638e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,7 +69,9 @@ install: sudo apt-get -y install python3 python3-dev libsmpeg-dev libswscale-dev libavformat-dev libavcodec-dev libjpeg-dev libtiff4-dev libX11-dev libmtdev-dev; sudo apt-get -y install python3-setuptools build-essential libgl1-mesa-dev libgles2-mesa-dev; sudo apt-get -y install xvfb pulseaudio xsel; - pip install --upgrade cython pillow pytest coveralls docutils PyInstaller; + export CYTHON_INSTALL=$(KIVY_NO_CONSOLELOG=1 python3 -c "from kivy.tools.packaging.cython_cfg import get_cython_versions; print(get_cython_versions()[0])" --config "kivy:log_level:error"); + python3 -m pip install -I "$CYTHON_INSTALL"; + python3 -m pip install --upgrade pillow pytest coveralls docutils PyInstaller; fi; if [ "${RUN}" == "docs" ]; then python3 -m pip install --upgrade sphinx==1.7.9 sphinxcontrib-blockdiag sphinxcontrib-seqdiag sphinxcontrib-actdiag sphinxcontrib-nwdiag; @@ -98,6 +100,7 @@ install: sudo installer -package gstreamer-1.0-1.10.2-x86_64.pkg -target /; sudo installer -package gstreamer-1.0-devel-1.10.2-x86_64.pkg -target /; curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py; + if [ "${RUN}" == "app" ] && ([ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS_TAG}" != "" ] || [[ "$TRAVIS_COMMIT_MESSAGE" =~ "[build app osx]" ]]); then curl -O -L http://www.sveinbjorn.org/files/software/platypus/platypus4.8.zip; unzip platypus4.8.zip; @@ -108,13 +111,14 @@ install: cp -a Platypus-4.8/Platypus.app/Contents/Resources/MainMenu.nib /usr/local/share/platypus/MainMenu.nib; chmod -R 755 /usr/local/share/platypus; fi; - if [ "${RUN}" == "unit" ]; then - export PATH=$PATH:$HOME/Library/Python/3.5/bin; - curl -O -L https://www.python.org/ftp/python/3.5.2/python-3.5.2-macosx10.6.pkg; - sudo installer -package python-3.5.2-macosx10.6.pkg -target /; - python3 get-pip.py --user; - python3 -m pip install --upgrade --user cython pillow pytest mock docutils PyInstaller; - fi; + + export PATH=$PATH:$HOME/Library/Python/3.5/bin; + curl -O -L https://www.python.org/ftp/python/3.5.2/python-3.5.2-macosx10.6.pkg; + sudo installer -package python-3.5.2-macosx10.6.pkg -target /; + python3 get-pip.py --user; + export CYTHON_INSTALL=$(KIVY_NO_CONSOLELOG=1 python3 -c "from kivy.tools.packaging.cython_cfg import get_cython_versions; print(get_cython_versions()[0])" --config "kivy:log_level:error"); + python3 -m pip install -I --user "$CYTHON_INSTALL"; + python3 -m pip install --upgrade --user pillow pytest mock docutils PyInstaller; fi; before_script: @@ -148,9 +152,9 @@ script: fi; if [ "${RUN}" == "wheels" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ] && ([ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS_TAG}" != "" ] || [[ "$TRAVIS_COMMIT_MESSAGE" =~ "[build wheel]" ]] || [[ "$TRAVIS_COMMIT_MESSAGE" =~ "[build wheel linux]" ]]); then mkdir wheelhouse; - wheel_date=$(python -c "from datetime import datetime; print(datetime.utcnow().strftime('%Y%m%d'))"); + wheel_date=$(python3 -c "from datetime import datetime; print(datetime.utcnow().strftime('%Y%m%d'))"); git_tag=$(git rev-parse --short HEAD); - tag_name=$(python -c "from __future__ import print_function; import kivy; _, tag, n = kivy.parse_kivy_version(kivy.__version__); print(tag + n) if n is not None else print(tag or 'something')" --config "kivy:log_level:error"); + tag_name=$(KIVY_NO_CONSOLELOG=1 python3 -c "import kivy; _, tag, n = kivy.parse_kivy_version(kivy.__version__); print(tag + n) if n is not None else print(tag or 'something')" --config "kivy:log_level:error"); wheel_name="$tag_name.$wheel_date.$git_tag-"; chmod +x .ci/build-wheels-linux.sh; @@ -182,7 +186,7 @@ script: git clone https://github.com/kivy/kivy-sdk-packager; pushd kivy-sdk-packager/osx; - app_date=$(python -c "from datetime import datetime; print(datetime.utcnow().strftime('%Y%m%d'))"); + app_date=$(python3 -c "from datetime import datetime; print(datetime.utcnow().strftime('%Y%m%d'))"); git_tag=$(git rev-parse --short HEAD); yes | ./create-osx-bundle.sh python3 master > output.txt; @@ -209,7 +213,8 @@ script: python$pyver_short -m pip install git+http://github.com/tito/osxrelocator --user; python$pyver_short -m pip install --upgrade --user pip setuptools wheel; - python$pyver_short -m pip install --upgrade --user cython pytest wheel pillow mock docutils; + python$pyver_short -m pip install -I --user "$CYTHON_INSTALL"; + python$pyver_short -m pip install --upgrade --user pytest wheel pillow mock docutils; python$pyver_short -m pip install --upgrade delocate; USE_SDL2=1 USE_GSTREAMER=1 python$pyver_short setup.py build_ext --inplace>output.txt; @@ -246,9 +251,9 @@ script: cp dist/*.whl ../wheelhouse/; done; - wheel_date=$(python -c "from datetime import datetime; print(datetime.utcnow().strftime('%Y%m%d'))"); + wheel_date=$(python3 -c "from datetime import datetime; print(datetime.utcnow().strftime('%Y%m%d'))"); git_tag=$(git rev-parse --short HEAD); - tag_name=$(python -c "from __future__ import print_function; import kivy; _, tag, n = kivy.parse_kivy_version(kivy.__version__); print(tag + n) if n is not None else print(tag or 'something')" --config "kivy:log_level:error"); + tag_name=$(KIVY_NO_CONSOLELOG=1 python3 -c "import kivy; _, tag, n = kivy.parse_kivy_version(kivy.__version__); print(tag + n) if n is not None else print(tag or 'something')" --config "kivy:log_level:error"); wheel_name="$tag_name.$wheel_date.$git_tag-"; ls ../wheelhouse/; diff --git a/kivy/tools/packaging/cython_cfg.py b/kivy/tools/packaging/cython_cfg.py new file mode 100644 index 000000000..138b15d18 --- /dev/null +++ b/kivy/tools/packaging/cython_cfg.py @@ -0,0 +1,82 @@ +import configparser +from os.path import join, dirname +import textwrap + +__all__ = ('get_cython_versions', 'get_cython_msg') + + +def get_cython_versions(setup_cfg=''): + _cython_config = configparser.ConfigParser() + if setup_cfg: + _cython_config.read(setup_cfg) + else: + _cython_config.read( + join(dirname(__file__), '..', '..', '..', 'setup.cfg')) + + cython_min = _cython_config['kivy']['cython_min'] + cython_max = _cython_config['kivy']['cython_max'] + cython_unsupported = _cython_config['kivy']['cython_exclude'].split(',') + # ref https://github.com/cython/cython/issues/1968 + + cython_requires = ( + 'cython>={min_version},<={max_version},{exclusion}'.format( + min_version=cython_min, + max_version=cython_max, + exclusion=','.join('!=%s' % excl for excl in cython_unsupported), + ) + ) + + return cython_requires, cython_min, cython_max, cython_unsupported + + +def get_cython_msg(): + cython_requires, cython_min, cython_max, cython_unsupported = \ + get_cython_versions() + cython_unsupported_append = ''' + + Please note that the following versions of Cython are not supported + at all: {}'''.format(', '.join(map(str, cython_unsupported))) + + cython_min_msg = textwrap.dedent(''' + This version of Cython is not compatible with Kivy. Please upgrade to + at least version {0}, preferably the newest supported version {1}. + + If your platform provides a Cython package, make sure you have upgraded + to the newest version. If the newest version available is still too low, + please remove it and install the newest supported Cython via pip: + + pip install -I "{3}"{2} + '''.format(cython_min, cython_max, + cython_unsupported_append if cython_unsupported else '', + cython_requires)) + + cython_max_msg = textwrap.dedent(''' + This version of Cython is untested with Kivy. While this version may + work perfectly fine, it is possible that you may experience issues. + Please downgrade to a supported version, or update cython_max in + setup.cfg to your version of Cython. It is best to use the newest + supported version, {1}, but the minimum supported version is {0}. + + If your platform provides a Cython package, check if you can downgrade + to a supported version. Otherwise, uninstall the platform package and + install Cython via pip: + + pip install -I "{3}"{2} + '''.format(cython_min, cython_max, + cython_unsupported_append if cython_unsupported else '', + cython_requires)) + + cython_unsupported_msg = textwrap.dedent(''' + This version of Cython suffers from known bugs and is unsupported. + Please install the newest supported version, {1}, if possible, but + the minimum supported version is {0}. + + If your platform provides a Cython package, check if you can install + a supported version. Otherwise, uninstall the platform package and + install Cython via pip: + + pip install -I "{3}"{2} + '''.format(cython_min, cython_max, cython_unsupported_append, + cython_requires)) + + return cython_min_msg, cython_max_msg, cython_unsupported_msg diff --git a/setup.cfg b/setup.cfg index c43512a74..8cfa7053d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,3 +4,7 @@ cover-package=kivy with-id=1 verbosity=2 logging-level=DEBUG +[kivy] +cython_min=0.24 +cython_max=0.29.10 +cython_exclude=0.27,0.27.2 diff --git a/setup.py b/setup.py index fe4f5f0b7..d97a2b089 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ from distutils.command.build_ext import build_ext from distutils.version import LooseVersion from distutils.sysconfig import get_python_inc from collections import OrderedDict -from time import time +from time import time, sleep from subprocess import check_output, CalledProcessError from datetime import datetime from sysconfig import get_paths @@ -83,23 +83,6 @@ def get_version(filename='kivy/version.py'): return VERSION -MIN_CYTHON_STRING = '0.24' -MIN_CYTHON_VERSION = LooseVersion(MIN_CYTHON_STRING) -MAX_CYTHON_STRING = '0.29.9' -MAX_CYTHON_VERSION = LooseVersion(MAX_CYTHON_STRING) -CYTHON_UNSUPPORTED = ( - # ref https://github.com/cython/cython/issues/1968 - '0.27', '0.27.2' -) -CYTHON_REQUIRES_STRING = ( - 'cython>={min_version},<={max_version},{exclusion}'.format( - min_version=MIN_CYTHON_STRING, - max_version=MAX_CYTHON_STRING, - exclusion=','.join('!=%s' % excl for excl in CYTHON_UNSUPPORTED), - ) -) - - def getoutput(cmd, env=None): import subprocess p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, @@ -199,57 +182,7 @@ for key in list(c_options.keys()): print('Environ change {0} -> {1}'.format(key, value)) c_options[key] = value - # ----------------------------------------------------------------------------- -# Cython check -# on python-for-android and kivy-ios, cython usage is external - -cython_unsupported_append = ''' - - Please note that the following versions of Cython are not supported - at all: {} -'''.format(', '.join(map(str, CYTHON_UNSUPPORTED))) - -cython_min = '''\ - This version of Cython is not compatible with Kivy. Please upgrade to - at least version {0}, preferably the newest supported version {1}. - - If your platform provides a Cython package, make sure you have upgraded - to the newest version. If the newest version available is still too low, - please remove it and install the newest supported Cython via pip: - - pip install -I Cython=={1}{2}\ -'''.format(MIN_CYTHON_STRING, MAX_CYTHON_STRING, - cython_unsupported_append if CYTHON_UNSUPPORTED else '') - -cython_max = '''\ - This version of Cython is untested with Kivy. While this version may - work perfectly fine, it is possible that you may experience issues. If - you do have issues, please downgrade to a supported version. It is - best to use the newest supported version, {1}, but the minimum - supported version is {0}. - - If your platform provides a Cython package, check if you can downgrade - to a supported version. Otherwise, uninstall the platform package and - install Cython via pip: - - pip install -I Cython=={1}{2}\ -'''.format(MIN_CYTHON_STRING, MAX_CYTHON_STRING, - cython_unsupported_append if CYTHON_UNSUPPORTED else '') - -cython_unsupported = '''\ - This version of Cython suffers from known bugs and is unsupported. - Please install the newest supported version, {1}, if possible, but - the minimum supported version is {0}. - - If your platform provides a Cython package, check if you can install - a supported version. Otherwise, uninstall the platform package and - install Cython via pip: - - pip install -I Cython=={1}{2}\ -'''.format(MIN_CYTHON_STRING, MAX_CYTHON_STRING, - cython_unsupported_append) - # We want to be able to install kivy as a wheel without a dependency # on cython, but we also want to use cython where possible as a setup # time dependency through `setup_requires` if building from source. @@ -412,6 +345,29 @@ def _check_and_fix_sdl2_mixer(f_path): environ['KIVY_DOC_INCLUDE'] = '1' import kivy +# Cython check +# on python-for-android and kivy-ios, cython usage is external +from kivy.tools.packaging.cython_cfg import get_cython_versions, get_cython_msg +CYTHON_REQUIRES_STRING, MIN_CYTHON_STRING, MAX_CYTHON_STRING, \ + CYTHON_UNSUPPORTED = get_cython_versions() +cython_min_msg, cython_max_msg, cython_unsupported_msg = get_cython_msg() + +if can_use_cython: + import Cython + print('\nFound Cython at', Cython.__file__) + + cy_version_str = Cython.__version__ + cy_ver = LooseVersion(cy_version_str) + print('Detected supported Cython version {}'.format(cy_version_str)) + + if cy_ver < LooseVersion(MIN_CYTHON_STRING): + print(cython_min_msg) + elif cy_ver in CYTHON_UNSUPPORTED: + print(cython_unsupported_msg) + elif cy_ver > LooseVersion(MAX_CYTHON_STRING): + print(cython_max_msg) + sleep(1) + # extra build commands go in the cmdclass dict {'command-name': CommandClass} # see tools.packaging.{platform}.build.py for custom build commands for # portable packages. Also e.g. we use build_ext command from cython if its