[英]In python, how can you compare two CalVer strings to determine if one is greater than, lesser than, or equal to, the other?
我偶爾需要根據各種依賴的版本調整我的 python 腳本。 在我的情況下,最常見的情況是,python 代碼庫與可能運行多年版本的前端 javascript 一起工作。 如果 javascript 依賴項的版本大於 A,則 python 應該執行 B。如果依賴項的版本小於 X,則 python 應該執行 Y,等等。
這些依賴項是日歷版本的 (CalVer)。 雖然我找到了許多用於維護項目自己的 CalVer 的工具,但我無法找到現成的解決方案來以這種方式評估 CalVers。
if "YY.MM.DD" > "YY.MM.DD.MICRO":
# Do this thing
else:
# Do that thing
比較日期很容易,但是當MICRO
版本混合在一起時,事情變得更加復雜。
我最終編寫了自己的解決方案,以允許我比較 CalVer 字符串,如下所示。
subject = "2021.01.31"
test = "2021.01.30.dev1"
if calver_evaluate(operator="gte", subject=subject, test=test):
# if "2021.01.31" >= "2021.01.30.dev1"
result = True
subject = "2021.01.31.0012"
test = "2021.01.31.1012"
if calver_evaluate(operator="gte", subject=subject, test=test):
# if "2021.01.31.0012" >= "2021.01.30.1012"
result = False
有關操作的完整詳細信息包含在函數的文檔字符串中。 請注意一些關於評估無法轉換為整數的微的有限規則。
import datetime
def calver_evaluate(operator=None, subject=None, test=None):
"""Evaluates two calver strings based on the operator.
Params
------
operator : str
Defines how to evaluate the subject and test params. Acceptable values are:
- "gt" or ">" for greater than
- "gte" or ">=" for greater than or equal to
- "e", "eq", "equal", "=", or "==" for equal to
- "lt" or "<" for less than
- "lte" or "<=" for less than or equal to
subject : str
A calver string formatted as YYYY.0M.0D.MICRO (recommended) or YY.MM.DD.MICRO.
https://calver.org/calendar_versioning.html
test : str
A calver string to evaluate against the subject, formatted as YYYY.0M.0D.MICRO
(recommended) or YY.MM.DD.MICRO.
https://calver.org/calendar_versioning.html
Returns
-------
bool
The results of the `subject`:`test` evaluation using the `operator`.
Notes
-----
The MICRO segment of the calver strings are only considered in the following
scenarios.
1. One calver has a MICRO value and the other does not. The calver without a
MICRO value is evaluated as `0`, making the calver *with* the MICRO, no matter
what the value, as the greater of the two.
`2021.01.01 == 2021.01.01.0`, therefore `2021.01.01.2 > 2021.01.01` and
`2021.01.01.dev1 > 2021.01.01`
2. Both calvers have MICRO values that are numeric and able to be converted to
integers.
3. Both calvers have string MICRO values **and** the operator selected is
"equals".
"""
if not operator or not subject or not test:
raise Exception("calver_evaluate: Missing keyword argument.")
allowed = ["lt","<","lte","<=","e","eq","equal","=","==","gte",">=","gt",">"]
if operator not in allowed:
raise Exception("calver_evaluate: Unrecognized evaluation operator.")
sparts = subject.split(".")
syear = int(sparts[0]) if int(sparts[0]) > 100 else int(sparts[0]) + 2000
smonth = int(sparts[1])
sday = int(sparts[2])
sdate = datetime.date(syear, smonth, sday)
smicro = sparts[3] if len(sparts) > 3 else 0
tparts = test.split(".")
tyear = int(tparts[0]) if int(tparts[0]) > 100 else int(tparts[0]) + 2000
tmonth = int(tparts[1])
tday = int(tparts[2])
tdate = datetime.date(tyear, tmonth, tday)
tmicro = tparts[3] if len(tparts) > 3 else 0
if unicode(smicro).isnumeric() and unicode(tmicro).isnumeric():
smicro = int(smicro)
tmicro = int(tmicro)
elif smicro == 0:
tmicro = 1
elif tmicro == 0:
smicro = 1
lt = ["lt","<"]
lte = ["lte","<="]
equal = ["e","eq","equal","=","=="]
gte = ["gte",">="]
gt = ["gt",">"]
check_micro = (
(
isinstance(smicro, int) and isinstance(tmicro, int) and
(smicro > 0 or tmicro > 0)
) or
(
operator in equal and
not isinstance(smicro, int) and
not isinstance(tmicro, int)
)
)
def evaluate_micro(operator, smicro, tmicro):
if operator in lt:
if smicro < tmicro:
return True
elif operator in lte:
if smicro <= tmicro:
return True
elif operator in equal:
if smicro == tmicro:
return True
elif operator in gte:
if smicro >= tmicro:
return True
elif operator in gt:
if smicro > tmicro:
return True
return False
if operator in lt and sdate <= tdate:
if sdate < tdate:
return True
elif sdate == tdate and check_micro:
return evaluate_micro(operator, smicro, tmicro)
elif operator in lte and sdate <= tdate:
if sdate == tdate and check_micro:
return evaluate_micro(operator, smicro, tmicro)
return True
elif operator in equal:
if sdate == tdate:
if check_micro:
return evaluate_micro(operator, smicro, tmicro)
return True
elif operator in gte and sdate >= tdate:
if sdate == tdate and check_micro:
return evaluate_micro(operator, smicro, tmicro)
return True
elif operator in gt and sdate >= tdate:
if sdate > tdate:
return True
elif sdate == tdate and check_micro:
return evaluate_micro(operator, smicro, tmicro)
return False
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.