def cli_repr_mapping(m, k, v): if issubclass_generic(k, NonStrCollection) or issubclass_generic( v, NonStrCollection): raise CLINestedCollectionsNotAllowed((m, k, v)) return "{k}{j}{v}".format(k=cli_repr(k), v=cli_repr(v), j=KEY_VAL_JOIN_CHAR)
def __init__(self, coll_type, key_type=object, val_type=object): if issubclass_generic(key_type, NonStrCollection) or issubclass_generic( val_type, NonStrCollection): raise CLINestedCollectionsNotAllowed( (coll_type, key_type, val_type)) super().__init__(coll_type, key_type, val_type) coll_type = self.reduce if issubclass(coll_type, (collections.Counter, collections.ChainMap)): self.constructor_allows_iterable = False
def completer_for_union(u, *types): types = [t for t in types if t not in (NoneType, None)] if all(issubclass_generic(t, typing.Tuple) for t in types): # complete a Union of tuples as a tuple of unions - a fair approximation that parses argtups = (get_generic_args(t) for t in types) unionargtups = itertools.zip_longest(*argtups, fillvalue=NoneType) uniontypes = (typing.Union[args] for args in unionargtups) return _multi_completer(CompleteTuple, *uniontypes) return _multi_completer(CompleteUnion, *types, remove_no_complete=True)
def config_repr_mapping(m, k=object, v=object): # have to check this here because the key type param is invariant; we can't resolve from a base class if issubclass_generic(k, NonStrCollection): raise ConfigCollectionKeysNotAllowed((m, k, v)) try: key_repr = config_key_repr(k) except UnknownSignature: raise ConfigIOUndefinedForKeyType((m, k, v)) else: return {key_repr: config_repr(v), ellipsis_: ellipsis_}
def is_collection(self): return issubclass_generic(self.type_, NonStrCollection)
def is_nested_collection(self): return issubclass_generic(self.type_, Collection[NonStrCollection])
def cli_repr_seq(s, t=typing.Any): if issubclass_generic(t, NonStrCollection): raise CLINestedCollectionsNotAllowed((s, t)) return cli_repr(t)
def test_py36_fake_types(type1, type2, pos): if pos: assert issubclass_generic(type1, type2) else: assert not issubclass_generic(type1, type2)
def test_transitive_generic(base, type_): assert issubclass_generic(type_, base)
def test_issubclass_generic_neg(t1, t2): assert not issubclass_generic(t1, t2)
def test_issubclass_generic_pos(t1, t2): assert issubclass_generic(t1, t2)
def __init__(self, coll_type, val_type=object): if issubclass_generic(val_type, NonStrCollection): raise CLINestedCollectionsNotAllowed((coll_type, val_type)) super().__init__(coll_type, val_type)
def __init__(self, coll_type, key_type=typing.Any, val_type=Empty): if issubclass_generic(key_type, NonStrCollection): raise ConfigCollectionKeysNotAllowed( (coll_type, key_type, val_type)) super().__init__(coll_type, key_type, val_type)
def instance_from( __classpath__=None, __args__=None, __kwargs__=None, __constructor__=None, target_type=None, ): """ Instantiate general values from configuration files. E.g. with the json-compatible configuration conf = {"__classpath__":"sklearn.cluster.KMeans", "__kwargs__": {"n_clusters": 10, "n_init": 10}}, instance_from(**conf) returns an sklearn.cluster.KMeans clustering model. :param __classpath__: str, optional path to the class to be instantiated. If no __constructor__ is passed, this will be called directly, otherwise it will be used for a final instance check. :param __args__: optional positional args to be passed to the class constructor (or function if classpath refers to a general callable) :param __kwargs__: optional keyword args to be passed to the class constructor (or function if classpath refers to a general callable) :param __constructor__: optional path to a callable to call to construct the desired instance :param target_type: optional type to check the classpath against before attempting to inflate an instance :return: an instance of the class (or the results of calling the function) identified by classpath """ logger.debug( "Attempting to instantiate {} instance with{} args {} and kwargs {}". format( __classpath__, " constructor {},".format(__constructor__) if __constructor__ is not None else "", __args__, __kwargs__, )) if __classpath__ is not None: cls = import_type(__classpath__) if not isinstance(cls, TYPE_TYPES): raise TypeError( "classpath {} does not specify a class or type; got {}".format( __classpath__, cls)) # don't waste time on the construction if the specified type is incorrect if target_type is not None: target_type_ = concretize_typevars(target_type) if not issubclass_generic(cls, target_type_): raise TypeError( "classpath {} does not specify a generic subclass of the target type {}" .format(__classpath__, target_type)) # only check the instance if the constructor is other than the class itself instance_check = __constructor__ is not None else: instance_check = False cls = None if __constructor__ is not None: constructor = import_object(__constructor__) if not callable(constructor): raise TypeError( "constructor {} does not specify a callable; got {}".format( __constructor__, constructor)) elif cls is None: raise ValueError("Must pass either __classpath__ or __constructor__") else: constructor = cls wrapper = typed_config_callable(constructor) if __kwargs__ is None and __args__ is None: obj = wrapper() elif __kwargs__ is None: obj = wrapper(*__args__) elif __args__ is None: obj = wrapper(**__kwargs__) else: obj = wrapper(*__args__, **__kwargs__) if instance_check and not isinstance_generic(obj, cls): raise TypeError( "Inflation using constructor {} resulted in a {} instance; expected {}" .format(constructor, type(obj), cls)) logger.info("Instantiated {} instance successfully{}".format( __classpath__, " with constructor {}".format(__constructor__) if __constructor__ is not None else "", )) return obj