Esempio n. 1
0
    def apply(self, hunk, filters, type, kwargs=None):
        """Apply the given list of filters to the hunk, returning a new
        ``MemoryHunk`` object.

        ``kwargs`` are options that should be passed along to the filters.
        If ``hunk`` is a file hunk, a ``source_path`` key will automatically
        be added to ``kwargs``.
        """
        assert type in self.VALID_TRANSFORMS
        log.debug(
            'Need to run method "%s" of filters (%s) on hunk %s with '
            'kwargs=%s', type, filters, hunk, kwargs)

        filters = [f for f in filters if getattr(f, type, None)]
        if not filters:  # Short-circuit
            log.debug('No filters have "%s" methods, returning hunk '
                      'unchanged' % (type, ))
            return hunk

        kwargs_final = self.kwargs.copy()
        kwargs_final.update(kwargs or {})

        def func():
            data = StringIO(hunk.data())
            for filter in filters:
                log.debug('Running method "%s" of  %s with kwargs=%s', type,
                          filter, kwargs_final)
                out = StringIO(
                    u'')  # For 2.x, StringIO().getvalue() returns str
                getattr(filter, type)(data, out, **kwargs_final)
                data = out
                data.seek(0)

            return data

        additional_cache_keys = []
        if kwargs_final:
            for filter in filters:
                additional_cache_keys += filter.get_additional_cache_keys(
                    **kwargs_final)

        # Note that the key used to cache this hunk is different from the key
        # the hunk will expose to subsequent merges, i.e. hunk.key() is always
        # based on the actual content, and does not match the cache key. The
        # latter also includes information about for example the filters used.
        #
        # It wouldn't have to be this way. Hunk could subsequently expose their
        # cache key through hunk.key(). This would work as well, but would be
        # an inferior solution: Imagine a source file which receives
        # non-substantial changes, in the sense that they do not affect the
        # filter output, for example whitespace. If a hunk's key is the cache
        # key, such a change would invalidate the caches for all subsequent
        # operations on this hunk as well, even though it didn't actually
        # change after all.
        key = ("hunk", hunk, tuple(filters), type, additional_cache_keys)
        return self._wrap_cache(key, func)
Esempio n. 2
0
    def apply(self, hunk, filters, type, kwargs=None):
        """Apply the given list of filters to the hunk, returning a new
        ``MemoryHunk`` object.

        ``kwargs`` are options that should be passed along to the filters.
        If ``hunk`` is a file hunk, a ``source_path`` key will automatically
        be added to ``kwargs``.
        """
        assert type in self.VALID_TRANSFORMS
        log.debug('Need to run method "%s" of filters (%s) on hunk %s with '
                  'kwargs=%s', type, filters, hunk, kwargs)

        filters = [f for f in filters if getattr(f, type, None)]
        if not filters:  # Short-circuit
            log.debug('No filters have "%s" methods, returning hunk '
                      'unchanged' % (type,))
            return hunk

        kwargs_final = self.kwargs.copy()
        kwargs_final.update(kwargs or {})

        def func():
            data = self.create_input_buffer_for(hunk.data())
            for filter in filters:
                data = self.convert_input_buffer_for(filter, data)
                out = self.create_output_buffer_for(filter)
                log.debug('Running method "%s" of  %s with kwargs=%s',
                    type, filter, kwargs_final)
                getattr(filter, type)(data, out, **kwargs_final)
                data = out
                data.seek(0)

            return data

        additional_cache_keys = []
        if kwargs_final:
            for filter in filters:
                additional_cache_keys += filter.get_additional_cache_keys(**kwargs_final)

        # Note that the key used to cache this hunk is different from the key
        # the hunk will expose to subsequent merges, i.e. hunk.key() is always
        # based on the actual content, and does not match the cache key. The
        # latter also includes information about for example the filters used.
        #
        # It wouldn't have to be this way. Hunk could subsequently expose their
        # cache key through hunk.key(). This would work as well, but would be
        # an inferior solution: Imagine a source file which receives
        # non-substantial changes, in the sense that they do not affect the
        # filter output, for example whitespace. If a hunk's key is the cache
        # key, such a change would invalidate the caches for all subsequent
        # operations on this hunk as well, even though it didn't actually
        # change after all.
        key = ("hunk", hunk, tuple(filters), type, additional_cache_keys)
        return self._wrap_cache(key, func)
Esempio n. 3
0
    def apply_func(self, filters, type, args, kwargs=None, cache_key=None):
        """Apply a filter that is not a "stream in, stream out" transform (i.e.
        like the input() and output() filter methods).  Instead, the filter
        method is given the arguments in ``args`` and should then produce an
        output stream. This is used, e.g., for the concat() and open() filter
        methods.

        Only one such filter can run per operation.

        ``cache_key`` may be a list of additional values to use as the cache
        key, in addition to the default key (the filter and arguments).
        """
        assert type in self.VALID_FUNCS
        log.debug(
            'Need to run method "%s" of one of the filters (%s) '
            'with args=%s, kwargs=%s', type, filters, args, kwargs)

        filters = [f for f in filters if getattr(f, type, None)]
        if not filters:  # Short-circuit
            log.debug('No filters have a "%s" method' % type)
            raise NoFilters()

        if len(filters) > 1:
            raise MoreThanOneFilterError(
                'These filters cannot be combined: %s' %
                (', '.join([f.name for f in filters])), filters)

        kwargs_final = self.kwargs.copy()
        kwargs_final.update(kwargs or {})

        def func():
            filter = filters[0]
            out = StringIO(u'')  # For 2.x, StringIO().getvalue() returns str
            log.debug('Running method "%s" of %s with args=%s, kwargs=%s',
                      type, filter, args, kwargs)
            getattr(filter, type)(out, *args, **kwargs_final)
            return out

        additional_cache_keys = []
        if kwargs_final:
            for filter in filters:
                additional_cache_keys += filter.get_additional_cache_keys(
                    **kwargs_final)

        key = ("hunk", args, tuple(filters), type, cache_key
               or [], additional_cache_keys)
        return self._wrap_cache(key, func)
Esempio n. 4
0
File: merge.py Progetto: Alpus/Eth
    def apply_func(self, filters, type, args, kwargs=None, cache_key=None):
        """Apply a filter that is not a "stream in, stream out" transform (i.e.
        like the input() and output() filter methods).  Instead, the filter
        method is given the arguments in ``args`` and should then produce an
        output stream. This is used, e.g., for the concat() and open() filter
        methods.

        Only one such filter can run per operation.

        ``cache_key`` may be a list of additional values to use as the cache
        key, in addition to the default key (the filter and arguments).
        """
        assert type in self.VALID_FUNCS
        log.debug('Need to run method "%s" of one of the filters (%s) '
                  'with args=%s, kwargs=%s', type, filters, args, kwargs)

        filters = [f for f in filters if getattr(f, type, None)]
        if not filters:  # Short-circuit
            log.debug('No filters have a "%s" method' % type)
            raise NoFilters()

        if len(filters) > 1:
            raise MoreThanOneFilterError(
                'These filters cannot be combined: %s' % (
                    ', '.join([f.name for f in filters])), filters)

        kwargs_final = self.kwargs.copy()
        kwargs_final.update(kwargs or {})

        def func():
            filter = filters[0]
            out = StringIO(u'')  # For 2.x, StringIO().getvalue() returns str
            log.debug('Running method "%s" of %s with args=%s, kwargs=%s',
                type, filter, args, kwargs)
            getattr(filter, type)(out, *args, **kwargs_final)
            return out

        additional_cache_keys = []
        if kwargs_final:
            for filter in filters:
                additional_cache_keys += filter.get_additional_cache_keys(**kwargs_final)

        key = ("hunk", args, tuple(filters), type, cache_key or [], additional_cache_keys)
        return self._wrap_cache(key, func)