def test_extract_report_owner_form3_collection(test_form3_collection, doc_num: int): """ Validate Form3 extraction code against a random sample of documents :param test_form3_collection: :return: """ file = list(test_form3_collection.glob("*.txt"))[doc_num] doc = Form3(file) assert doc.filename == file.name fields_list = doc.report_owners assert len(fields_list) > 0 for idx, fields in enumerate(fields_list): assert (len(fields)) == 19 assert fields["filename"] == file.name assert fields["order"] == f"{idx+1}" assert fields["type"] == "reportingOwner" assert fields["index"] == f"reportingOwner{idx+1}" assert validate(file, fields["rpt_owner_cik"], r"\d{10}") assert validate(file, fields["rpt_owner_name"], r".+") assert validate(file, fields["rpt_owner_city"], r".+") assert validate(file, fields["is_director"], r"[10]", none_allowed=True) assert validate(file, fields["is_officer"], r"[10]", none_allowed=True) assert validate(file, fields["is_ten_percent_owner"], r"[10]", none_allowed=True) assert validate(file, fields["is_other"], r"[10]", none_allowed=True)
def test_extract_report_owner_form3(test_form3): """ Validate Form3 extraction code against a single detailed example :param test_form3: :return: """ doc = Form3(test_form3) assert doc.accession_num == "0001209191-20-054135" assert doc.filename == test_form3.name fields_list = doc.report_owners assert len(fields_list) == 1 assert len(fields_list[0]) == 19 assert fields_list[0]["filename"] == test_form3.name assert fields_list[0]["accession_num"] == doc.accession_num assert fields_list[0]["order"] == "1" assert fields_list[0]["type"] == "reportingOwner" assert fields_list[0]["index"] == "reportingOwner1" assert fields_list[0]["rpt_owner_cik"] == "0001676526" assert fields_list[0]["rpt_owner_name"] == "Lawler John T." assert fields_list[0]["rpt_owner_street1"] == "ONE AMERICAN ROAD" assert fields_list[0]["rpt_owner_street2"] is None assert fields_list[0]["rpt_owner_city"] == "DEARBORN" assert fields_list[0]["rpt_owner_state"] == "MI" assert fields_list[0]["rpt_owner_zip_code"] == "48126" assert fields_list[0]["rpt_owner_state_descr"] is None assert fields_list[0]["is_director"] == "0" assert fields_list[0]["is_officer"] == "1" assert fields_list[0]["is_ten_percent_owner"] == "0" assert fields_list[0]["is_other"] == "0" assert fields_list[0]["officer_title"] == "Vice President, CFO" assert fields_list[0]["other_text"] is None
def test_extract_derivative_trans_form3_collection(test_form3_collection, doc_num: int): """ Validate Form3 extraction code against a random sample of documents :param test_form3_collection: :return: """ file = list(test_form3_collection.glob("*.txt"))[doc_num] doc = Form3(file) assert doc.filename == file.name fields_list = doc.derivatives assert len(fields_list) >= 0 for idx, fields in enumerate(fields_list): assert (len(fields)) == 12 assert fields["filename"] == file.name assert fields["accession_num"] == doc.accession_num assert fields["order"] == f"{idx+1}" assert fields["type"] == "derivHolding" assert fields["index"] == f"derivHolding{idx+1}" assert validate(file, fields["accession_num"], r"[\d-]+") assert validate(file, fields["security_title"], r".+") assert validate(file, fields["conversion_or_exercise_price"], r"[\d+\.]*") assert validate(file, fields["exercise_date"], r"(\d\d\d\d-\d\d-\d\d)?") assert validate(file, fields["expiration_date"], r"(\d\d\d\d-\d\d-\d\d)?") assert validate(file, fields["underlying_security_title"], r".+") assert validate(file, fields["underlying_security_shares"], r"[\d+\.]+") assert validate(file, fields["direct_or_indirect_ownership"], r"[DI]")
def test_extract_doclevel_form3_collection(test_form3_collection): """ Validate Form3 extraction code against a random sample of documents :param test_form3_collection: :return: """ for file in test_form3_collection.glob("*.txt"): doc = Form3(file) assert doc.filename == file.name fields = doc.doc_info assert len(fields) == 19 assert fields["filename"] == file.name assert fields["schema_version"] == "X0206" assert fields["document_type"] == "3" assert validate(file, fields["accession_num"], r"[\d-]+") assert validate(file, fields["sec_accept_datetime"], r"\d{14,14}") assert validate(file, fields["sec_file_num"], r"[\d-]+") assert validate(file, fields["doc_count"], r"\d+") assert validate(file, fields["filed_date"], r"\d{8,8}") assert validate(file, fields["conformed_period_of_report"], r"\d{8,8}") assert validate(file, fields["change_date"], r"\d{8,8}") assert validate(file, fields["period_of_report"], r"\d\d\d\d-\d\d-\d\d") assert validate( file, fields["not_subject_to_section_16"], r"[10]", none_allowed=True ) assert validate(file, fields["issuer_cik"], r"\d+") assert validate(file, fields["issuer_name"], r".+") assert validate(file, fields["issuer_trading_symbol"], r"[A-Z\.]+") assert validate(file, fields["regcik"], r"\d+") assert validate(file, fields["regsic"], r"\d\d\d\d", none_allowed=True) assert validate(file, fields["no_securities_owned"], r"[01]")
def test_extract_doclevel_form3(test_form3): """ Validate Form3 extraction code against a single detailed example :param test_form3: :return: """ doc = Form3(test_form3) assert doc.accession_num == "0001209191-20-054135" assert doc.filename == test_form3.name fields = doc.doc_info assert len(fields) == 19 assert fields["filename"] == test_form3.name assert fields["accession_num"] == doc.accession_num assert fields["sec_accept_datetime"] == "20201007163300" assert fields["sec_file_num"] == "001-03950" assert fields["doc_count"] == "2" assert fields["filed_date"] == "20201007" assert fields["conformed_period_of_report"] == "20201001" assert fields["change_date"] == "20201007" assert fields["schema_version"] == "X0206" assert fields["document_type"] == "3" assert fields["period_of_report"] == "2020-10-01" assert fields["not_subject_to_section_16"] is None assert fields["issuer_cik"] == "0000037996" assert fields["issuer_name"] == "FORD MOTOR CO" assert fields["issuer_trading_symbol"] == "F" assert fields["remarks"] is None assert fields["regcik"] == "0000037996" assert fields["regsic"] == "3711" assert fields["no_securities_owned"] == "0"
def test_extract_footnotes_form3(test_form3): """ Validate Form3 extraction code against a single detailed example :param test_form3: :return: """ doc = Form3(test_form3) assert doc.accession_num == "0001209191-20-054135" assert doc.filename == test_form3.name fields_list = doc.footnotes assert len(fields_list) == 19 assert len(fields_list[0]) == 6 assert fields_list[0]["filename"] == test_form3.name assert fields_list[0]["accession_num"] == doc.accession_num assert fields_list[0]["footnote"] == "F1" assert fields_list[0]["index"] == "derivHolding1" assert fields_list[0]["field"] == "conversionOrExercisePrice" assert fields_list[0]["text"][:27] == "These Ford Stock Fund Units" assert fields_list[18]["filename"] == test_form3.name assert fields_list[18]["accession_num"] == doc.accession_num assert fields_list[18]["footnote"] == "F9" assert fields_list[18]["index"] == "derivHolding9" assert fields_list[18]["field"] == "expirationDate" assert fields_list[18]["text"][:27] == "These Ford Restricted Stock"
def create_doc(file: Path) -> Document: xmlpath = Document.xml_document_fields["document_type"] regex = re.compile(f"<{xmlpath}>(.+)</{xmlpath}>") form_type = regex.findall(file.read_text())[0] if form_type == "3": return Form3(file) elif form_type == "4": return Form4(file) elif form_type == "5": return Form5(file) else: typer.secho(f"WARNING: {form_type} not a supported form type", fg=typer.colors.RED) return None
def test_extract_derivative_trans_form3(test_form3): """ Validate Form3 extraction code against a single detailed example :param test_form3: :return: """ doc = Form3(test_form3) assert doc.accession_num == "0001209191-20-054135" assert doc.filename == test_form3.name fields_list = doc.derivatives assert len(fields_list) == 9 assert len(fields_list[0]) == 12 assert fields_list[0]["filename"] == test_form3.name assert fields_list[0]["accession_num"] == doc.accession_num assert fields_list[0]["order"] == "1" assert fields_list[0]["type"] == "derivHolding" assert fields_list[0]["index"] == "derivHolding1" assert fields_list[0]["security_title"] == "BEP Ford Stock Fund Units" assert fields_list[0]["conversion_or_exercise_price"] == "" assert fields_list[0]["exercise_date"] == "" assert fields_list[0]["expiration_date"] == "" assert ( fields_list[0]["underlying_security_title"] == "Common Stock, $0.01 par value" ) assert fields_list[0]["underlying_security_shares"] == "65" assert fields_list[0]["direct_or_indirect_ownership"] == "D" assert len(fields_list[8]) == 12 assert fields_list[8]["filename"] == test_form3.name assert fields_list[8]["accession_num"] == doc.accession_num assert fields_list[8]["order"] == "9" assert fields_list[8]["type"] == "derivHolding" assert fields_list[8]["index"] == "derivHolding9" assert fields_list[8]["security_title"] == "Ford Stock Units" assert fields_list[8]["conversion_or_exercise_price"] == "" assert fields_list[8]["exercise_date"] == "" assert fields_list[8]["expiration_date"] == "" assert ( fields_list[8]["underlying_security_title"] == "Common Stock, $0.01 par value" ) assert fields_list[8]["underlying_security_shares"] == "247533" assert fields_list[8]["direct_or_indirect_ownership"] == "D"
def create_doc(file: Path) -> Union[None, Document]: """ A factory function returns a Document object with the right subtype. :param file: The file object that is the source of the Document :return: A Document object """ xmlpath = Document.xml_document_fields["document_type"] regex = re.compile(f"<{xmlpath}>(.+)</{xmlpath}>") form_type = regex.findall(file.read_text())[0] if form_type == "3": return Form3(file) elif form_type == "4": return Form4(file) elif form_type == "5": return Form5(file) else: typer.secho( f"WARNING: {form_type} not a supported form type", fg=typer.colors.RED ) return None
def test_extract_signature_form3(test_form3): """ Validate Form3 extraction code against a single detailed example :param test_form3: :return: """ doc = Form3(test_form3) assert doc.accession_num == "0001209191-20-054135" assert doc.filename == test_form3.name fields_list = doc.nonderivatives assert len(fields_list) == 1 assert len(fields_list[0]) == 8 assert fields_list[0]["filename"] == test_form3.name assert fields_list[0]["accession_num"] == doc.accession_num assert fields_list[0]["order"] == "1" assert fields_list[0]["type"] == "nonDerivHolding" assert fields_list[0]["index"] == "nonDerivHolding1" assert fields_list[0]["security_title"] == "Common Stock, $0.01 par value" assert fields_list[0]["shares_owned_following_transaction"] == "157800" assert fields_list[0]["direct_or_indirect_ownership"] == "D"
def test_extract_signature_form3_collection(test_form3_collection, doc_num: int): """ Validate Form3 extraction code against a random sample of documents :param test_form3_collection: :return: """ file = list(test_form3_collection.glob("*.txt"))[doc_num] doc = Form3(file) assert doc.filename == file.name fields_list = doc.signatures assert len(fields_list) > 0 for idx, fields in enumerate(fields_list): assert (len(fields)) == 7 assert fields["filename"] == file.name assert fields["accession_num"] == doc.accession_num assert fields["order"] == f"{idx+1}" assert fields["type"] == "signature" assert fields["index"] == f"signature{idx+1}" assert validate(file, fields["signature_name"], r".+") assert validate(file, fields["signature_date"], r"\d\d\d\d-\d\d-\d\d")
def test_extract_footnotes_form4_collection(test_form4_collection, doc_num: int): """ Validate Form4 extraction code against a random sample of documents :param test_form4_collection: :return: """ file = list(test_form4_collection.glob("*.txt"))[doc_num] doc = Form3(file) assert doc.filename == file.name fields_list = doc.footnotes assert len(fields_list) >= 0 for idx, fields in enumerate(fields_list): assert (len(fields)) == 6 assert fields["filename"] == file.name assert fields["accession_num"] == doc.accession_num assert validate(file, fields["accession_num"], r"[\d-]+") assert validate(file, fields["footnote"], r".+") assert validate(file, fields["index"], r"\w+\d+") assert validate(file, fields["field"], r"\w+") assert validate(file, fields["field"], r".+")
def test_extract_signature_form3(test_form3): """ Validate Form3 extraction code against a single detailed example :param test_form3: :return: """ doc = Form3(test_form3) assert doc.accession_num == "0001209191-20-054135" assert doc.filename == test_form3.name fields_list = doc.signatures assert len(fields_list) == 1 assert len(fields_list[0]) == 7 assert fields_list[0]["filename"] == test_form3.name assert fields_list[0]["accession_num"] == doc.accession_num assert fields_list[0]["order"] == "1" assert fields_list[0]["type"] == "signature" assert fields_list[0]["index"] == "signature1" assert fields_list[0][ "signature_name"] == "Jerome F. Zaremba,\nAttorney-in-Fact" assert fields_list[0]["signature_date"] == "2020-10-07"
def test_extract_nonderivatives_form3_collection(test_form3_collection, doc_num: int): """ Validate Form3 extraction code against a random sample of documents :param test_form3_collection: :return: """ file = list(test_form3_collection.glob("*.txt"))[doc_num] doc = Form3(file) assert doc.filename == file.name fields_list = doc.nonderivatives assert len(fields_list) >= 0 for idx, fields in enumerate(fields_list): assert (len(fields)) == 8 assert fields["filename"] == file.name assert fields["accession_num"] == doc.accession_num assert fields["order"] == f"{idx+1}" assert fields["type"] == "nonDerivHolding" assert fields["index"] == f"nonDerivHolding{idx+1}" assert validate(file, fields["security_title"], r".+") assert validate(file, fields["shares_owned_following_transaction"], r"[\d\.]+") assert validate(file, fields["direct_or_indirect_ownership"], r"[DI]")