def type_check(self, type_): if not isinstance_generic(type_, self.type_): bound = concretize_typevars(get_generic_args(self.type_)[0]) raise self.exc_cls( self.type_, type_, TypeError("{} is not a subclass of {}".format(type_, bound)), ) return type_
def type_check(self, value): if not isinstance_generic(value, self.type_): raise self.exc_cls(self.type_, value) return value
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
def test_callable_typechecker_neg(f, t): assert not isinstance_generic(f, t)
def test_callable_typechecker_pos(f, t): assert isinstance_generic(f, t)
def test_type_typechecker_pos(type_, t): assert isinstance_generic(type_, t)