# HG changeset patch # User Paul Boddie # Date 1512325154 -3600 # Node ID d39a2232c73745df4def2baeb675d0288f868565 # Parent 9f507afaa71b50033578813197c83f62ba5220fc Introduce datetime information between selectors where appropriate. Added a function for obtaining the selector chain from a single root. diff -r 9f507afaa71b -r d39a2232c737 tests/qualifiers.py --- a/tests/qualifiers.py Sun Dec 03 17:13:17 2017 +0100 +++ b/tests/qualifiers.py Sun Dec 03 19:19:14 2017 +0100 @@ -39,6 +39,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2003, 12, 24)) print len(l) == 7, 7, len(l) @@ -63,6 +65,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2003, 12, 24, 0, 0, 0)) print len(l) == 34, 34, len(l) @@ -84,6 +88,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24)) print len(l) == 10, 10, len(l) @@ -104,6 +110,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 113, 113, len(l) @@ -124,6 +132,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 57, 57, len(l) @@ -144,6 +154,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 17, 17, len(l) @@ -165,6 +177,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 5, 5, len(l) @@ -187,6 +201,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2000, 1, 31, 14, 0, 0)) print len(l) == 93, 93, len(l) @@ -208,6 +224,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2000, 1, 31, 14, 0, 0)) print len(l) == 93, 93, len(l) @@ -229,6 +247,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -249,6 +269,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 17, 17, len(l) @@ -269,6 +291,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 17, 17, len(l) @@ -289,6 +313,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 2, 20, 0, 0, 0)) print len(l) == 13, 13, len(l) @@ -310,6 +336,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 10, 7, 9, 0, 0)) print len(l) == 10, 10, len(l) @@ -332,6 +360,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -353,6 +383,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 25, 25, len(l) @@ -375,6 +407,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 8, 8, len(l) @@ -397,6 +431,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -418,6 +454,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 4, 4, len(l) @@ -440,6 +478,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -462,6 +502,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0)) print len(l) == 6, 6, len(l) @@ -484,6 +526,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0)) print len(l) == 6, 6, len(l) @@ -506,6 +550,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -528,6 +574,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -550,6 +598,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -571,6 +621,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 4, 1, 0, 0, 0)) print len(l) == 18, 18, len(l) @@ -593,6 +645,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2001, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -615,6 +669,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2003, 12, 24, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -637,6 +693,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2006, 2, 1, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -658,6 +716,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 3, 3, len(l) @@ -681,6 +741,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 3, 3, len(l) @@ -704,6 +766,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 11, 11, len(l) @@ -726,6 +790,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1999, 12, 24, 0, 0, 0)) print len(l) == 39, 39, len(l) @@ -748,6 +814,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2000, 12, 24, 0, 0, 0)) print len(l) == 6, 6, len(l) @@ -770,6 +838,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 6, 30, 0, 0, 0)) print len(l) == 10, 10, len(l) @@ -793,6 +863,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2004, 12, 24, 0, 0, 0)) print len(l) == 3, 3, len(l) @@ -816,6 +888,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1997, 12, 24, 0, 0, 0)) print len(l) == 3, 3, len(l) @@ -840,6 +914,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (1998, 4, 1, 0, 0, 0)) print len(l) == 7, 7, len(l) @@ -858,6 +934,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2019, 1, 1)) print len(l) == 37, 37, len(l) @@ -875,6 +953,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2019, 1, 1)) print len(l) == 32, 32, len(l) @@ -892,6 +972,8 @@ show(csel) s = get_selector(dt, sel) +csel = get_selectors_from_selector(s) +show(csel) l = s.materialise(dt, (2018, 1, 1)) print len(l) == 18, 18, len(l) diff -r 9f507afaa71b -r d39a2232c737 vRecurrence.py --- a/vRecurrence.py Sun Dec 03 17:13:17 2017 +0100 +++ b/vRecurrence.py Sun Dec 03 19:19:14 2017 +0100 @@ -488,24 +488,32 @@ from_dt = get_next(iter_dt) from_sel = get_next(iter_sel) have_sel = False + held_dt = [] # Consume from both lists, merging entries. - while from_dt and from_sel: - _level = from_dt.level + while from_sel: level = from_sel.level # Datetime value at wider resolution. - if _level < level: + if from_dt and from_dt.level < level: + held_dt.append(from_dt) from_dt = get_next(iter_dt) # Qualifier at wider or same resolution as datetime value. else: if not have_sel: - add_initial_selector(from_sel, level, l) - have_sel = True + have_sel = add_initial_selector(from_sel, level, l) + + # Introduce any held datetime values, if appropriate. + + elif can_restrict_selector(from_sel): + for from_held_dt in held_dt: + add_datetime_selector(from_held_dt, l) + + held_dt = [] # Add the qualifier to the combined list. @@ -513,7 +521,7 @@ # Datetime value at same resolution. - if _level == level: + if from_dt and from_dt.level == level: from_dt = get_next(iter_dt) # Get the next qualifier. @@ -523,45 +531,44 @@ # Complete the list by adding remaining datetime enumerators. while from_dt: - - # Ignore datetime values that conflict with day-level qualifiers. - - if not l or from_dt.level != freq["DAILY"] or \ - l[-1].level not in daylevels: - - l.append(from_dt) - + add_datetime_selector(from_dt, l) from_dt = get_next(iter_dt) - # Complete the list by adding remaining qualifiers. + return l - while from_sel: - if not have_sel: - add_initial_selector(from_sel, level, l) - have_sel = True +def can_restrict_selector(from_sel): - # Add the qualifier to the combined list. - - l.append(from_sel) + "Return whether 'from_sel' can be restricted using datetime information." - # Get the next qualifier. - - from_sel = get_next(iter_sel) - - return l + return not isinstance(from_sel, Pattern) and from_sel.qualifier != "BYDAY" def add_initial_selector(from_sel, level, l): """ - Take the first selector 'from_sel' at the given resolution 'level', using it - to create an initial selector, adding it to the combined list 'l' if - required. + Take the selector 'from_sel' at the given resolution 'level', using it to + create an initial selector, adding it to the combined list 'l' if required. + + Return whether a frequency selector has been introduced or if 'from_sel' is + such a selector. """ if isinstance(from_sel, Enum) and level > 0: parent_level = enum_parent_levels[level] repeat = Pattern(parent_level, {"interval" : 1}, freq_levels[parent_level]) l.append(repeat) + return True + + return isinstance(from_sel, Pattern) + +def add_datetime_selector(from_dt, l): + + """ + Take the selector 'from_dt' and add it to the list 'l' if it does not + conflict with any day-level qualifiers already in 'l'. + """ + + if not l or from_dt.level != freq["DAILY"] or l[-1].level not in daylevels: + l.append(from_dt) def get_multiple(qualifier): @@ -1531,4 +1538,13 @@ rule = (rule or "").split(";") return make_selectors(get_qualifiers(rule)) +def get_selectors_from_selector(selector): + + "Return the chain of selectors from 'selector', useful for debugging." + + if selector.selecting: + return [selector] + get_selectors_from_selector(selector.selecting) + else: + return [selector] + # vim: tabstop=4 expandtab shiftwidth=4