def field_mappings(): global __default_field_mappings if __default_field_mappings is None: # Sized fields are handled in _get_strategy_for_field() # URL fields are not yet handled __default_field_mappings = { dm.SmallIntegerField: st.integers(-32768, 32767), dm.IntegerField: st.integers(-2147483648, 2147483647), dm.BigIntegerField: st.integers(-9223372036854775808, 9223372036854775807), dm.PositiveIntegerField: st.integers(0, 2147483647), dm.PositiveSmallIntegerField: st.integers(0, 32767), dm.BinaryField: st.binary(), dm.BooleanField: st.booleans(), dm.DateField: st.dates(), dm.DateTimeField: st.datetimes(timezones=get_tz_strat()), dm.DurationField: st.timedeltas(), dm.EmailField: emails(), dm.FloatField: st.floats(), dm.NullBooleanField: st.one_of(st.none(), st.booleans()), dm.TimeField: st.times(timezones=get_tz_strat()), dm.UUIDField: st.uuids(), } # SQLite does not support timezone-aware times, or timedeltas that # don't fit in six bytes of microseconds, so we override those db = getattr(django_settings, 'DATABASES', {}).get('default', {}) if db.get('ENGINE', '').endswith('.sqlite3'): # pragma: no branch sqlite_delta = timedelta(microseconds=2**47 - 1) __default_field_mappings.update({ dm.TimeField: st.times(), dm.DurationField: st.timedeltas(-sqlite_delta, sqlite_delta), }) return __default_field_mappings
def rfc3339(name: str) -> st.SearchStrategy[str]: """Given the name of an RFC3339 date or time format, return a strategy for conforming values. See https://tools.ietf.org/html/rfc3339#section-5.6 """ # Hmm, https://github.com/HypothesisWorks/hypothesis/issues/170 # would make this a lot easier... assert name in RFC3339_FORMATS simple = { "date-fullyear": st.integers(0, 9999).map(str), "date-month": st.integers(1, 12).map(str), "date-mday": st.integers(1, 28).map(str), # incomplete but valid "time-hour": st.integers(0, 23).map(str), "time-minute": st.integers(0, 59).map(str), "time-second": st.integers(0, 59).map(str), # ignore negative leap seconds "time-secfrac": st.from_regex(r"\.[0-9]+"), } if name in simple: return simple[name] if name == "time-numoffset": return st.tuples(st.sampled_from(["+", "-"]), rfc3339("time-hour"), rfc3339("time-minute")).map(":".join) if name == "time-offset": return st.one_of(st.just("Z"), rfc3339("time-numoffset")) if name == "partial-time": return st.times().map(str) if name == "full-date": return st.dates().map(str) if name == "full-time": return st.tuples(rfc3339("partial-time"), rfc3339("time-offset")).map("".join) assert name == "date-time" return st.tuples(rfc3339("full-date"), rfc3339("full-time")).map("T".join)
class TestCompileGeneral(TestCase): @given( literals | st.dates() | st.datetimes() | st.decimals(allow_nan=False) | st.fractions() | st.timedeltas() | st.times() | st.uuids() ) def test_compile_pickle(self, form): self.assertEqual(form, eval(compiler.Compiler().pickle(form))) @given(literals) def test_compile_literal(self, form): self.assertEqual(form, eval(compiler.Compiler().quoted(form))) @given( st.characters( blacklist_characters='(){}[];".', whitelist_categories=["Lu", "Ll", "Lt", "Nl", "Sm"], ) ) def test_un_x_quote(self, char): x = munger.x_quote(char) self.assertTrue(("x" + x).isidentifier()) match = re.fullmatch("x(.*?)_", x) if match: self.assertEqual(char, munger.un_x_quote(match))
def random_base_type(draw, ignore: list = []): ignore = tuple(ignore) return draw( one_of( none(), builds(set), text(), dates(), builds(list), times(), uuids(), binary(), floats(), tuples(), booleans(), decimals(), integers(), datetimes(), fractions(), iterables(nothing()), characters(), builds(frozenset), timedeltas(), complex_numbers(), ).filter(lambda x: not isinstance(x, ignore)))
def arrays(draw, type, size=None): if isinstance(type, st.SearchStrategy): type = draw(type) elif not isinstance(type, pa.DataType): raise TypeError('Type must be a pyarrow DataType') if isinstance(size, st.SearchStrategy): size = draw(size) elif size is None: size = draw(_default_array_sizes) elif not isinstance(size, int): raise TypeError('Size must be an integer') shape = (size, ) if pa.types.is_list(type): offsets = draw(npst.arrays(np.uint8(), shape=shape)).cumsum() // 20 offsets = np.insert(offsets, 0, 0, axis=0) # prepend with zero values = draw(arrays(type.value_type, size=int(offsets.sum()))) return pa.ListArray.from_arrays(offsets, values) if pa.types.is_struct(type): h.assume(len(type) > 0) names, child_arrays = [], [] for field in type: names.append(field.name) child_arrays.append(draw(arrays(field.type, size=size))) # fields' metadata are lost here, because from_arrays doesn't accept # a fields argumentum, only names return pa.StructArray.from_arrays(child_arrays, names=names) if (pa.types.is_boolean(type) or pa.types.is_integer(type) or pa.types.is_floating(type)): values = npst.arrays(type.to_pandas_dtype(), shape=(size, )) return pa.array(draw(values), type=type) if pa.types.is_null(type): value = st.none() elif pa.types.is_time(type): value = st.times() elif pa.types.is_date(type): value = st.dates() elif pa.types.is_timestamp(type): tz = pytz.timezone(type.tz) if type.tz is not None else None value = st.datetimes(timezones=st.just(tz)) elif pa.types.is_binary(type): value = st.binary() elif pa.types.is_string(type): value = st.text() elif pa.types.is_decimal(type): # TODO(kszucs): properly limit the precision # value = st.decimals(places=type.scale, allow_infinity=False) h.reject() else: raise NotImplementedError(type) values = st.lists(value, min_size=size, max_size=size) return pa.array(draw(values), type=type)
def draw_data_dict(draw): sample_dict = draw(sample) for key in sample_dict.keys(): if sample_dict[key]['attributes']['Type'] == 'Time': value = draw( st.lists(st.times().map(lambda time: time.strftime("%H:%M:%S")) | st.just(''), min_size=1)) sample_dict[key]['input_data'] = value return sample_dict
def times(allow_naive=None, timezones=None): """Return a strategy for generating times. .. deprecated:: 3.9.0 use :py:func:`hypothesis.strategies.times` instead. The allow_naive and timezones arguments act the same as the datetimes strategy above. """ note_deprecation('Use hypothesis.strategies.times, which supports ' 'min_time and max_time arguments.') return st.times(timezones=tz_args_strat(allow_naive, timezones, 'times'))
def primitives(): return ( st.integers() | st.floats(allow_nan=False) | st.text() | st.binary() | st.datetimes(timezones=timezones() | st.none()) | st.dates() | st.times(timezones=timezones() | st.none()) | st.timedeltas() | st.booleans() | st.none() )
class TestCompileGeneral(TestCase): @given(literals | st.dates() | st.datetimes() | st.decimals(allow_nan=False) | st.fractions() | st.timedeltas() | st.times() | st.uuids()) def test_compile_pickle(self, form): self.assertEqual(form, eval(compiler.Compiler().pickle(form))) @given(literals) def test_compile_literal(self, form): self.assertEqual(form, eval(compiler.Compiler().atom(form))) def test_maybe_macro_error(self): with self.assertRaises(compiler.CompileError): compiler.readerless(('hissp.basic.._macro_.foobar', )) def test_post_compile_warn(self): c = compiler.Compiler('oops') with self.assertWarns(compiler.PostCompileWarning): python = c.compile([ ( 'operator..truediv', 0, 0, ), ( 'print', ( 'quote', 'oops', ), ), ]) self.assertIn( """\ __import__('operator').truediv( (0), (0)) # Traceback (most recent call last):""", python) self.assertIn( """\ # ZeroDivisionError: division by zero # print( 'oops')""", python)
def field_mappings(): global __default_field_mappings if __default_field_mappings is None: # Sized fields are handled in _get_strategy_for_field() # URL fields are not yet handled __default_field_mappings = { dm.SmallIntegerField: st.integers(-32768, 32767), dm.IntegerField: st.integers(-2147483648, 2147483647), dm.BigIntegerField: st.integers(-9223372036854775808, 9223372036854775807), dm.PositiveIntegerField: st.integers(0, 2147483647), dm.PositiveSmallIntegerField: st.integers(0, 32767), dm.BinaryField: st.binary(), dm.BooleanField: st.booleans(), dm.DateField: st.dates(), dm.DateTimeField: st.datetimes(timezones=get_tz_strat()), dm.DurationField: st.timedeltas(), dm.EmailField: emails(), dm.FloatField: st.floats(), dm.NullBooleanField: st.one_of(st.none(), st.booleans()), dm.TimeField: st.times(timezones=get_tz_strat()), dm.UUIDField: st.uuids(), } # SQLite does not support timezone-aware times, or timedeltas that # don't fit in six bytes of microseconds, so we override those db = getattr(django_settings, 'DATABASES', {}).get('default', {}) if db.get('ENGINE', '').endswith('.sqlite3'): # pragma: no branch sqlite_delta = timedelta(microseconds=2 ** 47 - 1) __default_field_mappings.update({ dm.TimeField: st.times(), dm.DurationField: st.timedeltas(-sqlite_delta, sqlite_delta), }) return __default_field_mappings
def generate_session_data() -> Dict[str, Any]: """Factory method for generating mocked session data.""" return st.dictionaries( st.text(ascii_letters, min_size=5, max_size=20), st.recursive( st.floats() | st.integers() | st.text(printable) | st.booleans() | st.nothing() | st.timedeltas() | st.times() | st.uuids(), st.lists, ), min_size=5, max_size=10, ).example()
def rfc3339(name: str) -> st.SearchStrategy[str]: """Get a strategy for date or time strings in the given RFC3339 format. See https://tools.ietf.org/html/rfc3339#section-5.6 """ # Hmm, https://github.com/HypothesisWorks/hypothesis/issues/170 # would make this a lot easier... assert name in RFC3339_FORMATS def zfill(width: int) -> Callable[[int], str]: return lambda v: str(v).zfill(width) simple = { "date-fullyear": st.integers(0, 9999).map(zfill(4)), "date-month": st.integers(1, 12).map(zfill(2)), "date-mday": st.integers(1, 28).map(zfill(2)), # incomplete but valid "time-hour": st.integers(0, 23).map(zfill(2)), "time-minute": st.integers(0, 59).map(zfill(2)), "time-second": st.integers(0, 59).map(zfill(2)), # ignore negative leap seconds "time-secfrac": st.from_regex(r"\.[0-9]+"), } if name in simple: return simple[name] if name == "time-numoffset": return st.tuples(st.sampled_from(["+", "-"]), rfc3339("time-hour"), rfc3339("time-minute")).map("%s%s:%s".__mod__) if name == "time-offset": return st.one_of(st.just("Z"), rfc3339("time-numoffset")) if name == "partial-time": return st.times().map(str) if name == "full-date": return st.dates().map(str) if name == "full-time": return st.tuples(rfc3339("partial-time"), rfc3339("time-offset")).map("".join) assert name == "date-time" return st.tuples(rfc3339("full-date"), rfc3339("full-time")).map("T".join)
@given(sampled_from(['min_value', 'max_value']), datetimes(timezones=timezones())) def test_datetime_bounds_must_be_naive(name, val): with pytest.raises(InvalidArgument): datetimes(**{name: val}).validate() def test_timezones_arg_to_datetimes_must_be_search_strategy(): all_timezones = zoneinfo.get_zonefile_instance().zones with pytest.raises(InvalidArgument): datetimes(timezones=all_timezones).validate() @given(times(timezones=timezones())) def test_timezone_aware_times_are_timezone_aware(dt): assert dt.tzinfo is not None def test_can_generate_non_utc(): times(timezones=timezones()).filter( lambda d: assume(d.tzinfo) and d.tzinfo.zone != u'UTC' ).validate() @given(sampled_from(['min_value', 'max_value']), times(timezones=timezones())) def test_time_bounds_must_be_naive(name, val): with pytest.raises(InvalidArgument): times(**{name: val}).validate()
def test_simplifies_towards_midnight(): d = minimal(times()) assert d.hour == d.minute == d.second == d.microsecond == 0
def test_can_find_non_midnight(): assert minimal(times(), lambda x: x.hour != 0).hour == 1
def test_can_find_non_midnight(): assert minimal(times(), lambda x: x.hour != 0).hour == 1 def test_can_find_on_the_minute(): find_any(times(), lambda x: x.second == 0) def test_can_find_off_the_minute(): find_any(times(), lambda x: x.second != 0) def test_simplifies_towards_midnight(): d = minimal(times()) assert d.hour == d.minute == d.second == d.microsecond == 0 def test_can_generate_naive_time(): find_any(times(), lambda d: not d.tzinfo) @given(times()) def test_naive_times_are_naive(dt): assert dt.tzinfo is None @checks_deprecated_behaviour def test_deprecated_min_date_is_respected(): assert minimal(dates(min_date=dt.date.min.replace(2003))).year == 2003
((0, 0, 0, 0, None), {}), ((1, 12, 14, 124731), {}), ((1, 12, 14, 124731), { "tzinfo": UTC }), ], ) def test_time(args, kwargs): act = rdt.make_time(*args, **kwargs) exp = pdt.time(*args, **kwargs) assert act == exp assert act.tzinfo is exp.tzinfo @given(t=st.times()) def test_time(t): act = rdt.get_time_tuple(t) exp = (t.hour, t.minute, t.second, t.microsecond) assert act == exp @pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6") @given(t=st.times()) def test_time_fold(t): t_nofold = t.replace(fold=0) t_fold = t.replace(fold=1) for t in (t_nofold, t_fold): act = rdt.get_time_tuple_fold(t)
def _for_model_time(field): # SQLITE supports TZ-aware datetimes, but not TZ-aware times. if getattr(django.conf.settings, "USE_TZ", False) and not using_sqlite(): return st.times(timezones=timezones()) return st.times()
def test_can_generate_non_utc(): times(timezones=timezones()).filter( lambda d: assume(d.tzinfo) and d.tzinfo.zone != "UTC").validate()
def _for_form_time(field): if getattr(django.conf.settings, "USE_TZ", False): return st.times(timezones=timezones()) return st.times()
def test_can_find_off_the_minute(): find_any(times(), lambda x: x.second != 0)
def test_can_generate_non_utc(): times(timezones=timezones()).filter( lambda d: assume(d.tzinfo) and d.tzinfo.zone != u'UTC' ).validate()
def test_can_generate_naive_time(): find_any(times(), lambda d: not d.tzinfo)
def arrays(draw, type, size=None): if isinstance(type, st.SearchStrategy): type = draw(type) elif not isinstance(type, pa.DataType): raise TypeError('Type must be a pyarrow DataType') if isinstance(size, st.SearchStrategy): size = draw(size) elif size is None: size = draw(_default_array_sizes) elif not isinstance(size, int): raise TypeError('Size must be an integer') shape = (size,) if pa.types.is_list(type): offsets = draw(npst.arrays(np.uint8(), shape=shape)).cumsum() // 20 offsets = np.insert(offsets, 0, 0, axis=0) # prepend with zero values = draw(arrays(type.value_type, size=int(offsets.sum()))) return pa.ListArray.from_arrays(offsets, values) if pa.types.is_struct(type): h.assume(len(type) > 0) names, child_arrays = [], [] for field in type: names.append(field.name) child_arrays.append(draw(arrays(field.type, size=size))) # fields' metadata are lost here, because from_arrays doesn't accept # a fields argumentum, only names return pa.StructArray.from_arrays(child_arrays, names=names) if (pa.types.is_boolean(type) or pa.types.is_integer(type) or pa.types.is_floating(type)): values = npst.arrays(type.to_pandas_dtype(), shape=(size,)) np_arr = draw(values) if pa.types.is_floating(type): # Workaround ARROW-4952: no easy way to assert array equality # in a NaN-tolerant way. np_arr[np.isnan(np_arr)] = -42.0 return pa.array(np_arr, type=type) if pa.types.is_null(type): value = st.none() elif pa.types.is_time(type): value = st.times() elif pa.types.is_date(type): value = st.dates() elif pa.types.is_timestamp(type): tz = pytz.timezone(type.tz) if type.tz is not None else None value = st.datetimes(timezones=st.just(tz)) elif pa.types.is_binary(type): value = st.binary() elif pa.types.is_string(type): value = st.text() elif pa.types.is_decimal(type): # TODO(kszucs): properly limit the precision # value = st.decimals(places=type.scale, allow_infinity=False) h.reject() else: raise NotImplementedError(type) values = st.lists(value, min_size=size, max_size=size) return pa.array(draw(values), type=type)
def test_time_bounds_must_be_naive(name, val): with pytest.raises(InvalidArgument): times(**{name: val}).validate()
def roundtrip(value): return json.loads(json.dumps(value, cls=KitchenSinkEncoder)) def default_assert(value): with pytest.raises(TypeError): json.dumps(value) assert value.isoformat() == roundtrip(value) # apply decorator multiple times to create different tests # pylint: disable=invalid-name test_default_dates = given(s.dates())(default_assert) test_default_datetimes = given(s.datetimes())(default_assert) test_default_times = given(s.times())(default_assert) def test_default_obj_has__serialize_method(): value = {"a": "b"} class Serializable: @staticmethod def _serialize(): return value assert value == roundtrip(Serializable()) def test_default_unsupported_type_goes_to_base_class(): class Unserializable:
_global_type_lookup = { # Types with core Hypothesis strategies type(None): st.none(), bool: st.booleans(), int: st.integers(), float: st.floats(), complex: st.complex_numbers(), fractions.Fraction: st.fractions(), decimal.Decimal: st.decimals(), text_type: st.text(), bytes: st.binary(), datetime.datetime: st.datetimes(), datetime.date: st.dates(), datetime.time: st.times(), datetime.timedelta: st.timedeltas(), uuid.UUID: st.uuids(), tuple: st.builds(tuple), list: st.builds(list), set: st.builds(set), frozenset: st.builds(frozenset), dict: st.builds(dict), # Built-in types type: st.sampled_from([type(None), bool, int, str, list, set, dict]), type(Ellipsis): st.just(Ellipsis), type(NotImplemented): st.just(NotImplemented), bytearray: st.binary().map(bytearray), memoryview: st.binary().map(memoryview), # Pull requests with more types welcome! }
datetimes( min_value=dt.datetime.max - dt.timedelta(days=3), timezones=timezones() ), lambda x: x.tzinfo != pytz.UTC, ) def test_timezones_arg_to_datetimes_must_be_search_strategy(): with pytest.raises(InvalidArgument): datetimes(timezones=pytz.all_timezones).validate() with pytest.raises(InvalidArgument): tz = [pytz.timezone(t) for t in pytz.all_timezones] datetimes(timezones=tz).validate() @given(times(timezones=timezones())) def test_timezone_aware_times_are_timezone_aware(dt): assert dt.tzinfo is not None def test_can_generate_non_utc(): times(timezones=timezones()).filter( lambda d: assume(d.tzinfo) and d.tzinfo.zone != u"UTC" ).validate() @given(sampled_from(["min_value", "max_value"]), times(timezones=timezones())) def test_time_bounds_must_be_naive(name, val): with pytest.raises(InvalidArgument): times(**{name: val}).validate()
def test_can_find_midnight(): find_any(times(), lambda x: x.hour == x.minute == x.second == 0)
def test_can_find_midnight(): find_any(times(), lambda x: x.hour == x.minute == x.second == 0) def test_can_find_non_midnight(): assert minimal(times(), lambda x: x.hour != 0).hour == 1 def test_can_find_on_the_minute(): find_any(times(), lambda x: x.second == 0) def test_can_find_off_the_minute(): find_any(times(), lambda x: x.second != 0) def test_simplifies_towards_midnight(): d = minimal(times()) assert d.hour == d.minute == d.second == d.microsecond == 0 def test_can_generate_naive_time(): find_any(times(), lambda d: not d.tzinfo) @given(times()) def test_naive_times_are_naive(dt): assert dt.tzinfo is None
"""Create lists drawn from only one of the types generated by the argument strategy. """ v = draw(types) if isinstance(v, list) and len(v) > 0: es = s.lists(s.from_type(type(v[0]))) else: es = s.from_type(type(v)) vl = draw(s.lists(es)) return vl toml_vals = s.recursive( s.text() | s.integers() | s.floats() | s.booleans() | s.datetimes(timezones=s.none() | timezones()) | s.dates() | s.times(), lambda leaves: (single_type_lists(leaves) | s.dictionaries(s.text(), leaves))) # Top-level TOML element must be a dict toml_data = s.dictionaries(s.text(), toml_vals) @given(toml_data) def test_circular_encode(data): assert patch_floats(qtoml.loads(qtoml.dumps(data))) == patch_floats(data) @given(s.text()) def test_string_encode(data): obj = {'key': data} assert qtoml.loads(qtoml.dumps(obj)) == obj
minimal( datetimes(min_value=dt.datetime.max - dt.timedelta(days=3), timezones=timezones()), lambda x: x.tzinfo != pytz.UTC, ) def test_timezones_arg_to_datetimes_must_be_search_strategy(): with pytest.raises(InvalidArgument): datetimes(timezones=pytz.all_timezones).validate() with pytest.raises(InvalidArgument): tz = [pytz.timezone(t) for t in pytz.all_timezones] datetimes(timezones=tz).validate() @given(times(timezones=timezones())) def test_timezone_aware_times_are_timezone_aware(dt): assert dt.tzinfo is not None def test_can_generate_non_utc(): times(timezones=timezones()).filter( lambda d: assume(d.tzinfo) and d.tzinfo.zone != "UTC").validate() @given(sampled_from(["min_value", "max_value"]), times(timezones=timezones())) def test_time_bounds_must_be_naive(name, val): with pytest.raises(InvalidArgument): times(**{name: val}).validate()
def test_can_generate_non_naive_time(): assert minimal(times(timezones=timezones()), lambda d: d.tzinfo).tzinfo == tz.UTC
def test_can_generate_non_naive_time(): assert minimal(times(timezones=timezones()), lambda d: d.tzinfo).tzinfo == pytz.UTC
# v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at http://mozilla.org/MPL/2.0/. # # END HEADER from __future__ import division, print_function, absolute_import import pytest import hypothesis.strategies as st from hypothesis import given, reject, example from hypothesis.errors import InvalidArgument base_reusable_strategies = ( st.text(), st.binary(), st.dates(), st.times(), st.timedeltas(), st.booleans(), st.complex_numbers(), st.floats(), st.floats(-1.0, 1.0), st.integers(), st.integers(1, 10), st.integers(1), ) @st.deferred def reusable(): return st.one_of( st.sampled_from(base_reusable_strategies), st.builds( st.floats, min_value=st.none() | st.floats(), max_value=st.none() | st.floats(), allow_infinity=st.booleans(), allow_nan=st.booleans() ),
# # END HEADER from __future__ import division, print_function, absolute_import import pytest import hypothesis.strategies as st from hypothesis import given, reject, example from hypothesis.errors import InvalidArgument base_reusable_strategies = ( st.text(), st.binary(), st.dates(), st.times(), st.timedeltas(), st.booleans(), st.complex_numbers(), st.floats(), st.floats(-1.0, 1.0), st.integers(), st.integers(1, 10), st.integers(1), ) @st.deferred def reusable(): return st.one_of( st.sampled_from(base_reusable_strategies),
def test_too_many_posargs_fails(): with pytest.raises(TypeError): st.times(time.min, time.max, st.none(), st.none()).validate()
_global_type_lookup = { # Types with core Hypothesis strategies type(None): st.none(), bool: st.booleans(), int: st.integers(), float: st.floats(), complex: st.complex_numbers(), fractions.Fraction: st.fractions(), decimal.Decimal: st.decimals(), text_type: st.text(), binary_type: st.binary(), datetime.datetime: st.datetimes(), datetime.date: st.dates(), datetime.time: st.times(), datetime.timedelta: st.timedeltas(), uuid.UUID: st.uuids(), tuple: st.builds(tuple), list: st.builds(list), set: st.builds(set), frozenset: st.builds(frozenset), dict: st.builds(dict), type(lambda: None): st.functions(), # Built-in types type(Ellipsis): st.just(Ellipsis), type(NotImplemented): st.just(NotImplemented), bytearray: st.binary().map(bytearray), memoryview: st.binary().map(memoryview), numbers.Real: st.floats(), numbers.Rational: st.fractions(),
def test_overlapping_posarg_kwarg_fails(): with pytest.raises(TypeError): st.times(time.min, time.max, st.none(), timezones=st.just(None)).validate()