পাইথন প্যাকেজে সংস্করণ এম্বেড করার মানক উপায়?


264

পাইথন প্যাকেজের সাথে ভার্সন স্ট্রিংটি এমনভাবে সংযুক্ত করার কোনও মানক উপায় আছে যা আমি নিম্নলিখিতগুলি করতে পারি?

import foo
print foo.version

আমি ধারণা করব যে কোনও অতিরিক্ত হার্ডকোডিং ছাড়াই সেই তথ্যটি পুনরুদ্ধার করার কোনও উপায় আছে, যেহেতু setup.pyইতিমধ্যে ছোট / বড় স্ট্রিং নির্দিষ্ট করা আছে specified আমি যে বিকল্প সমাধান পেয়েছি তা হ'ল import __version__আমার foo/__init__.pyএবং তারপরে __version__.pyতৈরি হয়েছিল setup.py


7
অবগতির জন্য, সেখানে একটি খুব ভাল ওভারভিউ আছে: packaging.python.org/en/latest/...
ionelmc

1
ইনস্টল করা প্যাকেজের সংস্করণটি সেটআপলগুলির সাহায্যে মেটাডেটা থেকে পুনরুদ্ধার করা যায় , তাই অনেক ক্ষেত্রে কেবল সংস্করণটি রাখা setup.pyযথেষ্ট। এই প্রশ্নটি দেখুন ।
সাজ

2
এফওয়াইআই, সংস্করণ সংখ্যার জন্য সত্যের একক উত্স (সেটআপ এবং রান সময় উভয় সময়ে) বজায় রাখতে মূলত 5 টি সাধারণ নিদর্শন রয়েছে
কেএফ লিন

@ionelmc পাইথনের ডকুমেন্টেশনে সিঙ্গেল- সোসারিংয়ের জন্য 7 টি পৃথক বিকল্পের তালিকা দেওয়া হয়েছে । এটি কি " সত্যের একক উত্স " ধারণার বিরোধিতা করে না ?
স্টিভয়েসিয়াক

আপনি কী জিজ্ঞাসা করছেন তা নিশ্চিত নয় সেখানে অনেকগুলি তালিকাভুক্ত রয়েছে কারণ প্যাকেজিং গাইডটি মতামত জানাতে চায় না।
ionelmc

উত্তর:


136

আপনার প্রশ্নের সরাসরি উত্তর নয়, তবে আপনাকে এটির নামকরণ বিবেচনা করা উচিত __version__, না version

এটি প্রায় অর্ধেক মানের। স্ট্যান্ডার্ড লাইব্রেরিতে অনেকগুলি মডিউল ব্যবহার করে __version__এবং এটি প্রচুর তৃতীয় পক্ষের মডিউলগুলিতেও ব্যবহৃত হয় , সুতরাং এটি আধা-মানক।

সাধারণত, __version__একটি স্ট্রিং, তবে কখনও কখনও এটি একটি ভাসা বা টিপলও হয়।

সম্পাদনা করুন: এস.লোট (আপনাকে ধন্যবাদ!) দ্বারা উল্লিখিত হিসাবে, পিইপি 8 এটিকে স্পষ্টভাবে বলেছে:

মডিউল স্তর স্তরের নাম

মডিউল স্তর "dunders" যেমন (দুই নেতৃস্থানীয় এবং দুই চিহ্ন আন্ডারস্কোর সঙ্গে অর্থাত নাম) __all__, __author__, __version__, ইত্যাদি মডিউল docstring পরে কিন্তু থেকে ছাড়া কোন আমদানি বিবৃতি সামনে স্থাপন করা উচিত __future__আমদানির।

আপনারও নিশ্চিত হওয়া উচিত যে সংস্করণ নম্বরটি পিইপি 440 ( পিইপি 386 এই মানের আগের সংস্করণ) বর্ণিত বিন্যাসের সাথে সঙ্গতিপূর্ণ।


9
এটি স্ট্রিং হওয়া উচিত, এবং টিউপল সংস্করণটির জন্য একটি ভার্সন_ইনফো থাকতে হবে ।
জেমস এন্টিল

জেমস: কেন __version_info__বিশেষভাবে? (যা আপনার নিজস্ব ডাবল-আন্ডারস্কোর শব্দটি "আবিষ্কার" করে)) [যখন জেমস মন্তব্য করেছেন, আন্ডারস্কোররা মন্তব্যগুলিতে কিছুই করেন নি, এখন তারা জোরকে নির্দেশ করে, তাই জেমস সত্যিই __version_info__খুব লিখেছিলেন । --- সম্পাদনা]

প্যাকেজগুলির মধ্যে কী সংস্করণটি বলা উচিত সে সম্পর্কে আপনি কিছু দেখতে পারেন py
সিয়েনকিউ

2
ঠিক। দেখে মনে হচ্ছে এই পিইপিগুলি একে অপরের সাথে বিরোধিতা করে। ওয়েল, পিইপি 8 "" যদি "এবং" ক্রুড "বলে, তাই এটি ভিসিএস কীওয়ার্ড প্রসারণটি ব্যবহার করে সত্যই সমর্থন করে না। এছাড়াও, আপনি যদি কখনও কোনও ভিন্ন ভিসিএসে স্যুইচ করেন তবে আপনি পুনর্বিবেচনার তথ্যটি হারাবেন। অতএব আমি কমপক্ষে বড় প্রকল্পগুলির জন্য একটি একক উত্স ফাইলে এম্বেড থাকা একটি পিইপি 386/440-অনুবর্তী সংস্করণ তথ্য ব্যবহার করার পরামর্শ দেব।
oefe

2
আপনি যেখানে এই সংস্করণ রাখবেন । এটি স্বীকৃত সংস্করণ হিসাবে বিবেচনা করে আমি এখানে অতিরিক্ত তথ্যটি দেখতে পছন্দ করব।
ডার্কগ্যাজে

120

আমি _version.pyসংস্করণ তথ্য সঞ্চয় করতে "একবার ক্যানোনিকাল স্থান" হিসাবে একটি ফাইল ব্যবহার করি :

  1. এটি একটি __version__বৈশিষ্ট্য সরবরাহ করে।

  2. এটি স্ট্যান্ডার্ড মেটাডেটা সংস্করণ সরবরাহ করে। সুতরাং এটি pkg_resourcesবা অন্যান্য সরঞ্জামগুলি সনাক্ত করা যাবে যা প্যাকেজ মেটাডেটা (EGG-INFO এবং / অথবা PKG-INFO, PEP 0345) পার্স করে।

  3. আপনার প্যাকেজটি তৈরি করার সময় এটি আপনার প্যাকেজ (বা অন্য কিছু) আমদানি করে না, যা কিছু পরিস্থিতিতে সমস্যার কারণ হতে পারে। (এটি কী কী সমস্যা সৃষ্টি করতে পারে সে সম্পর্কে নীচের মন্তব্যগুলি দেখুন))

  4. সংস্করণ সংখ্যাটি লিখিত আছে কেবল একটিই জায়গা, সুতরাং সংস্করণ নম্বর পরিবর্তিত হলে এটি পরিবর্তন করার জন্য কেবলমাত্র একটি জায়গা রয়েছে এবং অসামঞ্জস্যিত সংস্করণগুলির সম্ভাবনা কম রয়েছে।

একটি .py ফাইল, "_version.py" নামে যা আপনার পাইথন প্যাকেজের মধ্যে হয়, উদাহরণস্বরূপ হয় "এক ক্যানোনিকাল জায়গা" সংস্করণ সংখ্যা সঞ্চয় করতে: এখানে কিভাবে এটা কাজ করে myniftyapp/_version.py। এই ফাইলটি একটি পাইথন মডিউল, তবে আপনার সেটআপ.পি এটি আমদানি করে না! (এটি বৈশিষ্ট্যটিকে 3 পরাজিত করবে) পরিবর্তে আপনার সেটআপ.পি জানে যে এই ফাইলটির বিষয়বস্তু খুব সহজ, এরকম কিছু:

__version__ = "3.6.5"

এবং তাই আপনার সেটআপ.পি ফাইলটি খোলে এবং পার্স করে, কোড সহ:

import re
VERSIONFILE="myniftyapp/_version.py"
verstrline = open(VERSIONFILE, "rt").read()
VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
mo = re.search(VSRE, verstrline, re.M)
if mo:
    verstr = mo.group(1)
else:
    raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,))

তারপরে আপনার সেটআপ.পি এই স্ট্রিংটিকে "সংস্করণ" যুক্তিটির মান হিসাবে পাস করে setup(), এইভাবে সন্তোষজনক বৈশিষ্ট্য 2।

বৈশিষ্ট্য 1 টি সন্তুষ্ট করতে আপনার প্যাকেজটি (রান-টাইমে, সেটআপের সময় নয়!) থাকতে myniftyapp/__init__.pyপারে _ রূপান্তর ফাইলটি এর থেকে আমদানি করুন :

from _version import __version__

এখানে এই প্রযুক্তিটি একটি উদাহরণ যে আমি বছর ধরে ব্যবহার করছি।

এই উদাহরণের কোডটি কিছুটা জটিল, তবে সরলীকৃত উদাহরণ যা আমি এই মন্তব্যে লিখেছি তা একটি সম্পূর্ণ বাস্তবায়ন হওয়া উচিত।

সংস্করণ আমদানির উদাহরণ কোড এখানে ।

আপনি যদি এই পদ্ধতির সাথে কোনও ভুল দেখেন তবে দয়া করে আমাকে জানান।


8
আপনি কি দয়া করে # 3 প্রেরণার সমস্যাগুলি বর্ণনা করতে পারেন? গ্লিফ বলেছেন, "আপনার সেটআপ.পি চালিত হলে আপনার কোড সিস্টেমে কোথাও নেই বলে সেটআপটুলগুলি পছন্দ করে" এর সাথে কিছু করার ছিল তবে বিবরণী আমাকে এবং অন্যদের বোঝাতে সহায়তা করবে।
ইভান কোজিক

2
@ আইভা এখন, কি অর্ডারটি এই সরঞ্জামটি করা উচিত? এটা তোলে (setuptools / পিপ / virtualenv আজকের সিস্টেমের মধ্যে) এমনকি জানতে পারে না কি deps হয় না হওয়া পর্যন্ত আপনার মূল্যায়ন setup.py। এছাড়াও, যদি এটি সম্পূর্ণ গভীরতা-সম্পন্ন করার চেষ্টা করে এবং এটি করার আগে সমস্ত ডিপগুলি করে, তবে বিজ্ঞপ্তি ডিপগুলি থাকলে এটি আটকে যায়। তবে যদি নির্ভরতা ইনস্টল করার আগে এটি এই প্যাকেজটি তৈরির চেষ্টা করে, তবে আপনি যদি নিজের প্যাকেজটি আপনার থেকে আমদানি করেন তবে setup.pyঅগত্যা তার ডিপগুলি, বা তার ডিপগুলির সঠিক সংস্করণগুলি আমদানি করতে সক্ষম হবে না।
জুকো

3
আপনি কি "setup.py" ফাইল "পার্সন.পি" লিখবেন পার্স করার পরিবর্তে? এটি সহজ বলে মনে হচ্ছে।
জোনাথন হার্টলি

3
জোনাথন হার্টলি: আমি সম্মত হই যে আপনার "setup.py" এর পক্ষে "version.py" ফাইলটি বিশ্লেষণের পরিবর্তে লেখার পক্ষে কিছুটা সহজ হবে তবে আপনি যখন আপনার সেটআপ.পি সম্পাদনা করেছেন তখন এটি অসঙ্গতিটির জন্য একটি উইন্ডো খুলবে it নতুন সংস্করণ রয়েছে তবে ভার্সন.পি ফাইল আপডেট করার জন্য সেটআপ.পি চালানো হয়নি। ক্যানোনিকাল সংস্করণটি একটি পৃথক পৃথক ফাইলে থাকার আরেকটি কারণ হ'ল এটি অন্যান্য সরঞ্জামগুলির জন্য যেমন আপনার পুনর্বিবেচনা নিয়ন্ত্রণের অবস্থাটি পড়ার সরঞ্জামগুলির পক্ষে সংস্করণ ফাইলটি লিখতে সহজ করে তোলে ।
Zooko

3
execfile("myniftyapp/_version.py")সংস্করণ কোডটি ম্যানুয়ালি পার্স করার চেষ্টা করার পরিবর্তে সেটআপ.পি-এর মধ্যে অনুরূপ পন্থা । স্ট্যাকওভারফ্লো . com / a / 2073599 / 647002- এ প্রস্তাব দেওয়া হয়েছে - সেখানে আলোচনাও সহায়ক হতে পারে।
ম্যাডমন্ডস

97

পুনরায় লিখিত 2017-05

পাইথন কোড লেখার এবং বিভিন্ন প্যাকেজ পরিচালনার দশ বছরেরও বেশি সময় পরে আমি এই সিদ্ধান্তে পৌঁছেছি যে ডিআইওয়াই সম্ভবত সেরা পন্থা নয়।

আমি pbrআমার প্যাকেজগুলিতে সংস্করণ ব্যবহারের জন্য প্যাকেজ ব্যবহার শুরু করেছি। যদি আপনি গিটকে আপনার এসসিএম হিসাবে ব্যবহার করেন তবে এটি আপনার কাজের ফলের সাথে ম্যাজিকের মতো ফিট হয়ে যাবে, আপনার সপ্তাহের কাজের সাশ্রয় করবে (সমস্যাটি কতটা জটিল হতে পারে তা নিয়ে আপনি অবাক হয়ে যাবেন)।

আজ অবধি পিবিআর # 11 টি ব্যবহৃত সবচেয়ে বেশি ব্যবহৃত পাইথন প্যাকেজ এবং এই স্তরে পৌঁছানোতে কোনও নোংরা কৌশল অন্তর্ভুক্ত নয়: কেবল একটি ছিল: একটি সাধারণ প্যাকেজিংয়ের সমস্যাটিকে খুব সাধারণ উপায়ে ফিক্সিং করা।

pbr প্যাকেজ রক্ষণাবেক্ষণের ভার বেশি করতে পারে, কেবল সংস্করণে সীমাবদ্ধ নয় তবে এটি আপনাকে তার সমস্ত সুবিধা গ্রহণ করতে বাধ্য করে না।

সুতরাং আপনার কাছে একটি ধারণা দেওয়ার জন্য যে কোনও প্রতিশ্রুতিতে পিবিআর গ্রহণ করা কেমন লাগে সে সম্পর্কে পিবিআর-তে একটি প্যাকেজ সুইচ করে দেখুন

সম্ভবত আপনি লক্ষ্য করেছেন যে সংস্করণটি সংগ্রহস্থলটিতে মোটেই সঞ্চিত নয়। পিবিআর এটি গিট শাখা এবং ট্যাগ থেকে সনাক্ত করে।

গিট সংগ্রহস্থল না থাকলে কী হয় তা নিয়ে চিন্তা করার দরকার নেই কারণ আপনি যখন অ্যাপ্লিকেশনগুলি প্যাকেজ বা ইনস্টল করেন তখন পিবিআর "সংকলন" করে এবং সংস্করণটি ক্যাশে করে, তাই গিটের উপর কোনও রানটাইম নির্ভরতা নেই।

পুরানো সমাধান

আমি এখনও অবধি দেখা সেরা সমাধান এখানে এবং এটি ব্যাখ্যা করে কেন:

ভিতরে yourpackage/version.py:

# Store the version here so:
# 1) we don't load dependencies by storing it in __init__.py
# 2) we can import it in setup.py for the same reason
# 3) we can import it into your module module
__version__ = '0.12'

ভিতরে yourpackage/__init__.py:

from .version import __version__

ভিতরে setup.py:

exec(open('yourpackage/version.py').read())
setup(
    ...
    version=__version__,
    ...

যদি আপনি আরও একটি পদ্ধতির জানেন যা ভাল বলে মনে হয় তবে আমাকে জানান।


12
এর, না। এক্সিকিফাইল () পাইথন 3 তে বিদ্যমান নেই, তাই এক্সিকিউটিভ (ওপেন () (পড়ুন () পড়ুন) ভাল ব্যবহার করা ভাল।
ক্রিস্টোফ ভু-ব্রুজিয়ার

4
from .version import __version__সেটআপ.পি-তেও নেই কেন ?
এপ্রিলিয়ন

4
@ এপ্রিলিয়ন কারণ প্যাকেজটি setup.pyচলমান অবস্থায় লোড হয়নি - চেষ্টা করে দেখুন, আপনি একটি ত্রুটি পাবেন (বা কমপক্ষে, আমি :-))
দার্থবিথ

3
পিবিআরের লিঙ্কটি খারাপ গেটওয়ের ফলাফল।
মেরোজ

4
পিবিআর , নিঃসন্দেহে একটি দুর্দান্ত সরঞ্জাম, তবে আপনি প্রশ্নের সমাধান করতে ব্যর্থ হন। আপনি কীভাবে বর্তমান সংস্করণ বা ইনস্টল করা প্যাকেজটি বিআরপি-র মাধ্যমে অ্যাক্সেস করতে পারেন ।
nad2000

29

বিলম্বিত পিইপি 396 (মডিউল সংস্করণ নম্বর) অনুসারে এটি করার প্রস্তাবিত উপায় রয়েছে। এটি মডিউলগুলি অনুসরণ করার জন্য যুক্তিযুক্ত, একটি (স্বীকৃত optionচ্ছিক) মান বর্ণনা করে। এখানে একটি স্নিপেট রয়েছে:

3) যখন কোনও মডিউল (বা প্যাকেজ) কোনও সংস্করণ নম্বর অন্তর্ভুক্ত করে, তখন সংস্করণটি __version__বৈশিষ্ট্যে পাওয়া উচিত ।

৪) একটি মডিউল যা কোনও নেমস্পেস প্যাকেজের অভ্যন্তরে থাকে তাদের জন্য মডিউলটি __version__বৈশিষ্ট্যটি অন্তর্ভুক্ত করে । নেমস্পেস প্যাকেজ নিজেই এর নিজস্ব __version__বৈশিষ্ট্য অন্তর্ভুক্ত করা উচিত নয় ।

5) __version__বৈশিষ্ট্যের মানটি একটি স্ট্রিং হওয়া উচিত।


13
পিইপি গ্রহণ / মানিকৃত নয়, তবে পিছিয়ে দেওয়া হয়েছে (আগ্রহের অভাবে)। সুতরাং এটি নির্দিষ্ট করে দেওয়া একটি বিভ্রান্তিকর যে এটির দ্বারা নির্দিষ্ট " একটি মানক উপায় আছে "।
তাঁত

@ ওয়েভার: ওহ আমার! আমি নতুন কিছু শিখেছি। আমি জানতাম না যে এটির জন্য যাচাই করা দরকার।
অডডিংকিং

4
এটি লক্ষ করার জন্য সম্পাদিত a এখন আমি বিব্রত বোধ করছি, কারণ প্রকল্পগুলিতে এই "মান" অনুসরণ করতে বলার জন্য আমি বৈশিষ্ট্য অনুরোধ উত্থাপন করেছি।
অদ্ভুত ধারণা

1
আপনার আগ্রহী বলে মনে হচ্ছে সম্ভবত: আপনার সেই পিইপি-র মানকতার কাজটি হাতে নেওয়া উচিত :)
তাঁত

এটি স্বতন্ত্র মডিউলটির সংস্করণ দেওয়ার জন্য কাজ করবে তবে আমি নিশ্চিত নই যে এটি একটি সম্পূর্ণ প্রকল্পের সংস্করণে প্রয়োগ করা হবে।
স্টিভোসিয়াক

21

যদিও এটি সম্ভবত অনেক দেরি হয়ে গেছে, পূর্বের উত্তরের জন্য কিছুটা সহজ বিকল্প রয়েছে:

__version_info__ = ('1', '2', '3')
__version__ = '.'.join(__version_info__)

(এবং সংস্করণ সংখ্যার স্বতঃবৃদ্ধিকরণ অংশগুলি ব্যবহার করে স্ট্রিংয়ে রূপান্তর করা মোটামুটি সহজ str())

অবশ্যই, আমি যা দেখেছি, লোকেদের ব্যবহার করার সময় পূর্ব-উল্লিখিত সংস্করণটির মতো কিছু ব্যবহার করার ঝোঁক থাকে __version_info__, এবং এগুলি ইনটসের টিপল হিসাবে সংরক্ষণ করে; যাইহোক, আমি এটি করার পক্ষে একেবারেই লক্ষ্য করি না, কারণ আমি সন্দেহ করি যে এমন পরিস্থিতি রয়েছে যেখানে আপনি কৌতূহল বা অটো-ইনক্রিমেন্টেশন ব্যতীত কোনও উদ্দেশ্যে সংস্করণ সংখ্যার অংশে সংযোজন এবং বিয়োগের মতো গাণিতিক ক্রিয়াকলাপ সম্পাদন করবেন (এবং তারপরেও, int()এবং str()মোটামুটি সহজেই ব্যবহার করা যেতে পারে)। (অন্যদিকে, অন্য কারও কোডের স্ট্রিং টুপলের চেয়ে সংখ্যাগত টুপল আশা করা এবং এভাবে ব্যর্থ হওয়ার সম্ভাবনা রয়েছে))

এটি অবশ্যই আমার নিজের মতামত, এবং আমি আনন্দের সাথে সংখ্যাসূচক টিপল ব্যবহার করার ক্ষেত্রে অন্যদের ইনপুটটি পছন্দ করি।


শেজী আমাকে যেমন মনে করিয়ে দিয়েছিল, সংখ্যার স্ট্রিংয়ের তুলনামূলক (লেজিকাল) সরাসরি সংখ্যার তুলনা হিসাবে একই ফল পাওয়া যায় না; শীর্ষস্থানীয় জিরোগুলির জন্য এটি সরবরাহ করা প্রয়োজন। সুতরাং শেষ __version_info__পর্যন্ত পূর্ণসংখ্যার মানগুলির একটি দ্বিগুণ হিসাবে স্টোরিং (বা এটি যাই হোক না কেন) আরও কার্যকর সংস্করণের তুলনা করার অনুমতি দেয়।


12
সুন্দর (+1), তবে আপনি স্ট্রিংয়ের পরিবর্তে সংখ্যা পছন্দ করবেন না? যেমন__version_info__ = (1,2,3)
অরিপ

3
সংস্করণ সংখ্যা 9 ছাড়িয়ে গেলে স্ট্রিংগুলির তুলনা বিপজ্জনক হয়ে উঠতে পারে, কারণ উদাহরণস্বরূপ '10' <'2'।
ডি কোয়েজি

13
আমি __version_info__ = (0, 1, 0) __version__ = '.'.join(map(str, __version_info__))
এটিও করি তবে কালিগুলিকে সম্বোধন

2
নিয়ে সমস্যা __version__ = '.'.join(__version_info__)হল যে __version_info__ = ('1', '2', 'beta')হয়ে যাবে 1.2.beta, না 1.2betaবা1.2 beta
nagisa

4
আমি মনে করি এই পদ্ধতির সাথে সমস্যাটি হ'ল __ রূপান্তর__ ঘোষণা করার কোডের লাইনগুলি কোথায় রাখবেন। যদি সেগুলি সেটআপ.পি থাকে তবে আপনার প্রোগ্রামটি তাদের প্যাকেজের মধ্যে থেকে সেগুলি আমদানি করতে পারে না। সম্ভবত এটি আপনার কোনও সমস্যা নয়, এক্ষেত্রে, জরিমানা। যদি তারা আপনার প্রোগ্রামের মধ্যে চলে যায়, তবে আপনার সেটআপ.পি সেগুলি আমদানি করতে পারে, তবে এটি হওয়া উচিত নয়, যেহেতু আপনার প্রোগ্রামের নির্ভরতা এখনও ইনস্টল না করা অবস্থায় সেটআপ.পি ইনস্টল করার সময় চালিত হয় (নির্ভরতা কী তা নির্ধারণ করতে সেটআপ.পি ব্যবহার করা হয়) ।) সুতরাং জুকোর উত্তর: পণ্য প্যাকেজটি আমদানি না করে ম্যানুয়ালি একটি পণ্য উত্স ফাইলের থেকে মূল্য বিশ্লেষণ করুন
জোনাথন হার্টলি

11

এগুলির অনেকগুলি সমাধান এখানে gitসংস্করণ ট্যাগগুলি উপেক্ষা করে যার অর্থ এখনও একাধিক জায়গায় আপনার সংস্করণ ট্র্যাক করতে হবে (খারাপ)। আমি নিম্নলিখিত লক্ষ্য নিয়ে এটি পৌঁছেছি:

  • একটি ট্যাগে থেকে সব পাইথন সংস্করণ রেফারেন্স আহরণ gitরেপো
  • স্বয়ংক্রিয় git tag/ pushএবং setup.py uploadএকক কমান্ডের সাথে পদক্ষেপ যা কোনও ইনপুট নেয় না।

কিভাবে এটা কাজ করে:

  1. একটি make releaseকমান্ড থেকে , গিট রেপোতে সর্বশেষ ট্যাগ হওয়া সংস্করণটি পাওয়া যায় এবং বর্ধিত হয়। ট্যাগটি আবার ঠেলে দেওয়া হয় origin

  2. Makefileদোকানে সংস্করণ src/_version.pyযেখানে এটি পড়তে হবে setup.pyএবং রিলিজের মধ্যে অন্তর্ভুক্ত। উত্স নিয়ন্ত্রণ পরীক্ষা _version.pyকরে দেখুন!

  3. setup.pyকমান্ড নতুন সংস্করণ স্ট্রিং থেকে পড়ে package.__version__

বিবরণ:

Makefile নামক

# remove optional 'v' and trailing hash "v1.0-N-HASH" -> "v1.0-N"
git_describe_ver = $(shell git describe --tags | sed -E -e 's/^v//' -e 's/(.*)-.*/\1/')
git_tag_ver      = $(shell git describe --abbrev=0)
next_patch_ver = $(shell python versionbump.py --patch $(call git_tag_ver))
next_minor_ver = $(shell python versionbump.py --minor $(call git_tag_ver))
next_major_ver = $(shell python versionbump.py --major $(call git_tag_ver))

.PHONY: ${MODULE}/_version.py
${MODULE}/_version.py:
    echo '__version__ = "$(call git_describe_ver)"' > $@

.PHONY: release
release: test lint mypy
    git tag -a $(call next_patch_ver)
    $(MAKE) ${MODULE}/_version.py
    python setup.py check sdist upload # (legacy "upload" method)
    # twine upload dist/*  (preferred method)
    git push origin master --tags

releaseলক্ষ্য সবসময় 3rd সংস্করণ অঙ্ক বৃদ্ধি, কিন্তু আপনি ব্যবহার করতে পারেন next_minor_verবা next_major_verঅন্যান্য ডিজিটের বাড়ায় করতে। কমান্ডগুলি versionbump.pyস্ক্রিপ্টের উপর নির্ভর করে যা রেপোর মূলটিতে পরীক্ষা করা হয়

versionbump.py

"""An auto-increment tool for version strings."""

import sys
import unittest

import click
from click.testing import CliRunner  # type: ignore

__version__ = '0.1'

MIN_DIGITS = 2
MAX_DIGITS = 3


@click.command()
@click.argument('version')
@click.option('--major', 'bump_idx', flag_value=0, help='Increment major number.')
@click.option('--minor', 'bump_idx', flag_value=1, help='Increment minor number.')
@click.option('--patch', 'bump_idx', flag_value=2, default=True, help='Increment patch number.')
def cli(version: str, bump_idx: int) -> None:
    """Bumps a MAJOR.MINOR.PATCH version string at the specified index location or 'patch' digit. An
    optional 'v' prefix is allowed and will be included in the output if found."""
    prefix = version[0] if version[0].isalpha() else ''
    digits = version.lower().lstrip('v').split('.')

    if len(digits) > MAX_DIGITS:
        click.secho('ERROR: Too many digits', fg='red', err=True)
        sys.exit(1)

    digits = (digits + ['0'] * MAX_DIGITS)[:MAX_DIGITS]  # Extend total digits to max.
    digits[bump_idx] = str(int(digits[bump_idx]) + 1)  # Increment the desired digit.

    # Zero rightmost digits after bump position.
    for i in range(bump_idx + 1, MAX_DIGITS):
        digits[i] = '0'
    digits = digits[:max(MIN_DIGITS, bump_idx + 1)]  # Trim rightmost digits.
    click.echo(prefix + '.'.join(digits), nl=False)


if __name__ == '__main__':
    cli()  # pylint: disable=no-value-for-parameter

এটি ভার্সন উত্তোলন করে যাতে কীভাবে সংস্করণ নম্বরটি প্রসেস করা যায় এবং বাড়ানো যায় git

__init__.py

my_module/_version.pyফাইলে আমদানি করা হয় my_module/__init__.py। যে কোনও স্ট্যাটিক ইনস্টল কনফিগারেশন এখানে রাখুন যা আপনি আপনার মডিউলটি দিয়ে বিতরণ করতে চান।

from ._version import __version__
__author__ = ''
__email__ = ''

setup.py

শেষ পদক্ষেপটি my_moduleমডিউল থেকে সংস্করণ তথ্য পড়া to

from setuptools import setup, find_packages

pkg_vars  = {}

with open("{MODULE}/_version.py") as fp:
    exec(fp.read(), pkg_vars)

setup(
    version=pkg_vars['__version__'],
    ...
    ...
)

অবশ্যই, এই সমস্ত কাজ করার জন্য আপনার রেপোতে কমপক্ষে একটি সংস্করণ ট্যাগ শুরু করতে হবে।

git tag -a v0.0.1

1
প্রকৃতপক্ষে - এই পুরো থ্রেডটি ভুলে যায় যে এই আলোচনায় একটি ভিসিএস অত্যন্ত গুরুত্বপূর্ণ। কেবলমাত্র একটি obs: সংস্করণ বৃদ্ধিকরণটি একটি ম্যানুয়াল প্রক্রিয়া হিসাবে থাকা উচিত, তাই পছন্দসই উপায়টি হ'ল ম্যানুয়ালি একটি ট্যাগ তৈরি করুন এবং ধাক্কা দিন V ভিসিএস সরঞ্জামগুলি সেই ট্যাগটি আবিষ্কার করুন এবং যেখানে প্রয়োজন সেখানে এটি সংরক্ষণ করুন (বাহ - এই সম্পাদনা ইন্টারফেসটি সত্যই আমাকে পঙ্গু করছে - আমাকে কেবল নতুন
লাইনের

পাইথনের জন্য versionbump.pyযখন আমাদের কাছে দুর্দান্ত একটি বাম্পভার্সন প্যাকেজ রয়েছে তখন ব্যবহার করার দরকার নেই ।
অরণ

@ ওরান আমি ভার্সনবাম্পের দিকে তাকালাম। দস্তাবেজগুলি খুব পরিষ্কার নয় এবং এটি ট্যাগিং খুব ভালভাবে পরিচালনা করে না। আমার পরীক্ষায় এটি এমন রাষ্ট্রগুলিতে চলে গেছে বলে মনে হচ্ছে যা এটি ক্রাশের কারণ হয়ে উঠেছে: সাবপ্রসেস alled কলডপ্রসেসেররার: কমান্ড '[' গিট ',' কমিট ',' -এফ ',' / ভার / ফোল্ডার / আরএল / tjyk4hns7kndnx035p26wg692g_7t8 / T / tmppishngbo '] 'শূন্য-বহির্গমন প্রস্থান ফিরিয়ে আনা হয়েছে। ১।
সেমিচিন্টি

1
_version.pyসংস্করণ নিয়ন্ত্রণের সাথে কেন ট্র্যাক করা উচিত নয় ?
স্টিভয়েসিয়াক

1
পুনঃটুইট করুন এখন আপনাকে নিশ্চিত করতে হবে যে আপনি ট্যাগ এবং প্রতিশ্রুতি _version.py এ মানটির সাথে মেলে। একক সংস্করণ ট্যাগ ব্যবহার করা ক্লিনার আইএমও এবং এর অর্থ আপনি গিথুব ইউআই থেকে সরাসরি মুক্তি পেতে পারেন।
সেএমসিগিন্টি

10

আমি প্যাকেজ dir একটি JSON ফাইল ব্যবহার। এটি জুকোর প্রয়োজনীয়তা ফিট করে।

ভিতরে pkg_dir/pkg_info.json:

{"version": "0.1.0"}

ভিতরে setup.py:

from distutils.core import setup
import json

with open('pkg_dir/pkg_info.json') as fp:
    _info = json.load(fp)

setup(
    version=_info['version'],
    ...
    )

ভিতরে pkg_dir/__init__.py:

import json
from os.path import dirname

with open(dirname(__file__) + '/pkg_info.json') as fp:
    _info = json.load(fp)

__version__ = _info['version']

আমি pkg_info.jsonলেখকের মতো অন্যান্য তথ্যও রেখেছি । আমি জেএসএন ব্যবহার করতে পছন্দ করি কারণ আমি মেটাডেটা পরিচালনা স্বয়ংক্রিয় করতে পারি।


আপনি কীভাবে মেটাডেটা পরিচালনার স্বয়ংক্রিয়করণের জন্য জসন ব্যবহার করবেন তা বিশদভাবে বলতে পারেন? ধন্যবাদ!
রায়ঞ্জিলন

6

পাশাপাশি লক্ষণীয় যে __version__সেমিটি-স্ট্যান্ড হওয়ার পাশাপাশি । অজগর তেমন __version_info__যে একটি টিপল, সাধারণ ক্ষেত্রে আপনি যেমন কিছু করতে পারেন:

__version__ = '1.2.3'
__version_info__ = tuple([ int(num) for num in __version__.split('.')])

... এবং আপনি __version__কোনও ফাইল থেকে স্ট্রিং বা যা কিছু পেতে পারেন ।


1
এই ব্যবহারের উত্স সম্পর্কে আপনার কোনও রেফারেন্স / লিঙ্ক আছে __version_info__?
ক্রেগ ম্যাককুইন

3
ঠিক আছে এটি sys.version_info তে sys.version হিসাবে একই ম্যাপিং। সুতরাং: docs.python.org/library/sys.html#sys.version_info
জেমস

7
অন্যদিকে ( __version_info__ = (1, 2, 3)এবং __version__ = '.'.join(map(str, __version_info__))) ম্যাপিং করা আরও সহজ is
এরিক হে লেবিগোট

2
@ ইওএল - __version__ = '.'.join(str(i) for i in __version_info__)- কিছুটা লম্বা তবে বেশি পাইথোনিক।
আর্টঅফ ওয়ারফেয়ার

2
আমি নিশ্চিত নই যে আপনি যা প্রস্তাব করেছেন তাতে স্পষ্টতই বেশি পাইথোনিক, কারণ এতে একটি ডামি ভেরিয়েবল রয়েছে যা সত্যই প্রয়োজন হয় না এবং যার অর্থ প্রকাশ করা কিছুটা কঠিন ( iযার কোনও অর্থ নেই, version_numএটি একটি দীর্ঘ দীর্ঘ এবং অস্পষ্ট ...)। আমি map()পাইথনের অস্তিত্বকে শক্তিশালী ইঙ্গিত হিসাবে গ্রহণ করি যে এটি এখানে ব্যবহার করা উচিত, কারণ আমাদের এখানে যা করতে হবে তা হল সাধারণ ব্যবহারের ক্ষেত্রে map()(বিদ্যমান ফাংশনটির সাথে ব্যবহার করা) - আমি অন্যান্য অনেক যুক্তিসঙ্গত ব্যবহার দেখতে পাচ্ছি না।
এরিক হে লেবিগোট

5

পাইথন প্যাকেজে কোনও সংস্করণ স্ট্রিং এম্বেড করার মানক উপায় বলে মনে হচ্ছে না। আমি দেখেছি বেশিরভাগ প্যাকেজগুলি আপনার সমাধানের কিছু বৈকল্পিক, অর্থাৎ আইটনার ব্যবহার করে

  1. সংস্করণটি এম্বেড করুন setup.pyএবং setup.pyএকটি মডিউল তৈরি করুন (উদাহরণস্বরূপ version.py) কেবলমাত্র সংস্করণ তথ্য রয়েছে, যা আপনার প্যাকেজ দ্বারা আমদানি করা হয়েছে, বা

  2. বিপরীত: আপনার প্যাকেজ নিজেই সংস্করণ তথ্য, এবং আমদানি করা যে সংস্করণটি সেট করতে setup.py


আমি আপনার পুনঃসংশোধন পছন্দ করি তবে সেটআপ.পি থেকে এই মডিউলটি কীভাবে তৈরি করা যায়?
sorin

1
আমি বিকল্পের ধারণাটি পছন্দ করি (1), এটি কোনও ফাইল থেকে সংস্করণ নম্বরটি পার্স করার জুকোর উত্তরের চেয়ে সহজ বলে মনে হচ্ছে। কিন্তু কোনও ডিভো কেবল আপনার রেপো ক্লোন করে নিলে আপনি সংস্করণ.পি তৈরির বিষয়টি নিশ্চিত করতে পারবেন না। আপনি version.py এ যাচাই না করলে, যা ছোট্ট কুঁচকিতে খোলে যে আপনি সেটআপ.পি-র সংস্করণ নম্বরটি পরিবর্তন করতে পারেন, প্রতিশ্রুতিবদ্ধ হতে পারেন, ছেড়ে দিতে পারেন এবং তারপরে সংস্করণ.পি-তে পরিবর্তন করতে হবে (স্ল্যাশ ভুলে যেতে হবে) commit
জোনাথন হার্টলি

সম্ভবত আপনি ওপেন ("মাইপ্যাকেজ / সংস্করণ.পি", "ডাব্লু") "" এর মতো কিছুকে fp: fp.write ("__ সংস্করণ__ == '% s' \ n"% (__version__,) ব্যবহার করে মডিউলটি তৈরি করতে পারেন uma ) "" "
জোনাথন হার্টলি

1
আমি মনে করি বিকল্পটি ২. জাবের উত্তরের মন্তব্যে উল্লিখিত হিসাবে ইনস্টল করার সময় ব্যর্থ হওয়ার পক্ষে সংবেদনশীল।
জোনাথন হার্টলি

ওটা সম্পর্কে কি? আপনি আপনার সফ্টওয়্যারটির প্রধান প্যাকেজের __init__.py "এ __version__ = '0.0.1'" (যেখানে সংস্করণটি অবশ্যই একটি স্ট্রিং) রয়েছে put তারপরে পয়েন্ট ২- এর জন্য যান: আপনি প্যাকেজ থেকে সেটআপটিতে .__ init__ __ রূপান্তর__ কে ভি হিসাবে আমদানি করুন এবং তারপরে আপনি ভেরিয়েবল ভিটি আপনার সেটআপ.পির সংস্করণ হিসাবে সেট করেন। তারপরে আমার হিসাবে মাইপ্যাকটি আমদানি করুন, আমার .__ সংস্করণটি মুদ্রণ করুন the সংস্করণটি মুদ্রণ করবে। সংস্করণটি কেবলমাত্র এক জায়গায় সংরক্ষণ করা হবে, সম্পূর্ণ কোড থেকে অ্যাক্সেসযোগ্য এমন কোনও ফাইলে যা সফ্টওয়্যার সম্পর্কিত অন্য কোনও জিনিস আমদানি করে না।
সেফ

5

তীর এটি একটি আকর্ষণীয় উপায়ে পরিচালনা করে।

এখন ( 2e5031 বি থেকে )

ইন arrow/__init__.py:

__version__ = 'x.y.z'

ইন setup.py:

from arrow import __version__

setup(
    name='arrow',
    version=__version__,
    # [...]
)

আগে

ইন arrow/__init__.py:

__version__ = 'x.y.z'
VERSION = __version__

ইন setup.py:

def grep(attrname):
    pattern = r"{0}\W*=\W*'([^']+)'".format(attrname)
    strval, = re.findall(pattern, file_text)
    return strval

file_text = read(fpath('arrow/__init__.py'))

setup(
    name='arrow',
    version=grep('__version__'),
    # [...]
)

কি file_text?
এলে

2
আপডেট করা সমাধানটি আসলে ক্ষতিকারক। যখন সেটআপ.পি চলছে, এটি প্রয়োজনীয়ভাবে স্থানীয় ফাইল পাথ থেকে প্যাকেজের সংস্করণটি দেখতে পাবে না। এটি পূর্বে ইনস্টল করা সংস্করণে ফিরে যেতে পারে, যেমন pip install -e .কোনও উন্নয়ন শাখায় চালানো বা পরীক্ষা করার সময় কোনও কিছু। সেটআপ.পি একেবারে প্যাকেজটি আমদানির উপর নির্ভর করবে না এটি স্থাপনার পরামিতিগুলি নির্ধারণের জন্য এটি ইনস্টল করার প্রক্রিয়াধীন রয়েছে। বাবা।
এলী

হ্যাঁ আমি জানি না কেন তীর এই সমাধানটিতে পুনরায় প্রতিক্রিয়া দেখানোর সিদ্ধান্ত নিয়েছে। তাছাড়া "সঙ্গে আপডেট করা হয়েছে setup.py বার্তা বলছেন কমিট আধুনিক পাইথন মান " ... 🤷
Anto

4

আমি আরও একটি স্টাইল দেখেছি:

>>> django.VERSION
(1, 1, 0, 'final', 0)

1
হ্যাঁ, আমিও দেখেছি। বিটিডাব্লু প্রতিটি উত্তর অন্য স্টাইল গ্রহণ করে তাই এখন আমি জানি না কোন স্টাইলটি "মান"। উল্লিখিত
পিইপিগুলি

আর একটি উপায় দেখা; মোঙ্গোর পাইথন ক্লায়েন্ট আন্ডারস্কোর ছাড়াই সরল সংস্করণ ব্যবহার করে। সুতরাং এটি কাজ করে; $ পাইথন >>> পাইমোঙ্গো আমদানি করুন >>> পাইমঙ্গো.ভর্মন '2.7'
অ্যানি দ্য অ্যাজিল

বাস্তবায়নের .VERSIONঅর্থ এই নয় যে আপনাকে বাস্তবায়ন করতে হবে না __version__
একিউম্যানাস

এই djangoপ্রকল্পে বাস্তবায়ন প্রয়োজন ?
স্টিভয়েসিয়াক

3

ব্যবহার setuptoolsএবংpbr

সংস্করণ পরিচালনা করার জন্য কোনও মানক উপায় নেই, তবে আপনার প্যাকেজগুলি পরিচালনা করার মানক উপায় setuptools

সংস্করণ পরিচালনার জন্য আমি সামগ্রিকভাবে খুঁজে পেয়েছি সেরা সমাধানটি হ'ল এক্সটেনশনটি ব্যবহার setuptoolsকরা pbr। সংস্করণ পরিচালনার এটি এখন আমার স্ট্যান্ডার্ড পদ্ধতি।

সম্পূর্ণ প্যাকেজিংয়ের জন্য আপনার প্রকল্প সেট আপ করা সহজ প্রকল্পগুলির জন্য ওভারকিল হতে পারে, তবে যদি আপনাকে সংস্করণ পরিচালনা করতে হয় তবে আপনি সম্ভবত সবকিছু ঠিক করার জন্য সঠিক স্তরে রয়েছেন। এটি করা আপনার প্যাকেজটি পাইপিতে পুনরায় প্রেরণীয় করে তোলে যাতে প্রত্যেকে এটি পিপ দিয়ে ডাউনলোড করে ব্যবহার করতে পারে।

পিবিআর বেশিরভাগ মেটাডেটা setup.pyসরঞ্জামগুলির বাইরে এবং একটি setup.cfgফাইলের মধ্যে সরিয়ে দেয় যা পরে বেশিরভাগ মেটাডেটার উত্স হিসাবে ব্যবহৃত হয়, যা সংস্করণ অন্তর্ভুক্ত করতে পারে। এটি মেটাডাটা pyinstallerপ্রয়োজনের মতো কিছু ব্যবহার করে এক্সিকিউটেবলের মধ্যে প্যাকেজ করার অনুমতি দেয় (যদি তা হয় তবে আপনার সম্ভবত এই তথ্য প্রয়োজন হবে ), এবং অন্যান্য প্যাকেজ পরিচালনা / সেটআপ স্ক্রিপ্টগুলি থেকে মেটাডেটা পৃথক করে। আপনি setup.cfgম্যানুয়ালি সংস্করণ স্ট্রিংটি সরাসরি আপডেট করতে পারেন এবং *.egg-infoআপনার প্যাকেজ রিলিজগুলি তৈরি করার সময় এটি ফোল্ডারে টানা হবে । আপনার স্ক্রিপ্টগুলি তারপরে বিভিন্ন পদ্ধতি ব্যবহার করে মেটাডেটা থেকে সংস্করণটি অ্যাক্সেস করতে পারে (এই প্রক্রিয়াগুলি নীচের বিভাগগুলিতে বর্ণিত)।

ভিসিএস / এসসিএমের জন্য গিট ব্যবহার করার সময়, এই সেটআপটি আরও ভাল, কারণ এটি গিট থেকে প্রচুর মেটাডেটা টানবে যাতে আপনার রেপো সংস্করণ, লেখক, চেঞ্জলগস সহ কয়েকটি মেটাডেটার জন্য আপনার সত্যের উত্স হতে পারে, ইত্যাদি সংস্করণের জন্য বিশেষভাবে, এটি রেপোতে গিট ট্যাগের উপর ভিত্তি করে বর্তমান কমিটের জন্য একটি সংস্করণ স্ট্রিং তৈরি করবে।

যেহেতু পিবিআর সরাসরি আপনার গিট রেপো থেকে সংস্করণ, লেখক, চেঞ্জলগ এবং অন্যান্য তথ্য টানবে, সুতরাং এতে থাকা কিছু মেটাডেটা setup.cfgবাদ দেওয়া যাবে এবং যখনই আপনার প্যাকেজের জন্য বিতরণ তৈরি হবে (ব্যবহার setup.py)

রিয়েল-টাইম বর্তমান সংস্করণ

setuptoolsব্যবহার করে রিয়েল-টাইমে সর্বশেষতম তথ্যটি টানবে setup.py:

python setup.py --version

এটি সর্বশেষতম সংস্করণটি setup.cfgফাইল বা গিট রেপো থেকে নেওয়া হবে, যা সর্বশেষ প্রতিশ্রুতি তৈরি হয়েছিল এবং রেপোতে বিদ্যমান ট্যাগগুলির উপর ভিত্তি করে তৈরি করবে। যদিও এই আদেশটি কোনও বিতরণে সংস্করণটি আপডেট করে না।

সংস্করণ আপডেট করা হচ্ছে

যখন আপনি setup.py(যেমন py setup.py sdist, উদাহরণস্বরূপ) দিয়ে একটি বিতরণ তৈরি করবেন, তখন সমস্ত বর্তমান তথ্য বিতরণে উত্তোলন করা হবে এবং সংরক্ষণ করা হবে। এটি মূলত setup.py --versionকমান্ডটি চালায় এবং তারপরে সেই সংস্করণ তথ্য package.egg-infoফোল্ডারে ফাইলে সংরক্ষণ করে যা বিতরণ মেটাডেটা সঞ্চয় করে।

সংস্করণ মেটা-ডেটা আপডেট করার প্রক্রিয়াতে নোট:

যদি আপনি গিট থেকে সংস্করণ ডেটা টানতে পিবিআর ব্যবহার না করে থাকেন তবে কেবল নতুন নতুন সংস্করণ তথ্যের সাথে আপনার সেটআপ সিএফজি সরাসরি আপডেট করুন (যথেষ্ট সহজ, তবে নিশ্চিত হন যে এটি আপনার প্রকাশের প্রক্রিয়ার একটি আদর্শ অংশ)।

আপনি যদি গিট ব্যবহার করছেন এবং আপনার মেটাডেটা ফোল্ডারে গিট রেপো তথ্য আপডেট করার সহজ উপায় বা বাইনারি বিতরণ ( python setup.py sdistকোনও python setup.py bdist_xxxকমান্ডের ব্যবহার বা একটি ) তৈরি করার দরকার নেই <mypackage>.egg-infoহ'ল python setup.py installকমান্ডটি চালানো । এটি গিট রেপো থেকে মেটাডেটা টানানোর সাথে সম্পর্কিত সমস্ত পিবিআর ফাংশন পরিচালনা করবে এবং আপনার স্থানীয় .egg-infoফোল্ডারটি আপডেট করবে, আপনার নির্ধারিত যে কোনও এন্ট্রি-পয়েন্টগুলির জন্য স্ক্রিপ্ট এক্সিকিউটেবলগুলি ইনস্টল করবে এবং আপনি যখন এই আদেশটি চালাবেন তখন আউটপুট থেকে আপনি দেখতে পাবেন functions

নোট করুন যে .egg-infoফোল্ডারটি সাধারণত পাইথন .gitignoreফাইলগুলিতে (যেমন Gitignore.IO থেকে ) গিট রেপোতে নিজেকে সংরক্ষণ করা থেকে বাদ দেওয়া হয় কারণ এটি আপনার উত্স থেকে উত্পন্ন হতে পারে। যদি এটি বাদ দেওয়া হয় তবে নিশ্চিত হয়ে নিন যে রিলিজের আগে স্থানীয়ভাবে মেটাডেটা আপডেট করার জন্য আপনার কাছে একটি স্ট্যান্ডার্ড "রিলিজ প্রক্রিয়া" রয়েছে এবং আপনি পাইপআই.আর.ও আপলোড করেন বা অন্যথায় বিতরণ করেন এমন কোনও প্যাকেজের সঠিক সংস্করণ থাকতে এই ডেটা অবশ্যই অন্তর্ভুক্ত করা উচিত। আপনি যদি গিট রেপো এই তথ্যটি ধারণ করতে চান তবে নির্দিষ্ট ফাইলগুলিকে উপেক্ষা করা থেকে বাদ দিতে পারেন (অর্থাত্ যোগ !*.egg-info/PKG_INFOকরুন .gitignore)

স্ক্রিপ্ট থেকে সংস্করণ অ্যাক্সেস করা

আপনি প্যাকেজটিতে পাইথন স্ক্রিপ্টগুলির মধ্যে বর্তমান বিল্ড থেকে মেটাডেটা অ্যাক্সেস করতে পারেন। সংস্করণ হিসাবে, উদাহরণস্বরূপ, আমি এখন অবধি খুঁজে পেতে এটি করার বিভিন্ন উপায় রয়েছে:

## This one is a new built-in as of Python 3.8.0 should become the standard
from importlib-metadata import version

v0 = version("mypackage")
print('v0 {}'.format(v0))

## I don't like this one because the version method is hidden
import pkg_resources  # part of setuptools

v1 = pkg_resources.require("mypackage")[0].version
print('v1 {}'.format(v1))

# Probably best for pre v3.8.0 - the output without .version is just a longer string with
# both the package name, a space, and the version string
import pkg_resources  # part of setuptools

v2 = pkg_resources.get_distribution('mypackage').version
print('v2 {}'.format(v2))

## This one seems to be slower, and with pyinstaller makes the exe a lot bigger
from pbr.version import VersionInfo

v3 = VersionInfo('mypackage').release_string()
print('v3 {}'.format(v3))

__init__.pyঅন্যান্য কয়েকটি উত্তরের মতো ভার্সন তথ্যটি নীচে নীচে বের করার জন্য আপনি প্যাকেজে সরাসরি এগুলির একটি রাখতে পারেন :

__all__ = (
    '__version__',
    'my_package_name'
)

import pkg_resources  # part of setuptools

__version__ = pkg_resources.get_distribution("mypackage").version

সরাসরি প্রশ্নের উত্তর এখনই ডাউন ডাউন ভোটে পুনরায় ফর্ম্যাট করা।
লাইটসিসি

1

বেশ কয়েকটি ঘন্টা সহজ নির্ভরযোগ্য সমাধান অনুসন্ধান করার চেষ্টা করার পরে, এখানে অংশগুলি:

একটি সংস্করণ.পি ফাইল তৈরি করুন আপনার প্যাকেজ "/ মাইপ্যাকেজ" এর ফোল্ডারটি ভিতরে দিন:

# Store the version here so:
# 1) we don't load dependencies by storing it in __init__.py
# 2) we can import it in setup.py for the same reason
# 3) we can import it into your module module
__version__ = '1.2.7'

সেটআপ.পিতে:

exec(open('mypackage/version.py').read())
setup(
    name='mypackage',
    version=__version__,

মূল ফোল্ডারে init .py:

from .version import __version__

exec()যেহেতু setup.py মডিউল আমদানি করা যায় সামনে চালানো হয় ফাংশন, কোনো আমদানির স্ক্রিপ্ট বাহিরে চলে। আপনার এখনও কেবল এক জায়গায় এক ফাইলের সংস্করণ নম্বরটি পরিচালনা করতে হবে, তবে দুর্ভাগ্যক্রমে এটি সেটআপ.পিতে নেই। (এটাই নেতিবাচক, তবে কোনও আমদানি বাগ না হওয়াই উল্টোটি)


1

এই প্রশ্নটি প্রথম জিজ্ঞাসা করা হওয়ার পরে অভিন্ন সংস্করণকরণ এবং সম্মেলনের সমর্থনে প্রচুর কাজ শেষ হয়েছে । রুচিকর অপশন এখন বিস্তারিত মধ্যে পাইথন প্যাকেজিং ইউজার গাইড । এছাড়াও উল্লেখযোগ্য যে সংস্করণ সংখ্যা স্কিম পাইথন অপেক্ষাকৃত কঠোর PEP 440 প্রতি , এবং তাই কিছু বিবেকী পালন সমালোচনামূলক হলে আপনার প্যাকেজ কাছে প্রকাশ করা হবে পনির দোকান

সংস্করণ বিকল্পগুলির একটি সংক্ষিপ্ত ভাঙ্গন এখানে:

  1. setup.py( সেটআপলগুলিতে ) ফাইলটি পড়ুন এবং সংস্করণটি পান।
  2. একটি বাহ্যিক বিল্ড সরঞ্জাম ব্যবহার করুন ( __init__.pyউত্স নিয়ন্ত্রণের পাশাপাশি উভয় আপডেট করার জন্য ), যেমন- bump2version , পরিবর্তন বা zest.releaser
  3. __version__একটি নির্দিষ্ট মডিউলে বিশ্বব্যাপী ভেরিয়েবলের মান সেট করুন ।
  4. সেটআপ.পি এবং কোড পড়ার জন্য উভয়ের জন্য একটি সাধারণ ভার্সন পাঠ্য ফাইলে মান রাখুন।
  5. একটি setup.pyরিলিজের মাধ্যমে মানটি সেট করুন এবং রানটাইমের সময় তা বেছে নেওয়ার জন্য Importlib.metadata ব্যবহার করুন । (সতর্কতা, প্রাক-3.8 এবং পরবর্তী-3.8 সংস্করণ রয়েছে))
  6. __version__ইন মান সেট করুন এবং মধ্যে sample/__init__.pyনমুনা আমদানি করুন setup.py
  7. উত্স নিয়ন্ত্রণ থেকে সংস্করণ নিষ্কাশন করতে setuptools_scm ব্যবহার করুন যাতে কোডটি নয়, এটি ক্যানোনিকাল রেফারেন্স।

দ্রষ্টব্য যে (7) সর্বাধিক আধুনিক পদ্ধতির হতে পারে (বিল্ড মেটাটাটা কোডের থেকে স্বাধীন, অটোমেশন দ্বারা প্রকাশিত)। এছাড়াও লক্ষ করুন যে প্যাকেজ রিলিজের জন্য যদি সেটআপ ব্যবহার করা হয় তবে একটি সাধারণ সরল python3 setup.py --versionসংস্করণটি সরাসরি রিপোর্ট করবে।


-1

এটি মূল্যবান কিসের জন্য, আপনি যদি NumPy distutils ব্যবহার করেন তবে numpy.distutils.misc_util.Configurationএকটি make_svn_version_py()পদ্ধতি রয়েছে যা package.__svn_version__ভেরিয়েবলের ভিতরে পুনর্বিবেচনার সংখ্যাটি এম্বেড করে version


আপনি আরও বিশদ বা এটি কীভাবে কাজ করবে তার উদাহরণ সরবরাহ করতে পারেন?
স্টিভয়েসিয়াক

হুম। 2020 সালে, এটি (এটি সর্বদা ছিল?) ফরটারনের জন্য বোঝানো হয়েছিল । প্যাকেজ "numpy.distutils ফোর্টরান উত্সগুলি মোকাবেলা করার জন্য স্ট্যান্ডার্ড পাইথন ডিস্টুয়েলগুলি প্রসারিত NumPy এর অংশ" "
ingyhere

-1
  1. version.pyকেবলমাত্র ফাইলটিতে __version__ = <VERSION>প্যারাম সহ একটি ফাইল ব্যবহার করুন। setup.pyফাইলটিতে পরম আমদানি করুন এবং ফাইলটিতে __version__এর মূল্য রাখুন setup.py: version=__version__
  2. আরেকটি উপায় হ'ল কেবল একটি setup.pyফাইল ব্যবহার করা version=<CURRENT_VERSION>- CURRENT_VERSION হার্ডকোডযুক্ত।

যেহেতু আমরা যখনই নতুন ট্যাগ তৈরি করি তখনই ফাইলটিতে ম্যানুয়ালি সংস্করণটি পরিবর্তন করতে চাই না (একটি নতুন প্যাকেজ সংস্করণ প্রকাশের জন্য প্রস্তুত), আমরা নিম্নলিখিতটি ব্যবহার করতে পারি ..

আমি অত্যধিক bumpversion প্যাকেজ সুপারিশ । আমি বছরের পর বছর ধরে এটি ব্যবহার করে আসছি একটি সংস্করণ ump

version=<VERSION>আপনার setup.pyফাইলটি এটি ইতিমধ্যে না থাকলে যুক্ত করে শুরু করুন ।

প্রতিবার কোনও সংস্করণটি ঘোরানোর সময় আপনার মতো একটি শর্ট স্ক্রিপ্ট ব্যবহার করা উচিত:

bumpversion (patch|minor|major) - choose only one option
git push
git push --tags

তারপরে রেপো প্রতি একটি ফাইল যুক্ত করুন .bumpversion.cfg:

[bumpversion]
current_version = <CURRENT_TAG>
commit = True
tag = True
tag_name = {new_version}
[bumpversion:file:<RELATIVE_PATH_TO_SETUP_FILE>]

বিঃদ্রঃ:

  • আপনি অন্যান্য পদের মধ্যে যেমন প্রস্তাব দেওয়া হয়েছিল তেমন ফাইলের __version__অধীনে প্যারামিটার ব্যবহার করতে পারেন version.pyএবং এই জাতীয় ফোঁড়া ফাইলটি আপডেট করুন: [bumpversion:file:<RELATIVE_PATH_TO_VERSION_FILE>]
  • আপনার অবশ্যই git commit বা git resetআপনার রেপোতে থাকা সমস্ত কিছু, অন্যথায় আপনি একটি নোংরা রেপো ত্রুটি পাবেন।
  • আপনার ভার্চুয়াল পরিবেশে বাম্পভার্সনের প্যাকেজ অন্তর্ভুক্ত রয়েছে তা নিশ্চিত করুন এটি ছাড়া এটি কাজ করবে না।

@ সিএমসিগিন্টি বিলম্বের জন্য দুঃখিত, দয়া করে আমার উত্তরটি দেখুন ^^^ - মনে রাখবেন যে আপনাকে অবশ্যই রেপো বা গিটকে পুনরায় সেট করতে হবে এবং আপনার ভার্চুয়াল পরিবেশের প্যাকেজটি এতে অন্তর্ভুক্ত রয়েছে bumpversion, এটি কার্যকর হবে না তা নিশ্চিত করে নিন । সর্বশেষতম সংস্করণ ব্যবহার করুন।
ওরান

এখানে কী কী সমাধানের পরামর্শ দেওয়া হচ্ছে সে সম্পর্কে আমি কিছুটা অস্পষ্ট। আপনি কি ম্যানুয়ালি সংস্করণটি ট্র্যাক করার পরামর্শ দিচ্ছেন version.py, বা এটি দিয়ে ট্র্যাক করার পরামর্শ দিচ্ছেন bumpversion?
স্টিভয়েসিয়াক

পছন্দ করুন আমি যা বোঝানোর চেষ্টা করেছি তা হ'ল আপনি সেটআপ.পাই ফাইলের সংস্করণটি আপডেট করার জন্য বাম্পভারশনকে নির্দেশ করতে পারেন বা সংস্করণ.পি ফাইল আপডেট করার জন্য এটি আরও ভালভাবে ব্যবহার করতে পারেন। ভার্সন.পি ফাইল আপডেট __version__করা এবং সেটআপ.পি ফাইলটিতে পরম মানটি নেওয়া আরও সাধারণ অনুশীলন । আমার সমাধান উত্পাদনে ব্যবহৃত হয় এবং এটি একটি সাধারণ অনুশীলন। দ্রষ্টব্য: কেবল পরিষ্কার করার জন্য, স্ক্রিপ্টের অংশ হিসাবে বাম্পভার্সন ব্যবহার করা সবচেয়ে ভাল সমাধান, এটি আপনার সিআইতে রাখুন এবং এটি স্বয়ংক্রিয়ভাবে পরিচালিত হবে।
ওরান

-3

আপনি যদি সিভিএস (বা আরসিএস) ব্যবহার করেন এবং দ্রুত সমাধান চান, আপনি ব্যবহার করতে পারেন:

__version__ = "$Revision: 1.1 $"[11:-2]
__version_info__ = tuple([int(s) for s in __version__.split(".")])

(অবশ্যই, সংশোধন নম্বর সিভিএস দ্বারা আপনার জন্য প্রতিস্থাপিত করা হবে।)

এটি আপনাকে একটি মুদ্রণ-বান্ধব সংস্করণ এবং একটি সংস্করণ তথ্য দেয় যা আপনি আমদানি করছেন যে মডিউলটি অন্তত প্রত্যাশিত সংস্করণ রয়েছে তা যাচাই করতে আপনি ব্যবহার করতে পারেন:

import my_module
assert my_module.__version_info__ >= (1, 1)

আপনি কোন ফাইলটিতে সংরক্ষণের পরামর্শ __version__দিচ্ছেন? এই সমাধানের সাথে কীভাবে একজন সংস্করণ নম্বর বাড়িয়ে তুলবে?
স্টিভয়েসিয়াক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.