Ejemplo n.º 1
0
def read_holding(record: RawHolding,
                 regime: Optional[Regime] = None) -> Holding:
    r"""
    Create new :class:`Holding` object from simple datatypes from JSON input.

    Will yield multiple items if ``exclusive: True`` is present in ``record``.

    :param record:
        dict of values for constructing :class:`.Holding`

    :param regime:
        Collection of :class:`.Jurisdiction`\s and corresponding
        :class:`.Code`\s for discovering :class:`.Enactment`\s to
        reference in the new :class:`Holding`.

    :param many:
        if True, record represents a list of :class:`Holding`\s rather than
        just one.

    :returns:
        New :class:`.Holding`, and an updated dictionary with mentioned
        :class:`.Factor`\s as keys and their :class:`.TextQuoteSelector`\s
        as values.
    """
    schema = schemas.HoldingSchema(many=False)
    record, schema.context["mentioned"] = index_names(record)
    schema.context["regime"] = regime
    return schema.load(deepcopy(record))
Ejemplo n.º 2
0
def read_enactments(
    record: List[RawEnactment],
    code: Optional[Code] = None,
    regime: Optional[Regime] = None,
) -> List[Enactment]:
    r"""
    Create a new :class:`Enactment` object using imported JSON data.

    The new :class:`Enactment` can be composed from a :class:`.Code`
    referenced in the ``regime`` parameter.

    :param record:
        sequence of :class:`dict`\s with string fields from JSON for
        constructing new :class:`.Enactment`\s

    :param code:
        a :class:`.Code` that is the source for every :class:`Enactment`
        to be loaded, if they all come from the same :class:`.Code`

    :param regime:
        the :class:`.Regime` where the :class:`.Code`\s that are the
        source for this :class:`Enactment` can be found, or where
        it should be added

    :returns:
        a list of new :class:`Enactment` objects, optionally with text links.
    """
    schema = schemas.EnactmentSchema(many=True)
    record, schema.context["mentioned"] = index_names(record)
    schema.context["regime"] = regime
    schema.context["code"] = code
    return schema.load(deepcopy(record))
Ejemplo n.º 3
0
def read_enactment(record: RawEnactment,
                   code: Optional[Code] = None,
                   regime: Optional[Regime] = None) -> Enactment:
    r"""
    Create a new :class:`.Enactment` object using imported JSON data.

    The new :class:`.Enactment` can be composed from a :class:`.Code`
    referenced in the ``regime`` parameter.

    :param record:
        :class:`dict` with string fields from JSON for constructing
        new :class:`.Enactment`

    :param code:
        the :class:`.Code` that is the source for this
        :class:`Enactment`

    :param regime:
        the :class:`.Regime` where the :class:`.Code` that is the
        source for this :class:`Enactment` can be found, or where
        it should be added

    :returns:
        a new :class:`Enactment` object, optionally with text links.
    """
    schema = schemas.EnactmentSchema(many=False)
    record, schema.context["mentioned"] = index_names(record)
    schema.context["regime"] = regime
    schema.context["code"] = code
    return schema.load(deepcopy(record))
Ejemplo n.º 4
0
def extract_anchors_from_holding_record(
    record: List[RawHolding],
    client: Optional[Client] = None
) -> Tuple[List[Holding], List[EnactmentWithAnchors], List[TermWithAnchors],
           List[Dict[str, str]], ]:
    r"""
    Load a list of Holdings from JSON, with text links.

    :param record:
        a list of dicts representing holdings, in the JSON input format

    :param client:
        Legislice client for downloading missing fields from `record`

    :returns:
        a tuple of four objects containing holdings, terms, enactments,
        and anchors.
    """
    record_post_enactments, enactment_index = collect_enactments(record)
    if client:
        enactment_index_post_client = client.update_entries_in_enactment_index(
            enactment_index)
    else:
        enactment_index_post_client = enactment_index
    enactment_anchors, enactment_index_post_anchors = collect_anchors_from_index(
        enactment_index_post_client, "passage")

    enactment_result = []
    for anchor in enactment_anchors:
        anchor["passage"] = enactment_index_post_anchors.get_if_present(
            anchor["passage"])
        enactment_result.append(EnactmentWithAnchors(**anchor))

    record_post_terms, factor_index = index_names(record_post_enactments)
    factor_anchors, factor_index_post_anchors = collect_anchors_from_index(
        factor_index, "term")

    factor_result = []
    for anchor in factor_anchors:
        anchor["term"] = expand_holding(
            anchor["term"],
            factor_index=factor_index_post_anchors,
            enactment_index=enactment_index_post_anchors,
        )
        factor_result.append(TermWithAnchors(**anchor))

    factor_anchors = [TermWithAnchors(**anchor) for anchor in factor_anchors]

    expanded = expand_holdings(
        record_post_terms,
        factor_index=factor_index_post_anchors,
        enactment_index=enactment_index_post_anchors,
    )
    holding_anchors = [holding.pop("anchors", None) for holding in expanded]

    result = []
    for holding in expanded:
        result.append(Holding(**holding))
    return result, enactment_result, factor_result, holding_anchors
 def test_enactment_name_index(self, make_regime):
     """
     Test error message:
     'Name "securing for authors" not found in the index of mentioned Factors'
     """
     feist_records = loaders.load_holdings("holding_feist.json")
     record, mentioned = name_index.index_names(feist_records)
     assert "securing for authors" in mentioned
Ejemplo n.º 6
0
def read_rules_with_index(record: List[RawRule],
                          regime: Optional[Regime] = None,
                          many: bool = True) -> Tuple[List[Rule], Mentioned]:
    r"""Make :class:`Rule` and "mentioned" index from dict of fields and :class:`.Regime`\."""
    record, mentioned = index_names(record)
    schema = schemas.RuleSchema(many=many)
    schema.context["regime"] = regime
    schema.context["mentioned"] = mentioned
    rules = schema.load(deepcopy(record))
    return rules, mentioned
Ejemplo n.º 7
0
    def test_import_predicate_with_quantity(self):
        record = expand_shorthand(self.story_data)
        record, mentioned = index_names(record)
        expanded = readers.expand_factor(record, mentioned)
        story = Fact(**expanded)

        assert len(story.predicate) == 1
        assert story.predicate.content.startswith("The number of castles")
        assert story.predicate.sign == ">"
        assert story.predicate.quantity == 3
Ejemplo n.º 8
0
def read_holdings_with_index(record: List[RawHolding],
                             regime: Optional[Regime] = None,
                             many: bool = True) -> HoldingsIndexed:
    r"""Load a list of :class:`Holdings`\s from JSON, with "mentioned" index."""
    record, mentioned = index_names(record)
    schema = schemas.HoldingSchema(many=many)
    schema.context["regime"] = regime
    schema.context["mentioned"] = mentioned
    anchor_list = anchors.get_holding_anchors(record)
    holdings = schema.load(deepcopy(record))
    return HoldingsIndexed(holdings, mentioned, anchor_list)
Ejemplo n.º 9
0
    def test_enactment_with_anchor(self, make_regime):
        record, mentioned = name_index.index_names(self.test_enactments[1])
        schema = schemas.EnactmentSchema(many=False)
        schema.context["mentioned"] = mentioned
        schema.context["regime"] = make_regime
        enactment = schema.load(record)

        factor_anchors = anchors.get_named_anchors(mentioned)
        assert enactment.text.startswith(
            "nor shall any State deprive any person of life, liberty, or property"
        )
        assert (factor_anchors[enactment.name][0].exact ==
                "reference to the Due Process Clause")
Ejemplo n.º 10
0
 def test_link_longest_context_factors_first(self):
     """
     If read_holdings interprets the second "Bradley" string as
     a reference to Bradley rather than "Bradley's house", it's wrong.
     """
     to_read = {
         "outputs": [
             {"type": "fact", "content": "{Bradley's house} was a house"},
             {"type": "fact", "content": "{Bradley} lived at Bradley's house"},
         ]
     }
     record, mentioned = name_index.index_names(to_read)
     lived_at = record["outputs"][1]
     assert mentioned[lived_at]["context_factors"][1] == "Bradley's house"
Ejemplo n.º 11
0
def read_fact(record: RawFactor) -> Fact:
    r"""
    Construct a :class:`Fact` after loading a dict from JSON.

    :param record:
        parameter values to pass to :class:`.FactSchema`\.

    :returns:
        a :class:`Fact`, with optional mentioned factors
    """
    record, mentioned = index_names(record)
    schema = schemas.FactSchema()
    schema.context["mentioned"] = mentioned
    return schema.load(record)
Ejemplo n.º 12
0
def read_factors(record: List[RawFactor],
                 regime: Optional[Regime] = None,
                 **kwargs) -> Factor:
    r"""
    Turn fields from JSON into a :class:`Factor` object.

    :param record:
        parameter values to pass to schema

    :parame regime:
        to look up any :class:`.Enactment` references
    """
    schema = schemas.FactorSchema(many=True)
    record, schema.context["mentioned"] = index_names(record)
    schema.context["regime"] = regime
    return schema.load(record)
Ejemplo n.º 13
0
def read_rule(record: Dict, regime: Optional[Regime] = None) -> Rule:
    r"""
    Make :class:`Rule` from a :class:`dict` of fields and a :class:`.Regime`\.

    :param record:

    :param regime:

    :returns:
        iterator yielding :class:`Rule`\s with the items
        from ``mentioned_entities`` as ``context_factors``
    """
    record, mentioned = index_names(record)
    schema = schemas.RuleSchema()
    schema.context["mentioned"] = mentioned
    schema.context["regime"] = regime
    return schema.load(record)
Ejemplo n.º 14
0
def read_procedure(record: Dict,
                   regime: Optional[Regime] = None,
                   many=False) -> Procedure:
    r"""
    Turn fields from JSON into a :class:`Procedure` object.

    :param record:
        parameter values to pass to schema

    :param many:
        whether to use the "many" form of the Marshmallow
        schema (whether there are multiple Procedures)

    :parame regime:
        to look up any :class:`.Enactment` references
    """
    schema = schemas.ProcedureSchema(many=many)
    record, schema.context["mentioned"] = index_names(record)
    schema.context["regime"] = regime
    return schema.load(record)
Ejemplo n.º 15
0
    def test_make_fact_from_string(self, watt_factor):
        fact_float_data = {
            "content":
            "the distance between $person0 and $person1 was >= 20.1",
            "terms": [
                {
                    "type": "Entity",
                    "name": "Ann"
                },
                {
                    "type": "Entity",
                    "name": "Lee"
                },
            ],
        }
        record = expand_shorthand(fact_float_data)
        record, mentioned = index_names(record)
        expanded = readers.expand_factor(record, mentioned)

        fact_float_more = Fact(**expanded)
        fact_float_less = watt_factor["f8_int"]
        assert fact_float_more >= fact_float_less
 def test_index_before_apostrophe(self):
     """
     Not catching the error where 'Bradley exhibited an expectation of privacy in
     Bradley's marijuana patch' becomes '{} exhibited an expectation of privacy in {{}'
     """
     raw_holding = {
         "outputs": [
             {
                 "type": "Fact",
                 "content": "the {possessive noun}'s factor was linked correctly",
             },
             {
                 "type": "Fact",
                 "content": "the possessive noun's factor was still linked correctly",
             },
         ],
     }
     holding, mentioned = name_index.index_names(raw_holding)
     factor_name_1 = holding["outputs"][0]
     assert mentioned[factor_name_1]["context_factors"][0] == "possessive noun"
     factor_name_2 = holding["outputs"][1]
     assert mentioned[factor_name_2]["context_factors"][0] == "possessive noun"
Ejemplo n.º 17
0
def read_holdings(
    record: List[RawHolding],
    regime: Optional[Regime] = None,
    code: Optional[Code] = None,
) -> List[Holding]:
    r"""
    Load a list of :class:`Holdings`\s from JSON.

    :param record:
        a list of dicts representing holdings, in the JSON input format

    :parame regime:
        A collection of :class:`.Jurisdiction`\s and the :class:`.Code`\s
        that have been enacted in each. Used for constructing
        :class:`.Enactment`\s referenced by :class:`.Holding`\s.

    :returns:
        a list of :class:`.Holding` objects
    """
    schema = schemas.HoldingSchema(many=True)
    record, schema.context["mentioned"] = index_names(record)
    schema.context["regime"] = regime
    schema.context["code"] = code
    return schema.load(deepcopy(record))
Ejemplo n.º 18
0
 def test_index_names_from_sibling_inputs(self, make_regime):
     raw_rules = loaders.load_holdings("beard_rules.json")
     indexed_rules, mentioned = name_index.index_names(
         raw_rules[0]["inputs"])
     key = "the suspected beard occurred on or below the chin"
     assert mentioned[key]["context_factors"][0] == "the suspected beard"
 def test_mentioned_ordered_by_length(self, raw_factor):
     obj = text_expansion.expand_shorthand(raw_factor["relevant"])
     obj, mentioned = name_index.index_names(obj)
     shortest = mentioned.popitem()
     assert shortest[0] == "Short Name"
 def test_index_names_turns_context_factor_str_into_list(self, raw_factor):
     short_shot_long, mentioned = name_index.index_names(
         raw_factor["relevant"]["context_factors"][0]
     )
     assert isinstance(mentioned[short_shot_long]["context_factors"], list)
 def test_index_names(self, raw_factor):
     obj, mentioned = name_index.index_names(raw_factor["relevant"])
     factor = mentioned[obj]["context_factors"][0]
     assert mentioned[factor]["context_factors"][0] == "Short Name"
Ejemplo n.º 22
0
 def test_import_enactments_and_anchors(self, make_regime, make_opinion):
     """
     Testing issue that caused enactment expansion to fail only when
     text anchors were loaded.
     """
     raw_holdings = [
         {
             "inputs": {
                 "type": "fact",
                 "content": "{Rural's telephone directory} was a fact",
                 "anchors": [
                     {"exact": "facts", "prefix": "The first is that"},
                     {
                         "exact": "as to facts",
                         "prefix": "No one may claim originality",
                     },
                     {"exact": "facts", "prefix": "no one may copyright"},
                 ],
             },
             "outputs": {
                 "type": "fact",
                 "content": "Rural's telephone directory was copyrightable",
                 "truth": False,
                 "anchors": [
                     {
                         "exact": "are not copyrightable",
                         "prefix": "The first is that facts",
                     },
                     {"exact": "no one may copyright", "suffix": "facts"},
                 ],
             },
             "enactments": [
                 {
                     "source": "/us/const/article-I/8/8",
                     "exact": (
                         "To promote the Progress of Science and useful Arts, "
                         "by securing for limited Times to Authors"
                     ),
                     "name": "securing for authors",
                 },
                 {
                     "source": "/us/const/article-I/8/8",
                     "exact": "the exclusive Right to their respective Writings",
                     "name": "right to writings",
                 },
             ],
             "mandatory": True,
             "universal": True,
         },
         {
             "outputs": {
                 "type": "fact",
                 "content": "Rural's telephone directory was copyrightable",
                 "anchors": [
                     {
                         "exact": "copyrightable",
                         "prefix": "first is that facts are not",
                     },
                     "The sine qua non of|copyright|",
                 ],
             },
             "enactments": ["securing for authors", "right to writings"],
             "mandatory": True,
             "anchors": "compilations of facts|generally are|",
         },
     ]
     record, mentioned = name_index.index_names(raw_holdings)
     holding_anchors = anchors.get_holding_anchors(record)
     named_anchors = anchors.get_named_anchors(mentioned)
     schema = schemas.HoldingSchema(many=True)
     schema.context["mentioned"] = mentioned
     schema.context["regime"] = make_regime
     feist_holdings = schema.load(record)
     feist = make_opinion["feist_majority"]
     feist.posit(
         feist_holdings, holding_anchors=holding_anchors, named_anchors=named_anchors
     )
     assert feist.holdings[0].enactments[0].name == "securing for authors"
     assert feist.holdings[1].enactments[0].name == "securing for authors"
Ejemplo n.º 23
0
 def test_index_names_from_otherwise_identical_factors(self):
     expanded, mentioned = name_index.index_names(self.smith_holdings)
     fact = mentioned[expanded[1]["inputs"][0]]
     assert fact["context_factors"][0] == "Smythe"
Ejemplo n.º 24
0
 def test_anchors_from_fact_with_inferred_name(self):
     record, mentioned = index_names(self.fact)
     factor_anchors = anchors.get_named_anchors(mentioned)
     fact_anchors = factor_anchors[
         "false Rural's telephone directory was copyrightable"]
     assert fact_anchors[1].exact == "no one may copyright"
Ejemplo n.º 25
0
 def test_anchor_not_overwritten_when_indexing(self, raw_holding):
     watch = raw_holding["stolen watch"]
     record, mentioned = name_index.index_names(watch)
     assert len(mentioned["Mark stole a watch"]["anchors"]) == 2
Ejemplo n.º 26
0
 def test_make_enactment_anchor(self):
     record, mentioned = index_names(self.enactment_anchor)
     named_anchors = anchors.get_named_anchors(mentioned)
     enactment_anchors = named_anchors["copyright protection provision"]
     assert enactment_anchors[0].exact == "17 U.S.C. § 102(a)"
Ejemplo n.º 27
0
    def test_import_fact_with_entity_name_containing_another(self):
        expanded = expand_shorthand(self.house_data)
        record, mentioned = index_names(expanded)

        assert mentioned["Alice's house"]["type"] == "Entity"
Ejemplo n.º 28
0
 def test_index_names_from_sibling_inputs(self):
     raw_rules = loaders.load_holdings("beard_rules.yaml")
     indexed_rules, mentioned = name_index.index_names(
         raw_rules[0]["inputs"])
     key = "the suspected beard occurred on or below the chin"
     assert mentioned[key]["terms"][0] == "the suspected beard"