ตัวอย่าง setup.py?


89

หลังจากศึกษาหน้านี้:

http://docs.python.org/distutils/builtdist.html

ฉันหวังว่าจะพบไฟล์ setup.py เพื่อศึกษาเพื่อสร้างเป็นของตัวเอง (โดยมีเป้าหมายในการสร้างไฟล์ fedora rpm)

ชุมชนนี้ช่วยชี้ให้ฉันเห็นตัวอย่างที่ดีได้ไหม

คำตอบ:


62

คำแนะนำที่สมบูรณ์แบบของการเขียนsetup.pyสคริปต์ที่นี่ (พร้อมตัวอย่าง)

หากคุณต้องการตัวอย่างในโลกแห่งความเป็นจริงฉันสามารถชี้ให้คุณดูsetup.pyสคริปต์ของโครงการใหญ่ ๆ Django คือที่นี่ , pyglet เป็นที่นี่ คุณสามารถเรียกดูซอร์สของโปรเจ็กต์อื่น ๆ สำหรับไฟล์ชื่อ setup.py เพื่อดูตัวอย่างเพิ่มเติม

นี่ไม่ใช่ตัวอย่างง่ายๆ ลิงก์บทช่วยสอนที่ฉันให้มีเหล่านั้น สิ่งเหล่านี้ซับซ้อนกว่า แต่ยังใช้งานได้จริงอีกด้วย


30

คุณอาจพบว่าคู่มือการบรรจุหีบห่อของ HitchHiker มีประโยชน์แม้ว่าจะไม่สมบูรณ์ก็ตาม ผมขอเริ่มต้นด้วยการเริ่มต้นอย่างรวดเร็วกวดวิชา ลองก็เป็นเพียงแค่การเรียกดูผ่านแพคเกจหลามบนแพคเกจดัชนีหลาม เพียงดาวน์โหลด tarball แกะกล่องและดูsetup.pyไฟล์ หรือดีกว่านั้นเพียงแค่มองผ่านแพ็คเกจที่แสดงรายการที่เก็บซอร์สโค้ดสาธารณะเช่นที่โฮสต์บน GitHub หรือ BitBucket คุณจะต้องพบกับหนึ่งในหน้าแรก

ข้อเสนอแนะสุดท้ายของฉันคือไปหามันแล้วลองทำดู อย่ากลัวที่จะล้มเหลว ฉันไม่เข้าใจจริงๆจนกระทั่งฉันเริ่มสร้างมันขึ้นมาเอง การสร้างแพ็คเกจใหม่บน PyPI เป็นเรื่องเล็กน้อยและง่ายต่อการลบออก ดังนั้นสร้างแพ็คเกจจำลองและเล่นรอบ ๆ


26

อ่านครั้งแรกนี้ https://packaging.python.org/en/latest/current.html

คำแนะนำเครื่องมือการติดตั้ง

  1. ใช้ pip เพื่อติดตั้งแพ็คเกจ Python จาก PyPI
  2. ใช้ Virtualenv หรือ pyvenv เพื่อแยกการอ้างอิงเฉพาะแอ็พพลิเคชันจากการติดตั้ง Python ที่ใช้ร่วมกัน
  3. ใช้ pip wheel เพื่อสร้างแคชของการกระจายวงล้อเพื่อจุดประสงค์> เร่งการติดตั้งในภายหลัง
  4. หากคุณกำลังมองหาการจัดการกองซอฟต์แวร์ข้ามแพลตฟอร์มแบบครบวงจรให้พิจารณา buildout (เน้นที่ชุมชนการพัฒนาเว็บเป็นหลัก) หรือ Hashdist หรือ conda (ทั้งสองอย่างเน้นที่ชุมชนวิทยาศาสตร์เป็นหลัก)

คำแนะนำเครื่องมือบรรจุภัณฑ์

  1. ใช้ setuptools เพื่อกำหนดโปรเจ็กต์และสร้าง Source Distributions
  2. ใช้ส่วนขยาย bdist_wheel setuptools ที่มีให้จากโครงการล้อเพื่อสร้างล้อ นี่เป็นประโยชน์อย่างยิ่งหากโครงการของคุณมีส่วนขยายไบนารี
  3. ใช้เส้นใหญ่สำหรับการอัปโหลดการกระจายไปยัง PyPI

ผู้โจมตีรายนี้มีอายุมากขึ้นและมีแผนช่วยเหลือสำหรับโลกบรรจุภัณฑ์หลามที่เรียกว่า

ทางล้อ

ฉัน qoute pythonwheels.comที่นี่:

ล้อคืออะไร?

ล้อเป็นมาตรฐานใหม่ของการกระจายงูหลามและมีจุดมุ่งหมายเพื่อแทนที่ไข่ มีการสนับสนุนใน pip> = 1.4 และ setuptools> = 0.8

ข้อดีของล้อ

  1. ติดตั้งได้เร็วขึ้นสำหรับแพคเกจส่วนขยาย Python และ C ดั้งเดิม
  2. หลีกเลี่ยงการใช้รหัสโดยอำเภอใจสำหรับการติดตั้ง (หลีกเลี่ยง setup.py)
  3. การติดตั้งส่วนขยาย C ไม่จำเป็นต้องใช้คอมไพเลอร์บน Windows หรือ OS X
  4. ช่วยให้การแคชที่ดีขึ้นสำหรับการทดสอบและการรวมอย่างต่อเนื่อง
  5. สร้างไฟล์. pyc เป็นส่วนหนึ่งของการติดตั้งเพื่อให้แน่ใจว่าตรงกับตัวแปล python ที่ใช้
  6. การติดตั้งที่สอดคล้องกันมากขึ้นในแพลตฟอร์มและเครื่องจักร

ดูเรื่องราวทั้งหมดของบรรจุภัณฑ์หลามที่ถูกต้อง (และเกี่ยวกับล้อ) ได้ที่packaging.python.org


วิธี conda

สำหรับการคำนวณทางวิทยาศาสตร์ (แนะนำใน packaging.python.org ดูด้านบน) ฉันจะพิจารณาใช้บรรจุภัณฑ์ CONDAซึ่งสามารถมองว่าเป็นบริการของบุคคลที่สามที่สร้างขึ้นจาก PyPI และเครื่องมือ pip นอกจากนี้ยังใช้งานได้ดีในการตั้งค่าbinstarเวอร์ชันของคุณเองดังนั้นฉันคิดว่ามันสามารถทำเคล็ดลับสำหรับการจัดการแพ็คเกจสำหรับองค์กรแบบกำหนดเองที่ซับซ้อนได้

Conda สามารถติดตั้งลงในโฟลเดอร์ผู้ใช้ (ไม่มีสิทธิ์ผู้ใช้ขั้นสูง) และใช้งานได้เหมือนเวทมนตร์

ติดตั้ง conda

และการขยายตัวเสมือนจริงที่ทรงพลัง


วิธีไข่

ตัวเลือกนี้เกี่ยวข้องกับ python-distribute.org และล้าสมัยไปมากแล้ว (เช่นเดียวกับไซต์) ดังนั้นให้ฉันชี้ให้คุณเห็นหนึ่งในตัวอย่าง setup.py ที่พร้อมใช้งาน แต่มีขนาดกะทัดรัดที่ฉันชอบ:

  • ตัวอย่างที่เป็นประโยชน์ / การใช้งานสคริปต์ผสมและไฟล์ python เดียวใน setup.py มีให้ที่นี่
  • หนึ่งที่ดียิ่งขึ้นจากhyperopt

คำพูดนี้นำมาจากคำแนะนำเกี่ยวกับสถานะ setup.pyและยังคงใช้:

  • setup.py ไปแล้ว!
  • ห่างเหินไป!
  • แจกไป!
  • pip และ Virtualenv อยู่ที่นี่!
  • ไข่ ... ไปแล้ว!

ฉันเพิ่มอีกหนึ่งจุด (จากฉัน)

  • ล้อ !

ฉันอยากจะแนะนำให้ทำความเข้าใจเกี่ยวกับระบบนิเวศของบรรจุภัณฑ์ (จากคำแนะนำที่ gotgenes ชี้ให้เห็น) ก่อนที่จะพยายามคัดลอกวางโดยไม่สนใจ

ตัวอย่างส่วนใหญ่ในอินเทอร์เน็ตเริ่มต้นด้วย

from distutils.core import setup

แต่ตัวอย่างนี้ไม่สนับสนุนการสร้าง egg python setup.py bdist_egg (รวมถึงคุณสมบัติเก่าอื่น ๆ) ซึ่งมีอยู่ใน

from setuptools import setup

และเหตุผลที่ว่าพวกเขาจะเลิก

ตอนนี้ตามคู่มือ

คำเตือน

โปรดใช้แพ็กเกจ Distribute แทนแพ็กเกจ Setuptools เนื่องจากมีปัญหาในแพ็กเกจนี้ที่สามารถและไม่ได้รับการแก้ไข

setuptools ที่เลิกใช้แล้วจะถูกแทนที่ด้วยdistutils2ซึ่ง "จะเป็นส่วนหนึ่งของไลบรารีมาตรฐานใน Python 3.3" ฉันต้องบอกว่าฉันชอบ setuptools และไข่และยังไม่ได้รับความเชื่อมั่นอย่างสมบูรณ์จากความสะดวกสบายของ distutils2 มันต้องการ

pip install Distutils2

และติดตั้ง

python -m distutils2.run install

ปล

บรรจุภัณฑ์ไม่เคยเป็นเรื่องเล็กน้อย (มีคนเรียนรู้สิ่งนี้โดยพยายามพัฒนาใหม่) ดังนั้นฉันจึงคิดว่าหลายสิ่งหลายอย่างได้หายไปด้วยเหตุผล ฉันแค่หวังว่าครั้งนี้จะทำอย่างถูกต้อง


4
แล้วคำตอบนี้มีอายุอย่างไร? distutils2 มาพร้อมกับ python 3.3 หรือไม่ setuptools ตายและเหี่ยวเฉาหรือไม่?
Capi Etheriel

คุณสามารถอ้างอิงถึง "คำแนะนำเกี่ยวกับสถานะ setup.py" ได้หรือไม่ เนื่องจาก "setup.py หายไป!" มันผิด. เป็นปี 2017 และ setup.py ยังอยู่ที่นี่
karantan

12

ตัวอย่างน้อยที่สุด

from setuptools import setup, find_packages


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

ข้อมูลเพิ่มเติมในเอกสาร


5

ดูตัวอย่างที่สมบูรณ์นี้https://github.com/marcindulak/python-mycliของแพ็คเกจ python ขนาดเล็ก เป็นไปตามคำแนะนำบรรจุภัณฑ์จากhttps://packaging.python.org/en/latest/distributing.htmlใช้ setup.py กับ distutils และนอกจากนี้ยังแสดงวิธีสร้างแพ็คเกจ RPM และ deb

setup.py ของโปรเจ็กต์อยู่ด้านล่าง (ดู repo สำหรับแหล่งที่มาทั้งหมด):

#!/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

5

ฉันขอแนะนำsetup.pyของโครงการตัวอย่างของPython Packaging User Guide

คู่มือผู้ใช้ Python Packaging "มีจุดมุ่งหมายเพื่อเป็นแหล่งข้อมูลที่เชื่อถือได้เกี่ยวกับวิธีการจัดแพ็กเกจเผยแพร่และติดตั้งการแจกแจง Python โดยใช้เครื่องมือปัจจุบัน"


3

ที่นี่คุณจะพบตัวอย่างที่ง่ายที่สุดในการใช้ distutils และ setup.py:

https://docs.python.org/2/distutils/introduction.html#distutils-simple-example

สิ่งนี้จะถือว่าโค้ดทั้งหมดของคุณอยู่ในไฟล์เดียวและบอกวิธีการรวมโปรเจ็กต์ที่มีโมดูลเดียว


3

นี่คือยูทิลิตี้ที่ฉันเขียนเพื่อสร้างไฟล์ 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

นี่คือลิงค์ไปยังที่เก็บ เติมฟรีเพื่อปรับปรุงโซลูชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.