Beispiel #1
0
    def Register(self, func, extra_args=Callback._EXTRA_ARGS_CONSTANT, priority=5):
        '''
        Register a function in the callback.
        :param object func:
            Method or function that will be called later.

        :param int priority:
            If passed, it'll be be used to put the callback into the correct place based on the
            priority passed (lower numbers have higher priority).
        '''
        if extra_args is not self._EXTRA_ARGS_CONSTANT:
            extra_args = tuple(extra_args)

        key = self._GetKey(func)
        try:
            callbacks = self._callbacks
        except AttributeError:
            callbacks = self._callbacks = odict()

        callbacks.pop(key, None)  # Remove if it exists
        new_info = self._GetInfo(func, priority)

        i = 0
        for i, (info, _extra) in enumerate(callbacks.itervalues()):
            if info[self.INFO_POS_PRIORITY] > priority:
                break
        else:
            # Iterated all... so, go one more the last position.
            i += 1

        callbacks.insert(i, key, (new_info, extra_args))
Beispiel #2
0
    def testFlattenDictValuesWithODict(self):
        d = odict()
        d['z'] = 1

        inner_dict = odict()
        inner_dict['key'] = 2

        d['a'] = [
            inner_dict,
            3,
            [
                4,
                [5]
            ]
        ]
        assert FlattenDictValues(d) == range(1, 6)
Beispiel #3
0
 def __init__(self,
              cached_method,
              attr_name_list,
              cache_size=1,
              results=None):
     '''
     :type cached_method: bound method to be cached
     :param cached_method:
     :type attr_name_list: attr names in a C{str} separated by spaces OR in a sequence of C{str}
     :param attr_name_list:
     :type cache_size: the cache size
     :param cache_size:
     :type results: an optional ref. to an C{odict} for keep cache results
     :param results:
     '''
     CachedMethod.__init__(self, cached_method)
     if isinstance(attr_name_list, str):
         self._attr_name_list = attr_name_list.split()
     else:
         self._attr_name_list = attr_name_list
     self._cache_size = cache_size
     if results is None:
         self._results = odict()
     else:
         self._results = results
Beispiel #4
0
 def __init__(self, handle_errors=None):
     '''
     :param bool handle_errors:
         If True, any errors raised while calling the callbacks will not stop the execution
         flow of the application, but will call the system error handler so that error
         does not fail silently.
     '''
     if handle_errors is None:
         handle_errors = self.DEFAULT_HANDLE_ERRORS
     self._handle_errors = handle_errors
     # _callbacks is no longer lazily created: This makes the creation a bit slower, but
     # everything else is faster (as having to check for hasattr each time is slow).
     self._callbacks = odict()
Beispiel #5
0
    def __init__(cls, name, bases, attributes):
        '''
        Creates an Enum class.

        :param type cls:
            The class being defined.

        :param unicode name:
            The name of the class.

        :param list(type) bases:
            The class's base classes.

        :type attributes: dict(unicode -> object)
        :param attributes:
            The class attributes.
        '''
        super(EnumMetaclass, cls).__init__(name, bases, attributes)

        # Store EnumValues here for easy access.
        enums = odict()

        # Figure out the set of enum values on the base classes, to ensure
        # that we don't get any duplicate values (which would screw up
        # conversion from integer).
        for basecls in cls.__mro__:
            if hasattr(basecls, '_enums'):
                enums.update(basecls._enums)

        # Creates a class for the enumerate values
        Enumvalue_class = type(bytes(name + 'Value'), (EnumValue,), {})
        cls._value_type = Enumvalue_class

        # For each class attribute, create an EnumValue and store that back on
        # the class instead of the int.  Skip Python reserved names.  Also add
        # a mapping from the integer to the instance so we can return the same
        # object on conversion.

        for attr, intval in sorted(attributes.items(), key=itemgetter(1)):
            if not (attr.startswith('__') and attr.endswith('__')):
                intval = attributes[attr]
                if not isinstance(intval, (int, long)):
                    raise TypeError('Enum value is not an integer: %s=%r' % (attr, intval))
                Enumvalue = Enumvalue_class(cls, intval, attr)
                if intval in enums:
                    raise TypeError('Multiple enum values: %s' % intval)
                # Store as an attribute on the class, and save the attr name
                setattr(cls, attr, Enumvalue)
                enums[intval] = attr

        cls._enums = enums
Beispiel #6
0
    def _GetArgspecObject(self, args, trail, kwargs, defaults):
        '''
        Create the argspec object that helps when creating the cache key. Subclasses may want to customize the argspec
        object to help offer customized cache key generation algorithm.

        :param list(unicode) args:
            The names of the explicit arguments.
        :param unicode trail:
            The variable name used to store varargs.
            `None` if no varargs are accepted.
        :param unicode kwargs:
            The variable name used to store non-explict keyword arguments.
             `None` if no non-explicit keyword arguments are accepted.
        :param tuple(object) defaults:
            The default values (when existent) for the variable listed in the `args` parameter.
            When not all parameter have default values this tuple will have less elements than `args`. Given the
            function `def Foo(a, b, c=3, d=4): pass` than `args == ['a', 'b', 'c', 'd']` and `defaults == (3, 4)`.
            `None` if there are no defaults.
        :rtype: object
        :return:
            This object will be set as `self._argspec`, this object can be used by `self._GetCacheKey`.
            The base class uses a tuple with a bool indication if default are present and a `coilib50.basic.odict.odict`
            that is a mapping of "parameter name" -> "default value" (a string is used when the is no default).
        '''
        from ben10.foundation.odict import odict
        named_arguments = odict()
        if kwargs is not None:
            raise TypeError(
                'Non-declared keyword arguments (`**kwargs`) not supported.'
                ' Note that Memoize must be the first decorator (nearest to the function) used.'
            )
        if defaults is None:
            has_defaults = False
            defaults = ()
        else:
            has_defaults = True
        if self._memo_target == self.MEMO_INSTANCE_METHOD:
            args = args[1:]  # Ignore self when dealing with instance method
        first_default = len(args) - len(defaults)
        for i, arg in enumerate(args):
            if i < first_default:
                named_arguments[arg] = '@Memoize: no_default'
            else:
                named_arguments[arg] = defaults[i - first_default]
        return has_defaults, named_arguments
Beispiel #7
0
 def __init__(self, cached_method, attr_name_list, cache_size=1, results=None):
     '''
     :type cached_method: bound method to be cached
     :param cached_method:
     :type attr_name_list: attr names in a C{str} separated by spaces OR in a sequence of C{str}
     :param attr_name_list:
     :type cache_size: the cache size
     :param cache_size:
     :type results: an optional ref. to an C{odict} for keep cache results
     :param results:
     '''
     CachedMethod.__init__(self, cached_method)
     if isinstance(attr_name_list, str):
         self._attr_name_list = attr_name_list.split()
     else:
         self._attr_name_list = attr_name_list
     self._cache_size = cache_size
     if results is None:
         self._results = odict()
     else:
         self._results = results
Beispiel #8
0
    def Register(self, func, extra_args=_EXTRA_ARGS_CONSTANT):
        '''
        Registers a function in the callback.

        :param object func:
            Method or function that will be called later.

        :param list(object) extra_args:
            A list with the objects to be used
        '''
        if extra_args is not self._EXTRA_ARGS_CONSTANT:
            extra_args = tuple(extra_args)

        key = self._GetKey(func)
        try:
            callbacks = self._callbacks
        except:
            callbacks = self._callbacks = odict()

        callbacks.pop(key, None)  # Remove if it exists
        callbacks[key] = (self._GetInfo(func), extra_args)
Beispiel #9
0
 def __init__(self):
     self.environment = odict()
     self.alias = odict()
     self.calls = odict()
Beispiel #10
0
    def testPerformance__flaky(self):
        '''
        Results 2014-07-02 (support for defaults and passing kwargs)
        ---------------------------------------------------------
        call_no_positional is 6.1 times slower than baseline.
        call_with_defaults is 11.2 times slower than baseline.
        call_passing_kwargs is 13.4 times slower than baseline.
        ---------------------------------------------------------


        Results < 2014-07-02
        ---------------------------------------------------------
        call_no_positional is 5.3 times slower than baseline.
        call_with_defaults (no support)
        call_passing_kwargs (no support)
        ---------------------------------------------------------
        '''
        from ben10.foundation.odict import odict
        from textwrap import dedent
        import timeit

        for_size = 1000
        repeat = 7
        number = 10
        timing = odict()

        def Check(name, setup, stmt):
            timer = timeit.Timer(
                setup=(dedent(setup)),
                stmt=(dedent(stmt)),
            )
            timing[name] = min(timer.repeat(repeat=repeat, number=number))


        PRINT_PERFORMANCE = False
        def PrintPerformance(timing, name):
            if PRINT_PERFORMANCE:
                print '%s is %.1f times slower than baseline.' % (name, timing[name] / timing['baseline'])

        # Baseline
        Check(
            'baseline',
            'from random import Random;r = Random(1)',
            "for _i in xrange(%d): tuple((r.random(), 'g/cm3', 'density'))" % (for_size,)
            )


        Check(
            'call_no_positional',
            '''
            from ben10.foundation.memoize import Memoize

            @Memoize
            def Foo(arg1, arg2):
                pass
            ''',
            "for _i in xrange(%d): Foo('arg1', 'arg2'); Foo('arg1', 'arg2')" % (for_size,)
            )
        PrintPerformance(timing, 'call_no_positional')

        Check(
            'call_with_defaults',
            '''
            from ben10.foundation.memoize import Memoize

            @Memoize
            def Foo(arg1, arg2=None):
                pass
            ''',
            "for _i in xrange(%d): Foo('arg1'); Foo('arg1', 'arg2')" % (for_size,)
            )
        PrintPerformance(timing, 'call_with_defaults')

        Check(
            'call_passing_kwargs',
            '''
            from ben10.foundation.memoize import Memoize

            @Memoize
            def Foo(arg1, arg2=None):
                pass
            ''',
            "for _i in xrange(%d): Foo('arg1'); Foo('arg1', arg2='arg2')" % (for_size,)
            )
        PrintPerformance(timing, 'call_passing_kwargs')