def test(): '''Test basic workings of `is_iterable`.''' iterables = [ [1, 2, 3], (1, 2), {}, (), [[1]], 'asdfasdf', '' ] non_iterables = [ dict, list, type, None, True, False, Exception, lambda x: x ] for iterable in iterables: assert is_iterable(iterable) for non_iterable in non_iterables: assert not is_iterable(non_iterable)
def test(): '''Test basic workings of `is_iterable`.''' iterables = [[1, 2, 3], (1, 2), {}, (), [[1]], 'asdfasdf', ''] non_iterables = [ dict, list, type, None, True, False, Exception, lambda x: x ] for iterable in iterables: assert is_iterable(iterable) for non_iterable in non_iterables: assert not is_iterable(non_iterable)
def __init__(self, function): ''' Construct the `TempFunctionCallCounter`. For `function`, you may pass in either a function object, or a `(parent_object, function_name)` pair, or a `(getter, setter)` pair. ''' if cute_iter_tools.is_iterable(function): first, second = function if isinstance(second, basestring): actual_function = getattr(first, second) else: assert callable(first) and callable(second) actual_function = first( ) # `first` is the getter in this case. else: # not cute_iter_tools.is_iterable(function) assert callable(function) actual_function = function try: address = address_tools.object_to_string.get_address(function) parent_object_address, function_name = address.rsplit('.', 1) parent_object = address_tools.resolve(parent_object_address) except Exception: raise Exception("Couldn't obtain parent/name pair from " "function; supply one manually or " "alternatively supply a getter/setter pair.") first, second = parent_object, function_name self.call_counting_function = count_calls(actual_function) TempValueSetter.__init__(self, (first, second), value=self.call_counting_function)
def is_subclass(candidate, base_class): ''' Check if `candidate` is a subclass of `base_class`. You may pass in a tuple of base classes instead of just one, and it will check whether `candidate` is a subclass of any of these base classes. This has 2 advantages of over the built-in `issubclass`: 1. It doesn't throw an exception if `candidate` is not a type. (Python issue 10569.) 2. It manually checks for a `__subclasscheck__` method on `base_class`. This is helpful for Python 2.5 compatibility because Python started using `__subclasscheck__` in its built-in `issubclass` starting from Python 2.6. ''' # todo: disable ability to use nested iterables. if cute_iter_tools.is_iterable(base_class): return any(is_subclass(candidate, single_base_class) for single_base_class in base_class) elif not isinstance(candidate, (type, types.ClassType)): return False elif hasattr(base_class, '__subclasscheck__'): return base_class.__subclasscheck__(candidate) else: return issubclass(candidate, base_class)
def __init__(self, inputs=(), outputs=(), name=None): ''' Construct the emitter. `inputs` is a list of inputs, all of them must be emitters. `outputs` is a list of outputs, they must be either emitters or callables. `name` is a string name for the emitter. ''' assert cute_iter_tools.is_iterable(inputs) and \ cute_iter_tools.is_iterable(outputs) self._inputs = set() '''The emitter's inputs.''' self._outputs = set() '''The emitter's inputs.''' for output in outputs: self.add_output(output) self.__total_callable_outputs_cache = None ''' A cache of total callable outputs. This means the callable outputs of this emitter and any output emitters. ''' self._recalculate_total_callable_outputs() # We made sure to create the callable outputs cache before we add # inputs, so when we update their cache, it could use ours. for input in inputs: self.add_input(input) self.name = name '''The emitter's name.'''
def __init__(self, function): ''' Construct the `TempFunctionCallCounter`. For `function`, you may pass in either a function object, or a `(parent_object, function_name)` pair, or a `(getter, setter)` pair. ''' if cute_iter_tools.is_iterable(function): first, second = function if isinstance(second, basestring): actual_function = getattr(first, second) else: assert callable(first) and callable(second) actual_function = first() # `first` is the getter in this case. else: # not cute_iter_tools.is_iterable(function) assert callable(function) actual_function = function try: address = address_tools.object_to_string.get_address(function) parent_object_address, function_name = address.rsplit('.', 1) parent_object = address_tools.resolve(parent_object_address) except Exception: raise Exception("Couldn't obtain parent/name pair from " "function; supply one manually or " "alternatively supply a getter/setter pair.") first, second = parent_object, function_name self.call_counting_function = count_calls(actual_function) TempValueSetter.__init__( self, (first, second), value=self.call_counting_function )
def __init_analysis_cruncher_types(self): '''Figure out which crunchers this simpack can use.''' # todo: possibly fix `CRUNCHERS` to some canonical state in `.settings` from garlicsim.asynchronous_crunching import crunchers, BaseCruncher simpack = self.simpack self.cruncher_types_availability = OrderedDict() '''dict mapping from cruncher type to whether it can be used.''' self.available_cruncher_types = [] '''The cruncher types that this simpack can use.''' CRUNCHERS = self.settings.CRUNCHERS if isinstance(CRUNCHERS, str): (cruncher_type,) = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_.__name__ == CRUNCHERS] self.available_cruncher_types = [cruncher_type] self.cruncher_types_availability[cruncher_type] = True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] self.cruncher_types_availability.update(dict( ( unavailable_cruncher_type, ReasonedBool( False, 'The `%s` simpack specified `%s` as the only ' 'available cruncher type.' % \ (simpack.__name__.rsplit('.')[-1], cruncher_type.__name__) ) ) for unavailable_cruncher_type in unavailable_cruncher_types )) # # ################################################################### elif misc_tools.is_subclass(CRUNCHERS, BaseCruncher): cruncher_type = CRUNCHERS self.available_cruncher_types = [cruncher_type] self.cruncher_types_availability[cruncher_type] = True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] self.cruncher_types_availability.update(dict( ( unavailable_cruncher_type, ReasonedBool( False, 'The `%s` simpack specified `%s` as the only ' 'available cruncher type.' % \ (simpack.__name__.rsplit('.')[-1], cruncher_type.__name__) ) ) for unavailable_cruncher_type in unavailable_cruncher_types )) # # ################################################################### elif cute_iter_tools.is_iterable(CRUNCHERS): self.available_cruncher_types = [] for item in CRUNCHERS: if isinstance(item, str): (cruncher_type,) = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_.__name__ == item] else: assert misc_tools.is_subclass(item, BaseCruncher) cruncher_type = item self.available_cruncher_types.append(cruncher_type) self.cruncher_types_availability[cruncher_type] = True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] self.cruncher_types_availability.update(dict( ( unavailable_cruncher_type, ReasonedBool( False, 'The `%s` simpack specified a list of available ' 'crunchers and `%s` is not in it.' % \ (simpack.__name__.rsplit('.')[-1], unavailable_cruncher_type.__name__) ) ) for unavailable_cruncher_type in unavailable_cruncher_types )) # # ################################################################### elif isinstance(CRUNCHERS, collections.Callable): assert not isinstance(CRUNCHERS, BaseCruncher) self.available_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if CRUNCHERS(cruncher_type_)] for available_cruncher_type in self.available_cruncher_types: self.cruncher_types_availability[available_cruncher_type] = \ True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] for unavailable_cruncher_type in unavailable_cruncher_types: reason = getattr( CRUNCHERS(unavailable_cruncher_type), 'reason', 'No reason was given for `%s` not being accepted.' % \ unavailable_cruncher_type.__name__ ) self.cruncher_types_availability[ unavailable_cruncher_type ] = ReasonedBool(False, reason) # # ################################################################### ####################################################################### else: raise InvalidSimpack("The `CRUNCHERS` setting must be either a " "cruncher type (or name string), a list of " "cruncher types, or a filter function for " "cruncher types. You supplied `%s`, which is " "neither." % CRUNCHERS)
def __init_analysis_cruncher_types(self): '''Figure out which crunchers this simpack can use.''' # todo: possibly fix `CRUNCHERS` to some canonical state in `.settings` from garlicsim.asynchronous_crunching import crunchers, BaseCruncher simpack = self.simpack self.cruncher_types_availability = OrderedDict() '''dict mapping from cruncher type to whether it can be used.''' self.available_cruncher_types = [] '''The cruncher types that this simpack can use.''' CRUNCHERS = self.settings.CRUNCHERS if isinstance(CRUNCHERS, basestring): (cruncher_type,) = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_.__name__ == CRUNCHERS] self.available_cruncher_types = [cruncher_type] self.cruncher_types_availability[cruncher_type] = True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] self.cruncher_types_availability.update(dict( ( unavailable_cruncher_type, ReasonedBool( False, 'The `%s` simpack specified `%s` as the only ' 'available cruncher type.' % \ (simpack.__name__.rsplit('.')[-1], cruncher_type.__name__) ) ) for unavailable_cruncher_type in unavailable_cruncher_types )) # # ################################################################### elif misc_tools.is_subclass(CRUNCHERS, BaseCruncher): cruncher_type = CRUNCHERS self.available_cruncher_types = [cruncher_type] self.cruncher_types_availability[cruncher_type] = True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] self.cruncher_types_availability.update(dict( ( unavailable_cruncher_type, ReasonedBool( False, 'The `%s` simpack specified `%s` as the only ' 'available cruncher type.' % \ (simpack.__name__.rsplit('.')[-1], cruncher_type.__name__) ) ) for unavailable_cruncher_type in unavailable_cruncher_types )) # # ################################################################### elif cute_iter_tools.is_iterable(CRUNCHERS): self.available_cruncher_types = [] for item in CRUNCHERS: if isinstance(item, basestring): (cruncher_type,) = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_.__name__ == item] else: assert misc_tools.is_subclass(item, BaseCruncher) cruncher_type = item self.available_cruncher_types.append(cruncher_type) self.cruncher_types_availability[cruncher_type] = True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] self.cruncher_types_availability.update(dict( ( unavailable_cruncher_type, ReasonedBool( False, 'The `%s` simpack specified a list of available ' 'crunchers and `%s` is not in it.' % \ (simpack.__name__.rsplit('.')[-1], unavailable_cruncher_type.__name__) ) ) for unavailable_cruncher_type in unavailable_cruncher_types )) # # ################################################################### elif callable(CRUNCHERS): assert not isinstance(CRUNCHERS, BaseCruncher) self.available_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if CRUNCHERS(cruncher_type_)] for available_cruncher_type in self.available_cruncher_types: self.cruncher_types_availability[available_cruncher_type] = \ True ### Giving unavailability reasons: ################################ # # unavailable_cruncher_types = \ [cruncher_type_ for cruncher_type_ in crunchers.cruncher_types_list if cruncher_type_ not in self.available_cruncher_types] for unavailable_cruncher_type in unavailable_cruncher_types: reason = getattr( CRUNCHERS(unavailable_cruncher_type), 'reason', 'No reason was given for `%s` not being accepted.' % \ unavailable_cruncher_type.__name__ ) self.cruncher_types_availability[ unavailable_cruncher_type] = ReasonedBool(False, reason) # # ################################################################### ####################################################################### else: raise InvalidSimpack("The `CRUNCHERS` setting must be either a " "cruncher type (or name string), a list of " "cruncher types, or a filter function for " "cruncher types. You supplied `%s`, which is " "neither." % CRUNCHERS)