diff --git a/CHANGES.txt b/CHANGES.txt index 641d34c..63fc8f5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,7 +4,10 @@ Changes 1.2.0b3 (unreleased) -------------------- -- Nothing changed yet. +- Now includes default values when saving, making the OCF files larger. + +- It's now possible to pass in the data to the Captable object when + creating it, instead of adding the data to the attribute lists later. 1.2.0b2 (2025-02-04) diff --git a/docs/source/using.rst b/docs/source/using.rst index 345efd9..ef30c04 100644 --- a/docs/source/using.rst +++ b/docs/source/using.rst @@ -46,7 +46,6 @@ but you then need to create ``File`` objects for each file, with dummy md5 hashe ... id="d6c49a5a-257d-4b41-9f1d-073a77dfe719", ... name={"legal_name": "Person Y"}, ... stakeholder_type="INDIVIDUAL", - ... comments=[], ... ) ... ) @@ -69,6 +68,20 @@ but you then need to create ``File`` objects for each file, with dummy md5 hashe ... ) ... ) +It is also possible to create the list of objects first, and pass them in to the +Captable constructor:: + + >>> sh_list = [ + ... api.Stakeholder( + ... object_type="STAKEHOLDER", + ... id="'917efd77a370-d1f9-14b4-d752-a5a94c6d", + ... name={"legal_name": "Person X"}, + ... stakeholder_type="INDIVIDUAL", + ... ) + ... } + + >>> cap2 = Captable(stakeholders=sh_list) + And once you have filled in all the lists with all the information, you save the captable: @@ -102,12 +115,7 @@ A captable will then be created and Python objects will be stored in it. 'pyocf example docs' >>> cap.stakeholders # doctest: +NORMALIZE_WHITESPACE - [Stakeholder(id='d6c49a5a-257d-4b41-9f1d-073a77dfe719', comments=[], - object_type='STAKEHOLDER', name=Name(legal_name='Person Y', first_name=None, - last_name=None), stakeholder_type=, issuer_assigned_id=None, current_relationship=None, - primary_contact=None, contact_info=None, addresses=None, tax_ids=None), - Stakeholder(id='d6c49a5a-257d-4b41-9f1d-073a77dfe719', comments=[], + [Stakeholder(id='d6c49a5a-257d-4b41-9f1d-073a77dfe719', comments=None, object_type='STAKEHOLDER', name=Name(legal_name='Person Y', first_name=None, last_name=None), stakeholder_type=, issuer_assigned_id=None, current_relationship=None, diff --git a/src/pyocf/captable.py b/src/pyocf/captable.py index 096830d..bf3fde2 100644 --- a/src/pyocf/captable.py +++ b/src/pyocf/captable.py @@ -43,16 +43,40 @@ class Captable: - manifest: ocfmanifestfile.OCFManifestFile = None - documents: list[Document] = [] - financings: list[Financing] = [] - stakeholders: list[Stakeholder] = [] - stock_classes: list[StockClass] = [] - stock_legend_templates: list[StockLegendTemplate] = [] - stock_plans: list[StockPlan] = [] - transactions: list[Transaction] = [] - valuations: list[Valuation] = [] - vesting_terms: list[VestingTerms] = [] + manifest: ocfmanifestfile.OCFManifestFile + documents: list[Document] + financings: list[Financing] + stakeholders: list[Stakeholder] + stock_classes: list[StockClass] + stock_legend_templates: list[StockLegendTemplate] + stock_plans: list[StockPlan] + transactions: list[Transaction] + valuations: list[Valuation] + vesting_terms: list[VestingTerms] + + def __init__( + self, + manifest: ocfmanifestfile.OCFManifestFile = None, + documents: list[Document] = None, + financings: list[Financing] = None, + stakeholders: list[Stakeholder] = None, + stock_classes: list[StockClass] = None, + stock_legend_templates: list[StockLegendTemplate] = None, + stock_plans: list[StockPlan] = None, + transactions: list[Transaction] = None, + valuations: list[Valuation] = None, + vesting_terms: list[VestingTerms] = None, + ): + self.manifest = manifest + self.documents = documents or [] + self.financings = financings or [] + self.stakeholders = stakeholders or [] + self.stock_classes = stock_classes or [] + self.stock_legend_templates = stock_legend_templates or [] + self.stock_plans = stock_plans or [] + self.transactions = transactions or [] + self.valuations = valuations or [] + self.vesting_terms = vesting_terms or [] @classmethod def load(cls, location): @@ -103,7 +127,7 @@ def file_factory(p): def _save_ocf_files(self, manifest_path, issuer, file_factory, pretty): if issuer is None and self.manifest is None: raise ValueError( - "You must specify an issuer, either by passing the value to the" + "You must specify an issuer, either by passing the value to the " "save method, or by creating a Manifest." ) @@ -125,7 +149,7 @@ def _save_ocf_files(self, manifest_path, issuer, file_factory, pretty): with file_factory(ocffilename) as ocffile: itemfile = fileob(items=getattr(self, filetype)) - jsonstr = itemfile.json(exclude_unset=True) + jsonstr = itemfile.model_dump_json() if pretty: jsonstr = json.dumps(json.loads(jsonstr), indent=4) jsonstr = jsonstr.encode("UTF-8") @@ -156,7 +180,7 @@ def _save_ocf_files(self, manifest_path, issuer, file_factory, pretty): self.manifest = ocfmanifestfile.OCFManifestFile(**manifest_data) with file_factory(manifest_path) as ocffile: - jsonstr = self.manifest.json() + jsonstr = self.manifest.model_dump_json() if pretty: jsonstr = json.dumps(json.loads(jsonstr), indent=4) ocffile.write(jsonstr.encode("UTF-8")) diff --git a/tests/test_basic.py b/tests/test_basic.py index 8e336a5..d824370 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -7,6 +7,7 @@ from pyocf.api import StakeholdersFile from pyocf.api import Stakeholder from pyocf.api import Name, Phone, CountryCode +from pyocf.captable import Captable def test_basic_loading(): @@ -79,3 +80,15 @@ def test_constrained_strings(): with pytest.raises(ValueError): CountryCode("SPUT") + + +def test_captable_init(): + stakeholders = [ + Stakeholder( + id="steve", + name=Name(legal_name="Stake Holder"), + stakeholder_type=StakeholderType.ENUM_INDIVIDUAL, + ) + ] + captable = Captable(stakeholders=stakeholders) + assert captable.stakeholders[0].name.legal_name == "Stake Holder" diff --git a/tests/test_save.py b/tests/test_save.py index 1148781..fbf2eed 100644 --- a/tests/test_save.py +++ b/tests/test_save.py @@ -57,6 +57,11 @@ def test_save_directory(): # Do some simple checks on the data assert b'"file_type": "OCF_MANIFEST_FILE"' in data assert b'"filepath": "StockLegends.ocf.json",' in data + + transactions = [x for x in files if x.name == "Transactions.ocf.json"][0] + data = transactions.open("rb").read() + assert b'"object_type": "TX_EQUITY_COMPENSATION_RELEASE"' in data + except (PermissionError, NotADirectoryError): # Bugs in windows give permission errors for absolutely no reason # when deleting temporary files. Ignore them.