Example #1
0
def make_registrations():
    def make_date(p: Callable) -> datetime.date:
        year, month, day = p(int), p(int), p(int)
        # This condition isn't technically required, but it develops useful
        # symbolic inequalities before the realization below:
        if not (1 <= year <= 9999 and 1 <= month <= 12 and 1 <= day <= 31):
            raise IgnoreAttempt('Invalid date')
        try:
            return datetime.date(realize(year), realize(month), realize(day))
        except ValueError:
            raise IgnoreAttempt('Invalid date')

    register_type(datetime.date, make_date)

    def make_timedelta(p: Callable) -> datetime.timedelta:
        microseconds, seconds, days = p(int), p(int), p(int)
        # the normalized ranges, per the docs:
        if not (0 <= microseconds < 1000000 and 0 <= seconds < 3600 * 24
                and -999999999 <= days <= 999999999):
            raise IgnoreAttempt('Invalid timedelta')
        try:
            return datetime.timedelta(days=realize(days),
                                      seconds=realize(seconds),
                                      microseconds=realize(microseconds))
        except OverflowError:
            raise IgnoreAttempt('Invalid timedelta')

    register_type(datetime.timedelta, make_timedelta)
Example #2
0
def make_registrations():
    # NOTE: defaultdict could be symbolic (but note the default_factory is changable/stateful):
    register_type(collections.defaultdict,
                  lambda p, kt=Any, vt=Any: collections.defaultdict(
                      p(Callable[[], vt]), p(Dict[kt, vt])))  # type: ignore
    register_type(collections.ChainMap,
                  lambda p, kt=Any, vt=Any: collections.ChainMap(*p(Tuple[Dict[
                      kt, vt], ...])))  # type: ignore
    register_type(collections.abc.Mapping,
                  lambda p, kt=Any, vt=Any: p(Dict[kt, vt]))  # type: ignore
    register_type(collections.abc.MutableMapping,
                  lambda p, kt=Any, vt=Any: p(Dict[kt, vt]))  # type: ignore
    register_type(collections.OrderedDict,
                  lambda p, kt=Any, vt=Any: collections.OrderedDict(
                      p(Dict[kt, vt])))  # type: ignore
    register_type(
        collections.Counter,
        lambda p, t=Any: collections.Counter(p(Dict[t, int])))  # type: ignore
    # TODO: MappingView is missing
    register_type(
        collections.abc.ItemsView,
        lambda p, kt=Any, vt=Any: p(Set[Tuple[kt, vt]]))  # type: ignore
    register_type(collections.abc.KeysView,
                  lambda p, t=Any: p(Set[t]))  # type: ignore
    register_type(collections.abc.ValuesView,
                  lambda p, t=Any: p(Set[t]))  # type: ignore

    register_type(collections.abc.Container, lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Collection,
                  lambda p, t=Any: p(Tuple[t, ...]))

    register_type(collections.deque,
                  lambda p, t=Any: collections.deque(p(Tuple[t, ...])))
    # TODO: When ready, use custom deque class instead:
    # register_type(collections.deque, lambda p, t=Any: ListBasedDeque(p(List[t, ...]))) # type: ignore

    register_type(collections.abc.Iterable, lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Iterator,
                  lambda p, t=Any: iter(p(Iterable[t])))  # type: ignore

    register_type(collections.abc.MutableSequence,
                  lambda p, t=Any: p(List[t]))  # type: ignore
    register_type(collections.abc.Reversible,
                  lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Sequence, lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Sized, lambda p, t=Any: p(Tuple[t, ...]))

    register_type(collections.abc.MutableSet,
                  lambda p, t=Any: p(Set[t]))  # type: ignore

    register_type(collections.abc.ByteString,
                  lambda p: bytes(b % 256 for b in p(List[int])))
    register_type(collections.abc.Hashable, lambda p: p(int))
Example #3
0
def make_registrations():

    # WARNING: This is destructive for the datetime module.
    # It disables the C implementation for the entire interpreter.
    sys.modules["_datetime"] = None  # type: ignore
    importlib.reload(datetime)

    # Default pickling will realize the symbolic args; avoid this:
    datetime.date.__deepcopy__ = lambda s, _memo: datetime.date(
        s.year, s.month, s.day)
    datetime.time.__deepcopy__ = lambda s, _memo: datetime.time(
        s.hour, s.minute, s.second, s.microsecond, s.tzinfo)
    datetime.datetime.__deepcopy__ = lambda s, _memo: datetime.datetime(
        s.year, s.month, s.day, s.hour, s.minute, s.second, s.microsecond, s.
        tzinfo)
    datetime.timedelta.__deepcopy__ = lambda d, _memo: _timedelta_skip_construct(
        d.days, d.seconds, d.microseconds)

    # Mokey patch validation so that we can defer it.
    orig_check_date_fields = datetime._check_date_fields
    orig_check_time_fields = datetime._check_time_fields
    datetime._check_date_fields = lambda y, m, d: (y, m, d)
    datetime._check_time_fields = lambda h, m, s, u, f: (h, m, s, u, f)

    # TODO: `timezone` never makes a tzinfo with DST, so this is incomplete.
    # A complete solution would require generating a symbolc dst() member function.
    register_type(datetime.tzinfo, lambda p: p(datetime.timezone))

    # NOTE: these bounds have changed over python versions (e.g. [1]), so we pull the
    # following private constants from the runtime directly.
    # [1] https://github.com/python/cpython/commit/92c7e30adf5c81a54d6e5e555a6bdfaa60157a0d#diff-2a8962dcecb109859cedd81ddc5729bea57d156e0947cb8413f99781a0860fd1R2272
    _max_tz_offset = datetime.timezone._maxoffset
    _min_tz_offset = datetime.timezone._minoffset

    def make_timezone(p: Any) -> datetime.timezone:
        if p.space.smt_fork(desc="use explicit timezone"):
            delta = p(datetime.timedelta, "_offset")
            with ResumedTracing():
                if _min_tz_offset < delta < _max_tz_offset:
                    return datetime.timezone(delta, realize(p(str, "_name")))
                else:
                    raise IgnoreAttempt("Invalid timezone offset")
        else:
            return datetime.timezone.utc

    register_type(datetime.timezone, make_timezone)

    def make_date(p: Any) -> datetime.date:
        year, month, day = p(int, "_year"), p(int, "_month"), p(int, "_day")
        try:
            p.space.defer_assumption(
                "Invalid date",
                lambda: (not _raises_value_error(orig_check_date_fields,
                                                 (year, month, day))),
            )
            return datetime.date(year, month, day)
        except ValueError:
            raise IgnoreAttempt("Invalid date")

    register_type(datetime.date, make_date)

    def make_time(p: Any) -> datetime.time:
        hour = p(int, "_hour")
        minute = p(int, "_minute")
        sec = p(int, "_sec")
        usec = p(int, "_usec")
        tzinfo = p(Optional[datetime.timezone], "_tzinfo")
        try:
            p.space.defer_assumption(
                "Invalid datetime",
                lambda:
                (not _raises_value_error(orig_check_time_fields,
                                         (hour, minute, sec, usec, 0))),
            )
            return datetime.time(hour, minute, sec, usec, tzinfo)
        except ValueError:
            raise IgnoreAttempt("Invalid datetime")

    register_type(datetime.time, make_time)

    def make_datetime(p: Any) -> datetime.datetime:
        year, month, day, hour, minute, sec, usec = (
            p(int, "_year"),
            p(int, "_month"),
            p(int, "_day"),
            p(int, "_hour"),
            p(int, "_minute"),
            p(int, "_sec"),
            p(int, "usec"),
        )
        tzinfo = p(Optional[datetime.timezone], "_tz")
        try:
            p.space.defer_assumption(
                "Invalid datetime",
                lambda:
                (not _raises_value_error(orig_check_date_fields,
                                         (year, month, day)) and
                 not _raises_value_error(orig_check_time_fields,
                                         (hour, minute, sec, usec, 0))),
            )
            return datetime.datetime(year, month, day, hour, minute, sec, usec,
                                     tzinfo)
        except ValueError:
            raise IgnoreAttempt("Invalid datetime")

    register_type(datetime.datetime, make_datetime)

    def make_timedelta(p: Callable) -> datetime.timedelta:
        microseconds, seconds, days = p(int,
                                        "_usec"), p(int,
                                                    "_sec"), p(int, "_days")
        with ResumedTracing():
            # the normalized ranges, per the docs:
            if not (0 <= microseconds < 1000000 and 0 <= seconds < 3600 * 24
                    and -999999999 <= days <= 999999999):
                raise IgnoreAttempt("Invalid timedelta")
            try:
                return _timedelta_skip_construct(days, seconds, microseconds)
            except OverflowError:
                raise IgnoreAttempt("Invalid timedelta")

    register_type(datetime.timedelta, make_timedelta)
Example #4
0
    def __array__(self):
        if any(size < 0 for size in self.shape):
            raise IgnoreAttempt('ndarray disallows negative dimensions')
        concrete_shape = tuple(map(int, self.shape))
        concrete_dtype = realize(self.dtype)
        # For the contents, we just construct it with ones. This makes it much
        # less complete in terms of finding counterexamples, but is sufficient
        # for array dimension and type reasoning. If we were more ambitious,
        # we would rewrite a (slow) implementation of numpy in terms of native
        # Python types.
        return np.ones(concrete_shape, concrete_dtype)


# Make crosshair use our custom class whenever it needs a symbolic
# ndarray instance:
register_type(np.ndarray, SymbolicNdarray)


def matrix_multiply(image1: np.ndarray, image2: np.ndarray) -> np.ndarray:
    '''
    pre: image1.dtype == image2.dtype == np.float64
    pre: len(image1.shape) == len(image2.shape) == 2
    pre: image1.shape[1] == image2.shape[0]
    post: __return__.shape == (image1.shape[0], image2.shape[1])
    '''
    return image1 @ image2


def unit_normalize(a: np.ndarray) -> np.ndarray:
    '''
    >>> unit_normalize(np.arange(-1, 2))
Example #5
0
def make_registrations() -> None:
    register_type(random.Random, lambda p: random.Random(p(int)))
Example #6
0
def make_registrations():
    register_type(collections.defaultdict,
                  lambda p, kt=Any, vt=Any: PureDefaultDict(
                      p(Optional[Callable[[], vt]], "_initalizer"),
                      p(Dict[kt, vt])))  # type: ignore
    register_type(collections.ChainMap,
                  lambda p, kt=Any, vt=Any: collections.ChainMap(*p(Tuple[Dict[
                      kt, vt], ...])))  # type: ignore
    register_type(collections.abc.Mapping,
                  lambda p, kt=Any, vt=Any: p(Dict[kt, vt]))  # type: ignore
    register_type(collections.abc.MutableMapping,
                  lambda p, kt=Any, vt=Any: p(Dict[kt, vt]))  # type: ignore
    register_type(collections.OrderedDict,
                  lambda p, kt=Any, vt=Any: collections.OrderedDict(
                      p(Dict[kt, vt])))  # type: ignore
    register_type(
        collections.Counter,
        lambda p, t=Any: collections.Counter(p(Dict[t, int])))  # type: ignore
    # TODO: MappingView is missing
    register_type(
        collections.abc.ItemsView,
        lambda p, kt=Any, vt=Any: p(Set[Tuple[kt, vt]]))  # type: ignore
    register_type(collections.abc.KeysView,
                  lambda p, t=Any: p(Set[t]))  # type: ignore
    register_type(collections.abc.ValuesView,
                  lambda p, t=Any: p(List[t]))  # type: ignore

    register_type(collections.abc.Container, lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Collection,
                  lambda p, t=Any: p(Tuple[t, ...]))

    register_type(collections.deque,
                  lambda p, t=Any: ListBasedDeque(p(List[t])))  # type: ignore

    register_type(collections.abc.Iterable, lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Iterator,
                  lambda p, t=Any: iter(p(Iterable[t])))  # type: ignore

    register_type(collections.abc.MutableSequence,
                  lambda p, t=Any: p(List[t]))  # type: ignore
    register_type(collections.abc.Reversible,
                  lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Sequence, lambda p, t=Any: p(Tuple[t, ...]))
    register_type(collections.abc.Sized, lambda p, t=Any: p(Tuple[t, ...]))

    register_type(collections.abc.MutableSet,
                  lambda p, t=Any: p(Set[t]))  # type: ignore

    register_type(collections.abc.ByteString, make_byte_string)
    register_type(collections.abc.Hashable, lambda p: p(int))
Example #7
0
def make_registrations():

    # WARNING: This is destructive for the datetime module.
    # It disables the C implementation for the entire interpreter.
    sys.modules['_datetime'] = None  # type: ignore
    importlib.reload(datetime)

    # Default pickling will realize the symbolic args; avoid this:
    datetime.date.__deepcopy__ = lambda s, _memo: datetime.date(
        s.year, s.month, s.day)
    datetime.time.__deepcopy__ = lambda s, _memo: datetime.time(
        s.hour, s.minute, s.second, s.microsecond, s.tzinfo)
    datetime.datetime.__deepcopy__ = lambda s, _memo: datetime.datetime(
        s.year, s.month, s.day, s.hour, s.minute, s.second, s.microsecond, s.
        tzinfo)
    datetime.timedelta.__deepcopy__ = lambda d, _memo: _timedelta_skip_construct(
        d.days, d.seconds, d.microseconds)

    # Mokey patch validation so that we can defer it.
    orig_check_date_fields = datetime._check_date_fields
    orig_check_time_fields = datetime._check_time_fields
    datetime._check_date_fields = lambda y, m, d: (y, m, d)
    datetime._check_time_fields = lambda h, m, s, u, f: (h, m, s, u, f)

    # TODO: `timezone` never makes a tzinfo with DST, so this is incomplete.
    # A complete solution would require generating a symbolc dst() member function.
    register_type(datetime.tzinfo, lambda p: p(datetime.timezone))

    _min_tz_offset, _max_tz_offset = -datetime.timedelta(
        hours=24), datetime.timedelta(hours=24)

    def make_timezone(p: Any) -> datetime.timezone:
        if p.space.smt_fork():
            delta = p(datetime.timedelta)
            if _min_tz_offset < delta < _max_tz_offset:
                return datetime.timezone(delta, p(str))
            else:
                raise IgnoreAttempt('Invalid timezone offset')
        else:
            return datetime.timezone.utc

    register_type(datetime.timezone, make_timezone)

    def make_date(p: Any) -> datetime.date:
        year, month, day = p(int), p(int), p(int)
        try:
            p.space.defer_assumption(
                'Invalid date', lambda:
                (not _raises_value_error(orig_check_date_fields,
                                         (year, month, day))))
            return datetime.date(year, month, day)
        except ValueError:
            raise IgnoreAttempt('Invalid date')

    register_type(datetime.date, make_date)

    def make_time(p: Any) -> datetime.time:
        hour, minute, sec, usec = p(int), p(int), p(int), p(int)
        tzinfo = p(datetime.timezone) if p.space.smt_fork() else None
        try:
            p.space.defer_assumption(
                'Invalid datetime', lambda:
                (not _raises_value_error(orig_check_time_fields,
                                         (hour, minute, sec, usec, 0))))
            return datetime.time(hour, minute, sec, usec, tzinfo)
        except ValueError:
            raise IgnoreAttempt('Invalid datetime')

    register_type(datetime.time, make_time)

    def make_datetime(p: Any) -> datetime.datetime:
        year, month, day, hour, minute, sec, usec = p(int), p(int), p(int), p(
            int), p(int), p(int), p(int)
        tzinfo = p(datetime.tzinfo) if p.space.smt_fork() else None
        try:
            p.space.defer_assumption(
                'Invalid datetime', lambda:
                (not _raises_value_error(orig_check_date_fields,
                                         (year, month, day)) and
                 not _raises_value_error(orig_check_time_fields,
                                         (hour, minute, sec, usec, 0))))
            return datetime.datetime(year, month, day, hour, minute, sec, usec,
                                     tzinfo)
        except ValueError:
            raise IgnoreAttempt('Invalid datetime')

    register_type(datetime.datetime, make_datetime)

    def make_timedelta(p: Callable) -> datetime.timedelta:
        microseconds, seconds, days = p(int), p(int), p(int)
        # the normalized ranges, per the docs:
        if not (0 <= microseconds < 1000000 and 0 <= seconds < 3600 * 24
                and -999999999 <= days <= 999999999):
            raise IgnoreAttempt('Invalid timedelta')
        try:
            return _timedelta_skip_construct(days, seconds, microseconds)
        except OverflowError:
            raise IgnoreAttempt('Invalid timedelta')

    register_type(datetime.timedelta, make_timedelta)