def choose_type(space: StateSpace, from_type: Type) -> Type: subtypes = get_subclass_map()[from_type] # Note that this is written strangely to leverage the default # preference for false when forking: if not subtypes or not space.smt_fork(): return from_type for subtype in subtypes[:-1]: if not space.smt_fork(): return choose_type(space, subtype) return choose_type(space, subtypes[-1])
def proxy_for_type(typ: Type, space: StateSpace, varname: str, meet_class_invariants=True, allow_subtypes=False) -> object: typ = normalize_pytype(typ) origin = origin_of(typ) type_args = type_args_of(typ) # special cases if isinstance(typ, type) and issubclass(typ, enum.Enum): enum_values = list(typ) # type:ignore for enum_value in enum_values[:-1]: if space.smt_fork(): return enum_value return enum_values[-1] proxy_factory = _SIMPLE_PROXIES.get(origin) if proxy_factory: def recursive_proxy_factory(t: Type): return proxy_for_type(t, space, varname + space.uniq(), allow_subtypes=allow_subtypes) recursive_proxy_factory.space = space # type: ignore recursive_proxy_factory.pytype = typ # type: ignore recursive_proxy_factory.varname = varname # type: ignore return proxy_factory(recursive_proxy_factory, *type_args) if allow_subtypes and typ is not object: typ = choose_type(space, typ) return proxy_for_class(typ, space, varname, meet_class_invariants)
def pick_code(space: StateSpace) -> Tuple[str, int, int]: last_idx = len(INT_TYPE_BOUNDS) - 1 for (idx, (code, rng)) in enumerate(INT_TYPE_BOUNDS.items()): if idx < last_idx: if space.smt_fork(desc=f"not_{code}_array"): continue return (code, *rng) assert False, "Not Reachable"