src/services/intervals.py
BeforeProposed
+18−2
1010
1111
1212def spans(document, policy):
13 return [Span(item.start, item.end, (item.kind,), policy.action(item.kind))
14 for item in document.annotations if policy.action(item.kind) != 'keep']
13 active = sorted(
14 (item for item in document.annotations if policy.action(item.kind) != 'keep'),
15 key=lambda item: (item.start, item.end, item.kind),
16 )
17 groups = []
18 for item in active:
19 if not groups or item.start >= groups[-1]['end']:
20 groups.append({'start': item.start, 'end': item.end, 'items': [item]})
21 else:
22 groups[-1]['end'] = max(groups[-1]['end'], item.end)
23 groups[-1]['items'].append(item)
24 result = []
25 for group in groups:
26 kinds = tuple(sorted({item.kind for item in group['items']}))
27 # A composite span must never expose text through conflicting policies.
28 action = 'mask' if len(kinds) > 1 else policy.action(kinds[0])
29 result.append(Span(group['start'], group['end'], kinds, action))
30 return result