Changeset - 2cb131423f97
[Not reviewed]
0 6 0
Brett Smith - 4 years ago 2020-03-28 13:47:40
brettcsmith@brettcsmith.org
errors: Redo InvalidMetadataError.

This needs to be generally usable for transactions.
6 files changed with 13 insertions and 27 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/errors.py
Show inline comments
...
 
@@ -64,29 +64,16 @@ class ConfigurationError(Error):
 
            source = {}
 
        self._fill_source(source)
 
        super().__init__(message, entry, source)
 

	
 

	
 
class InvalidMetadataError(Error):
 
    def __init__(self, txn, post, key, value=None, source=None):
 
        if value is None:
 
            msg_fmt = "{post.account} missing {key}"
 
        else:
 
            msg_fmt = "{post.account} has invalid {key}: {value}"
 
        super().__init__(
 
            msg_fmt.format(post=post, key=key, value=value),
 
            txn,
 
            source,
 
        )
 

	
 

	
 
class InvalidEntityError(InvalidMetadataError):
 
    def __init__(self, txn, post=None, key='entity', value=None, source=None):
 
    def __init__(self, txn, key, value=None, post=None, source=None):
 
        if post is None:
 
            srcname = 'transaction'
 
        else:
 
            srcname = post.account
 
        if value is None:
 
            msg = "{} missing entity".format(srcname)
 
            msg = "{} missing {}".format(srcname, key)
 
        else:
 
            msg = "{} entity malformed: {}".format(srcname, value)
 
        super(InvalidMetadataError, self).__init__(msg, txn, source)
 
            msg = "{} has invalid {}: {}".format(srcname, key, value)
 
        super().__init__(msg, txn, source)
conservancy_beancount/plugin/core.py
Show inline comments
...
 
@@ -214,13 +214,13 @@ class _NormalizePostingMetadataHook(_PostingHook):
 

	
 
    # If the posting does not specify METADATA_KEY, the hook calls
 
    # _default_value to get a default. This method should either return
 
    # a value string from METADATA_ENUM, or else raise InvalidMetadataError.
 
    # This base implementation does the latter.
 
    def _default_value(self, txn: Transaction, post: data.Posting) -> MetaValueEnum:
 
        raise errormod.InvalidMetadataError(txn, post, self.METADATA_KEY)
 
        raise errormod.InvalidMetadataError(txn, self.METADATA_KEY, None, post)
 

	
 
    def post_run(self, txn: Transaction, post: data.Posting) -> errormod.Iter:
 
        source_value = post.meta.get(self.METADATA_KEY)
 
        set_value = source_value
 
        error: Optional[errormod.Error] = None
 
        if source_value is None:
...
 
@@ -230,12 +230,12 @@ class _NormalizePostingMetadataHook(_PostingHook):
 
                error = error_
 
        else:
 
            try:
 
                set_value = self.VALUES_ENUM[source_value]
 
            except KeyError:
 
                error = errormod.InvalidMetadataError(
 
                    txn, post, self.METADATA_KEY, source_value,
 
                    txn, self.METADATA_KEY, source_value, post,
 
                )
 
        if error is None:
 
            post.meta[self.METADATA_KEY] = set_value
 
        else:
 
            yield error
conservancy_beancount/plugin/meta_entity.py
Show inline comments
...
 
@@ -34,17 +34,17 @@ class MetaEntity(core.TransactionHook):
 
            txn_entity_ok = None
 
        elif isinstance(txn_entity, str):
 
            txn_entity_ok = bool(self.ENTITY_RE.match(txn_entity))
 
        else:
 
            txn_entity_ok = False
 
        if txn_entity_ok is False:
 
            yield errormod.InvalidEntityError(txn, value=txn_entity)
 
            yield errormod.InvalidMetadataError(txn, self.METADATA_KEY, txn_entity)
 
        for post in data.iter_postings(txn):
 
            if post.account.is_under('Assets', 'Liabilities'):
 
                continue
 
            entity = post.meta.get(self.METADATA_KEY)
 
            if entity is None:
 
                yield errormod.InvalidEntityError(txn, post)
 
                yield errormod.InvalidMetadataError(txn, self.METADATA_KEY, entity, post)
 
            elif entity is txn_entity:
 
                pass
 
            elif not self.ENTITY_RE.match(entity):
 
                yield errormod.InvalidEntityError(txn, post, value=entity)
 
                yield errormod.InvalidMetadataError(txn, self.METADATA_KEY, entity, post)
conservancy_beancount/plugin/meta_income_type.py
Show inline comments
...
 
@@ -46,7 +46,7 @@ class MetaIncomeType(core._NormalizePostingMetadataHook):
 
        return post.account.is_income()
 

	
 
    def _default_value(self, txn: Transaction, post: data.Posting) -> MetaValueEnum:
 
        try:
 
            return self.DEFAULT_VALUES[post.account]
 
        except KeyError:
 
            raise errormod.InvalidMetadataError(txn, post, self.METADATA_KEY) from None
 
            raise errormod.InvalidMetadataError(txn, self.METADATA_KEY, None, post) from None
conservancy_beancount/plugin/meta_project.py
Show inline comments
...
 
@@ -84,8 +84,7 @@ class MetaProject(core._NormalizePostingMetadataHook):
 
        if post.account.is_under(
 
                'Accrued:VacationPayable',
 
                'Expenses:Payroll',
 
        ):
 
            return self.DEFAULT_PROJECT
 
        else:
 
            raise errormod.InvalidMetadataError(txn, post, self.METADATA_KEY)
 

	
 
            raise errormod.InvalidMetadataError(txn, self.METADATA_KEY, None, post)
tests/test_meta_entity.py
Show inline comments
...
 
@@ -57,13 +57,13 @@ def test_invalid_values_on_postings(hook, src_value):
 
    txn = testutil.Transaction(postings=[
 
        ('Assets:Cash', -25),
 
        ('Expenses:General', 25, {TEST_KEY: src_value}),
 
    ])
 
    errors = list(hook.run(txn))
 
    assert len(errors) == 1
 
    assert errors[0].message == "Expenses:General entity malformed: {}".format(src_value)
 
    assert errors[0].message == "Expenses:General has invalid entity: {}".format(src_value)
 

	
 
@pytest.mark.parametrize('src_value', VALID_VALUES)
 
def test_valid_values_on_transactions(hook, src_value):
 
    txn = testutil.Transaction(**{TEST_KEY: src_value}, postings=[
 
        ('Assets:Cash', -25),
 
        ('Expenses:General', 25),
...
 
@@ -75,13 +75,13 @@ def test_invalid_values_on_transactions(hook, src_value):
 
    txn = testutil.Transaction(**{TEST_KEY: src_value}, postings=[
 
        ('Assets:Cash', -25),
 
        ('Expenses:General', 25),
 
    ])
 
    errors = list(hook.run(txn))
 
    assert 1 <= len(errors) <= 2
 
    assert all(error.message == "transaction entity malformed: {}".format(src_value)
 
    assert all(error.message == "transaction has invalid entity: {}".format(src_value)
 
               for error in hook.run(txn))
 

	
 
@pytest.mark.parametrize('account,required', [
 
    ('Accrued:AccountsReceivable', True),
 
    ('Assets:Cash', False),
 
    ('Expenses:General', True),
0 comments (0 inline, 0 general)