setup.py的例子?


Answers:


60

在此处完整地完成setup.py脚本编写的演练。(有一些例子)

如果您想要一个真实的示例,我可以为您介绍setup.py几个主要项目的脚本。Django的在这里,pyglet的在这里。您可以浏览其他项目的源代码以找到名为setup.py的文件,以获取更多示例。

这些不是简单的例子。我给的教程链接有那些。这些比较复杂,但也更实用。


30

您可能会发现《HitchHiker包装指南》很有帮助,即使它并不完整。我将从“快速入门”教程开始。也可以尝试仅浏览Python Package Index上的Python包。只需下载压缩包,将其解压缩,然后查看setup.py文件即可。甚至更好的是,只有打扰浏览列出公共源代码存储库的软件包,例如托管在GitHub或BitBucket上的软件包。您一定会在首页上碰到一个。

我的最终建议是去尝试并尝试制作一个。不要害怕失败。我真的不明白,直到我自己开始制作它们。在PyPI上创建一个新包并删除它很容易。因此,创建一个虚拟包装并试一下。


26

首先阅读 https://packaging.python.org/en/latest/current.html

安装工具建议

  1. 使用pip从PyPI安装Python软件包。
  2. 使用virtualenv或pyvenv从共享的Python安装中隔离应用程序特定的依赖项。
  3. 为了加快后续安装的速度,请使用pip wheel创建车轮分布的缓存。
  4. 如果您要管理完全集成的跨平台软件堆栈,请考虑扩展(主要针对Web开发社区)或Hashdist或conda(主要针对科学社区)。

打包工具建议

  1. 使用setuptools定义项目并创建源分发。
  2. 使用wheel项目中提供的bdist_wheel setuptools扩展来创建wheel。如果您的项目包含二进制扩展名,这将特别有益。
  3. 使用麻线将发行版上传到PyPI。

这个答案已经老化了,确实有一个针对python包装世界的救援计划,名为

车轮方式

我在这里qoute pythonwheels.com

什么是车轮?

轮子是python分发的新标准,旨在替换鸡蛋。pip> = 1.4和setuptools> = 0.8中提供了支持。

车轮的优点

  1. 纯python和本机C扩展软件包的安装速度更快。
  2. 避免执行任意代码进行安装。(避免setup.py)
  3. C扩展的安装不需要Windows或OS X上的编译器。
  4. 允许更好地缓存以进行测试和持续集成。
  5. 在安装过程中创建.pyc文件,以确保它们与使用的python解释器匹配。
  6. 跨平台和机器的安装更加一致。

正确的python包装(以及有关车轮)的完整内容在Packaging.python.org中介绍。


康达方式

对于科学计算(在packaging.python.org上也建议这样做,请参见上文),我将考虑使用CONDA打包,可以将其视为基于PyPI和pip工具的第三方服务。在设置您自己的binstar版本上,它也非常有用,因此我想它可以完成复杂的自定义企业软件包管理的技巧。

可以将Conda安装到用户文件夹中(无超级用户权限),并且与

康达安装

和强大的虚拟环境扩展。


鸡蛋方式

该选项与python-distribute.org有关,并且已过时(以及该站点),所以我将您引向我喜欢的易于使用但紧凑的setup.py示例之一:

  • 将脚本和单个python文件混合到setup.py中的一个非常实际的示例/实现在此处给出
  • hyperopt甚至更好的一种

此引用来自于setup.py状态的指南,仍然适用:

  • setup.py不见了!
  • distutils消失了!
  • 散布了!
  • 点和virtualenv在这里留下来!
  • 鸡蛋……不见了!

我再加一分(来自我)

  • 轮子

我建议在尝试无意识的复制粘贴之前,先了解一下包装生态系统(从getgenes指向的指南中)。

互联网上的大多数示例都始于

from distutils.core import setup

但这例如不支持构建egg python setup.py bdist_egg(以及其他一些功能),该功能已在

from setuptools import setup

原因是它们已被弃用

现在按照指南

警告

请使用Distribute软件包而不是Setuptools软件包,因为此软件包中存在无法解决的问题。

不推荐使用的setuptools将由distutils2取代,该工具将“成为Python 3.3中标准库的一部分”。我必须说我喜欢setuptools和egg,但尚未完全被distutils2的便利说服。这个需要

pip install Distutils2

并安装

python -m distutils2.run install

聚苯乙烯

包装从来都不是一件容易的事(一个人通过尝试开发新产品来学习这一点),所以我认为很多事情都是出于某种原因。我只是希望这次能够正确完成。


4
那么,这个答案如何老化?distutils2是python 3.3附带的吗?setuptools死了吗?
Capi Etheriel 2014年

您可以参考“ setup.py状态指南”吗?因为这个“ setup.py不见了!” 是错的。现在是2017年,setup.py si仍然在这里。
karantan

11

最小的例子

from setuptools import setup, find_packages


setup(
    name="foo",
    version="1.0",
    packages=find_packages(),
)

文档中的更多信息


5

查看一个完整的示例,该示例是一个小型python软件包的https://github.com/marcindulak/python-mycli。它基于https://packaging.python.org/en/latest/distributing.html上的打包建议,将setup.py与distutils结合使用,此外还演示了如何创建RPM和deb软件包。

该项目的setup.py包含在下面(完整信息请参见回购):

#!/usr/bin/env python

import os
import sys

from distutils.core import setup

name = "mycli"

rootdir = os.path.abspath(os.path.dirname(__file__))

# Restructured text project description read from file
long_description = open(os.path.join(rootdir, 'README.md')).read()

# Python 2.4 or later needed
if sys.version_info < (2, 4, 0, 'final', 0):
    raise SystemExit, 'Python 2.4 or later is required!'

# Build a list of all project modules
packages = []
for dirname, dirnames, filenames in os.walk(name):
        if '__init__.py' in filenames:
            packages.append(dirname.replace('/', '.'))

package_dir = {name: name}

# Data files used e.g. in tests
package_data = {name: [os.path.join(name, 'tests', 'prt.txt')]}

# The current version number - MSI accepts only version X.X.X
exec(open(os.path.join(name, 'version.py')).read())

# Scripts
scripts = []
for dirname, dirnames, filenames in os.walk('scripts'):
    for filename in filenames:
        if not filename.endswith('.bat'):
            scripts.append(os.path.join(dirname, filename))

# Provide bat executables in the tarball (always for Win)
if 'sdist' in sys.argv or os.name in ['ce', 'nt']:
    for s in scripts[:]:
        scripts.append(s + '.bat')

# Data_files (e.g. doc) needs (directory, files-in-this-directory) tuples
data_files = []
for dirname, dirnames, filenames in os.walk('doc'):
        fileslist = []
        for filename in filenames:
            fullname = os.path.join(dirname, filename)
            fileslist.append(fullname)
        data_files.append(('share/' + name + '/' + dirname, fileslist))

setup(name='python-' + name,
      version=version,  # PEP440
      description='mycli - shows some argparse features',
      long_description=long_description,
      url='https://github.com/marcindulak/python-mycli',
      author='Marcin Dulak',
      author_email='X.Y@Z.com',
      license='ASL',
      # https://pypi.python.org/pypi?%3Aaction=list_classifiers
      classifiers=[
          'Development Status :: 1 - Planning',
          'Environment :: Console',
          'License :: OSI Approved :: Apache Software License',
          'Natural Language :: English',
          'Operating System :: OS Independent',
          'Programming Language :: Python :: 2',
          'Programming Language :: Python :: 2.4',
          'Programming Language :: Python :: 2.5',
          'Programming Language :: Python :: 2.6',
          'Programming Language :: Python :: 2.7',
          'Programming Language :: Python :: 3',
          'Programming Language :: Python :: 3.2',
          'Programming Language :: Python :: 3.3',
          'Programming Language :: Python :: 3.4',
      ],
      keywords='argparse distutils cli unittest RPM spec deb',
      packages=packages,
      package_dir=package_dir,
      package_data=package_data,
      scripts=scripts,
      data_files=data_files,
      )

和RPM规范文件(或多或少遵循Fedora / EPEL包装指南)可能类似于:

# Failsafe backport of Python2-macros for RHEL <= 6
%{!?python_sitelib: %global python_sitelib      %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
%{!?python_sitearch:    %global python_sitearch     %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
%{!?python_version: %global python_version      %(%{__python} -c "import sys; sys.stdout.write(sys.version[:3])")}
%{!?__python2:      %global __python2       %{__python}}
%{!?python2_sitelib:    %global python2_sitelib     %{python_sitelib}}
%{!?python2_sitearch:   %global python2_sitearch    %{python_sitearch}}
%{!?python2_version:    %global python2_version     %{python_version}}

%{!?python2_minor_version: %define python2_minor_version %(%{__python} -c "import sys ; print sys.version[2:3]")}

%global upstream_name mycli


Name:           python-%{upstream_name}
Version:        0.0.1
Release:        1%{?dist}
Summary:        A Python program that demonstrates usage of argparse
%{?el5:Group:       Applications/Scientific}
License:        ASL 2.0

URL:            https://github.com/marcindulak/%{name}
Source0:        https://github.com/marcindulak/%{name}/%{name}-%{version}.tar.gz

%{?el5:BuildRoot:   %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)}
BuildArch:      noarch

%if 0%{?suse_version}
BuildRequires:      python-devel
%else
BuildRequires:      python2-devel
%endif


%description
A Python program that demonstrates usage of argparse.


%prep
%setup -qn %{name}-%{version}


%build
%{__python2} setup.py build


%install
%{?el5:rm -rf $RPM_BUILD_ROOT}
%{__python2} setup.py install --skip-build --prefix=%{_prefix} \
   --optimize=1 --root $RPM_BUILD_ROOT


%check
export PYTHONPATH=`pwd`/build/lib
export PATH=`pwd`/build/scripts-%{python2_version}:${PATH}
%if 0%{python2_minor_version} >= 7
%{__python2} -m unittest discover -s %{upstream_name}/tests -p '*.py'
%endif


%clean
%{?el5:rm -rf $RPM_BUILD_ROOT}


%files
%doc LICENSE README.md
%{_bindir}/*
%{python2_sitelib}/%{upstream_name}
%{?!el5:%{python2_sitelib}/*.egg-info}


%changelog
* Wed Jan 14 2015 Marcin Dulak <X.Y@Z.com> - 0.0.1-1
- initial version

2
请,而不是简单地复制/粘贴链接,而是尝试提取实际上能回答问题的重要部分
fredmaggiowski 16'4



2

这是我编写的实用程序,用于生成带有有用注释和链接的简单setup.py文件(模板)。我希望这会有用。

安装

sudo pip install setup-py-cli

用法

要生成setup.py文件,只需在终端中输入。

setup-py

现在setup.py文件应该出现在当前目录中。

生成的setup.py

from distutils.core import setup
from setuptools import find_packages
import os


# User-friendly description from README.md
current_directory = os.path.dirname(os.path.abspath(__file__))
try:
    with open(os.path.join(current_directory, 'README.md'), encoding='utf-8') as f:
        long_description = f.read()
except Exception:
    long_description = ''

setup(
    # Name of the package
    name=<name of current directory>,

    # Packages to include into the distribution
    packages=find_packages('.'), 

    # Start with a small number and increase it with every change you make
    # https://semver.org
    version='1.0.0',

    # Chose a license from here: https://help.github.com/articles/licensing-a-repository
    # For example: MIT
    license='',

    # Short description of your library
    description='',

    # Long description of your library
    long_description = long_description,
    long_description_context_type = 'text/markdown',

    # Your name
    author='', 

    # Your email
    author_email='',     

    # Either the link to your github or to your website
    url='',

    # Link from which the project can be downloaded
    download_url='',

    # List of keyword arguments
    keywords=[],

    # List of packages to install with this one
    install_requires=[],

    # https://pypi.org/classifiers/
    classifiers=[]  
)

生成的setup.py的内容:

  • 根据当前目录的名称自动实现软件包名称。
  • 一些基本领域需要满足。
  • 澄清评论和有用资源的链接。
  • 自动从README.md插入描述,如果没有README.md,则为空字符串。

这是存储库的链接。免费填充以增强解决方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.