:mod:`lookout.style.format.annotations.annotated_data` ====================================================== .. py:module:: lookout.style.format.annotations.annotated_data Module Contents --------------- .. py:exception:: NoAnnotation Bases::class:`Exception` Raised by `AnnotationManager` methods if there is no Annotation found. See documentation about `AnnotationManager.find_overlapping_annotation()` or `AnnotationManager.find_covering_annotation()` for more information. .. py:class:: AnnotationsSpan(start, stop, *args, **kwargs) Bases::class:`dict` Annotations collection for a specific span (or range). Dictionary-like object. .. attribute:: start .. attribute:: stop .. attribute:: span .. py:class:: AnnotationManager(sequence:str) Manager of `Annotation`-s for a text, e.g. source code. All the methods to work with annotated data should be placed in this class. Candidates can be found here: https://uima.apache.org/d/uimafit-current/api/org/apache/uima/fit/util/JCasUtil.html .. attribute:: sequence .. method:: __len__(self) Return the size of the underlying sequence. .. method:: __getitem__(self, item:Union[int, slice, Tuple[int, int]]) Get the underlying sequence item or sequence slice for the specified range. :param item: index, slice or (start, stop) tuple. :return: The corresponding part of the sequence. .. method:: count(self, annotation_type:Type[Annotation]) Count the number of annotations of a specific type. .. method:: add(self, *annotations) Add several annotations. .. method:: _add(self, annotation:Annotation) Add an annotation. Annotations of the same type may not overlap. .. method:: get(self, annotation_type:Type[Annotation], span:Optional[Tuple[int, int]]=None) Return an annotation for the given span and type. Looking for an exact (type and span) match only. :param annotation_type: Annotation type to get. :param span: Annotation span (range) to get. If span is not specified it returns an annotation that cover all content (aka global annotation). :return: Requested `Annotation`. .. method:: iter_by_type_nested(self, annotation_type:Type[Annotation], *covered_by, start_offset:Optional[int]=None) Iterate over annotations of the specified type which are covered by some other annotation types. Iteration goes over `annotation_type` objects. Annotations which are specified in `covered_by` are added to the resulting `AnnotationsSpan` object. Spans of the additional annotations should fully cover the spans of `annotation_type`. For example, suppose that you have *line* and *token* annotations. Each line contains several tokens. If you try to iterate through *line* and set *token* as `covered_by` annotation you get only *line* annotation inside `AnnotationsSpan`. It happens because you can annotate *token* with *line* but not *line* with *token*: *token* is covered by only one line and not vice versa. So, manager.iter_by_type_nested(line, token) # gives you only line annotation as output, # *token* annotations not found manager.iter_by_type_nested(token, line) # gives you *token* and *line* annotations # because it is possible to find only one # covering *line* annotation. `covered_by` can't be empty. If you need to iterate over a single annotation type, you should call `AnnotationManager.iter_annotation()` instead. :param annotation_type: Type of annotation to iterate through. :param covered_by: Additional annotations that should be added to the main one if they cover its span. :param start_offset: Start to iterate from a specific offset. Can be used as a key argument only. :return: Iterator over annotations of the requested type. .. method:: iter_by_type(self, annotation_type:Type[Annotation], *, start_offset:Optional[int]=None) Iterate over annotations of the specified type. If you need to iterate through several annotations use `AnnotationManager.iter_annotations()` instead. :param annotation_type: Type of annotation to iterate through. :param start_offset: Start to iterate from the spesific offset. Can be used as a key argument only. :return: Iterator through annotations of requested type. .. method:: _find_annotations(self, annotation_type:Type[Annotation], start:int, stop:int, inspect:Callable, action:str) .. method:: find_overlapping_annotation(self, annotation_type:Type[Annotation], start:int, stop:int) Find an annotation of the given type that intersects the interval [start, stop). :param annotation_type: Annotation type to look for. :param start: Start of the search interval. :param stop: End of the search interval. Stop point itself is excluded. :raise NoAnnotation: There is no such annotation that overlaps with the given interval. :return: `Annotation` of the requested type. .. method:: find_covering_annotation(self, annotation_type:Type[Annotation], start:int, stop:int) Find an annotation of the given type that fully covers the interval [start, stop). :param annotation_type: Annotation type to look for. :param start: Start of the search interval. :param stop: End of the search interval. Stop point itself is excluded. :raise NoAnnotation: There is no such annotation that overlaps with the given interval. :return: `Annotation` of the requested type. .. classmethod:: _check_spans_overlap(cls, start1:int, stop1:int, start2:int, stop2:int) Check if two spans have at least 1 common point. Span 1 is [start1, stop1). `stop1` itself is excluded. Span 2 is [start2, stop2). `stop2` itself is excluded. Everywhere in next examples x < y < z. Corner cases explained: 1. [x, y) and [y, z) have no overlap because y is excluded from the 1st interval. 2. 0-intervals: 2.1. [y, y) and [y, y) are overlapping because it is the same interval. 2.2. [y, y) and [y, z) have no overlap. 2.3. [x, y) and [y, y) have no overlap. 2.4. [x, z) and [y, y) are overlapping because [x, z) fully covers y point. Despite the fact that overlapping rules are defined for 0-intervals, it is unsafe to rely on them. If you want to get an additional annotation of the 0-interval annotation, link one annotation to another. See `TokenAnnotation` for example. :param start1: Start offset of the first span. :param stop1: Stop offset of the first span. :param start2: Start offset of the second span. :param stop2: Stop offset of the second span. :return: True if two spans overlap, otherwise False. .. classmethod:: from_file(cls, file:UnicodeFile) Create `AnnotationManager` instance from `UnicodeFile`. :param file: `file.content` will be used as data to be annotated with `file.path`, `file.language` and `file.uast`. :return: new AnnotationManager instance.