Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: abp/filters/renderer.py

Issue 29465720: Issue 4970 - Document the library API of python-abp (Closed)
Patch Set: Rebase to match the new master and retouche the docstrings. Created Oct. 24, 2017, 4:06 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 # This file is part of Adblock Plus <https://adblockplus.org/>, 1 # This file is part of Adblock Plus <https://adblockplus.org/>,
2 # Copyright (C) 2006-present eyeo GmbH 2 # Copyright (C) 2006-present eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details. 11 # GNU General Public License for more details.
12 # 12 #
13 # You should have received a copy of the GNU General Public License 13 # You should have received a copy of the GNU General Public License
14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
15 15
16 """Combine filter list fragments to produce filter lists."""
17
16 from __future__ import unicode_literals 18 from __future__ import unicode_literals
17 19
18 import base64 20 import base64
19 import hashlib 21 import hashlib
20 import itertools 22 import itertools
21 import logging 23 import logging
22 import time 24 import time
23 25
24 from .parser import parse_filterlist, Comment, Metadata 26 from .parser import parse_filterlist, Comment, Metadata
25 from .sources import NotFound 27 from .sources import NotFound
26 28
27 __all__ = ['render_filterlist', 'IncludeError', 'MissingHeader'] 29 __all__ = ['IncludeError', 'MissingHeader', 'render_filterlist']
28 30
29 _logger = logging.getLogger(__name__) 31 _logger = logging.getLogger(__name__)
30 32
31 33
32 class IncludeError(Exception): 34 class IncludeError(Exception):
33 """Error in processing include instruction. 35 """Error in processing include instruction."""
34
35 :param error: Description of the error.
36 :param stack: A list of the names of included files.
37 """
38 36
39 def __init__(self, error, stack): 37 def __init__(self, error, stack):
40 stack_str = ' from '.join(map("'{}'".format, reversed(stack))) 38 stack_str = ' from '.join(map("'{}'".format, reversed(stack)))
41 if stack_str: 39 if stack_str:
42 error = '{} when including {}'.format(error, stack_str) 40 error = '{} when including {}'.format(error, stack_str)
43 Exception.__init__(self, error) 41 Exception.__init__(self, error)
44 42
45 43
46 class MissingHeader(Exception): 44 class MissingHeader(Exception):
47 """First line of the result is not a valid header.""" 45 """First line of the result is not a valid header."""
48 46
49 47
50 def _get_and_parse_fragment(name, sources, default_source, include_stack=[]): 48 def _get_and_parse_fragment(name, sources, default_source, include_stack=[]):
51 """Retrieve and parse fragment. 49 """Retrieve and parse fragment.
52 50
53 :returns: a tuple `(lines_iterator, inherited_source)` where 51 Returns
54 `inherited_source` is the default source to use for included 52 -------
55 fragments. 53 tuple (iterator of str, Source)
54 First part is the content of the fragment line by line; second part is
55 the default source to be used for included fragments.
56
56 """ 57 """
57 if ':' in name: 58 if ':' in name:
58 source_name, name_in_source = name.split(':', 1) 59 source_name, name_in_source = name.split(':', 1)
59 try: 60 try:
60 source = sources[source_name] 61 source = sources[source_name]
61 except KeyError: 62 except KeyError:
62 raise IncludeError("Unknown source: '{}'".format(source_name), 63 raise IncludeError("Unknown source: '{}'".format(source_name),
63 include_stack) 64 include_stack)
64 else: 65 else:
65 source, name_in_source = default_source, name 66 source, name_in_source = default_source, name
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 """Validate the final list.""" 160 """Validate the final list."""
160 first_line, rest = _first_and_rest(lines) 161 first_line, rest = _first_and_rest(lines)
161 if first_line.type != 'header': 162 if first_line.type != 'header':
162 raise MissingHeader('No header found at the beginning of the input.') 163 raise MissingHeader('No header found at the beginning of the input.')
163 return itertools.chain([first_line], rest) 164 return itertools.chain([first_line], rest)
164 165
165 166
166 def render_filterlist(name, sources, top_source=None): 167 def render_filterlist(name, sources, top_source=None):
167 """Produce filter list from fragments. 168 """Produce filter list from fragments.
168 169
169 :param name: Name of the top level fragment. 170 Parameters
170 :param sources: A mapping of source names to sources for getting fragments. 171 ----------
171 :param top_source: Default source used for getting top fragment. 172 name : str
172 :returns: Iterable of of filter list lines (see `line_type` in parser.py). 173 Name of the top level fragment.
173 :raises IncludeError: When an include error can't be processed. 174 sources : dict of str -> Source
174 :raises ParseError: When any of the fragments contain lines that can't 175 Sources for loading included fragments.
175 be parsed. 176 top_source : Source
176 :raises MissingHeader: If the top level fragment doesn't start with a valid 177 The source used to load the top level fragment.
177 header. 178
179 Returns
180 -------
181 iterable of namedtuple (see `_line_type` in parser.py)
182 Rendered filter list.
183
184 Raises
185 ------
186 IncludeError
187 When an include error can't be processed.
188 ParseError
189 When any of the fragments contain lines that can't be parsed.
190 MissingHeader
191 If the top level fragment doesn't start with a valid header. This would
192 lead to rendering an invalid filter list, so we immediately abort.
193
178 """ 194 """
179 _logger.info('Rendering: %s', name) 195 _logger.info('Rendering: %s', name)
180 lines, default_source = _get_and_parse_fragment(name, sources, top_source) 196 lines, default_source = _get_and_parse_fragment(name, sources, top_source)
181 lines = _process_includes(sources, default_source, [name], lines) 197 lines = _process_includes(sources, default_source, [name], lines)
182 for proc in [_process_timestamps, _insert_version, _remove_duplicates, 198 for proc in [_process_timestamps, _insert_version, _remove_duplicates,
183 _insert_checksum, _validate]: 199 _insert_checksum, _validate]:
184 lines = proc(lines) 200 lines = proc(lines)
185 return lines 201 return lines
OLDNEW

Powered by Google App Engine
This is Rietveld