def test_instance_of_callable(self): def func1(x: int, y: str) -> object: pass def func2() -> int: pass def func3(x: int): pass def func4(): pass def func5(x): pass def func6(l: List[List[List[int]]]): pass self.assertTrue(instance_of(func1, Callable[[int, str], object])) self.assertTrue(instance_of(func1, Callable[[object, str], object])) self.assertTrue(not instance_of(func1, Callable[[str, str], object])) self.assertTrue(not instance_of(func1, Callable[[str, str], int])) self.assertTrue(instance_of(func2, Callable[[], int])) self.assertTrue(instance_of(func3, Callable[[int], Any])) self.assertTrue(instance_of(func4, Callable)) self.assertTrue(instance_of(func5, Callable[[Any], Any])) self.assertTrue( instance_of(func6, Callable[[List[List[List[int]]]], Any]))
def test_instance_of_nptyping_ndarray(self): local_state = State() register_get_type(numpy.ndarray, nptyping.NDArray.type_of, local_state) arr = numpy.array([1, 2, 3]) arr_type = nptyping.NDArray[(3, ), int] self.assertTrue(instance_of(arr, arr_type, state=local_state)) self.assertTrue(instance_of([arr], List[arr_type], state=local_state)) self.assertTrue( instance_of([arr], List[nptyping.NDArray], state=local_state)) self.assertTrue(not instance_of( [arr], List[nptyping.NDArray[(4, ), float]], state=local_state))
def test_instance_of_literal(self): self.assertTrue(instance_of(42, Literal[42])) self.assertTrue(instance_of(42, Literal[42], int)) self.assertTrue(not instance_of(43, Literal[42])) self.assertTrue(not instance_of(42, Literal[42], str)) self.assertTrue(not instance_of(42, Literal)) self.assertTrue(instance_of(Any, Literal[Any])) self.assertTrue(not instance_of(42, Literal[Any])) self.assertTrue(not instance_of(42, Literal)) self.assertTrue(instance_of(2, Literal[1, 2]))
def test_get_type_union(self): union_type = get_type(Union[int, str]) # The following line should not raise. Union[(union_type, )] self.assertTrue(instance_of(Union[int, str], union_type))
def _get_modules_from_source(source: Union[Path, str, Module, Iterable[Module]], in_private_modules: bool = False, raise_on_fail: bool = False) -> Iterable[Module]: """ Get an iterable of Modules from the given source. Args: source: anything that can be turned into an iterable of Modules. in_private_modules: if True, private modules are explored as well. raise_on_fail: if True, raises an ImportError upon the first import failure. Returns: an iterable of Module instances. """ if isinstance(source, Path): modules = discover_modules(source, in_private_modules, raise_on_fail) elif isinstance(source, str): modules = discover_modules(Path(source), in_private_modules, raise_on_fail) elif isinstance(source, Module): modules = [source] elif instance_of(source, Iterable[Module]): modules = source # type: ignore else: raise ValueError('The given source must be a Path, string or module. ' 'Given: {}'.format(source)) return modules
def _discover_attributes_in_lines(lines: List[str], module: Module, signature: type, include_privates: bool) -> List[Attribute]: """ Discover any attributes within the lines of codee and according to the given constraints. Args: lines: the lines of code in which is searched for any attributes. module: the module from which these lines originate. signature: only attributes that are subtypes of this signature are included. include_privates: if True, private attributes are included as well. Returns: a list of all discovered attributes. """ attributes = [] for index, line in enumerate(lines): match = _match_attribute(line) if match: name, hint, value, comment = match docstring = _find_attribute_docstring(lines[0:index]) attribute = _create_attribute(name, hint, value, docstring, comment, module, line, index + 1) if (instance_of(attribute.value, signature) and (attribute.is_public or include_privates)): attributes.append(attribute) return attributes
def __init__( self, tags: Tuple[str, ...], args: Tuple[Edge, ...], kind: ConstraintKind, param: Any = None, ): # validate based on the solver provided spec if kind not in ConstraintInvariants: raise ValueError(f"Unknown constraint {kind}.") arity, types, param_type, converter = ConstraintInvariants[kind] if arity != len(tags): raise ValueError( f"Invalid number of entities for constraint {kind}. Provided {len(tags)}, required {arity}." ) if any(e.geomType() not in types for e in args): raise ValueError( f"Unsupported geometry types {[e.geomType() for e in args]} for constraint {kind}." ) if not instance_of(param, param_type): raise ValueError( f"Unsupported argument types {get_type(param)}, required {param_type}." ) # if all is fine store everything and possibly convert the params self.tags = tags self.args = args self.kind = kind self.param = tcast(Any, converter)(param) if converter else param
def constrain(self, *args, param=None): """ Define a new constraint. """ # dispatch on arguments if len(args) == 2: q1, kind = args id1, s1 = self._query(q1) elif len(args) == 3 and instance_of(args[1], UnaryConstraintKind): q1, kind, param = args id1, s1 = self._query(q1) elif len(args) == 3: q1, q2, kind = args id1, s1 = self._query(q1) id2, s2 = self._query(q2) elif len(args) == 4: q1, q2, kind, param = args id1, s1 = self._query(q1) id2, s2 = self._query(q2) elif len(args) == 5: id1, s1, id2, s2, kind = args elif len(args) == 6: id1, s1, id2, s2, kind, param = args else: raise ValueError(f"Incompatible arguments: {args}") # handle unary and binary constraints if instance_of(kind, UnaryConstraintKind): loc1, id1_top = self._subloc(id1) c = Constraint((id1_top, ), (s1, ), (loc1, ), kind, param) elif instance_of(kind, BinaryConstraintKind): loc1, id1_top = self._subloc(id1) loc2, id2_top = self._subloc(id2) c = Constraint((id1_top, id2_top), (s1, s2), (loc1, loc2), kind, param) else: raise ValueError(f"Unknown constraint: {kind}") self.constraints.append(c) return self
def test_instance_of_union(self): self.assertTrue(instance_of(F(), Union[int, A])) self.assertTrue(instance_of(F(), Union[A, int])) self.assertTrue(instance_of(F(), Union[A, str])) self.assertTrue(instance_of(F(), Optional[str])) self.assertTrue(instance_of(None, Optional[str])) self.assertTrue(instance_of(Any, Union[int, Literal[Any]]))
def test_instance_of_typing_literal(self): # This is to mock Python 3.8 Literal. class LiteralMockMeta(type): __name__ = 'Literal' def __instancecheck__(self, instance): raise Exception( 'typing.Literal does not allow instance checks.') class LiteralMock(metaclass=LiteralMockMeta): __args__ = (42, ) self.assertTrue(instance_of(42, LiteralMock))
def __init__( self, objects: Tuple[str, ...], args: Tuple[Shape, ...], sublocs: Tuple[Location, ...], kind: ConstraintKind, param: Any = None, ): """ Construct a constraint. :param objects: object names referenced in the constraint :param args: subshapes (e.g. faces or edges) of the objects :param sublocs: locations of the objects (only relevant if the objects are nested in a sub-assembly) :param kind: constraint kind :param param: optional arbitrary parameter passed to the solver """ # validate if not instance_of(kind, ConstraintKind): raise ValueError(f"Unknown constraint {kind}.") if kind in CompoundConstraints: kinds, convert_compound = CompoundConstraints[kind] for k, p in zip(kinds, convert_compound(param)): self._validate(args, k, p) else: self._validate(args, kind, param) # convert here for simple constraints convert = ConstraintInvariants[kind][-1] param = convert(param) if convert else param # store self.objects = objects self.args = args self.sublocs = sublocs self.kind = kind self.param = param
def _validate(self, args: Tuple[Shape, ...], kind: ConstraintKind, param: Any): arity, marker_types, param_type, converter = ConstraintInvariants[kind] # check arity if arity != len(args): raise ValueError( f"Invalid number of entities for constraint {kind}. Provided {len(args)}, required {arity}." ) # check arguments arg_check: Dict[Any, Callable[[Shape], Any]] = { gp_Pnt: self._getPnt, gp_Dir: self._getAxis, gp_Pln: self._getPln, gp_Lin: self._getLin, None: lambda x: True, # dummy check for None marker } for a, t in zip(args, tcast(Tuple[Type[ConstraintMarker], ...], marker_types)): try: arg_check[t](a) except ValueError: raise ValueError(f"Unsupported entity {a} for constraint {kind}.") # check parameter if not instance_of(param, param_type) and param is not None: raise ValueError( f"Unsupported argument types {get_type(param)}, required {param_type}." ) # check parameter conversion try: if param is not None and converter: converter(param) except Exception as e: raise ValueError(f"Exception {e} occured in the parameter conversion")
def discover_functions( source: Union[Path, str, Module, Iterable[Module], type], signature: Type[Callable] = Callable, # type: ignore include_privates: bool = False, in_private_modules: bool = False, raise_on_fail: bool = False) -> List[type]: """ Discover any functions within the given source and according to the given constraints. Args: source: the source in which is searched for any functions. signature: only functions that have this signature (parameters and return type) are included. include_privates: if True, private functions are included as well. in_private_modules: if True, private modules are explored as well. raise_on_fail: if True, raises an ImportError upon the first import failure. Returns: a list of all discovered functions. """ def filter_(*args_: Iterable[Any]) -> bool: return (isfunction(*args_) or ismethod(*args_)) if not isinstance(source, type): filter_ = isfunction # type: ignore elements = _discover_elements(source, filter_, include_privates, in_private_modules, raise_on_fail) result = [ elem for elem in elements if (signature is Callable or instance_of(elem, signature)) ] result.sort(key=lambda func: func.__name__) return result
def test_instance_of_list_with_union(self): self.assertTrue(instance_of([1, '2', 3], List[Union[int, str]])) self.assertTrue(not instance_of([1, '2', 3], List[Union[int, float]]))
def test_instance_of_tuple(self): self.assertTrue(instance_of((1, ), Tuple[int])) self.assertTrue(instance_of((1, 2, 3), Tuple[int, ...]))
def test_instance_of_type(self): self.assertTrue(instance_of(int, Type)) self.assertTrue(instance_of(int, Type[int])) self.assertTrue(not instance_of(str, Type[int]))
def test_lambda_instance_of_callable(self): self.assertTrue(instance_of(lambda x, y: 42, Callable[[int, str], str])) self.assertTrue(instance_of(lambda: 42, Callable[[], str]))
def test_instance_of_py39_types(self): self.assertTrue(instance_of({'42': 42}, Dict[str, int])) self.assertTrue(not instance_of({'42': 42}, Dict[str, str])) self.assertTrue(not instance_of({42: 42}, Dict[str, int])) self.assertTrue(instance_of([1, 2, 3], list[int])) self.assertTrue(not instance_of([1, 2, 3], list[str]))
def test_instance_of(self): self.assertTrue(instance_of([[[1], [2]]], List[List[List[int]]])) self.assertTrue(instance_of([[[1], ['2']]], List[List[List[object]]])) self.assertTrue(instance_of([], List[int])) self.assertTrue(instance_of({}, Dict[int, int]))
def test_instance_of_multiple(self): self.assertTrue(instance_of(F(), A)) self.assertTrue(instance_of(F(), str)) self.assertTrue(instance_of(F(), A, str)) self.assertTrue(not instance_of(F(), A, str, int))
def test_instance_of_nptyping_ndarray(self): arr = numpy.array([1, 2, 3]) arr_type = nptyping.NDArray[(3, ), int] self.assertTrue(instance_of(arr, arr_type))
def test_instance_of_numpy(self): self.assertTrue(instance_of(numpy.array([1, 2, 3]), numpy.ndarray))
def solve(self) -> "Assembly": """ Solve the constraints. """ # Get all entities and number them. First entity is marked as locked ents = {} i = 0 locked = [] for c in self.constraints: for name in c.objects: if name not in ents: ents[name] = i i += 1 if c.kind == "Fixed" or name == self.name: locked.append(ents[name]) # Lock the first occuring entity if needed. if not locked: unary_objects = [ c.objects[0] for c in self.constraints if instance_of(c.kind, UnaryConstraintKind) ] binary_objects = [ c.objects[0] for c in self.constraints if instance_of(c.kind, BinaryConstraintKind) ] for b in binary_objects: if b not in unary_objects: locked.append(ents[b]) break # Lock the first occuring entity if needed. if not locked: locked.append(0) locs = [self.objects[n].loc for n in ents] # construct the constraint mapping constraints = [] for c in self.constraints: ixs = tuple(ents[obj] for obj in c.objects) pods = c.toPODs() for pod in pods: constraints.append((ixs, pod)) # check if any constraints were specified if not constraints: raise ValueError("At least one constraint required") # instantiate the solver solver = ConstraintSolver(locs, constraints, locked=locked) # solve locs_new, self._solve_result = solver.solve() # update positions for loc_new, n in zip(locs_new, ents): self.objects[n].loc = loc_new return self
def test_instance_of_iterable(self): self.assertTrue(instance_of([1, 2, 3], Iterable[int])) self.assertTrue(instance_of((1, 2, 3), Iterable[int]))
def test_instance_of_tuple_with_union(self): self.assertTrue(instance_of((1, '2', 3), Tuple[Union[int, str], ...])) self.assertTrue(not instance_of((1, '2', 3), Tuple[Union[int, float], ...]))