How to add dependencies to an rpm built by python - python

I am trying to create an rpm of a python package using setuptools. Using the following command on linux:
$ python setup.py bdist --formats=rpm
The RPM builds fine; however, the requirement (cryptography), does not appear as a dependency in the RPM.
Is there any way to specify which dependencies this package requires?
The setup.py file looks like this:
from setuptools import setup, find_packages
if __name__ == "__main__":
setup(
name="dummy",
version=0.1,
description="This is a dummy package",
install_requires=[
"cryptography>=1.3.4",
],
)

Related

Install .desktop file with setuptools and pyproject.toml

I have a GUI Python app that I'm trying to distribute a desktop entry with. Normally, one would write a setup.py with setuptools that has this in it:
from setuptools import setup
setup(
name = 'myapp',
version = '0.0.1',
packages = ['myapp'],
data_files = [
('share/applications', ['myapp.desktop']),
],
)
This is deprecated, however, and my goal is to use only pyproject.toml in my repo with no setup.py or setup.cfg needed. I have been unable to find any information on how I would go about doing this.

Python setup.py only for installation required packages

Is possible to avoid using pip and requirements.txt in favor of just using setup.py to install missing libraries but not having build all other stuff?
Normally it's looks like (and is run python setup.py install:
from setuptools import setup, find_packages
setup(
name="HelloWorld",
version="0.1",
packages=find_packages(),
install_requires=['docutils>=0.3'],
)
And I wish to use only install_requires=['docutils>=0.3'] to have those dependencies resolved and avoid all build artifacts.
Depending on the setup you are using, there is:
install_requires with setuptools
See also:
https://packaging.python.org/requirements/
Adding 'install_requires' to setup.py when making a python package

Tox can't copy non-python file while installing the module

This is the tree structure of the module I'm writing the setup.py file for:
ls .
LICENSE
README.md
bin
examples
module
scratch
setup.py
tests
tox.ini
I configured my setup.py as follows:
from setuptools import setup, find_packages
setup(
name="package_name",
version="0.1",
packages=find_packages(),
install_requires=[
# [...]
],
extras_require={
# [...]
},
tests_require={
'pytest',
'doctest'
},
scripts=['bin/bootstrap'],
data_files=[
('license', ['LICENSE']),
],
# [...]
# could also include long_description, download_url, classifiers, etc.
)
If I install the package from my python environment (also a virtualenv)
pip install .
the LICENSE file gets correctly installed.
But running tox:
[tox]
envlist = py27, py35
[testenv]
deps =
pytest
git+https://github.com/djc/couchdb-python
docopt
commands = py.test \
{posargs}
I get this error:
running install_data
creating build/bdist.macosx-10.11-x86_64/wheel/leafline-0.1.data
creating build/bdist.macosx-10.11-x86_64/wheel/leafline-0.1.data/data
creating build/bdist.macosx-10.11-x86_64/wheel/leafline-0.1.data/data/license
error: can't copy 'LICENSE': doesn't exist or not a regular file
Removing the data_files part from the setup.py makes tox running correctly.
Your issue here is that setuptools is not able to find the 'LICENSE' file in the files that have been included for building the source distribution. You have 2 options, to tell setuptools to include that file (both have been pointed to here):
Add a MANIFEST.in file (like https://github.com/pypa/sampleproject/)
Use include_package_data=True in your setup.py file.
Using MANIFEST.in is often simpler and easier to verify due to https://pypi.org/project/check-manifest/, making it possible to use automation to verify that things are indeed correct (if you use a VCS like Git or SVN).
pip install . builds a wheel using python setup.py bdist_wheel which is installed by simply unpacking it appropriately, as defined in the Wheel Specification: https://www.python.org/dev/peps/pep-0427/
tox builds a source distribution using python setup.py sdist, which is then unpacked and installed using python setup.py install.
That might be a reason for the difference in behavior for you.
I have some resource files inside my packages which I use during the execution. To make setup store them in a package with python code, I use include_package_data=True and I access them using importlib.resources. You can use backport for an older Python version than 3.7 or another library.
Before each release I have a script which verifies, that all files I need are placed inside a bdist wheel to be sure that everything is on the place.

How to create a Pure-Python wheel

From the following setup.py file, I am trying to create a pure-python wheel from a project that should contain only python 2.7 code.
from setuptools import setup
setup(
name='foo',
version='0.0.1',
description='',
url='',
install_requires=[
'bpython',
'Django==1.8.2',
],
)
However, when I run python setup.py bdist_wheel the wheel file that is generated is platform specific foo-0.0.1-cp27-none-macosx_10_9_x86_64.whl wheel file instead of the expected foo-0.0.1-cp27-none-any.whl. When I try to install this wheel on a different platform it fails saying it is not compatible with this Python.
I there something I need to change about the setup.py file or python interpreter, perhaps, that will allow this wheel to be used on any platform?
The simplistic way is to add --universal to your commandline, as you can see from running python setup.py bdist_wheel --help:
--universal make a universal wheel (default: false)
Alternatively you can add a setup.cfg file next to your setup.py that
takes care of this:
[bdist_wheel]
universal = 1
If you don't like yet another configuration file clobbering your package,
you can just write such a file in your setup.py just before it calls setup() and then remove it after that call returns, this is what I do
in the shared setup.py for all my projects on PyPI e.g. used in ruamel.yaml.
Adding the classifiers field to my setup.py fixed this issue.
from setuptools import setup
setup(
name='foo',
version='0.0.1',
description='',
url='',
classifiers=[
'Programming Language :: Python :: 2.7',
],
install_requires=[
'bpython',
'Django==1.8.2',
],
)
This part of the filename is controlled by the bdist_wheel option called python tag:
python2 setup.py bdist_wheel --help | grep python-tag
--python-tag Python implementation compatibility tag (default: 'py2')
However the default is generally 'py2' (or 'py3' for a python3 runtime), so to get a platform-specific wheel you must have something else in your configuration that is not shown in the question.
Regardless, you can specify the tag explicitly in your setup file:
from setuptools import setup
setup(
name="foo",
version="0.0.1",
...
options={"bdist_wheel": {"python_tag": "cp27"}},
)
This configuration will create a wheel named foo-0.0.1-cp27-none-any.whl.

Marking Cython as a Build Dependency?

There is a Python package with a setup.py that reads thusly:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(
name = 'fastahack',
ext_modules=[
Extension("fastahack.cfastahack",
sources=["fastahack/cfastahack.pyx", "lib/Fasta.cpp", "lib/split.cpp"],
libraries=["stdc++"],
include_dirs=["lib/"],
language="c++"),
],
package_data = {'lib': ['*.pyx', "*.c", "*.h", "README.rst"]},
package_dir = {"fastahack": "fastahack"},
cmdclass = {'build_ext': build_ext},
packages = ['fastahack', 'fastahack.tests'],
author = "Brent Pedersen",
author_email="bpederse#gmail.com",
#test_suite='nose.collector'
)
This setup.py can't be imported if Cython is not installed. As far as I know, importing setup.py is how tools like pip figure out the dependencies of a package. I want to set up this package so that it could be uploaded to PyPI, with the fact that it depends on Cython noted, so that Cython will be downloaded and installed when you try to "pip install fastahack", or when you try to "pip install" directly from the Git repository.
How would I package this module so that it installs correctly from the Internet when Cython is not installed? Always using the latest version of Cython would be a plus.
You can specify Cython as a build dependency using PEP-518 project specification.
In the file pyproject.toml (in the same directory as setup.py) insert:
[build-system]
requires = ["setuptools", "wheel", "Cython"]
Cython will then be installed before building your package.
Note that (currently) you need to pass --no-use-pep517 to pip install if you are installing your package locally as editable (ie with --editable or -e) setuptools v64 supports editable installs with pyproject.toml builds
My standard template for setup.py:
have_cython = False
try:
from Cython.Distutils import build_ext as _build_ext
have_cython = True
except ImportError:
from distutils.command.build_ext import build_ext as _build_ext
if have_cython:
foo = Extension('foo', ['src/foo.pyx'])
else:
foo = Extension('foo', ['src/foo.c'])
setup (
...
ext_modules=[foo],
cmdclass={'build_ext': build_ext}
And don't forget to provide extention .c files with package - that will allow users to build module without installing cython.
Use a try and except for the Cython import and modify your setup based on whether or not your import succeeds. Look at the setup.py of Pandas for an example

Categories