Пример #1
0
def datetimes(min_datetime=dt.datetime.min,
              max_datetime=dt.datetime.max,
              timezones=none()):
    """A strategy for generating datetimes, which may be timezone-aware.

    This strategy works by drawing a naive datetime between ``min_datetime``
    and ``max_datetime``, which must both be naive (have no timezone).

    ``timezones`` must be a strategy that generates tzinfo objects (or None,
    which is valid for naive datetimes).  A value drawn from this strategy
    will be added to a naive datetime, and the resulting tz-aware datetime
    returned.

    .. note::
        tz-aware datetimes from this strategy may be ambiguous or non-existent
        due to daylight savings, leap seconds, timezone and calendar
        adjustments, etc.  This is intentional, as malformed timestamps are a
        common source of bugs.

    :py:func:`hypothesis.extra.timezones` requires the ``pytz`` package, but
    provides all timezones in the Olsen database.  If you also want to allow
    naive datetimes, combine strategies like ``none() | timezones()``.

    Alternatively, you can create a list of the timezones you wish to allow
    (e.g. from the standard library, ``datetutil``, or ``pytz``) and use
    :py:func:`sampled_from`.  Ensure that simple values such as None or UTC
    are at the beginning of the list for proper minimisation.

    """
    # Why must bounds be naive?  In principle, we could also write a strategy
    # that took aware bounds, but the API and validation is much harder.
    # If you want to generate datetimes between two particular momements in
    # time I suggest (a) just filtering out-of-bounds values; (b) if bounds
    # are very close, draw a value and subtract it's UTC offset, handling
    # overflows and nonexistent times; or (c) do something customised to
    # handle datetimes in e.g. a four-microsecond span which is not
    # representable in UTC.  Handling (d), all of the above, leads to a much
    # more complex API for all users and a useful feature for very few.
    from hypothesis.searchstrategy.datetime import DatetimeStrategy

    check_type(dt.datetime, min_datetime, 'min_datetime')
    check_type(dt.datetime, max_datetime, 'max_datetime')
    if min_datetime.tzinfo is not None:
        raise InvalidArgument('min_datetime=%r must not have tzinfo' %
                              (min_datetime, ))
    if max_datetime.tzinfo is not None:
        raise InvalidArgument('max_datetime=%r must not have tzinfo' %
                              (max_datetime, ))
    check_valid_interval(min_datetime, max_datetime, 'min_datetime',
                         'max_datetime')
    if not isinstance(timezones, SearchStrategy):
        raise InvalidArgument(
            'timezones=%r must be a SearchStrategy that can provide tzinfo '
            'for datetimes (either None or dt.tzinfo objects)' % (timezones, ))
    return DatetimeStrategy(min_datetime, max_datetime, timezones)
Пример #2
0
def test_DatetimeStrategy_draw_may_fail():
    def is_failure_inducing(b):
        try:
            return strat._attempt_one_draw(ConjectureData.for_buffer(b)) is None
        except StopTest:
            return False

    strat = DatetimeStrategy(dt.datetime.min, dt.datetime.max, none())
    failure_inducing = minimal(binary(), is_failure_inducing)
    data = ConjectureData.for_buffer(failure_inducing * 100)
    with pytest.raises(StopTest):
        data.draw(strat)
    assert data.status == Status.INVALID