<commit_before>"""timer2 - Scheduler for Python functions."""

from __future__ import generators

import atexit
import heapq
import sys
import traceback
import warnings

from itertools import count
from threading import Condition, Event, Lock, Thread
from time import time, sleep, mktime

from datetime import datetime, timedelta

VERSION = (0, 1, 0)
__version__ = ".".join(map(str, VERSION))
__author__ = "<NAME>"
__contact__ = "<EMAIL>"
__homepage__ = "http://github.com/ask/timer/"
__docformat__ = "restructuredtext"

DEFAULT_MAX_INTERVAL = 2


class TimedFunctionFailed(UserWarning):
    pass


class Entry(object):
    cancelled = False

    def __init__(self, fun, args=None, kwargs=None):
        self.fun = fun
        self.args = args or []
        self.kwargs = kwargs or {}
        self.tref = self

    def __call__(self):
        return self.fun(*self.args, **self.kwargs)

    def cancel(self):
        self.tref.cancelled = True


def to_timestamp(d):
    if isinstance(d, datetime):
        return mktime(d.timetuple())
    return d


class Schedule(object):
    """ETA scheduler."""
    on_error = None

    def __init__(self, max_interval=DEFAULT_MAX_INTERVAL, on_error=None):
        self.max_interval = float(max_interval)
        self.on_error = on_error or self.on_error
        self._queue = []

    def handle_error(self, exc_info):
        if self.on_error:
            self.on_error(exc_info)
            return True

    def enter(self, entry, eta=None, priority=0):
        """Enter function into the scheduler.

        :param entry: Item to enter.
        :keyword eta: Scheduled time as a :class:`datetime.datetime` object.
        :keyword priority: Unused.

        """
        try:
            eta = to_timestamp(eta)
        except OverflowError:
            if not self.handle_error(sys.exc_info()):
                raise

        if eta is None:
            # schedule now.
            eta = time()

        heapq.heappush(self._queue, (eta, priority, entry))
        return entry

    def __iter__(self):
        """The iterator yields the time to sleep for between runs."""

        # localize variable access
        nowfun = time
        pop = heapq.heappop

        while 1:
            if self._queue:
                eta, priority, entry = verify = self._queue[0]
                now = nowfun()

                if now < eta:
                    yield min(eta - now, self.max_interval)
                else:
                    event = pop(self._queue)

                    if event is verify:
                        if not entry.cancelled:
                            try:
                                entry()
                            except Exception, exc:
                                typ, val, tb = einfo = sys.exc_info()
                                if not self.handle_error(einfo):
                                    warnings.warn(repr(exc),
                                                  TimedFunctionFailed)
                                    traceback.print_exception(typ, val, tb)
                        continue
                    else:
                        heapq.heappush(self._queue, event)
            yield None

    def empty(self):
        """Is the schedule empty?"""
        return not self._queue

    def clear(self):
        self._queue = []

    def info(self):
        return ({"eta": eta, "priority": priority, "item": item}
                    for eta, priority, item in self.queue)

    @property
    def queue(self):
        events = list(self._queue)
        return map(heapq.heappop, [events] * len(events))


class Timer(Thread):
    Entry = Entry

    running = False
    on_tick = None
    _timer_count = count(1).next

    def __init__(self, schedule=None, on_error=None, on_tick=None, **kwargs):
        self.schedule = schedule or Schedule(on_error=on_error)
        self.on_tick = on_tick or self.on_tick

        Thread.__init__(self)
        self._shutdown = Event()
        self._stopped = Event()
        self.mutex = Lock()
        self.not_empty = Condition(self.mutex)
        self.setDaemon(True)
        self.setName("Timer-%s" % (self._timer_count(), ))

    def next(self):
        self.not_empty.acquire()
        try:
            delay = self.scheduler.next()
            if delay is None:
                print("WAITING FOR ENTRY")
                self.not_empty.wait()
            return delay
        finally:
            self.not_empty.release()

    def run(self):
        self.running = True
        self.scheduler = iter(self.schedule)

        while not self._shutdown.isSet():
            delay = self.next()
            if delay:
                if self.on_tick:
                    self.on_tick(delay)
                if sleep is None:<commit_msg>timer2.Timer: Add timeout when waiting for not_empty<commit_after>"""timer2 - Scheduler for Python functions."""

from __future__ import generators

import atexit
import heapq
import sys
import traceback
import warnings

from itertools import count
from threading import Condition, Event, Lock, Thread
from time import time, sleep, mktime

from datetime import datetime, timedelta

VERSION = (0, 1, 0)
__version__ = ".".join(map(str, VERSION))
__author__ = "<NAME>"
__contact__ = "<EMAIL>"
__homepage__ = "http://github.com/ask/timer/"
__docformat__ = "restructuredtext"

DEFAULT_MAX_INTERVAL = 2


class TimedFunctionFailed(UserWarning):
    pass


class Entry(object):
    cancelled = False

    def __init__(self, fun, args=None, kwargs=None):
        self.fun = fun
        self.args = args or []
        self.kwargs = kwargs or {}
        self.tref = self

    def __call__(self):
        return self.fun(*self.args, **self.kwargs)

    def cancel(self):
        self.tref.cancelled = True


def to_timestamp(d):
    if isinstance(d, datetime):
        return mktime(d.timetuple())
    return d


class Schedule(object):
    """ETA scheduler."""
    on_error = None

    def __init__(self, max_interval=DEFAULT_MAX_INTERVAL, on_error=None):
        self.max_interval = float(max_interval)
        self.on_error = on_error or self.on_error
        self._queue = []

    def handle_error(self, exc_info):
        if self.on_error:
            self.on_error(exc_info)
            return True

    def enter(self, entry, eta=None, priority=0):
        """Enter function into the scheduler.

        :param entry: Item to enter.
        :keyword eta: Scheduled time as a :class:`datetime.datetime` object.
        :keyword priority: Unused.

        """
        try:
            eta = to_timestamp(eta)
        except OverflowError:
            if not self.handle_error(sys.exc_info()):
                raise

        if eta is None:
            # schedule now.
            eta = time()

        heapq.heappush(self._queue, (eta, priority, entry))
        return entry

    def __iter__(self):
        """The iterator yields the time to sleep for between runs."""

        # localize variable access
        nowfun = time
        pop = heapq.heappop

        while 1:
            if self._queue:
                eta, priority, entry = verify = self._queue[0]
                now = nowfun()

                if now < eta:
                    yield min(eta - now, self.max_interval)
                else:
                    event = pop(self._queue)

                    if event is verify:
                        if not entry.cancelled:
                            try:
                                entry()
                            except Exception, exc:
                                typ, val, tb = einfo = sys.exc_info()
                                if not self.handle_error(einfo):
                                    warnings.warn(repr(exc),
                                                  TimedFunctionFailed)
                                    traceback.print_exception(typ, val, tb)
                        continue
                    else:
                        heapq.heappush(self._queue, event)
            yield None

    def empty(self):
        """Is the schedule empty?"""
        return not self._queue

    def clear(self):
        self._queue = []

    def info(self):
        return ({"eta": eta, "priority": priority, "item": item}
                    for eta, priority, item in self.queue)

    @property
    def queue(self):
        events = list(self._queue)
        return map(heapq.heappop, [events] * len(events))


class Timer(Thread):
    Entry = Entry

    running = False
    on_tick = None
    _timer_count = count(1).next

    def __init__(self, schedule=None, on_error=None, on_tick=None, **kwargs):
        self.schedule = schedule or Schedule(on_error=on_error)
        self.on_tick = on_tick or self.on_tick

        Thread.__init__(self)
        self._shutdown = Event()
        self._stopped = Event()
        self.mutex = Lock()
        self.not_empty = Condition(self.mutex)
        self.setDaemon(True)
        self.setName("Timer-%s" % (self._timer_count(), ))

    def next(self):
        self.not_empty.acquire()
        try:
            delay = self.scheduler.next()
            if delay is None:
                self.not_empty.wait(1.0)
            return delay
        finally:
            self.not_empty.release()

    def run(self):
        self.running = True
        self.scheduler = iter(self.schedule)

        while not self._shutdown.isSet():
            delay = self.next()
            if delay:
                if self.on_tick:
                    self.on_tick(delay)
                if sleep is None:
{'fraction_non_alphanumeric': 0.09582155199497329, 'fraction_numerical': 0.002199183160540371, 'mean_word_length': 1.6765695067264574, 'pattern_counts': {'":': 6, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1839332', 'n_tokens_mistral': 2724, 'n_tokens_neox': 2610, 'n_words': 708}