Beispiel #1
0
 def select_all(self) -> None:
     """Select all text of Enactment."""
     if self.content:
         self._selection = TextPositionSet(
             TextPositionSelector(0, len(self.content)))
     else:
         self._selection = TextPositionSet()
     for child in self._children:
         child.select_all()
Beispiel #2
0
 def test_error_for_unusable_selector(self, section_11_subdivided):
     schema = EnactmentSchema()
     section = schema.load(section_11_subdivided)
     selection = TextPositionSet(TextPositionSelector(0, 10),
                                 TextPositionSelector(1000, 1010))
     with pytest.raises(ValueError):
         section.children[3].select(selection)
Beispiel #3
0
    def select_more_text_from_changed_version(self, other: Enactment) -> None:
        """
        Select more text from a different text version at the same citation path.

        :param other:
            An :class:`Enactment` representing different text enacted at a
            different time, at the same `node` (or USLM path citation) as self.
            This Element's :attr:`~Enactment.node` attribute must be the same
            string as self's node attribute. It's not sufficient for `other`
            to have an Enactment listed in its :attr:`~Enactment._children`
            attribute with the same node attribute,
            or for `other` to have the same node attribute as an ancestor of self.
        """
        incoming_quote_selectors = [
            selector.as_quote_selector(other.text)
            for selector in other.tree_selection()
        ]
        incoming_position_selectors = []
        for quote_selector in incoming_quote_selectors:
            position = quote_selector.as_position(self.text)
            if position:
                incoming_position_selectors.append(position)
            if not quote_selector.is_unique_in(self.text):
                raise ValueError(
                    f"Incoming text selection {quote_selector} cannot be placed because it "
                    f"is not unique in the provision text.")
        self.select_more_text_in_current_branch(
            TextPositionSet(incoming_position_selectors))
Beispiel #4
0
 def test_select_method_clears_previous_selection(self, test_client,
                                                  section_8):
     old_version = test_client.read_from_json(section_8["children"][1])
     old_selector = TextPositionSet(TextPositionSelector(start=0, end=65), )
     old_version.select(old_selector)
     assert old_version.selected_text() == (
         "Any such person issued a notice to remedy under subsection 1 must…"
     )
Beispiel #5
0
class HoldingWithAnchors(BaseModel):
    """A :class:`.Holding` with a :class:`.TextPositionSet` that anchors it."""

    holding: Holding
    anchors: TextPositionSet = TextPositionSet()

    @validator("anchors", pre=True)
    def validate_anchors(cls, value: TextPositionSet) -> TextPositionSet:
        """Validate that the anchors are non-empty."""
        if value is None:
            return TextPositionSet()
        return value
Beispiel #6
0
    def select_from_text_positions(
            self, selection: TextPositionSet) -> TextPositionSet:
        """Select text using position selectors and return any unused position selectors."""
        selections = self.select_from_text_positions_without_nesting(selection)

        selections = [
            selection - self.padded_length for selection in selections
        ]
        for child in self.children:
            selections = child.select_from_text_positions(
                TextPositionSet(selections))
        return selections
Beispiel #7
0
class EnactmentWithAnchors(BaseModel):
    """A term with a set of anchors."""

    passage: EnactmentPassage
    anchors: TextPositionSet = TextPositionSet()

    @validator("anchors", pre=True)
    def validate_anchors(cls, value: TextPositionSet) -> TextPositionSet:
        """Validate that the anchors are non-empty."""

        if value is None:
            return TextPositionSet()
        return value
Beispiel #8
0
class TermWithAnchors(BaseModel):
    """A term with a set of anchors."""

    term: Union[Entity, Fact, Allegation, Pleading, Exhibit, Evidence]
    anchors: TextPositionSet = TextPositionSet()

    @validator("anchors", pre=True)
    def validate_anchors(cls, value: TextPositionSet) -> TextPositionSet:
        """Validate that the anchors are non-empty."""

        if value is None:
            return TextPositionSet()
        return value
Beispiel #9
0
 def test_select_nested_text_with_positions(self, section_11_subdivided):
     phrases = TextPositionSet(
         TextPositionSelector(0, 51),
         TextPositionSelector(61, 73),
         TextPositionSelector(112, 127),
     )
     schema = EnactmentSchema()
     section = schema.load(section_11_subdivided)
     section.select(phrases)
     text_sequence = section.text_sequence()
     assert str(text_sequence) == (
         "The Department of Beards may issue licenses to "
         "such…hairdressers…as they see fit…")
Beispiel #10
0
 def convert_selection_to_set(
     self,
     selection: Union[bool, str, TextPositionSelector, TextPositionSet,
                      TextQuoteSelector, Sequence[TextQuoteSelector], ],
 ) -> TextPositionSet:
     """Create a TextPositionSet from a different selection method."""
     if selection is True:
         return TextPositionSet(
             TextPositionSelector(0,
                                  len(self.content) + 1,
                                  include_end=False))
     factory = TextPositionSetFactory(self.text)
     return factory.from_selection(selection)
Beispiel #11
0
 def __init__(
     self,
     children: List[Enactment] = None,
     selection: Union[bool, List[TextPositionSelector]] = True,
     *args,
     **kwargs,
 ):
     """Assign selected text as attr, including any selected text in child nodes."""
     self._children = children or []
     super().__init__(*args, **kwargs)
     self._selection = TextPositionSet()
     if selection:
         self.select_more(selection)
Beispiel #12
0
    def __init__(
        self,
        children: List[str] = None,
        selection: Union[bool, List[TextPositionSelector]] = True,
        *args,
        **kwargs,
    ):
        """Select text of Enactment that can't have nested Enactments."""
        self._children = children or []
        super().__init__(*args, **kwargs)

        if selection:
            self.select_without_children(selection)
        else:
            self._selection = TextPositionSet()
Beispiel #13
0
    def select_from_text_positions_without_nesting(
        self, selections: Union[List[TextPositionSelector], RangeSet]
    ) -> TextPositionSet:
        r"""
        Move selectors from `selection` to `self._selection` and return any that can't be used.

        Replaces any preexisting _selection attribute on this Enactment object.

        :param selection:
            A TextPositionSet of TextPositionSelectors to apply to this Enactment.

        :returns:
            Any unused selections (beyond the end of the node content)
        """
        self._selection: List[TextPositionSelector] = []

        if isinstance(selections, RangeSet):
            selections = selections.ranges()
        selections = deque(selections)

        while selections and selections[0].start < len(self.content):
            current = selections.popleft()
            if current.end < len(self.content):
                self._selection.append(current)
            else:
                self._selection.append(
                    TextPositionSelector(start=current.start,
                                         end=len(self.content)))
                if current.end > self.padded_length:
                    selections.appendleft(
                        TextPositionSelector(start=self.padded_length,
                                             end=current.end))
        selection_as_set = TextPositionSet(self._selection)
        self._selection = selection_as_set.add_margin(text=self.content,
                                                      margin_width=4)
        return TextPositionSet(selections)
Beispiel #14
0
 def test_get_positions_from_quotes(self, section_11_subdivided):
     schema = EnactmentSchema()
     section = schema.load(section_11_subdivided)
     quotes = [
         TextQuoteSelector(
             exact="The Department of Beards may issue licenses to such"),
         TextQuoteSelector(exact="hairdressers",
                           suffix=", or other male grooming"),
         TextQuoteSelector(exact="as they see fit"),
     ]
     positions = section.convert_quotes_to_position(quotes)
     assert positions == TextPositionSet(
         TextPositionSelector(0, 51),
         TextPositionSelector(61, 73),
         TextPositionSelector(112, 127),
     )
Beispiel #15
0
    def test_get_recursive_selection(self, section_8, test_client):
        version = test_client.read_from_json(section_8["children"][1])
        selector = TextPositionSet(TextPositionSelector(start=0, end=65), )
        version.select(selector)
        version.children[4].select(
            "obtain a beardcoin from the Department of Beards")
        selector_set = version.tree_selection()
        ranges = selector_set.ranges()
        assert ranges[0].start == 0
        assert ranges[0].end == 65

        assert ranges[1].start == 218
        assert ranges[1].end == 266

        as_quotes = selector_set.as_quotes(version.text)
        assert as_quotes[
            1].exact == "obtain a beardcoin from the Department of Beards"
Beispiel #16
0
    def posit_holding(
        self,
        holding: Union[Holding, Rule, HoldingWithAnchors],
        holding_anchors: Optional[Union[TextPositionSelector,
                                        TextQuoteSelector,
                                        TextPositionSet]] = None,
        named_anchors: Optional[List[TermWithAnchors]] = None,
        enactment_anchors: Optional[List[EnactmentWithAnchors]] = None,
        context: Optional[Sequence[Factor]] = None,
    ) -> None:
        r"""Record that this Opinion endorses specified :class:`Holding`\s."""
        named_anchors = named_anchors or []
        enactment_anchors = enactment_anchors or []

        if isinstance(holding, HoldingWithAnchors):
            holding, holding_anchors = holding.holding, holding.anchors
        if isinstance(holding_anchors, (TextQuoteSelector, str)):
            holding_anchors = [holding_anchors]
        if isinstance(holding_anchors, List) and isinstance(
                holding_anchors[0], (str, TextQuoteSelector)):
            holding_anchors = TextPositionSet.from_quotes(holding_anchors)
        if isinstance(holding, Rule):
            logger.warning("posit_holding was called with a Rule "
                           "that was automatically converted to a Holding")
            holding = Holding(rule=holding)

        if not isinstance(holding, Holding):
            raise TypeError('"holding" must be an object of type Holding.')

        for named_anchor in named_anchors:
            self.anchored_holdings.add_term(term=named_anchor.term,
                                            anchors=named_anchor.anchors)

        for enactment_anchor in enactment_anchors:
            self.anchored_holdings.add_enactment(
                enactment=enactment_anchor.passage,
                anchors=named_anchor.anchors)

        matching_holding = self.get_matching_holding(holding)
        if matching_holding:
            matching_holding.anchors += holding.anchors
        else:
            if context:
                holding = holding.new_context(context, source=self)
            self.anchored_holdings.holdings.append(
                HoldingWithAnchors(holding=holding, anchors=holding_anchors))
Beispiel #17
0
    def test_insert_duplicate_anchor_in_factor_index(self):
        api = Entity(name="the Java API", generic=True, plural=False)
        quote_selector = TextQuoteSelector(
            exact="it possesses at least some minimal degree of creativity.")
        anchors = TextPositionSet(quotes=quote_selector)
        fact = Fact(
            predicate=Predicate(
                content=
                "$product possessed at least some minimal degree of creativity"
            ),
            terms=[api],
        )
        term = TermWithAnchors(term=fact, anchors=anchors)
        index = AnchoredHoldings(holdings=[], named_anchors=[term])

        index.add_term(term=fact, anchors=anchors)
        assert len(index.named_anchors) == 1
        assert index.named_anchors[0].anchors.quotes == [quote_selector]
Beispiel #18
0
    def test_add_selection_from_child_node(self, section_8, test_client):
        parent_version = test_client.read_from_json(section_8["children"][1])
        parent_selector = TextPositionSet(
            TextPositionSelector(start=0, end=65), )
        parent_version.select(parent_selector)
        parent_version.children[4].select(
            "obtain a beardcoin from the Department of Beards")
        assert parent_version.selected_text() == (
            "Any such person issued a notice to remedy under subsection 1 must…"
            "obtain a beardcoin from the Department of Beards…")

        child_version = test_client.read_from_json(
            section_8["children"][1]["children"][3])
        child_version.select()

        combined = parent_version + child_version

        assert combined.selected_text() == (
            "Any such person issued a notice to remedy under subsection 1 must…"
            "remove the beard with a laser, or "
            "obtain a beardcoin from the Department of Beards…")
Beispiel #19
0
 def validate_anchors(cls, value: TextPositionSet) -> TextPositionSet:
     """Validate that the anchors are non-empty."""
     if value is None:
         return TextPositionSet()
     return value
Beispiel #20
0
 def select_none(self) -> None:
     """Deselect any Enactment text, including in child nodes."""
     self._selection = TextPositionSet()
     for child in self._children:
         child.select_none()
Beispiel #21
0
 def tree_selection(self) -> TextPositionSet:
     """Return set of selectors for selected text in this provision and its children."""
     new_selector_set, new_tree_length = self._tree_selection(
         selector_set=TextPositionSet(), tree_length=0)
     return new_selector_set