Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
173 views
in Technique[技术] by (71.8m points)

python - Best practices: how do you list required dependencies in your setup.py?

This is how I do it currently:

import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))

requires = [
    'pyramid',
    'pyramid_debugtoolbar',
    'waitress',
    'requests',
    'mock',
    'gunicorn',
    'mongoengine',
    ]

setup(name='repoapi',
      version='0.0',
      description='repoapi',
      packages=find_packages(),
      include_package_data=True,
      zip_safe=False,
      install_requires=requires,
      tests_require=requires,
      test_suite="repoapi",
      entry_points="""
      [paste.app_factory]
      main = repoapi:main
      """,
      )

Is this an okay way? I have some troubles. For example, for pyramid, I cannot use the system-wide nosetests plugin to run tests. I need to install pyramid in the global python site-packages!

But I don't want that. So I must install nose in the virtualenv of this project. But I don't want it to be a dependency. I don't feel like it should belong to requires. It isn't. Yet, I also don't want to install by hand all the time. Yeah I know I have a lot of I don't want to do this and that...

But how would you solve that? I don't want to tamper the global python site-packages, but I want to install nose as part of the virtualenv.

Also, pip install requirement files. It's slightly more accurate because I don't need to specify the version manually and I don't need to be afraid of updating setup.py manually. Just throw pip freeze > file.txt and done.

However, pip can return garbage because we throw garbage packages into virtualenv.

So many blades. What's the best practice? How do you deal with these issues?

Maybe I missed it, but https://github.com/django/django/blob/master/setup.py, how did Django do it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can split up your requirements into "install" dependencies and "test" dependencies like this:

import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))

install_requires = [
    'pyramid',
    'pyramid_debugtoolbar',
    'waitress',
    'requests',
    'gunicorn',
    'mongoengine',
    ]

tests_require = [
    'mock',
    'nose',
    ]

setup(name='repoapi',
      ...
      install_requires=install_requires,
      tests_require=tests_require,
      test_suite="nose.collector",
      ...
      )

This way, when someone installs the package, only the "install" dependencies are installed. So, if someone only wants to use the package (and they aren't interested in running the tests), then they don't have to install the test dependencies.

When you do want to run the tests, you can use this:

$ python setup.py test

Per the docs:

Note that these required projects will not be installed on the system where the tests are run, but only downloaded to the project’s setup directory if they’re not already installed locally.

Once the "test" dependencies are in place, then it will run the "test_suite" command. Since you mentioned nose as your preferred test runner, I showed how you use "nose.collector" to configure that.

Incidentally, the Django setup.py is not the cleanest example for understanding the basics of setuptools. I think the Sentry setup.py is a better example to learn from.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...