### Schedule Every 20 Minutes Source: https://tzcron.readthedocs.io/en/latest/complex-expressions.html Use the step syntax to specify intervals. This example schedules an event every 20 minutes. ```python >>> schedule = tzcron.Schedule("*/20 * * * * *", pytz.utc) >>> [s.isoformat() for s in itertools.islice(schedule, 2)] ['2016-09-25T22:00:00+00:00', '2016-09-25T22:20:00+00:00'] ``` -------------------------------- ### Limit Schedule by Start and End Times Source: https://tzcron.readthedocs.io/en/latest/_sources/basic-usage.txt Create a schedule with a start and end time to generate occurrences within a specific range. The example generates occurrences for every 30 minutes within a two-hour window. ```python import datetime as dt import tzcron import pytz now = dt.datetime.now(pytz.utc) now_p2h = now + dt.timedelta(hours=2) schedule = tzcron.Schedule("30 * * * * *", pytz.utc, now, now_p2h) ``` ```python [s.isoformat() for s in schedule] ``` -------------------------------- ### Limit Schedule by Start and End Times Source: https://tzcron.readthedocs.io/en/latest/basic-usage.html Create a schedule with a start and end time to generate occurrences within a specific range. The example shows generating occurrences with minute=30 between now and two hours from now. ```python import datetime as dt import tzcron import pytz now = dt.datetime.now(pytz.utc) # '2016-09-25T20:10:20.916687+00:00' now_p2h = now + dt.timedelta(hours=2) schedule = tzcron.Schedule("30 * * * * *", pytz.utc, now, now_p2h) [s.isoformat() for s in schedule] ``` -------------------------------- ### Importer and Lazy Module Setup Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Initializes the meta path importer and defines the base class for lazy loading of moved objects. ```python self.__get_module(fullname) # eventually raises ImportError return None get_source = get_code # same as get_code _importer = _SixMetaPathImporter(__name__) class _MovedItems(_LazyModule): """Lazy loading of moved objects""" __path__ = [] # mark as package ``` -------------------------------- ### Schedule in January Source: https://tzcron.readthedocs.io/en/latest/complex-expressions.html Specify months using their three-letter English abbreviations. This example schedules an event for every day in January at 10:30 AM UTC. ```python >>> schedule = tzcron.Schedule("30 10 * JAN * *", pytz.utc) >>> [s.isoformat() for s in itertools.islice(schedule, 2)] ['2017-01-01T10:30:00+00:00', '2017-01-02T10:30:00+00:00'] ``` -------------------------------- ### Schedule Even Minutes Between 0 and 10 Source: https://tzcron.readthedocs.io/en/latest/complex-expressions.html Combine range and step syntax to create complex schedules. This example schedules events for even minutes between 0 and 10. ```python >>> schedule = tzcron.Schedule("0-10/2 * * * * *", pytz.utc) >>> [s.isoformat() for s in itertools.islice(schedule, 4)] ['2016-09-25T22:00:00+00:00', '2016-09-25T22:02:00+00:00', '2016-09-25T22:04:00+00:00', '2016-09-25T22:06:00+00:00'] ``` -------------------------------- ### Schedule Mondays and Tuesdays Source: https://tzcron.readthedocs.io/en/latest/complex-expressions.html Specify multiple values for a cron field using a comma-separated list. This example schedules an event for every Monday and Tuesday at 10:30 AM UTC. ```python >>> schedule = tzcron.Schedule("30 10 * * mon,tue *", pytz.utc) >>> [s.isoformat() for s in itertools.islice(schedule, 3)] ['2016-09-26T10:30:00+00:00', '2016-09-27T10:30:00+00:00', '2016-10-03T10:30:00+00:00'] ``` -------------------------------- ### Generate Recurrence Rule with Start and End Dates Source: https://tzcron.readthedocs.io/en/latest/_modules/tzcron.html Generates a recurrence rule for cron expressions, adjusting the start date to be one second after the minute if the second is zero. Use this when precise minute-level recurrence is needed. ```python import datetime as dt from rrule import rrule # Assuming start_date and end_date are datetime objects # and arguments is a dictionary arguments = {} start_date = dt.datetime.now() end_date = None if start_date.second == 0 and start_date.microsecond != 0: start_date = start_date + dt.timedelta(0, 1) arguments["dtstart"] = start_date if end_date: arguments["until"] = end_date # TODO: This can be optimized to values bigger than minutely # by checking if the minutes and hours are provided. # After hours (rrule.DAILY) it gets trickier as we have multiple # parameters affecting the recurrence (weekday/ month-day) return rrule(rrule.MINUTELY, **arguments) ``` -------------------------------- ### Schedule Every Thursday Source: https://tzcron.readthedocs.io/en/latest/complex-expressions.html Use three-letter English abbreviations for weekdays to specify recurring schedules. This example schedules an event for every Thursday at 10:30 AM UTC. ```python >>> schedule = tzcron.Schedule("30 10 * * thu *", pytz.utc) >>> [s.isoformat() for s in itertools.islice(schedule, 2)] ['2016-09-29T10:30:00+00:00', '2016-10-06T10:30:00+00:00'] ``` -------------------------------- ### Schedule within a Minute Range Source: https://tzcron.readthedocs.io/en/latest/complex-expressions.html Define a range of values for a cron field using a hyphen. This example schedules events for minutes 10 through 15 of every hour. ```python >>> schedule = tzcron.Schedule("10-15 * * * * *", pytz.utc) >>> [s.isoformat() for s in itertools.islice(schedule, 2)] ['2016-09-25T22:10:00+00:00', '2016-09-25T22:11:00+00:00'] ``` -------------------------------- ### Generate Occurrences with Specific Cron Expression Source: https://tzcron.readthedocs.io/en/latest/basic-usage.html Use a cron expression with year, month, day, day of week, hour, and minute to define a schedule. This example generates occurrences every first day of a month at 10:30 AM. ```python import itertools schedule = tzcron.Schedule("30 10 1 * * *", pytz.utc) [s.isoformat() for s in itertools.islice(schedule, 2)] ``` -------------------------------- ### Generate Occurrences in a Specific Timezone Source: https://tzcron.readthedocs.io/en/latest/basic-usage.html Create a schedule in a specific timezone, such as New York, to generate occurrences based on that timezone's local time. The example generates occurrences every day at 8:30 AM in New York. ```python import itertools import pytz schedule = tzcron.Schedule("30 10 1 * * *", pytz.timezone("America/New_York")) [s.isoformat() for s in itertools.islice(schedule, 2)] ``` -------------------------------- ### Define the Schedule class Source: https://tzcron.readthedocs.io/en/latest/_modules/tzcron.html The Schedule class handles the generation of occurrences based on a cron expression and timezone. It requires start and end dates to have timezone information. ```python class Schedule(six.Iterator): """Schedule allows to get a list of occurrences given a cron specification and tz Schedule is a class that relying in dateutil.rrule generates a list of occurrences given a schedule, timezone and start-end datetime Once the Schedule is built, it is iterable. Being each element an occurrence of the schedule The class provides no support for occurrences falling in DST change times. It will throw an exception if a schedule falls into a DST change period and advance the iterator. This allows the application to decide on those situations. Filters allow to specify a filtering condition for the occurrence See the year filter as an example. A good use of it is to skip non business days with a calendar. """ def __init__(self, expression, t_zone, start_date=None, end_date=None, filters=None): """Creates a schedule definition :param expression: cron expression defining the schedule :type expression: str :param t_zone: timezone we want the schedule to be applied on :type t_zone: instance of a subclass of tzinfo :param start_date: inclusive date to start to generate occurrences. Defaults to now :type start_date: datetime (with tzinfo) :param end_date: inclusive date of the last occurrence to generate. Defaults to never :type end_date: datetime (with tzinfo) :param filters: list of extra functions to filter occurrences. :type filters: list of callable """ start_date = start_date or dt.datetime.now(pytz.utc) # starts defaults to now self.t_zone = t_zone self.expression = expression self.start_date = start_date self.end_date = end_date if start_date.tzinfo is None or (end_date and end_date.tzinfo is None): raise TypeError("Start and End dates should have a timezone") start_t = start_date.astimezone(self.t_zone) end_t = end_date.astimezone(self.t_zone) if end_date else None # all datetime objects are in the desired tz. Lets strip out the timezones start_t = start_t.replace(tzinfo=None) end_t = end_t.replace(tzinfo=None) if end_t else None self._rrule = process(expression, start_t, end_t) self.__rrule_iterator = iter(self._rrule) self.filters = filters or [] self.filters.append(get_year_filter(self.expression.split(" ")[-1])) def __str__(self): return "Cron: {} @{} [{}->{}]".format(self.expression, self.t_zone, self.start_date, self.end_date) def __iter__(self): return self def __next__(self): """ Returns the next occurrence or raises StopIteration This method adds some extra validation for the returned iteration that are not natively handled by rrule """ while True: next_it = next(self.__rrule_iterator) next_it = self.t_zone.localize(next_it, is_dst=None) if not all([filt(next_it) for filt in self.filters]): continue return next_it ``` -------------------------------- ### Schedule Class Source: https://tzcron.readthedocs.io/en/latest/api.html The Schedule class allows users to get a list of occurrences based on a cron specification and a timezone. It relies on dateutil.rrule to generate these occurrences. The class is iterable, with each element representing an occurrence. ```APIDOC ## Schedule Class ### Description Allows to get a list of occurrences given a cron specification and tz. Schedule is a class that relying in dateutil.rrule generates a list of occurrences given a schedule, timezone and start-end datetime. Once the Schedule is built, it is iterable. Being each element an occurrence of the schedule. The class provides no support for occurrences falling in DST change times. It will throw an exception if a schedule falls into a DST change period and advance the iterator. This allows the application to decide on those situations. Filters allow to specify a filtering condition for the occurrence. See the year filter as an example. A good use of it is to skip non business days with a calendar. ### Method `__init__` ### Endpoint N/A (Class definition) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from tzcron import Schedule schedule = Schedule( expression='0 12 * * Mon', t_zone='America/New_York', start_date='2023-01-01', end_date='2023-12-31' ) for occurrence in schedule: print(occurrence) ``` ### Response #### Success Response (200) N/A (Class definition, iteration yields datetime objects) #### Response Example ``` 2023-01-02 12:00:00-05:00 2023-01-09 12:00:00-05:00 ... ``` ``` -------------------------------- ### Configure module package path Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Initializes module path and package metadata for PEP 302 and PEP 451 compliance. ```python __path__ = [] # required for PEP 302 and PEP 451 __package__ = __name__ # see PEP 366 @ReservedAssignment if globals().get("__spec__") is not None: __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable ``` -------------------------------- ### Utility Functions for Documentation and Imports Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Helper functions for attaching docstrings and performing dynamic module imports. ```python def _add_doc(func, doc): """Add documentation to a function.""" func.__doc__ = doc def _import_module(name): """Import module, returning the module after the last dot.""" __import__(name) return sys.modules[name] ``` -------------------------------- ### Iterate Over Schedule Occurrences Source: https://tzcron.readthedocs.io/en/latest/basic-usage.html Iterate over a tzcron Schedule object to retrieve all occurrences of the specified schedule. Use the `next()` function to get individual occurrences. ```python next(schedule) ``` -------------------------------- ### Creating six.moves.urllib Namespace Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Constructs a six.moves.urllib namespace that mirrors the Python 3 structure, providing access to submodules. ```python class Module_six_moves_urllib(types.ModuleType): """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" __path__ = [] # mark as package parse = _importer._get_module("moves.urllib_parse") error = _importer._get_module("moves.urllib_error") request = _importer._get_module("moves.urllib_request") response = _importer._get_module("moves.urllib_response") robotparser = _importer._get_module("moves.urllib_robotparser") def __dir__(self): return ['parse', 'error', 'request', 'response', 'robotparser'] _importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib") ``` -------------------------------- ### Create classes with metaclasses Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Utility to create a base class with a specified metaclass, useful for cross-version compatibility. ```python def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. class metaclass(meta): def __new__(cls, name, this_bases, d): return meta(name, bases, d) return type.__new__(metaclass, 'temporary_class', (), {}) ``` -------------------------------- ### Meta Path Importer for Module Resolution Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Implements a PEP302 finder and loader to manage dynamic module imports and package detection. ```python class _SixMetaPathImporter(object): """ A meta path importer to import six.moves and its submodules. This class implements a PEP302 finder and loader. It should be compatible with Python 2.5 and all existing versions of Python3 """ def __init__(self, six_module_name): self.name = six_module_name self.known_modules = {} def _add_module(self, mod, *fullnames): for fullname in fullnames: self.known_modules[self.name + "." + fullname] = mod def _get_module(self, fullname): return self.known_modules[self.name + "." + fullname] def find_module(self, fullname, path=None): if fullname in self.known_modules: return self return None def __get_module(self, fullname): try: return self.known_modules[fullname] except KeyError: raise ImportError("This loader does not know module " + fullname) def load_module(self, fullname): try: # in case of a reload return sys.modules[fullname] except KeyError: pass mod = self.__get_module(fullname) if isinstance(mod, MovedModule): mod = mod._resolve() else: mod.__loader__ = self sys.modules[fullname] = mod return mod def is_package(self, fullname): """ Return true, if the named module is a package. We need this method to get correct spec objects with Python 3.4 (see PEP451) """ return hasattr(self.__get_module(fullname), "__path__") def get_code(self, fullname): """Return None Required, if is_package is implemented""" ``` -------------------------------- ### Python 3 vs. Python 2 Method and Function Handling Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Defines helper functions for creating and accessing bound/unbound methods and functions, adapting to differences between Python 2 and Python 3. ```python if PY3: def get_unbound_function(unbound): return unbound create_bound_method = types.MethodType def create_unbound_method(func, cls): return func Iterator = object else: def get_unbound_function(unbound): return unbound.im_func def create_bound_method(func, obj): return types.MethodType(func, obj, obj.__class__) def create_unbound_method(func, cls): return types.MethodType(func, None, cls) class Iterator(object): def next(self): return type(self).__next__(self) callable = callable _add_doc(get_unbound_function, """Get the function out of a possibly unbound function""") ``` -------------------------------- ### Define Python Version Compatibility Constants Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Sets global constants to differentiate between Python 2 and 3 environments and defines standard type aliases. ```python PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 PY34 = sys.version_info[0:2] >= (3, 4) if PY3: string_types = str, integer_types = int, class_types = type, text_type = str binary_type = bytes MAXSIZE = sys.maxsize else: string_types = basestring, integer_types = (int, long) class_types = (type, types.ClassType) text_type = unicode binary_type = str if sys.platform.startswith("java"): # Jython always uses 32 bits. MAXSIZE = int((1 << 31) - 1) else: # It's possible to have sizeof(long) != sizeof(Py_ssize_t). class X(object): def __len__(self): return 1 << 31 try: len(X()) except OverflowError: # 32-bit MAXSIZE = int((1 << 31) - 1) else: # 64-bit MAXSIZE = int((1 << 63) - 1) del X ``` -------------------------------- ### Implement print function compatibility Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Provides a print function that supports flush arguments for Python versions older than 3.3. ```python if sys.version_info[:2] < (3, 3): _print = print_ def print_(*args, **kwargs): fp = kwargs.get("file", sys.stdout) flush = kwargs.pop("flush", False) _print(*args, **kwargs) if flush and fp is not None: fp.flush() ``` -------------------------------- ### Schedule Class Initialization Source: https://tzcron.readthedocs.io/en/latest/_modules/tzcron.html Initializes a Schedule object to define and iterate through cron-based occurrences within a specified timezone. ```APIDOC ## Schedule Class ### Description Schedule allows to get a list of occurrences given a cron specification and tz. It relies on dateutil.rrule to generate occurrences within a specified timezone and date range. The class is iterable, with each element being an occurrence. Note: The class does not natively support occurrences falling into DST change times. It will throw an exception in such cases, allowing the application to handle them. ### Method __init__ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **expression** (str) - Required - cron expression defining the schedule. - **t_zone** (instance of tzinfo subclass) - Required - timezone for the schedule. - **start_date** (datetime with tzinfo) - Optional - inclusive date to start generating occurrences. Defaults to the current time. - **end_date** (datetime with tzinfo) - Optional - inclusive date of the last occurrence to generate. Defaults to never. - **filters** (list of callable) - Optional - list of extra functions to filter occurrences. A year filter is automatically added based on the expression. ### Request Example ```python import datetime as dt import pytz from tzcron import Schedule # Example: Schedule for every day at 2 PM UTC expression = "0 14 * * *" t_zone = pytz.utc start_date = dt.datetime.now(pytz.utc) schedule = Schedule(expression, t_zone, start_date=start_date) ``` ### Response #### Success Response (200) Initialization of the Schedule object does not return a value, but it prepares the object for iteration. #### Response Example None (initialization does not return a value) ``` -------------------------------- ### Ensure Unicode compatibility Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html A decorator that defines __unicode__ and __str__ methods for Python 2 compatibility. ```python def python_2_unicode_compatible(klass): """ A decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method returning text and apply this decorator to the class. """ if PY2: if '__str__' not in klass.__dict__: raise ValueError("@python_2_unicode_compatible cannot be applied " "to %s because it doesn't define __str__()." % klass.__name__) klass.__unicode__ = klass.__str__ klass.__str__ = lambda self: self.__unicode__().encode('utf-8') return klass ``` -------------------------------- ### Schedule Across DST Change - tzcron Source: https://tzcron.readthedocs.io/en/latest/dst.html Demonstrates scheduling a task at 8:30 AM in the Europe/Madrid timezone, showing how tzcron correctly handles the DST change on October 30th, 2016, resulting in different UTC offsets for occurrences before and after the change. ```python >>> import datetime as dt >>> import pytz >>> import tzcron >>> madrid_tz = pytz.timezone("Europe/Madrid") >>> start_t = madrid_tz.localize(dt.datetime(2016, 10, 29)) >>> schedule = tzcron.Schedule("30 8 * * * *", madrid_tz, start_t) >>> [s.isoformat() for s in itertools.islice(schedule, 2)] ['2016-10-29T08:30:00+02:00', '2016-10-30T08:30:00+01:00'] ``` -------------------------------- ### Assertion Method Aliases for Python 2/3 Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Provides consistent names for assertion methods like assertCountEqual, assertRaisesRegex, and assertRegex, mapping to Python 2 or 3 specific names. ```python def assertCountEqual(self, *args, **kwargs): return getattr(self, _assertCountEqual)(*args, **kwargs) def assertRaisesRegex(self, *args, **kwargs): return getattr(self, _assertRaisesRegex)(*args, **kwargs) def assertRegex(self, *args, **kwargs): return getattr(self, _assertRegex)(*args, **kwargs) ``` -------------------------------- ### Lazy Loading urllib.robotparser Attributes Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Sets up lazy loading for attributes in the six.moves.urllib.robotparser module, maintaining Python 3 API. ```python class Module_six_moves_urllib_robotparser(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_robotparser""" _urllib_robotparser_moved_attributes = [ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), ] for attr in _urllib_robotparser_moved_attributes: setattr(Module_six_moves_urllib_robotparser, attr.name, attr) del attr Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes _importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), "moves.urllib_robotparser", "moves.urllib.robotparser") ``` -------------------------------- ### Backport functools.wraps Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Provides a backported version of functools.wraps for Python versions older than 3.4. ```python if sys.version_info[0:2] < (3, 4): def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): def wrapper(f): f = functools.wraps(wrapped, assigned, updated)(f) f.__wrapped__ = wrapped return f return wrapper else: wraps = functools.wraps ``` -------------------------------- ### Implement Specific Cron Parsers Source: https://tzcron.readthedocs.io/en/latest/_modules/tzcron.html Concrete implementations of the Parser class for different cron fields. ```python class MinuteParser(Parser): """Custom parser for minutes""" MIN_VALUE = 0 MAX_VALUE = 59 class HourParser(Parser): """Custom parser for hours""" MIN_VALUE = 0 MAX_VALUE = 23 class MonthDayParser(Parser): """Custom parser for month days""" MIN_VALUE = 1 MAX_VALUE = 31 class MonthParser(Parser): """Custom parser for months""" MIN_VALUE = 1 MAX_VALUE = 12 REPLACEMENTS = { "JAN": "1", "FEB": "2", "MAR": "3", "APR": "4", "MAY": "5", "JUN": "6", "JUL": "7", "AUG": "8", "SEP": "9", "OCT": "10", "NOV": "11", "DEC": "12" } class WeekDayParser(Parser): """Custom parser for week days""" MIN_VALUE = 1 MAX_VALUE = 7 REPLACEMENTS = { "MON": "1", "TUE": "2", "WED": "3", "THU": "4", "FRI": "5", "SAT": "6", "SUN": "7" } ``` -------------------------------- ### Schedule During DST Spring Forward - tzcron Source: https://tzcron.readthedocs.io/en/latest/dst.html Demonstrates scheduling a task at 2:30 AM in the Europe/Madrid timezone during a DST spring forward. This scenario results in a NonExistentTimeError because the time 2:30 AM on March 27th, 2016, does not exist due to clocks moving forward. ```python >>> start_t = madrid_tz.localize(dt.datetime(2016, 3, 26)) >>> schedule = tzcron.Schedule("30 2 * * * *", madrid_tz, start_t) >>> [s.isoformat() for s in itertools.islice(schedule, 2)] Traceback (most recent call last): File "", line 1, in File "", line 1, in File "tzcron.py", line 125, in __next__ next_it = self.t_zone.localize(next_it, is_dst=None) File "pytz/tzinfo.py", line 327, in localize raise NonExistentTimeError(dt) pytz.exceptions.NonExistentTimeError: 2016-03-27 02:30:00 ``` -------------------------------- ### Create a tzcron Schedule Source: https://tzcron.readthedocs.io/en/latest/_sources/basic-usage.txt Instantiate a tzcron Schedule object with a cron expression and a timezone. The schedule is initialized with UTC. ```python import tzcron import pytz schedule = tzcron.Schedule("* * * * * *", pytz.utc) ``` -------------------------------- ### Moved Attributes and Modules Registry Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html A comprehensive list of attribute and module mappings that redirect legacy Python 2 names to their modern Python 3 equivalents. ```python _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("intern", "__builtin__", "sys"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), MovedAttribute("StringIO", "StringIO", "io"), MovedAttribute("UserDict", "UserDict", "collections"), MovedAttribute("UserList", "UserList", "collections"), MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), MovedModule("html_parser", "HTMLParser", "html.parser"), MovedModule("http_client", "httplib", "http.client"), MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), MovedModule("cPickle", "cPickle", "pickle"), MovedModule("queue", "Queue"), MovedModule("reprlib", "repr"), MovedModule("socketserver", "SocketServer"), MovedModule("_thread", "thread", "_thread"), MovedModule("tkinter", "Tkinter"), MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), MovedModule("tkinter_tix", "Tix", "tkinter.tix"), MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"), MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"), MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), MovedModule("tkinter_font", "tkFont", "tkinter.font"), MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"), MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), ] ``` -------------------------------- ### Create a tzcron Schedule Source: https://tzcron.readthedocs.io/en/latest/basic-usage.html Instantiate a tzcron Schedule object with a cron expression and a timezone. The schedule object can be converted to a string for display. ```python import tzcron import pytz schedule = tzcron.Schedule("* * * * * *", pytz.utc) str(schedule) ``` -------------------------------- ### Print Function Compatibility Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Provides a compatible 'print_' function for older Python versions (2.4, 2.5) that mimics the behavior of Python 3's print function. ```python print_ = getattr(moves.builtins, "print", None) if print_ is None: def print_(*args, **kwargs): """The new-style print function for Python 2.4 and 2.5.""" fp = kwargs.pop("file", sys.stdout) if fp is None: return def write(data): if not isinstance(data, basestring): data = str(data) # If the file has an encoding, encode unicode with it. if (isinstance(fp, file) and isinstance(data, unicode) and fp.encoding is not None): errors = getattr(fp, "errors", None) if errors is None: errors = "strict" data = data.encode(fp.encoding, errors) fp.write(data) want_unicode = False sep = kwargs.pop("sep", None) if sep is not None: if isinstance(sep, unicode): want_unicode = True elif not isinstance(sep, str): raise TypeError("sep must be None or a string") end = kwargs.pop("end", None) if end is not None: ``` -------------------------------- ### String Encoding/Decoding Functions for Python 2/3 Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Defines 'b' for byte literals and 'u' for text literals, handling encoding differences between Python 2 and Python 3. ```python if PY3: def b(s): return s.encode("latin-1") def u(s): return s unichr = chr import struct int2byte = struct.Struct(">B").pack del struct byte2int = operator.itemgetter(0) indexbytes = operator.getitem iterbytes = iter import io StringIO = io.StringIO BytesIO = io.BytesIO _assertCountEqual = "assertCountEqual" if sys.version_info[1] <= 1: _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" else: _assertRaisesRegex = "assertRaisesRegex" _assertRegex = "assertRegex" else: def b(s): return s # Workaround for standalone backslash def u(s): return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") unichr = unichr int2byte = chr def byte2int(bs): return ord(bs[0]) def indexbytes(buf, i): return ord(buf[i]) iterbytes = functools.partial(itertools.imap, ord) import StringIO StringIO = BytesIO = StringIO.StringIO _assertCountEqual = "assertItemsEqual" _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" ``` -------------------------------- ### Define and Apply a Custom Schedule Filter Source: https://tzcron.readthedocs.io/en/latest/_sources/filters.txt Defines a filter function to match specific time criteria and applies it to a schedule instance. ```python >>> def is_funny_date(occurrence): ... return occurrence.minute == occurrence.hour ... >>> schedule = tzcron.Schedule("* * * * * *", pytz.utc, filters=[is_funny_date]) >>> [s.isoformat() for s in itertools.islice(schedule, 2)] ['2016-09-25T22:22:00+00:00', '2016-09-25T23:23:00+00:00'] ``` -------------------------------- ### Raise From Exception Handling for Python 2/3 Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Implements a 'raise_from' function that supports the 'from' keyword for exception chaining in Python 3, with a fallback for older versions. ```python if sys.version_info[:2] == (3, 2): exec_("def raise_from(value, from_value): if from_value is None: raise value raise value from from_value ") elif sys.version_info[:2] > (3, 2): exec_("def raise_from(value, from_value): raise value from from_value ") else: def raise_from(value, from_value): raise value ``` -------------------------------- ### List Available Timezones Source: https://tzcron.readthedocs.io/en/latest/basic-usage.html Retrieve a list of all available timezones supported by the pytz library. This is useful for selecting the correct timezone when creating a tzcron schedule. ```python import pytz pytz.all_timezones ``` -------------------------------- ### Exec Function for Python 2/3 Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Defines a compatible 'exec_' function that works with Python 2's exec statement or Python 3's built-in exec. ```python if PY3: exec_ = getattr(moves.builtins, "exec") def reraise(tp, value, tb=None): if value is None: value = tp() if value.__traceback__ is not tb: raise value.with_traceback(tb) raise value else: def exec_(_code_, _globs_=None, _locs_=None): """Execute code in a namespace.""" if _globs_ is None: frame = sys._getframe(1) _globs_ = frame.f_globals if _locs_ is None: _locs_ = frame.f_locals del frame elif _locs_ is None: _locs_ = _globs_ exec("exec _code_ in _globs_, _locs_") exec_("def reraise(tp, value, tb=None):\n raise tp, value, tb\n") ``` -------------------------------- ### Add Windows-Specific Modules Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Conditionally adds Windows-specific modules to the moved attributes list if the platform is win32. This ensures compatibility with older Windows registry modules. ```python if sys.platform == "win32": _moved_attributes += [ MovedModule("winreg", "_winreg"), ] for attr in _moved_attributes: setattr(_MovedItems, attr.name, attr) if isinstance(attr, MovedModule): _importer._add_module(attr, "moves." + attr.name) del attr _MovedItems._moved_attributes = _moved_attributes Moves = _MovedItems(__name__ + ".moves") _importer._add_module(moves, "moves") ``` -------------------------------- ### Dictionary Iteration Functions for Python 2/3 Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html Provides iterator functions for dictionary keys, values, and items, adapting to Python 3's direct methods or Python 2's .iter* methods. ```python if PY3: def iterkeys(d, **kw): return iter(d.keys(**kw)) def itervalues(d, **kw): return iter(d.values(**kw)) def iteritems(d, **kw): return iter(d.items(**kw)) def iterlists(d, **kw): return iter(d.lists(**kw)) viewkeys = operator.methodcaller("keys") viewvalues = operator.methodcaller("values") viewitems = operator.methodcaller("items") else: def iterkeys(d, **kw): return d.iterkeys(**kw) def itervalues(d, **kw): return d.itervalues(**kw) def iteritems(d, **kw): return d.iteritems(**kw) def iterlists(d, **kw): return d.iterlists(**kw) viewkeys = operator.methodcaller("viewkeys") viewvalues = operator.methodcaller("viewvalues") viewitems = operator.methodcaller("viewitems") ``` -------------------------------- ### process Function Source: https://tzcron.readthedocs.io/en/latest/_modules/tzcron.html Generates an rrule object from a cron expression and date range. ```APIDOC ## Function: process(expression, start_date, end_date=None) ### Description Given a cron expression and a start/end date, returns an rrule object. Works with "naive" datetime objects. ### Parameters - `expression` (string): The cron expression string. - `start_date` (datetime): The start date for the rrule. - `end_date` (datetime, optional): The end date for the rrule. ### Raises - `TypeError`: If timezones are present in `start_date` or `end_date`. ### Returns - `rrule` object: An rrule object configured based on the cron expression and date range. ``` -------------------------------- ### Specific Parsers Source: https://tzcron.readthedocs.io/en/latest/_modules/tzcron.html Concrete implementations of the Parser class for different components of a cron expression. ```APIDOC ## Specific Parsers ### MinuteParser Custom parser for minutes. - `MIN_VALUE`: 0 - `MAX_VALUE`: 59 ### HourParser Custom parser for hours. - `MIN_VALUE`: 0 - `MAX_VALUE`: 23 ### MonthDayParser Custom parser for month days. - `MIN_VALUE`: 1 - `MAX_VALUE`: 31 ### MonthParser Custom parser for months. - `MIN_VALUE`: 1 - `MAX_VALUE`: 12 - `REPLACEMENTS`: {"JAN": "1", "FEB": "2", ..., "DEC": "12"} ### WeekDayParser Custom parser for week days. - `MIN_VALUE`: 1 - `MAX_VALUE`: 7 - `REPLACEMENTS`: {"MON": "1", "TUE": "2", ..., "SUN": "7"} ``` -------------------------------- ### Parser Class Source: https://tzcron.readthedocs.io/en/latest/_modules/tzcron.html Abstract base class for parsing specific parts of Quartz expressions. It defines methods for handling ranges, steps, and replacements. ```APIDOC ## Abstract Class: Parser ### Description Abstract class to create parsers for parts of quartz expressions. Each parser can be used per token and a specific parser needs to provide the valid ranges of the quartz part and a dict of REPLACEMENTS in upper case. ### Methods - `_parse_item(expression)`: Parses one of the comma separated expressions within the full quartz. - `parse(expression)`: Parses the quartz expression and returns a sorted list of unique elements. ### Attributes - `MIN_VALUE`: Minimum value the expression can have. - `MAX_VALUE`: Maximum value (inclusive) the expression can have. - `REPLACEMENTS`: Dictionary of string replacements for the expression (e.g., month names to numbers). ``` -------------------------------- ### Decorate classes with metaclasses Source: https://tzcron.readthedocs.io/en/latest/_modules/six.html A class decorator that applies a metaclass to a class, handling slots and internal attributes correctly. ```python def add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" def wrapper(cls): orig_vars = cls.__dict__.copy() slots = orig_vars.get('__slots__') if slots is not None: if isinstance(slots, str): slots = [slots] for slots_var in slots: orig_vars.pop(slots_var) orig_vars.pop('__dict__', None) orig_vars.pop('__weakref__', None) return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper ```