def __init__(self, forward_function=None, back_function=None, *arguments, **keywords): if (not (forward_function is None or is_callable(forward_function)) or not (back_function is None or is_callable(back_function))): raise TypeError('both functions must be callable or None') super(FunctionalMediator, self).__init__() self.__forward_function = forward_function or _identity self.__back_function = back_function or _identity self.__arguments = arguments self.__keywords = keywords
def wrap (cls, callable_object, arguments = (), keywords = None): """ Return a callable with semantics of the binding class this method is called for. I{If necessary} (e.g. if C{arguments} tuple is not empty), this method creates a binding instance first. In any case, you can assume that returned object will I{behave} identically to an instance of this class with C{callable_object} and C{arguments} passed to C{L{__init__}} method. However, the returned object I{is not required} to be an instance. This is the preferred method of creating bindings. It is generally more memory- and call-time-efficient since in some cases no new objects are created at all. @param callable_object: the callable object that will be invoked by this binding from C{L{__call__}} method. @type callable_object: callable @param arguments: optional list of argument for C{callable_object} that will be prepended to call arguments. @type arguments: iterable @rtype: callable @raises TypeError: if C{callable_object} is not callable or C{arguments} is not iterable. """ if arguments or keywords: return cls (callable_object, arguments, keywords) else: if not is_callable (callable_object): raise TypeError ("'callable_object' must be callable") return callable_object
def wrap(cls, callable_object, arguments=(), keywords=None): """ Return a callable with semantics of the binding class this method is called for. I{If necessary} (e.g. if C{arguments} tuple is not empty), this method creates a binding instance first. In any case, you can assume that returned object will I{behave} identically to an instance of this class with C{callable_object} and C{arguments} passed to C{L{__init__}} method. However, the returned object I{is not required} to be an instance. This is the preferred method of creating bindings. It is generally more memory- and call-time-efficient since in some cases no new objects are created at all. @param callable_object: the callable object that will be invoked by this binding from C{L{__call__}} method. @type callable_object: callable @param arguments: optional list of argument for C{callable_object} that will be prepended to call arguments. @type arguments: iterable @rtype: callable @raises TypeError: if C{callable_object} is not callable or C{arguments} is not iterable. """ if arguments or keywords: return cls(callable_object, arguments, keywords) else: if not is_callable(callable_object): raise TypeError("'callable_object' must be callable") return callable_object
def __init__(self, transformer, variable): if not is_callable (transformer): raise TypeError ('transformer must be callable') super (_VariableTransformation, self).__init__(transformer (variable.get ())) self.__transformer = transformer self.__variable = weakref.ref (variable, self.__on_usage_change) variable.changed.connect (self.__update)
def __init__(self, predicate, variable): if not is_callable (predicate): raise TypeError ('predicate must be callable') super (_PredicateOverVariable, self).__init__(predicate (variable.get ())) self.__predicate = predicate self.__variable = weakref.ref (variable, self.__on_usage_change) variable.changed.connect (self.__update)
def __init__(self, predicate, variable): if not is_callable(predicate): raise TypeError('predicate must be callable') super(_PredicateOverVariable, self).__init__(predicate(variable.get())) self.__predicate = predicate self.__variable = weakref.ref(variable, self.__on_usage_change) variable.changed.connect(self.__update)
def test_is_callable (self): self.assert_(is_callable (is_callable)) self.assert_(is_callable (UtilsTestCase)) self.assert_(is_callable (UtilsTestCase.test_is_callable)) self.assert_(not is_callable (None)) self.assert_(not is_callable (5)) self.assert_(not is_callable ('foo')) self.assert_(not is_callable ([]))
def __init__(self, transformer, variable): if not is_callable(transformer): raise TypeError('transformer must be callable') super(_VariableTransformation, self).__init__(transformer(variable.get())) self.__transformer = transformer self.__variable = weakref.ref(variable, self.__on_usage_change) variable.changed.connect(self.__update)
def __init__(self, true_value=True, false_value=False, fallback=None): if fallback is None: fallback = bool else: if not is_callable(fallback): raise TypeError("'fallback' must be a callable") super(BooleanMediator, self).__init__() self.__true_value = true_value self.__false_value = false_value self.__fallback = fallback
def __init__(self, callable_object, arguments=(), callback=None, keywords=None): """ Initialize a new weak binding which will call C{callable_object}, I{prepending} fixed C{arguments} (if any) to those specified at call time. Here, C{callable_object} is usually a function or a method, but can in principle be anything callable, including an already existing binding. If C{callable_object} is a bound method, its object is referenced weakly. It is also legal to create weak bindings for other callables, but they will behave identically to plain bindings in that case. See also C{L{wrap}} class method for a different way of creating weak bindings. @param callable_object: the callable object that will be invoked by this binding from C{L{__call__}} method. @type callable_object: callable @param arguments: optional list of argument for C{callable_object} that will be prepended to call arguments. @type arguments: iterable @param callback: optional callable that will be called if binding’s object is garbage-collected. @type callback: callable or C{None} @raises TypeError: if C{callable_object} is not callable or C{arguments} is not iterable. @raises CannotWeakReferenceError: if C{callable_object} is a bound method, but its object is not weakly referencable. """ super(WeakBinding, self).__init__(callable_object, arguments, keywords) if self._object is not None: if callback is not None and not is_callable(callback): raise TypeError("'callback' must be callable") try: self.__callback = callback self._object = weakref.ref(self._object, self.__object_garbage_collected) except: raise CannotWeakReferenceError(self._object) else: self._object = _NONE_REFERENCE self.__hash = None
def __init__(self, callable_object, arguments = (), keywords = None): """ Initialize a new binding which will call C{callable_object}, I{prepending} fixed C{arguments} (if any) to those specified at call time. Here, C{callable_object} is usually a function or a method, but can in principle be anything callable, including an already existing binding. See also C{L{wrap}} class method for a different way of creating bindings. @param callable_object: the callable object that will be invoked by this binding from C{L{__call__}} method. @type callable_object: callable @param arguments: optional list of argument for C{callable_object} that will be prepended to call arguments. @type arguments: iterable @raises TypeError: if C{callable_object} is not callable or C{arguments} is not iterable. """ if not is_callable (callable_object): raise TypeError ("'callable_object' must be callable") # This raises `TypeError' if `arguments' or `keywords' type is inappropriate. arguments = tuple (arguments) if keywords is None: keywords = frozendict.EMPTY # Note: not isinstance, subclasses might become modifiable again. elif type (keywords) is not frozendict: keywords = frozendict (keywords) super (Binding, self).__init__() if isinstance (callable_object, BindingCompatibleTypes): if _PY3K: self._object = callable_object.__self__ self._function = callable_object.__func__ self._class = type (self._object) else: self._object = callable_object.im_self self._function = callable_object.im_func self._class = callable_object.im_class else: self._object = None self._function = callable_object self._class = None self._arguments = arguments self._keywords = keywords
def __init__(self, callable_object, arguments=(), keywords=None): """ Initialize a new binding which will call C{callable_object}, I{prepending} fixed C{arguments} (if any) to those specified at call time. Here, C{callable_object} is usually a function or a method, but can in principle be anything callable, including an already existing binding. See also C{L{wrap}} class method for a different way of creating bindings. @param callable_object: the callable object that will be invoked by this binding from C{L{__call__}} method. @type callable_object: callable @param arguments: optional list of argument for C{callable_object} that will be prepended to call arguments. @type arguments: iterable @raises TypeError: if C{callable_object} is not callable or C{arguments} is not iterable. """ if not is_callable(callable_object): raise TypeError("'callable_object' must be callable") # This raises `TypeError' if `arguments' or `keywords' type is inappropriate. arguments = tuple(arguments) if keywords is None: keywords = frozendict.EMPTY # Note: not isinstance, subclasses might become modifiable again. elif type(keywords) is not frozendict: keywords = frozendict(keywords) super(Binding, self).__init__() if isinstance(callable_object, BindingCompatibleTypes): if _PY3K: self._object = callable_object.__self__ self._function = callable_object.__func__ self._class = type(self._object) else: self._object = callable_object.im_self self._function = callable_object.im_func self._class = callable_object.im_class else: self._object = None self._function = callable_object self._class = None self._arguments = arguments self._keywords = keywords
def __init__(self, callable_object, arguments = (), callback = None, keywords = None): """ Initialize a new weak binding which will call C{callable_object}, I{prepending} fixed C{arguments} (if any) to those specified at call time. Here, C{callable_object} is usually a function or a method, but can in principle be anything callable, including an already existing binding. If C{callable_object} is a bound method, its object is referenced weakly. It is also legal to create weak bindings for other callables, but they will behave identically to plain bindings in that case. See also C{L{wrap}} class method for a different way of creating weak bindings. @param callable_object: the callable object that will be invoked by this binding from C{L{__call__}} method. @type callable_object: callable @param arguments: optional list of argument for C{callable_object} that will be prepended to call arguments. @type arguments: iterable @param callback: optional callable that will be called if binding’s object is garbage-collected. @type callback: callable or C{None} @raises TypeError: if C{callable_object} is not callable or C{arguments} is not iterable. @raises CannotWeakReferenceError: if C{callable_object} is a bound method, but its object is not weakly referencable. """ super (WeakBinding, self).__init__(callable_object, arguments, keywords) if self._object is not None: if callback is not None and not is_callable (callback): raise TypeError ("'callback' must be callable") try: self.__callback = callback self._object = weakref.ref (self._object, self.__object_garbage_collected) except: raise CannotWeakReferenceError (self._object) else: self._object = _NONE_REFERENCE self.__hash = None
def __init__(self, predicate, initial_object): """ Initialize a new predicate conditon, setting its initial state to C{predicate (initial_object)}. C{predicate} is stored to be invoked also on any subsequent calls to C{L{update}} method. Return value of C{predicate} is always coerced using C{bool} function, so it needn’t return a boolean value. @param predicate: a callable accepting one argument used to compute condition’s state. @param initial_object: the value to be passed to C{predicate} to find initial state. @type initial_object: C{object} @raises exception: whatever C{predicate} raises, if anything. """ if not is_callable(predicate): raise TypeError('predicate must be callable') super(PredicateCondition, self).__init__(predicate(initial_object)) self.__predicate = predicate
def back(self, function): """ Return a callable accepting one argument that applies back transformation to it and passes result to C{function}. It holds that if C{m1} and C{m2} are two equal mediators and C{f1} and C{f2} are two equal callables (e.g. functions), then: >>> m1.back (f1) == m2.back (f2) In addition to that, for any C{value} to which back transformation can be applied, >>> m1.back (f1) (value) == m2.back (f2) (value) == m1.back_value (value) @rtype: callable @raises TypeError: if C{function} is not callable. """ if is_callable(function): return _Back(self, function) else: raise TypeError("'function' must be callable")
def __init__(self, predicate, initial_object): """ Initialize a new predicate conditon, setting its initial state to C{predicate (initial_object)}. C{predicate} is stored to be invoked also on any subsequent calls to C{L{update}} method. Return value of C{predicate} is always coerced using C{bool} function, so it needn’t return a boolean value. @param predicate: a callable accepting one argument used to compute condition’s state. @param initial_object: the value to be passed to C{predicate} to find initial state. @type initial_object: C{object} @raises exception: whatever C{predicate} raises, if anything. """ if not is_callable (predicate): raise TypeError ('predicate must be callable') super (PredicateCondition, self).__init__(predicate (initial_object)) self.__predicate = predicate
def _generate_derived_type_dictionary(cls, options): """ Generate an iterable of pairs in the form (Python identifier, value) for a new type created by C{L{derive_type}}. Exact pairs should be influenced by C{options}, which are C{options} as passed to C{derive_type} plus C{cls} (for convenience) and C{new_class_name}. This method is not meant to be callable from outside, use C{L{derive_type}} for that instead. Overriden implementations of this method are recommended but not required to be generator functions. They should generally start like this: >>> def _generate_derived_type_dictionary (cls, options): ... for attribute in super (..., cls)._generate_derived_type_dictionary (options): ... yield attribute ... ... ... That is only an approximation and you can, for instance, change or override attributes returned by super-method. C{options} dictionary is constructed in such a way you should be able to evaluate all function-defining statements in it. For instance, you can write own C{_generate_derived_type_dictionary} like this: >>> def _generate_derived_type_dictionary (cls, options): ... ... ... ... functions = {} ... ... if 'foo_value' in options: ... exec 'def foo (self): return foo_value' \ ... in { 'foo_value': options['foo_value'] }, functions ... ... ... ... ... for function in functions.iteritems (): ... yield function Returned value for C{__slots__} is treated specially. While normally values associated with the same name override previous values, values for C{__slots__} are combined into a tuple instead. Note that it is not recommended to use C{options} for execution globals or locals dictionary directly. This way your code may become vulnerable to other option addition, e.g. for some derivative of the class. For instance, you may use C{property} built-in, then setting it in C{options} will hide the built-in from your code. Consider using C{L{_filter_options}} utility method. @param options: dictionary of options passed to C{L{derive_type}} method, plus C{cls} and C{new_class_name}. @type options: C{dict} @rtype: iterable @returns: Pairs of (Python identifier, value) for the new type. @raises exception: if there is any error in C{options}. """ functions = {} filtered_options = AbstractValueObject._filter_options( options, 'cls', 'getter', 'setter') if 'object' in options: object = options['object'] if not is_valid_identifier(object): raise ValueError("'%s' is not a valid Python identifier" % object) yield '__slots__', mangle_identifier(options['new_class_name'], object) execute(('def __init__(self, %s):\n' ' cls.__init__(self)\n' ' %s = %s') % (object, AbstractValueObject._get_object(options), object), filtered_options, functions) if 'property' in options: property = options['property'] if property == object: raise ValueError( "'property' option cannot be the same as 'object'") if not is_valid_identifier(property): raise ValueError("'%s' is not a valid Python identifier" % property) execute( '%s = property (lambda self: %s)' % (mangle_identifier(options['new_class_name'], property), AbstractValueObject._get_object(options)), functions) else: if 'property' in options: raise ValueError( "'property' without 'object' option doesn't make sense") if 'dict' in options and options['dict']: # Gracefully ignore if this type already has a dict. if not _type_has_dictionary(cls): yield '__slots__', '__dict__' if 'getter' in options: if not is_callable(options['getter']): raise TypeError("'getter' must be a callable") execute( 'def get (self): return getter (%s)' % AbstractValueObject._get_object(options), filtered_options, functions) if 'setter' in options: if not is_callable(options['setter']): raise TypeError("'setter' must be a callable") execute( 'def set (self, value): return setter (%s, value)' % AbstractValueObject._get_object(options), filtered_options, functions) for function in functions.items(): yield function
def _generate_derived_type_dictionary (cls, options): """ Generate an iterable of pairs in the form (Python identifier, value) for a new type created by C{L{derive_type}}. Exact pairs should be influenced by C{options}, which are C{options} as passed to C{derive_type} plus C{cls} (for convenience) and C{new_class_name}. This method is not meant to be callable from outside, use C{L{derive_type}} for that instead. Overriden implementations of this method are recommended but not required to be generator functions. They should generally start like this: >>> def _generate_derived_type_dictionary (cls, options): ... for attribute in super (..., cls)._generate_derived_type_dictionary (options): ... yield attribute ... ... ... That is only an approximation and you can, for instance, change or override attributes returned by super-method. C{options} dictionary is constructed in such a way you should be able to evaluate all function-defining statements in it. For instance, you can write own C{_generate_derived_type_dictionary} like this: >>> def _generate_derived_type_dictionary (cls, options): ... ... ... ... functions = {} ... ... if 'foo_value' in options: ... exec 'def foo (self): return foo_value' \ ... in { 'foo_value': options['foo_value'] }, functions ... ... ... ... ... for function in functions.iteritems (): ... yield function Returned value for C{__slots__} is treated specially. While normally values associated with the same name override previous values, values for C{__slots__} are combined into a tuple instead. Note that it is not recommended to use C{options} for execution globals or locals dictionary directly. This way your code may become vulnerable to other option addition, e.g. for some derivative of the class. For instance, you may use C{property} built-in, then setting it in C{options} will hide the built-in from your code. Consider using C{L{_filter_options}} utility method. @param options: dictionary of options passed to C{L{derive_type}} method, plus C{cls} and C{new_class_name}. @type options: C{dict} @rtype: iterable @returns: Pairs of (Python identifier, value) for the new type. @raises exception: if there is any error in C{options}. """ functions = {} filtered_options = AbstractValueObject._filter_options (options, 'cls', 'getter', 'setter') if 'object' in options: object = options['object'] if not is_valid_identifier (object): raise ValueError ("'%s' is not a valid Python identifier" % object) yield '__slots__', mangle_identifier (options['new_class_name'], object) execute (('def __init__(self, %s):\n' ' cls.__init__(self)\n' ' %s = %s') % (object, AbstractValueObject._get_object (options), object), filtered_options, functions) if 'property' in options: property = options['property'] if property == object: raise ValueError ("'property' option cannot be the same as 'object'") if not is_valid_identifier (property): raise ValueError ("'%s' is not a valid Python identifier" % property) execute ('%s = property (lambda self: %s)' % (mangle_identifier (options['new_class_name'], property), AbstractValueObject._get_object (options)), functions) else: if 'property' in options: raise ValueError ("'property' without 'object' option doesn't make sense") if 'dict' in options and options['dict']: # Gracefully ignore if this type already has a dict. if not _type_has_dictionary (cls): yield '__slots__', '__dict__' if 'getter' in options: if not is_callable (options['getter']): raise TypeError ("'getter' must be a callable") execute ('def get (self): return getter (%s)' % AbstractValueObject._get_object (options), filtered_options, functions) if 'setter' in options: if not is_callable (options['setter']): raise TypeError ("'setter' must be a callable") execute ('def set (self, value): return setter (%s, value)' % AbstractValueObject._get_object (options), filtered_options, functions) for function in functions.items (): yield function
def test_dummy_reference (self): self.assert_(is_callable (DummyReference (None))) self.assert_(DummyReference (None) () is None) self.assert_(is_callable (DummyReference (self))) self.assert_(DummyReference (self) () is self)