Change check for Cython to attempt fallback to setuptools on supporte… (#5998)
Change check for Cython to attempt fallback to setuptools on supporte… (#5998)

* Change check for Cython to attempt fallback to setuptools on supported platforms.

This attempts to solve Issue #5984 without causing more problems for Issue #5558.

* Correct argument to extras_require.

* Refactor the declaration and usage of Cython

- Use setuptools.setup by default if available for import.
- The objective for that complicated import/cython is commented.
- Also have more specific variable names, and have their usage be
  clarified.

- Remove Cython from install_requires as it already is declared under
  setup_requires, and that it conflicts with install_requires due to
  issues in setuptools.

  - https://github.com/pypa/setuptools/issues/209
  - https://github.com/pypa/setuptools/issues/391

- This commit goes back to breaking installation in environments without
  Cython, but should be rectified in the next commit.

* Actually fix the specific usage of Cython

- In order for setup.py to make use of the Cython installed during by
  the setup_requires to be usable, it must be imported after it is
  installed by that step, thus it cannot be done at the top level and
  this can be achieved by importing it when it's actually called. A
  build_ext factory function is created for this.
- Still allow whatever Cython already present on the current environment
  be attempted to be used.  This may end up being unnecessary as if it
  is always declared in setup_requires (which isn't currently the case
  due to the complicated/documented block), it _should_ pull in the
  exact/supported version of Cython for usage.  This should be
  investigated so that this complicated logic may be avoided.

* Make distutils happy by not using factory function

- As it turns out, calling setup.py build_ext will result in a code path
  within setuptools that will invoke distutils in a way that forces an
  issubclass check, which ultimately results in an exception due to that
  function not being a class.
- To fix this, we go back to constructing a base class except also using
  the "new" style class (to make Python 2 happy) so that the __new__
  method will actually be called so that the logic to select the Cython
  version of build_ext will be invoked.
- Also use the super class protocol to invoke parent methods.

* Declare version bounds directly on setup_requires

- This allows us to fully remove the brittle version checks
- Also this allows us to directly declare setup_requires if Cython is
  definitely required, as this would allow the correct version to be
  installed directly by setuptools during the execution of the setup
  step.
- No need to check for failed Cython imports due to the presence of the
  setup_requires declaration.

* Add comment explaining the initialisation routine for KivyBuildExt.

Details of how setuptools deals with both cmdclass and when setup_requires
dependencies come in to scope are both relevant.

* Bring comment in to line with earlier changes.

The cython checks are significantly simpler now, and the rationale is also slightly different.

matham/kivy,kivy/kivy,kivy/kivy,inclement/kivy,matham/kivy,rnixx/kivy,akshayaurora/kivy,akshayaurora/kivy,inclement/kivy,matham/kivy,rnixx/kivy,kivy/kivy,akshayaurora/kivy,inclement/kivy,matham/kivy,rnixx/kivy