If a `BYXXX` sequence is passed to the constructor at the same level as `FREQ` (e.g. `FREQ=HOURLY,BYHOUR={2,4,7},INTERVAL=3`), there are some specifications which cannot be reached given some starting conditions. This occurs whenever the interval is not coprime with
(self, start, byxxx, base)
| 1030 | ii.rebuild(year, month) |
| 1031 | |
| 1032 | def __construct_byset(self, start, byxxx, base): |
| 1033 | """ |
| 1034 | If a `BYXXX` sequence is passed to the constructor at the same level as |
| 1035 | `FREQ` (e.g. `FREQ=HOURLY,BYHOUR={2,4,7},INTERVAL=3`), there are some |
| 1036 | specifications which cannot be reached given some starting conditions. |
| 1037 | |
| 1038 | This occurs whenever the interval is not coprime with the base of a |
| 1039 | given unit and the difference between the starting position and the |
| 1040 | ending position is not coprime with the greatest common denominator |
| 1041 | between the interval and the base. For example, with a FREQ of hourly |
| 1042 | starting at 17:00 and an interval of 4, the only valid values for |
| 1043 | BYHOUR would be {21, 1, 5, 9, 13, 17}, because 4 and 24 are not |
| 1044 | coprime. |
| 1045 | |
| 1046 | :param start: |
| 1047 | Specifies the starting position. |
| 1048 | :param byxxx: |
| 1049 | An iterable containing the list of allowed values. |
| 1050 | :param base: |
| 1051 | The largest allowable value for the specified frequency (e.g. |
| 1052 | 24 hours, 60 minutes). |
| 1053 | |
| 1054 | This does not preserve the type of the iterable, returning a set, since |
| 1055 | the values should be unique and the order is irrelevant, this will |
| 1056 | speed up later lookups. |
| 1057 | |
| 1058 | In the event of an empty set, raises a :exception:`ValueError`, as this |
| 1059 | results in an empty rrule. |
| 1060 | """ |
| 1061 | |
| 1062 | cset = set() |
| 1063 | |
| 1064 | # Support a single byxxx value. |
| 1065 | if isinstance(byxxx, integer_types): |
| 1066 | byxxx = (byxxx, ) |
| 1067 | |
| 1068 | for num in byxxx: |
| 1069 | i_gcd = gcd(self._interval, base) |
| 1070 | # Use divmod rather than % because we need to wrap negative nums. |
| 1071 | if i_gcd == 1 or divmod(num - start, i_gcd)[1] == 0: |
| 1072 | cset.add(num) |
| 1073 | |
| 1074 | if len(cset) == 0: |
| 1075 | raise ValueError("Invalid rrule byxxx generates an empty set.") |
| 1076 | |
| 1077 | return cset |
| 1078 | |
| 1079 | def __mod_distance(self, value, byxxx, base): |
| 1080 | """ |