Beispiel #1
0
def test_composite_parameter_name_clashes():
    with pytest.raises(ValueError) as e:
        params.CompositeParameter(
            params.BiasedCoin(0.5),
            arg0=params.BiasedCoin(0.5),
        )
    assert 'duplicate' in e.value.args[0].lower()
    with pytest.raises(ValueError) as e:
        params.CompositeParameter(__init__=params.BiasedCoin(0.5), )
    assert 'invalid' in e.value.args[0].lower()
Beispiel #2
0
class GaussianFloatStrategy(FloatStrategy):
    """A float strategy such that every conditional distribution is drawn from
    a gaussian."""
    parameter = params.CompositeParameter(mean=params.NormalParameter(0, 1), )

    def produce(self, random, pv):
        return random.normalvariate(pv.mean, 1)
Beispiel #3
0
 def __init__(self, float_strategy):
     super(ComplexStrategy, self).__init__()
     self.parameter = params.CompositeParameter(
         real=float_strategy.parameter,
         imaginary=float_strategy.parameter,
     )
     self.float_strategy = float_strategy
Beispiel #4
0
class OneCharStringStrategy(SearchStrategy):
    """A strategy which generates single character strings of text type."""
    descriptor = text_type
    ascii_characters = (text_type('0123456789') +
                        text_type(string.ascii_letters) + text_type(' \t\n'))
    parameter = params.CompositeParameter(
        ascii_chance=params.UniformFloatParameter(0, 1))

    def produce(self, random, pv):
        if dist.biased_coin(random, pv.ascii_chance):
            return random.choice(self.ascii_characters)
        else:
            while True:
                result = hunichr(random.randint(0, sys.maxunicode))
                if unicodedata.category(result) != 'Cs':
                    return result

    def simplify(self, x):
        if x in self.ascii_characters:
            for i in hrange(self.ascii_characters.index(x), -1, -1):
                yield self.ascii_characters[i]
        else:
            o = ord(x)
            for c in reversed(self.ascii_characters):
                yield text_type(c)
            if o > 0:
                yield hunichr(o // 2)
                yield hunichr(o - 1)
Beispiel #5
0
class FixedBoundedFloatStrategy(SearchStrategy):
    """A strategy for floats distributed between two endpoints.

    The conditional distribution tries to produce values clustered
    closer to one of the ends.

    """
    descriptor = float

    parameter = params.CompositeParameter(
        cut=params.UniformFloatParameter(0, 1),
        leftwards=params.BiasedCoin(0.5),
    )

    def __init__(self, lower_bound, upper_bound):
        SearchStrategy.__init__(self)
        self.lower_bound = float(lower_bound)
        self.upper_bound = float(upper_bound)

    def produce(self, random, pv):
        if pv.leftwards:
            left = self.lower_bound
            right = pv.cut
        else:
            left = pv.cut
            right = self.upper_bound
        return left + random.random() * (right - left)

    def simplify(self, value):
        yield self.lower_bound
        yield self.upper_bound
        yield (self.lower_bound + self.upper_bound) * 0.5
    class FooStrategy(strat.SearchStrategy):
        descriptor = Foo
        parameter = params.CompositeParameter()
        has_immutable_data = False

        def produce(self, random, pv):
            return Foo()
Beispiel #7
0
 def __init__(self, characters=None):
     SearchStrategy.__init__(self)
     if characters is not None and not isinstance(characters, text_type):
         raise ValueError('Invalid characters %r: Not a %s' %
                          (characters, text_type))
     self.characters = characters or (text_type('0123456789') +
                                      text_type(string.ascii_letters))
     self.parameter = params.CompositeParameter()
Beispiel #8
0
 def __init__(self):
     super(BoundedFloatStrategy, self).__init__()
     self.inner_strategy = FixedBoundedFloatStrategy(0, 1)
     self.parameter = params.CompositeParameter(
         left=params.NormalParameter(0, 1),
         length=params.ExponentialParameter(1),
         spread=self.inner_strategy.parameter,
     )
Beispiel #9
0
 def __init__(self, strategies, tuple_type):
     SearchStrategy.__init__(self)
     strategies = tuple(strategies)
     self.tuple_type = tuple_type
     self.descriptor = self.newtuple([s.descriptor for s in strategies])
     self.element_strategies = strategies
     self.parameter = params.CompositeParameter(
         x.parameter for x in self.element_strategies)
     self.has_immutable_data = all(s.has_immutable_data for s in strategies)
Beispiel #10
0
    def __init__(self, strategies, average_length=50.0):
        SearchStrategy.__init__(self)

        self.descriptor = _unique(x.descriptor for x in strategies)
        self.element_strategy = one_of_strategies(strategies)
        self.parameter = params.CompositeParameter(
            average_length=params.ExponentialParameter(1.0 / average_length),
            child_parameter=self.element_strategy.parameter,
        )
Beispiel #11
0
 def __init__(self, main_strategy, examples):
     assert examples
     assert all(main_strategy.could_have_produced(e) for e in examples)
     self.examples = tuple(examples)
     self.main_strategy = main_strategy
     self.descriptor = main_strategy.descriptor
     self.parameter = params.CompositeParameter(
         examples=params.NonEmptySubset(examples),
         example_probability=params.UniformFloatParameter(0.0, 0.5),
         main=main_strategy.parameter)
     self.has_immutable_data = main_strategy.has_immutable_data
     if hasattr(main_strategy, 'element_strategy'):
         self.element_strategy = main_strategy.element_strategy
Beispiel #12
0
 def __init__(self, strategies):
     SearchStrategy.__init__(self)
     flattened_strategies = []
     for s in strategies:
         if isinstance(s, OneOfStrategy):
             flattened_strategies += s.element_strategies
         else:
             flattened_strategies.append(s)
     strategies = tuple(flattened_strategies)
     if len(strategies) <= 1:
         raise ValueError('Need at least 2 strategies to choose amongst')
     descriptor = descriptors.one_of(
         _unique(s.descriptor for s in strategies))
     self.descriptor = descriptor
     self.element_strategies = list(strategies)
     n = len(self.element_strategies)
     self.parameter = params.CompositeParameter(
         enabled_children=params.NonEmptySubset(range(n)),
         child_parameters=params.CompositeParameter(
             e.parameter for e in self.element_strategies))
     self.has_immutable_data = all(s.has_immutable_data
                                   for s in self.element_strategies)
Beispiel #13
0
class RandomStrategy(SearchStrategy):
    """A strategy which produces Random objects.

    The conditional distribution is simply a RandomWithSeed seeded with
    a 128 bits of data chosen uniformly at random.

    """
    descriptor = Random
    parameter = params.CompositeParameter()
    has_immutable_data = False

    def produce(self, random, pv):
        return RandomWithSeed(random.getrandbits(128))

    def could_have_produced(self, value):
        return isinstance(value, RandomWithSeed)
Beispiel #14
0
class ExponentialFloatStrategy(FloatStrategy):
    """
    A float strategy such that every conditional distribution is of the form
    aX + b where a = +/- 1 and X is an exponentially distributed random
    variable.
    """
    parameter = params.CompositeParameter(
        lambd=params.GammaParameter(2, 50),
        zero_point=params.NormalParameter(0, 1),
        negative=params.BiasedCoin(0.5),
    )

    def produce(self, random, pv):
        value = random.expovariate(pv.lambd)
        if pv.negative:
            value = -value
        return pv.zero_point + value
Beispiel #15
0
class FullRangeFloats(FloatStrategy):
    parameter = params.CompositeParameter(
        negative_probability=params.UniformFloatParameter(0, 1),
        subnormal_probability=params.UniformFloatParameter(0, 0.5),
    )

    def produce(self, random, pv):
        sign = int(dist.biased_coin(random, pv.negative_probability))
        if dist.biased_coin(random, pv.subnormal_probability):
            exponent = 0
        else:
            exponent = random.getrandbits(11)

        return compose_float(sign, exponent, random.getrandbits(52))

    def could_have_produced(self, value):
        return isinstance(value, float)
Beispiel #16
0
class RandomGeometricIntStrategy(IntStrategy):
    """A strategy that produces integers whose magnitudes are a geometric
    distribution and whose sign is randomized with some probability.

    It will tend to be biased towards mostly negative or mostly
    positive, and the size of the integers tends to be biased towards
    the small.

    """
    parameter = params.CompositeParameter(
        negative_probability=params.BetaFloatParameter(0.5, 0.5),
        p=params.BetaFloatParameter(alpha=0.2, beta=1.8),
    )

    def produce(self, random, parameter):
        value = dist.geometric(random, parameter.p)
        if dist.biased_coin(random, parameter.negative_probability):
            value = -value
        return value
Beispiel #17
0
class JustStrategy(SearchStrategy):
    """
    A strategy which simply returns a single fixed value with probability 1.
    """
    # We could do better here but it's probably not worth it
    # deepcopy has optimisations that will probably work just as well as
    # our check
    has_immutable_data = False

    def __init__(self, value):
        SearchStrategy.__init__(self)
        self.descriptor = descriptors.Just(value)

    def __repr__(self):
        return 'JustStrategy(value=%r)' % (self.descriptor.value, )

    parameter = params.CompositeParameter()

    def produce(self, random, pv):
        return self.descriptor.value

    def could_have_produced(self, value):
        return actually_equal(self.descriptor.value, value)
Beispiel #18
0
class BoundedIntStrategy(SearchStrategy):
    """A strategy for providing integers in some interval with inclusive
    endpoints."""

    descriptor = int
    parameter = params.CompositeParameter()

    def __init__(self, start, end):
        SearchStrategy.__init__(self)
        self.start = start
        self.end = end
        if start > end:
            raise ValueError('Invalid range [%d, %d]' % (start, end))
        self.parameter = params.NonEmptySubset(tuple(range(start, end + 1)),
                                               activation_chance=min(
                                                   0.5,
                                                   3.0 / (end - start + 1)))

    def produce(self, random, parameter):
        if self.start == self.end:
            return self.start
        return random.choice(parameter)

    def simplify(self, x):
        if x == self.start:
            return
        for t in hrange(x - 1, self.start - 1, -1):
            yield t
        mid = (self.start + self.end) // 2
        if x > mid:
            yield self.start + (self.end - x)
            for t in hrange(x + 1, self.end + 1):
                yield t

    def could_have_produced(self, i):
        return isinstance(i, integer_types) and (self.start <= i <= self.end)
Beispiel #19
0
class BrokenFloatStrategy(SearchStrategy):
    descriptor = float
    parameter = params.CompositeParameter()

    def produce(self, random, pv):
        return random.random()
Beispiel #20
0
class FooStrategy(SearchStrategy):
    descriptor = Foo
    parameter = params.CompositeParameter()

    def produce(self, random, pv):
        return Foo()
Beispiel #21
0
class DatetimeStrategy(SearchStrategy):
    descriptor = datetime
    parameter = params.CompositeParameter(
        p_hour=params.UniformFloatParameter(0, 1),
        p_minute=params.UniformFloatParameter(0, 1),
        p_second=params.UniformFloatParameter(0, 1),
        month=params.NonEmptySubset(list(range(1, 13))),
        naive_chance=params.UniformFloatParameter(0, 0.5),
        utc_chance=params.UniformFloatParameter(0, 1),
        timezones=params.NonEmptySubset(
            list(map(pytz.timezone, pytz.all_timezones))))

    def produce(self, random, pv):
        year = random.randint(MINYEAR, MAXYEAR)
        month = random.choice(pv.month)
        base = datetime(
            year=year,
            month=month,
            day=draw_day_for_month(random, year, month),
            hour=maybe_zero_or(random, pv.p_hour, random.randint(0, 23)),
            minute=maybe_zero_or(random, pv.p_minute, random.randint(0, 59)),
            second=maybe_zero_or(random, pv.p_second, random.randint(0, 59)),
            microsecond=random.randint(0, 1000000 - 1),
        )
        if random.random() <= pv.naive_chance:
            return base
        if random.random() <= pv.utc_chance:
            return pytz.UTC.localize(base)
        return random.choice(pv.timezones).localize(base)

    def simplify(self, value):
        if not value.tzinfo:
            yield pytz.UTC.localize(value)
        elif value.tzinfo != pytz.UTC:
            yield pytz.UTC.normalize(value.astimezone(pytz.UTC))
        s = {value}
        s.add(value.replace(microsecond=0))
        s.add(value.replace(second=0))
        s.add(value.replace(minute=0))
        s.add(value.replace(hour=0))
        s.add(value.replace(day=1))
        s.add(value.replace(month=1))
        s.remove(value)
        for t in s:
            yield t
        year = value.year
        if year == 2000:
            return
        yield value.replace(year=2000)
        # We swallow a bunch of value errors here.
        # These can happen if the original value was february 29 on a
        # leap year and the current year is not a leap year.
        # Note that 2000 was a leap year which is why we didn't need one above.
        mid = (year + 2000) // 2
        if mid != 2000 and mid != year:
            try:
                yield value.replace(year=mid)
            except ValueError:
                pass
        years = hrange(year, 2000, -1 if year > 2000 else 1)
        for year in years:
            if year == mid:
                continue
            try:
                yield value.replace(year)
            except ValueError:
                pass
Beispiel #22
0
class AwkwardStrategy(SearchStrategy):
    descriptor = Awkward
    parameter = params.CompositeParameter()

    def produce(self, random, pv):
        return Awkward()