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

Kivy requires Cython to be installed by the user in some situations, which makes depending on it as a package problematic #5984

Closed
flaviusb opened this issue Oct 9, 2018 · 13 comments

Comments

@flaviusb
Copy link
Contributor

flaviusb commented Oct 9, 2018

Versions

  • Python: Python 3.6.5
  • OS: Linux (4.12.12-gentoo x86_64)
  • Kivy: 1.10.1
  • Kivy installation method: install_requires in setup.py

Description

I am trying to create a package that uses kivy, that a user can install using pip, so that I can upload it to PyPI. This is a package that a user should be able to have as a dependency in their own package using the usual 'install_requires' method in setup.py, ideally using vanilla setuptools. At present, I have to install Cython separately in order to get Kivy to install, as Kivy does not correctly manage its dependencies.

Code and Logs

After clearing out wheel cache, to replicate installing on a fresh system, and in the directory I am developing the package in:

$ virtualenv --no-site-packages install
Using base prefix '/usr'
New python executable in /home/flaviusb/code/rvit/install/bin/python3.6
Also creating executable in /home/flaviusb/code/rvit/install/bin/python
Installing setuptools, pip, wheel...done.
$ . install/bin/activate
(install) $ pip install -e .
Obtaining file:///home/flaviusb/code/rvit
Collecting kivy (from rvit==0.1)
  Using cached https://files.pythonhosted.org/packages/7d/8b/89d220b7f96dc2662b81319067f679b4cd73cda66f4aa850db5b6c6cfc7a/Kivy-1.10.1.tar.gz
    Complete output from command python setup.py egg_info:
    Using distutils
    
    Cython is missing, it's required for compiling kivy !
    
    
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-qf1pe7c9/kivy/setup.py", line 232, in <module>
        from Cython.Distutils import build_ext
    ModuleNotFoundError: No module named 'Cython'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-qf1pe7c9/kivy/


@tshirtman
Copy link
Member

Yes, i opened this one #5558 some time ago to try to find a solution to this, i tried to ship the code in the package to avoid the build time dependency on cython, but since the generated C code depends on the python version, we would need multiple source packages, and i didn't investigate yet if this was possible.

@tito
Copy link
Member

tito commented Oct 10, 2018

IMO, either there is a wheel so you don't need Cython, either you install source version therefore Cython is required? Trying to create a source version containing all potential python version seems counter-intuitive

@tshirtman
Copy link
Member

Some platforms don't have a wheel (e.g rpi though it seems it would be possible https://www.piwheels.org/), and the linux wheel certainly can't be official yet (as it depends on the provisionnal manylinux2010 definition pypa/manylinux#182).

@flaviusb
Copy link
Contributor Author

@tito for clarity, just confirming that in the case there is no wheel, the user would have to separately install cython first, as putting it in the install_requires of a project that depends on kivy would not work, as pip builds each dependency for a project isolated so that it can only see it's own dependencies plus the user environment, and kivy does not register a dependency on cython through install_requires or other equivalent means in these problematic situations at present.

@flaviusb
Copy link
Contributor Author

flaviusb commented Oct 10, 2018

Would a work around like having an extras option to override the cython checking segment of kivy's setup.py to add cython to the install_requires be something that makes sense for kivy (eg https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies)?

Edit: spelling

@flaviusb
Copy link
Contributor Author

Some related issues I had not found until now:
#5375 #4675 pfassina/callllama#2

flaviusb added a commit to flaviusb/kivy that referenced this issue Oct 23, 2018
…d platforms.

This attempts to solve Issue kivy#5984 without causing more problems for Issue kivy#5558.
flaviusb added a commit to flaviusb/kivy that referenced this issue Oct 23, 2018
…d platforms.

This attempts to solve Issue kivy#5984 without causing more problems for Issue kivy#5558.
@vkuehn
Copy link

vkuehn commented Dec 11, 2018

for Cpython and Pygame I have been fallen in the same trapp. Manually installing worked.
However it's a pain when you like to create a setup

@rootVIII
Copy link

Having this issue on Ubuntu 16.04 with python3... bummer

@vkuehn
Copy link

vkuehn commented Dec 12, 2018

from the comments before I would expect that this is always an issue

@farleylai
Copy link
Contributor

farleylai commented Jan 1, 2019

Since the release cycle is kind of long, installing from the repo is a common practice. Without Cython declared as the dependency, pip is not going to install from git in the right order of a requirements.txt.

@ghost
Copy link

ghost commented Jan 1, 2019

pip installs setup_requires, doesn't it? (because it runs setup.py and that one will then do that first thing before calling any of the build_ext things, so if Cython is only imported in-line inside the build_ext code instead of globally at the top of the setup.py file it should still work) Would it therefore help to add Cython to setup_requires instead of install_requires or requirements.txt? I imagine that way it might not end up packaged in the actual binary wheel later on

@flaviusb
Copy link
Contributor Author

flaviusb commented Jan 1, 2019

@Jonast The PR here #5998 deals with this issue; the comments and commits there document how this actually ends up working out.

tito pushed a commit that referenced this issue Mar 4, 2019
#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.

  - pypa/setuptools#209
  - pypa/setuptools#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.
@flaviusb
Copy link
Contributor Author

flaviusb commented Mar 5, 2019

The PR #5998 has been merged, which should fix this issue.

@flaviusb flaviusb closed this as completed Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants