ฉันจะรับรุ่นที่กำหนดsetup.py
จากแพ็คเกจของฉัน (เพื่อ--version
หรือวัตถุประสงค์อื่น ๆ ) ได้อย่างไร
ฉันจะรับรุ่นที่กำหนดsetup.py
จากแพ็คเกจของฉัน (เพื่อ--version
หรือวัตถุประสงค์อื่น ๆ ) ได้อย่างไร
คำตอบ:
ในการเรียกคืนเวอร์ชันจากภายในแพ็คเกจของคุณเมื่อรันไทม์ (คำถามของคุณดูเหมือนคำถามที่ถามจริง) คุณสามารถใช้:
import pkg_resources # part of setuptools
version = pkg_resources.require("MyProject")[0].version
หากคุณต้องการไปในทางอื่น 'รอบ (ซึ่งดูเหมือนจะเป็นสิ่งที่ผู้เขียนคำตอบอื่น ๆ ที่นี่ดูเหมือนจะคิดว่าคุณถาม) ใส่สตริงรุ่นในไฟล์แยกต่างหากและอ่านเนื้อหาของไฟล์setup.py
นั้นมา
คุณสามารถสร้าง version.py ในแพ็คเกจด้วย__version__
บรรทัดจากนั้นอ่านจาก setup.py โดยใช้execfile('mypackage/version.py')
เพื่อให้มันตั้งค่า__version__
ในเนมสเปซ setup.py
หากคุณต้องการวิธีที่ง่ายกว่ามากที่จะทำงานกับเวอร์ชัน Python ทั้งหมดและแม้แต่ภาษาที่ไม่ใช่ภาษาไพ ธ อนที่อาจต้องการการเข้าถึงสตริงเวอร์ชัน:
เก็บสตริงรุ่นเป็นเนื้อหาเพียงอย่างเดียวของไฟล์ข้อความธรรมดาชื่อเช่นและอ่านไฟล์ว่าในช่วงVERSION
setup.py
version_file = open(os.path.join(mypackage_root_dir, 'VERSION'))
version = version_file.read().strip()
VERSION
ไฟล์เดียวกันนั้นจะทำงานได้ดีเหมือนกันในโปรแกรมอื่น ๆ แม้แต่ไฟล์ที่ไม่ใช่ Python และคุณจะต้องเปลี่ยนสตริงเวอร์ชันในที่เดียวสำหรับโปรแกรมทั้งหมด
อย่างไรก็ตามอย่านำเข้าแพคเกจของคุณจาก setup.py ตามคำแนะนำในคำตอบอื่นที่นี่: มันจะทำงานได้ดีสำหรับคุณ (เพราะคุณได้ติดตั้งแพ็กเกจของคุณไว้แล้ว) แต่มันจะสร้างความเสียหายให้กับผู้ใช้ใหม่ของแพ็คเกจของคุณ เนื่องจากพวกเขาจะไม่สามารถติดตั้งแพ็คเกจของคุณโดยไม่ต้องติดตั้งการพึ่งพาตนเองก่อน
execfile
ทำงานได้ดีจริงๆ ... แต่ (น่าเศร้า) ไม่สามารถใช้งานกับ Python 3 ได้
with open('mypackage/version.py') as f: exec(f.read())
execfile('mypackage/version.py')
(จากstackoverflow.com/a/437857/647002 )
mymodule
ลองนึกภาพการกำหนดค่านี้:
setup.py
mymodule/
/ __init__.py
/ version.py
/ myclasses.py
จากนั้นให้จินตนาการถึงสถานการณ์ปกติที่คุณมีการพึ่งพาและsetup.py
ดูเหมือนว่า:
setup(...
install_requires=['dep1','dep2', ...]
...)
และตัวอย่าง__init__.py
:
from mymodule.myclasses import *
from mymodule.version import __version__
และตัวอย่างเช่นmyclasses.py
:
# these are not installed on your system.
# importing mymodule.myclasses would give ImportError
import dep1
import dep2
mymodule
ระหว่างการตั้งค่าหากคุณsetup.py
นำเข้าmymodule
แล้วระหว่างการติดตั้งที่คุณจะมีโอกาสมากที่สุดจะได้รับImportError
ที่คุณจะมีโอกาสมากที่สุดจะได้รับนี่เป็นข้อผิดพลาดทั่วไปมากเมื่อแพ็คเกจของคุณมีการขึ้นต่อกัน หากแพ็คเกจของคุณไม่มีการขึ้นต่อกันอื่น ๆ กว่าบิวอินคุณอาจจะปลอดภัย อย่างไรก็ตามนี่ไม่ใช่วิธีปฏิบัติที่ดี เหตุผลสำหรับสิ่งนี้คือมันไม่ได้เป็นหลักฐานในอนาคต บอกว่าพรุ่งนี้รหัสของคุณจำเป็นต้องพึ่งพาคนอื่น
__version__
ที่ไหนหากคุณ hardcode __version__
ในsetup.py
แล้วมันอาจไม่ตรงกับรุ่นที่คุณจะจัดส่งในโมดูลของคุณ เพื่อให้สอดคล้องคุณจะวางไว้ในที่เดียวและอ่านจากที่เดียวกันเมื่อคุณต้องการ การใช้import
คุณอาจได้รับปัญหา # 1
setuptools
คุณจะใช้การรวมกันของopen
, exec
และให้ Dict สำหรับexec
ตัวแปรเพิ่ม:
# setup.py
from setuptools import setup, find_packages
from distutils.util import convert_path
main_ns = {}
ver_path = convert_path('mymodule/version.py')
with open(ver_path) as ver_file:
exec(ver_file.read(), main_ns)
setup(...,
version=main_ns['__version__'],
...)
และในการmymodule/version.py
เปิดเผยรุ่น:
__version__ = 'some.semantic.version'
วิธีนี้รุ่นจะจัดส่งมาพร้อมกับโมดูลและคุณไม่มีปัญหาในระหว่างการตั้งค่าพยายามที่จะนำเข้าโมดูลที่ขาดการอ้างอิง (ยังไม่ได้ติดตั้ง)
เทคนิคที่ดีที่สุดคือการกำหนด__version__
ในรหัสผลิตภัณฑ์ของคุณจากนั้นนำเข้าสู่ setup.py จากที่นั่น สิ่งนี้ให้คุณค่าที่คุณสามารถอ่านได้ในโมดูลการทำงานของคุณและมีเพียงที่เดียวเท่านั้นที่จะกำหนด
ไม่ได้ติดตั้งค่าใน setup.py และ setup.py จะไม่ติดหลังจากการติดตั้ง
สิ่งที่ฉันทำ (ตัวอย่าง) ใน coverage.py:
# coverage/__init__.py
__version__ = "3.2"
# setup.py
from coverage import __version__
setup(
name = 'coverage',
version = __version__,
...
)
อัปเดต (2017): coverage.py ไม่นำเข้าตัวเองเพื่อรับเวอร์ชันอีกต่อไป การนำเข้ารหัสของคุณสามารถถอนการติดตั้งได้เพราะรหัสผลิตภัณฑ์ของคุณจะพยายามนำเข้าการอ้างอิงซึ่งยังไม่ได้ติดตั้งเนื่องจาก setup.py เป็นสิ่งที่ติดตั้ง
__version__
อยู่ในนั้นถูกทำลายอย่างใดการนำเข้าของคุณก็จะถูกทำลายเช่นกัน Python ไม่ทราบวิธีตีความข้อความที่คุณต้องการเท่านั้น @pjeby ถูกต้อง: หากโมดูลของคุณต้องการนำเข้าโมดูลอื่น ๆ พวกเขาอาจยังไม่ได้ติดตั้งและมันจะวุ่นวาย เทคนิคนี้ใช้งานได้หากคุณระมัดระวังว่าการนำเข้าไม่ได้เป็นการ จำกัด การนำเข้าอื่น ๆ
pip install <packagename>
ฉันได้รับข้อผิดพลาดต่อไปนี้: ImportError: No module named <packagename>
. โปรดเตือนผู้อ่านของคุณว่าคุณไม่สามารถเรียกใช้ไฟล์ setup.py เช่นนี้ในสภาพแวดล้อมที่ไม่ได้ติดตั้งแพ็คเกจ
คำถามของคุณค่อนข้างคลุมเครือ แต่ฉันคิดว่าสิ่งที่คุณถามคือวิธีระบุ
คุณจำเป็นต้องนิยาม__version__
ดังนี้:
__version__ = '1.4.4'
จากนั้นคุณสามารถยืนยันได้ว่า setup.py รู้เกี่ยวกับเวอร์ชันที่คุณเพิ่งระบุ:
% ./setup.py --version
1.4.4
ฉันไม่พอใจกับคำตอบเหล่านี้ ... ไม่ต้องการ setuptools หรือสร้างโมดูลแยกต่างหากสำหรับตัวแปรเดี่ยวดังนั้นฉันจึงได้สิ่งเหล่านี้
เมื่อคุณแน่ใจว่าโมดูลหลักอยู่ในรูปแบบ pep8 และจะยังคงอยู่:
version = '0.30.unknown'
with file('mypkg/mymod.py') as f:
for line in f:
if line.startswith('__version__'):
_, _, version = line.replace("'", '').split()
break
หากคุณต้องการระวังเป็นพิเศษและใช้ parser จริง:
import ast
version = '0.30.unknown2'
with file('mypkg/mymod.py') as f:
for line in f:
if line.startswith('__version__'):
version = ast.parse(line).body[0].value.s
break
setup.py นั้นเป็นโมดูลของการโยนทิ้งดังนั้นจึงไม่เป็นปัญหาหากเป็นบิตที่น่าเกลียด
ปรับปรุง: meta.py
ตลกพอฉันได้ย้ายออกไปจากนี้ในปีที่ผ่านมาและเริ่มใช้เป็นไฟล์แยกต่างหากในแพคเกจที่เรียกว่า ฉันใส่ข้อมูลเมตาจำนวนมากลงไปที่นั่นซึ่งฉันอาจต้องการเปลี่ยนบ่อยๆ ดังนั้นไม่ใช่เพียงแค่ค่าเดียว
ast.get_docstring()
กับบางอย่าง.split('\n')[0].strip()
เพื่อกรอกข้อมูลdescription
จากแหล่งที่มาโดยอัตโนมัติ สิ่งหนึ่งที่น้อยกว่าในการซิงค์
สร้างไฟล์ในแผนผังต้นทางของคุณเช่นใน yourbasedir / yourpackage / _version.py ปล่อยให้ไฟล์นั้นมีโค้ดเพียงบรรทัดเดียวเช่นนี้
__version__ = "1.1.0-r4704"
จากนั้นใน setup.py ของคุณให้เปิดไฟล์นั้นแล้วแยกวิเคราะห์หมายเลขเวอร์ชันดังนี้:
verstr = "ไม่ทราบ" ลอง: verstrline = open ('yourpackage / _version.py', "rt"). read () ยกเว้น EnvironmentError: ผ่าน # โอเคไม่มีไฟล์เวอร์ชั่น อื่น: VSRE = r "^ __ version__ = ['\"] ([^' \ "] *) ['\"] " mo = re.search (VSRE, verstrline, re.M) ถ้า mo: verstr = mo.group (1) อื่น: เพิ่ม RuntimeError ("ไม่สามารถหารุ่นใน yourpackage / _version.py")
ในที่สุดค่ะ yourbasedir/yourpackage/__init__.py
การนำเข้า _version เช่นนี้:
__version__ = "ไม่ทราบ" ลอง: จาก _version นำเข้า __version__ ยกเว้น ImportError: # เรากำลังทำงานในแผนผังที่ไม่มี _version.py ดังนั้นเราจึงไม่ทราบว่าเวอร์ชันของเราคืออะไร ผ่านไป
ตัวอย่างของรหัสที่ทำนี่คือแพ็คเกจ "pyutil" ที่ฉันดูแล (ดู PyPI หรือ google search - stackoverflow ไม่อนุญาตให้ฉันใส่ไฮเปอร์ลิงก์ไปยังคำตอบนี้)
@pjeby ถูกต้องที่คุณไม่ควรนำเข้าแพ็คเกจจาก setup.py ของตัวเอง สิ่งนี้จะใช้งานได้เมื่อคุณทดสอบโดยการสร้าง Python interpreter ใหม่และเรียกใช้งาน setup.py ในสิ่งแรก: python setup.py
แต่มีบางกรณีที่มันไม่ทำงาน นั่นเป็นเพราะimport youpackage
ไม่ได้หมายถึงการอ่านไดเรกทอรีการทำงานปัจจุบันสำหรับไดเรกทอรีที่ชื่อ "yourpackage" มันหมายถึงการค้นหาในปัจจุบันsys.modules
สำหรับคีย์ "yourpackage" และจากนั้นทำสิ่งต่าง ๆ ถ้ามันไม่ได้อยู่ที่นั่น ดังนั้นจึงใช้ได้เสมอเมื่อคุณทำpython setup.py
เพราะคุณมีความสดใหม่ที่ว่างเปล่าsys.modules
แต่สิ่งนี้ไม่ได้ผล
ตัวอย่างเช่นถ้า py2exe กำลังเรียกใช้งาน setup.py ของคุณเป็นส่วนหนึ่งของกระบวนการบรรจุแอปพลิเคชัน ฉันเห็นกรณีเช่นนี้ซึ่ง py2exe จะใส่หมายเลขเวอร์ชันผิดบนแพ็คเกจเนื่องจากแพ็คเกจได้รับหมายเลขเวอร์ชันมาimport myownthing
ใน setup.py แต่แพคเกจนั้นมีการนำเข้าเวอร์ชันที่แตกต่างกันก่อนหน้านี้ในระหว่างการเรียกใช้ py2exe ในทำนองเดียวกันถ้า setuptools, easy_install, กระจายหรือ distutils2 กำลังพยายามสร้างแพ็คเกจของคุณเป็นส่วนหนึ่งของกระบวนการติดตั้งแพ็คเกจอื่นที่ขึ้นอยู่กับคุณ จากนั้นแพคเกจของคุณจะสามารถนำเข้าได้ในเวลาที่มีการประเมินค่า setup.py หรือว่ามีแพ็กเกจเวอร์ชันของคุณที่นำเข้ามาในช่วงชีวิตของล่าม Python หรือไม่หรือการนำเข้าแพ็คเกจของคุณต้องติดตั้งแพ็กเกจอื่นก่อน หรือมีผลข้างเคียงสามารถเปลี่ยนผลลัพธ์ได้ ฉันมีปัญหาหลายครั้งที่พยายามใช้แพ็กเกจ Python ซ้ำซึ่งทำให้เกิดปัญหากับเครื่องมือเช่น py2exe และ setuptools เนื่องจาก setup.py พวกเขานำเข้าแพ็คเกจตัวเองเพื่อค้นหาหมายเลขเวอร์ชัน
เทคนิคนี้เล่นกับเครื่องมือในการสร้างyourpackage/_version.py
ไฟล์ให้คุณโดยอัตโนมัติตัวอย่างเช่นการอ่านประวัติการควบคุมการแก้ไขของคุณและการเขียนหมายเลขเวอร์ชันตามแท็กล่าสุดในประวัติการควบคุมการแก้ไข นี่คือเครื่องมือที่ใช้สำหรับ darcs: http://tahoe-lafs.org/trac/darcsver/browser/trunk/README.rstและนี่คือข้อมูลโค้ดที่ทำสิ่งเดียวกันสำหรับ git: http: // github .com / วอร์เนอร์ / หลาม ECDSA / หยด / 0ed702a9d4057ecf33eea969b8cf280eaccd89a1 / setup.py # L34
สิ่งนี้ควรใช้งานได้โดยใช้นิพจน์ทั่วไปและขึ้นอยู่กับเขตข้อมูลเมทาดาทาที่จะมีรูปแบบดังนี้:
__fieldname__ = 'value'
ใช้สิ่งต่อไปนี้ที่จุดเริ่มต้นของ setup.py:
import re
main_py = open('yourmodule.py').read()
metadata = dict(re.findall("__([a-z]+)__ = '([^']+)'", main_py))
หลังจากนั้นคุณสามารถใช้ข้อมูลเมตาในสคริปต์ของคุณดังนี้:
print 'Author is:', metadata['author']
print 'Version is:', metadata['version']
ด้วยโครงสร้างเช่นนี้
setup.py
mymodule/
/ __init__.py
/ version.py
/ myclasses.py
โดยที่version.pyมี:
__version__ = 'version_string'
คุณสามารถทำได้ในsetup.py :
import sys
sys.path[0:0] = ['mymodule']
from version import __version__
สิ่งนี้จะไม่ทำให้เกิดปัญหากับการพึ่งพาใด ๆ ที่คุณมีใน mymodule / __ init__.py
เพื่อหลีกเลี่ยงการนำเข้าไฟล์ (และดำเนินการรหัส) หนึ่งสามารถแยกมันและกู้คืนversion
แอตทริบิวต์จากต้นไม้ไวยากรณ์:
# assuming 'path' holds the path to the file
import ast
with open(path, 'rU') as file:
t = compile(file.read(), path, 'exec', ast.PyCF_ONLY_AST)
for node in (n for n in t.body if isinstance(n, ast.Assign)):
if len(node.targets) == 1:
name = node.targets[0]
if isinstance(name, ast.Name) and \
name.id in ('__version__', '__version_info__', 'VERSION'):
v = node.value
if isinstance(v, ast.Str):
version = v.s
break
if isinstance(v, ast.Tuple):
r = []
for e in v.elts:
if isinstance(e, ast.Str):
r.append(e.s)
elif isinstance(e, ast.Num):
r.append(str(e.n))
version = '.'.join(r)
break
รหัสนี้พยายามค้นหา__version__
หรือการVERSION
กำหนดที่ระดับบนสุดของการส่งคืนโมดูลคือค่าสตริง ด้านขวาอาจเป็นสตริงหรือทูเปิลก็ได้
มีหลายพันวิธีในการปรนนิบัติแมว - นี่คือของฉัน:
# Copied from (and hacked):
# https://github.com/pypa/virtualenv/blob/develop/setup.py#L42
def get_version(filename):
import os
import re
here = os.path.dirname(os.path.abspath(__file__))
f = open(os.path.join(here, filename))
version_file = f.read()
f.close()
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError("Unable to find version string.")
ทำความสะอาดhttps://stackoverflow.com/a/12413800จาก @ gringo-suave:
from itertools import ifilter
from os import path
from ast import parse
with open(path.join('package_name', '__init__.py')) as f:
__version__ = parse(next(ifilter(lambda line: line.startswith('__version__'),
f))).body[0].value.s
ตอนนี้เป็นขั้นต้นและต้องมีการปรับปรุงบางอย่าง (อาจมีการโทรหาสมาชิกแบบไม่เปิดเผยใน pkg_resources ที่ฉันพลาด) แต่ฉันไม่เห็นว่าทำไมสิ่งนี้ถึงใช้งานไม่ได้และทำไมไม่มีใครแนะนำเลยถึงวันที่ ไม่เปิดใช้งานนี้) ... โปรดทราบว่านี่คือ Python 2.x และจะต้องมี pkg_resources (ถอนหายใจ):
import pkg_resources
version_string = None
try:
if pkg_resources.working_set is not None:
disto_obj = pkg_resources.working_set.by_key.get('<my pkg name>', None)
# (I like adding ", None" to gets)
if disto_obj is not None:
version_string = disto_obj.version
except Exception:
# Do something
pass
เราต้องการที่จะนำข้อมูลเมตาเกี่ยวกับแพคเกจของเราpypackagery
ใน__init__.py
แต่ไม่สามารถเพราะมันมีการพึ่งพาบุคคลที่สามเป็น PJ Eby ชี้แล้วออก (ดูคำตอบและคำเตือนเกี่ยวกับสภาพการแข่งขันของเขา)
เราแก้ไขได้โดยการสร้างโมดูลแยกpypackagery_meta.py
ที่มีเฉพาะข้อมูลเมตา:
"""Define meta information about pypackagery package."""
__title__ = 'pypackagery'
__description__ = ('Package a subset of a monorepo and '
'determine the dependent packages.')
__url__ = 'https://github.com/Parquery/pypackagery'
__version__ = '1.0.0'
__author__ = 'Marko Ristin'
__author_email__ = 'marko.ristin@gmail.com'
__license__ = 'MIT'
__copyright__ = 'Copyright 2018 Parquery AG'
จากนั้นนำเข้าข้อมูลเมตาในpackagery/__init__.py
:
# ...
from pypackagery_meta import __title__, __description__, __url__, \
__version__, __author__, __author_email__, \
__license__, __copyright__
# ...
และในที่สุดก็ใช้มันในsetup.py
:
import pypackagery_meta
setup(
name=pypackagery_meta.__title__,
version=pypackagery_meta.__version__,
description=pypackagery_meta.__description__,
long_description=long_description,
url=pypackagery_meta.__url__,
author=pypackagery_meta.__author__,
author_email=pypackagery_meta.__author_email__,
# ...
py_modules=['packagery', 'pypackagery_meta'],
)
คุณต้องรวมpypackagery_meta
ไว้ในแพ็คเกจของคุณด้วยpy_modules
อาร์กิวเมนต์การตั้งค่า มิฉะนั้นคุณไม่สามารถนำเข้ามันเมื่อทำการติดตั้งเนื่องจากการกระจายแพ็คเกจจะขาดหายไป
ง่ายและตรงไปตรงมาสร้างไฟล์ที่เรียกว่าsource/package_name/version.py
มีเนื้อหาดังต่อไปนี้:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
__version__ = "2.6.9"
จากนั้นในไฟล์ของsource/package_name/__init__.py
คุณคุณนำเข้าเวอร์ชันเพื่อให้ผู้อื่นใช้:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from .version import __version__
ตอนนี้คุณสามารถใส่มัน setup.py
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
try:
filepath = 'source/package_name/version.py'
version_file = open( filepath )
__version__ ,= re.findall( '__version__ = "(.*)"', version_file.read() )
except Exception as error:
__version__ = "0.0.1"
sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )
finally:
version_file.close()
การทดสอบนี้กับงูหลาม2.7
, 3.3
, 3.4
, 3.5
, 3.6
และ3.7
บน Linux, Windows และ Mac OS ฉันใช้แพคเกจของฉันที่มีการรวมและการทดสอบหน่วยสำหรับแพลตฟอร์มเหล่านี้ทั้งหมด คุณสามารถดูผลลัพธ์จาก.travis.yml
และappveyor.yml
ที่นี่:
เวอร์ชันสำรองกำลังใช้ตัวจัดการบริบท:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
try:
filepath = 'source/package_name/version.py'
with open( filepath ) as file:
__version__ ,= re.findall( '__version__ = "(.*)"', file.read() )
except Exception as error:
__version__ = "0.0.1"
sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )
คุณสามารถใช้codecs
โมดูลเพื่อจัดการข้อผิดพลาด unicode ได้ทั้งบน Python 2.7
และ3.6
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
import codecs
try:
filepath = 'source/package_name/version.py'
with codecs.open( filepath, 'r', errors='ignore' ) as file:
__version__ ,= re.findall( '__version__ = "(.*)"', file.read() )
except Exception as error:
__version__ = "0.0.1"
sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )
หากคุณกำลังเขียนโมดูล Python 100% ใน C / C ++ โดยใช้ Python C Extensions คุณสามารถทำสิ่งเดียวกันได้ แต่ใช้ C / C ++ แทน Python
ในกรณีนี้ให้สร้างสิ่งต่อไปนี้setup.py
:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import re
import sys
import codecs
from setuptools import setup, Extension
try:
filepath = 'source/version.h'
with codecs.open( filepath, 'r', errors='ignore' ) as file:
__version__ ,= re.findall( '__version__ = "(.*)"', file.read() )
except Exception as error:
__version__ = "0.0.1"
sys.stderr.write( "Warning: Could not open '%s' due %s\n" % ( filepath, error ) )
setup(
name = 'package_name',
version = __version__,
package_data = {
'': [ '**.txt', '**.md', '**.py', '**.h', '**.hpp', '**.c', '**.cpp' ],
},
ext_modules = [
Extension(
name = 'package_name',
sources = [
'source/file.cpp',
],
include_dirs = ['source'],
)
],
)
ซึ่งอ่านรุ่นจากไฟล์version.h
:
const char* __version__ = "1.0.12";
แต่อย่าลืมที่จะสร้างMANIFEST.in
เพื่อรวมversion.h
ไฟล์:
include README.md
include LICENSE.txt
recursive-include source *.h
และมันถูกรวมเข้ากับแอปพลิเคชันหลักด้วย:
#include <Python.h>
#include "version.h"
// create the module
PyMODINIT_FUNC PyInit_package_name(void)
{
PyObject* thismodule;
...
// https://docs.python.org/3/c-api/arg.html#c.Py_BuildValue
PyObject_SetAttrString( thismodule, "__version__", Py_BuildValue( "s", __version__ ) );
...
}
อ้างอิง:
ปรับใช้แพคเกจกับเซิร์ฟเวอร์และแบบแผนการตั้งชื่อไฟล์สำหรับแพ็คเกจดัชนี:
ตัวอย่างสำหรับการแปลงเวอร์ชั่น pip แบบไดนามิก:
ชนะ:
Mac:
from setuptools_scm import get_version
def _get_version():
dev_version = str(".".join(map(str, str(get_version()).split("+")[0]\
.split('.')[:-1])))
return dev_version
ค้นหาตัวอย่าง setup.py เรียกการจับคู่เวอร์ชั่น pip แบบไดนามิกจากคอมมิทคอม
setup(
version=_get_version(),
name=NAME,
description=DESCRIPTION,
long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS,
# add few more for wheel wheel package ...conversion
)
ฉันใช้ตัวแปรสภาพแวดล้อมด้านล่าง
VERSION = 0.0.0 python setup.py sdist bdist_wheel
ใน setup.py
import os
setup(
version=os.environ['VERSION'],
...
)
สำหรับการตรวจสอบความสอดคล้องกับเวอร์ชั่นของแพคเกอร์ฉันใช้สคริปต์ด้านล่าง
PKG_VERSION=`python -c "import pkg; print(pkg.__version__)"`
if [ $PKG_VERSION == $VERSION ]; then
python setup.py sdist bdist_wheel
else
echo "Package version differs from set env variable"
fi