fix: fixes age function where comparing a timezone-aware and a naive datetime object could cause an exception.
This commit is contained in:
parent
01dca174d2
commit
9fe0905092
4 changed files with 49 additions and 4 deletions
|
|
@ -31,6 +31,7 @@ Fixes
|
|||
^^^^^
|
||||
|
||||
- ssh: Fixed an issue where the app.service_api.token field could be left empty in the configuration. The application will now automatically populate this field if it is missing.
|
||||
- timezone: Fixed an issue in the age function where comparing a timezone-aware and a naive datetime object could cause an exception.
|
||||
|
||||
Upgrade notes
|
||||
^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -330,11 +330,24 @@ def age(prevdate, now=None, show_short_version=False, show_suffix=True, short_fo
|
|||
def get_year(prevdate):
|
||||
return prevdate.year
|
||||
|
||||
def _normalize_datetime_pair(prevdate, now):
|
||||
"""
|
||||
Ensure both datetime objects are the same kind (either both naive or both timezone-aware).
|
||||
If not, comparing them will raise a TypeError due to mismatched timezone awareness.
|
||||
"""
|
||||
if prevdate.tzinfo or now.tzinfo:
|
||||
utc = datetime.timezone.utc
|
||||
return prevdate.replace(tzinfo=utc), now.replace(tzinfo=utc)
|
||||
|
||||
return prevdate, now # no timezone
|
||||
|
||||
now = now or datetime.datetime.now()
|
||||
order = ["year", "month", "day", "hour", "minute", "second"]
|
||||
deltas = {}
|
||||
future = False
|
||||
|
||||
prevdate, now = _normalize_datetime_pair(prevdate, now)
|
||||
|
||||
if prevdate > now:
|
||||
now_old = now
|
||||
now = prevdate
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ var AgeModule = (function () {
|
|||
var prevdate = moment(prevdate);
|
||||
var now = now || moment().utc();
|
||||
|
||||
if (prevdate.isUTC() || now.isUTC()) {
|
||||
prevdate = prevdate.clone().utc();
|
||||
now = now.clone().utc();
|
||||
}
|
||||
|
||||
var show_short_version = show_short_version || false;
|
||||
var show_suffix = show_suffix || true;
|
||||
var short_format = short_format || false;
|
||||
|
|
|
|||
|
|
@ -177,6 +177,32 @@ def test_age(age_args, expected, kw, baseapp):
|
|||
assert translate(age(n + delt(**age_args), now=n, **kw)) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"prevdate_fn, now_fn",
|
||||
[
|
||||
(functools.partial(datetime.datetime.now, tz=datetime.timezone.max), datetime.datetime.now),
|
||||
(datetime.datetime.now, datetime.datetime.now),
|
||||
(datetime.datetime.now, functools.partial(datetime.datetime.now, tz=datetime.timezone.max)),
|
||||
(
|
||||
functools.partial(datetime.datetime.now, tz=datetime.timezone.max),
|
||||
functools.partial(datetime.datetime.now, tz=datetime.timezone.max),
|
||||
),
|
||||
(functools.partial(datetime.datetime.now, tz=datetime.timezone.max), lambda: None),
|
||||
(datetime.datetime.now, lambda: None),
|
||||
],
|
||||
)
|
||||
def test_age_timezone_aware(now_fn, prevdate_fn):
|
||||
from rhodecode.lib.utils2 import age
|
||||
|
||||
now = now_fn()
|
||||
prevdate = prevdate_fn()
|
||||
|
||||
try:
|
||||
age(prevdate, now)
|
||||
except Exception as e:
|
||||
pytest.fail(f"Function raised an exception: {e}")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"age_args, expected, kw",
|
||||
[
|
||||
|
|
@ -326,19 +352,19 @@ def test_metatag_extraction(sample, expected_tags):
|
|||
(("lang", "[lang => .NET]"), '<div class="metatag" tag="lang">.NET</div>'),
|
||||
(
|
||||
("license", "[license => BSD 3-clause]"),
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/BSD 3-clause">BSD 3-clause</a></div>',
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/BSD 3-clause">BSD 3-clause</a></div>', # noqa: W605
|
||||
),
|
||||
(
|
||||
("license", "[license => GPLv3]"),
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/GPLv3">GPLv3</a></div>',
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/GPLv3">GPLv3</a></div>', # noqa: W605
|
||||
),
|
||||
(
|
||||
("license", "[license => MIT]"),
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/MIT">MIT</a></div>',
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/MIT">MIT</a></div>', # noqa: W605
|
||||
),
|
||||
(
|
||||
("license", "[license => AGPLv3]"),
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/AGPLv3">AGPLv3</a></div>',
|
||||
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/AGPLv3">AGPLv3</a></div>', # noqa: W605
|
||||
),
|
||||
(
|
||||
("ref", "[requires => RepoName]"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue