7197: merge the fix from master

All date tests pass cleanly on gramps40 branch.
Merged the following commits.

	commit a90139cb9a
	Author: Vassilii Khachaturov <vassilii@tarunz.org>
	Date:   Fri Nov 15 15:04:03 2013 +0200

		7197, 7100: missing recalc_sort_value in ny code

		Fix bug #7197

	commit baae6ac615
	Author: Vassilii Khachaturov <vassilii@tarunz.org>
	Date:   Thu Nov 14 22:45:42 2013 +0200

		7197: readjust sanity date wrt newyear/slash

		Attempt to fix the failing
		 DateHandlerTest.test_invalid_month_with_ny
		(see 7197:32625). Tests still fail, investigation shows
		there's a problem in Date.set setting Julian+Mar25 date even if the
		date validation check is disabled by inserting a return before
		the validation block, i.e., before this line
				if modifier != Date.MOD_TEXTONLY:
		which seems to be the root cause of the remaining failing tests.
		which seems to be the root cause of the remaining failing tests.

		To investigate, add the return and try
		LC_ALL=en_GB.utf8 LANG=en_GB.utf8 GRAMPS_RESOURCES=$PWD \
		 python -m unittest -v \
		 gramps.gen.lib.test.date_test.MatchDateTest.test_match

	commit 4147721112
	Author: Vassilii Khachaturov <vassilii@tarunz.org>
	Date:   Wed Nov 13 22:34:24 2013 +0200

		7197: refactor code

		extract Date._adjust_newyear out of Date.set

	commit b3ab87bc5a
	Author: Vassilii Khachaturov <vassilii@tarunz.org>
	Date:   Wed Nov 13 22:02:21 2013 +0200

		7197: refactor code

		replace all copies of logging with a single point at the exception
		rethrow point

	commit c4daa151a5
	Author: Vassilii Khachaturov <vassilii@tarunz.org>
	Date:   Wed Nov 13 17:39:47 2013 +0200

		7197: date sanity check breaks on Julian+Mar25

		Date.convert_calendar resets the new year setting to 0,
		so the sanity check fails. Commit the initial fix that
		unblocks the failing test.
This commit is contained in:
Vassilii Khachaturov 2013-11-15 15:43:27 +02:00
parent e097fb58c3
commit 68c0615bc4

View File

@ -4,6 +4,7 @@
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2009 Douglas S. Blank
# Copyright (C) 2013 Paul Franklin
# Copyright (C) 2013 Vassilii Khachaturov
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -1493,6 +1494,31 @@ class Date(object):
day = max(d, 1)
return (year, month, day)
def _adjust_newyear(self):
"""
Returns year adjustment performed (0 or -1).
"""
ny = self.get_new_year()
year_delta = 0
if ny: # new year offset?
if ny == Date.NEWYEAR_MAR1:
split = (3, 1)
elif ny == Date.NEWYEAR_MAR25:
split = (3, 25)
elif ny == Date.NEWYEAR_SEP1:
split = (9, 1)
elif isinstance(ny, (list, tuple)):
split = ny
else:
split = (0, 0)
if (self.get_month(), self.get_day()) >= split and split != (0, 0):
year_delta = -1
d1 = Date(self.get_year() + year_delta, self.get_month(), self.get_day())
d1.set_calendar(self.calendar)
d1.recalc_sort_value()
self.sortval = d1.sortval
return year_delta
def set(self, quality=None, modifier=None, calendar=None,
value=None,
text=None, newyear=0):
@ -1573,24 +1599,7 @@ class Date(object):
self.set_calendar(Date.CAL_JULIAN)
self.recalc_sort_value()
ny = self.get_new_year()
year_delta = 0
if ny: # new year offset?
if ny == Date.NEWYEAR_MAR1:
split = (3, 1)
elif ny == Date.NEWYEAR_MAR25:
split = (3, 25)
elif ny == Date.NEWYEAR_SEP1:
split = (9, 1)
elif isinstance(ny, (list, tuple)):
split = ny
else:
split = (0, 0)
if (self.get_month(), self.get_day()) >= split and split != (0, 0):
year_delta = -1
d1 = Date(self.get_year() + year_delta, self.get_month(), self.get_day())
d1.set_calendar(self.calendar)
self.sortval = d1.sortval
year_delta = self._adjust_newyear()
if text:
self.text = text
@ -1598,35 +1607,46 @@ class Date(object):
if modifier != Date.MOD_TEXTONLY:
sanity = Date(self)
sanity.convert_calendar(self.calendar, known_valid = False)
# convert_calendar resets slash and new year, restore these as needed
if sanity.get_slash() != self.get_slash():
sanity.set_slash(self.get_slash())
if self.is_compound() and sanity.get_slash2() != self.get_slash2():
sanity.set_slash2(self.get_slash2())
if sanity.get_new_year() != self.get_new_year():
sanity.set_new_year(self.get_new_year())
sanity._adjust_newyear()
# We don't do the roundtrip conversion on self, becaue
# it would remove uncertainty on day/month expressed with zeros
# Did the roundtrip change the date value?!
if sanity.dateval != value:
try:
# Maybe it is OK because of undetermined value adjustment?
zl = zip(sanity.dateval, value)
# Loop over all values present, whether compound or not
for d,m,y,sl in zip(*[iter(zl)]*4):
# each of d,m,y,sl is a pair from dateval and value, to compare
adjusted,original = sl
if adjusted != original:
raise DateError("Invalid date value {}".
format(value))
for adjusted,original in d,m:
if adjusted != original and not(original == 0 and adjusted == 1):
log.debug("Sanity check failed - self: {}, sanity: {}".format(
self.to_struct(), sanity.to_struct()))
raise DateError("Invalid day/month {} passed in value {}".
format(original, value))
adjusted,original = y
adjusted -= year_delta
if adjusted != original and not(original == 0 and adjusted == 1):
log.debug("Sanity check failed - self: {}, sanity: {}".format(
self.to_struct(), sanity.to_struct()))
raise DateError("Invalid year {} passed in value {}".
format(original, value))
# ignore slash difference
except DateError:
log.debug("Sanity check failed - self: {}, sanity: {}".format(
self.to_struct(), sanity.to_struct()))
raise
def recalc_sort_value(self):
"""