Example #1
0
def parse_file(file,
               report_filename=None,
               report_firstline=1,
               encoding=None,
               **kw):
    """Parse a beancount input file and return Ledger with the list of
    transactions and tree of accounts.

    Args:
      file: file object or path to the file to be parsed.
      kw: a dict of keywords to be applied to the C parser.
    Returns:
      A tuple of (
        list of entries parsed in the file,
        list of errors that were encountered during parsing, and
        a dict of the option values that were parsed from the file.)
    """
    if encoding is not None and codecs.lookup(encoding).name != 'utf-8':
        raise ValueError('Only UTF-8 encoded files are supported.')
    with contextlib.ExitStack() as ctx:
        if file == '-':
            file = sys.stdin.buffer
        # It would be more appropriate here to check for io.RawIOBase but
        # that does not work for io.BytesIO despite it implementing the
        # readinto() method.
        elif not isinstance(file, io.IOBase):
            file = ctx.enter_context(open(file, 'rb'))
        builder = grammar.Builder()
        parser = _parser.Parser(builder)
        parser.parse(file,
                     filename=report_filename,
                     lineno=report_firstline,
                     **kw)
    return builder.finalize()
Example #2
0
    def test_parser_parse(self):
        # Do not use a string to avoid issues due to string interning.
        name = object()
        self.assertEqual(sys.getrefcount(name), 2)

        f = io.BytesIO(b"")
        f.name = name
        self.assertEqual(sys.getrefcount(f.name), 3)

        builder = grammar.Builder()
        parser = _parser.Parser(builder)
        parser.parse(f)
        # The Parser object keeps a reference to the input file.
        self.assertEqual(sys.getrefcount(f), 3)
        # There are references to the file name from the Parser object
        # and from the the parsing results. In the case of an empty
        # input file from the options dictionary stored in the builder.
        self.assertEqual(sys.getrefcount(name), 5)
        builder.options = {}
        self.assertEqual(sys.getrefcount(name), 4)

        del parser
        # Once the Parser object is gone we should have just the local
        # reference to the file object and two references to name.
        self.assertEqual(sys.getrefcount(name), 3)
        self.assertEqual(sys.getrefcount(f), 2)
Example #3
0
def parse_file(file, report_filename=None, report_firstline=1, **kw):
    """Parse a beancount input file and return Ledger with the list of
    transactions and tree of accounts.

    Args:
      file: file object or path to the file to be parsed.
      kw: a dict of keywords to be applied to the C parser.
    Returns:
      A tuple of (
        list of entries parsed in the file,
        list of errors that were encountered during parsing, and
        a dict of the option values that were parsed from the file.)
    """
    close_file = None
    if file == '-':
        close_file = file = sys.stdin.buffer
    # It would be more appropriate here to check for io.RawIOBase but
    # that does not work for io.BytesIO despite it implementing the
    # readinto() method.
    elif not isinstance(file, io.IOBase):
        close_file = file = open(file, 'rb')

    builder = grammar.Builder()
    parser = _parser.Parser(builder)
    parser.parse(file, filename=report_filename, lineno=report_firstline, **kw)

    if close_file:
        close_file.close()
    return builder.finalize()
Example #4
0
 def test_parse_string(self):
     # TODO(blais): Remove, this is temporary, for testing locally.
     filename = os.getenv("L")
     assert filename
     builder = grammar.Builder()
     out = extmodule.parse(builder, filename)
     print(out)
Example #5
0
def parse_string(string, **kw):
    """Parse a beancount input file and return Ledger with the list of
    transactions and tree of accounts.

    Args:
      string: a str, the contents to be parsed instead of a file's.
      **kw: See parse.c. This function parses out 'dedent' which removes
        whitespace from the front of the text (default is False).
    Return:
      Same as the output of parse_file().
    """
    if kw.pop('dedent', None):
        string = textwrap.dedent(string)
    builder = grammar.Builder(None)
    _parser.parse_string(string, builder, **kw)
    builder.options['filename'] = '<string>'
    return builder.finalize()
Example #6
0
def parse_file(filename, **kw):
    """Parse a beancount input file and return Ledger with the list of
    transactions and tree of accounts.

    Args:
      filename: the name of the file to be parsed.
      kw: a dict of keywords to be applied to the C parser.
    Returns:
      A tuple of (
        list of entries parsed in the file,
        list of errors that were encountered during parsing, and
        a dict of the option values that were parsed from the file.)
    """
    abs_filename = path.abspath(filename) if filename else None
    builder = grammar.Builder(abs_filename)
    _parser.parse_file(filename, builder, **kw)
    return builder.finalize()
Example #7
0
def parse_string(string, report_filename=None, **kw):
    """Parse a beancount input file and return Ledger with the list of
    transactions and tree of accounts.

    Args:
      string: A string, the contents to be parsed instead of a file's.
      report_filename: A string, the source filename from which this string
        has been extracted, if any. This is stored in the metadata of the
        parsed entries.
      **kw: See parse.c. This function parses out 'dedent' which removes
        whitespace from the front of the text (default is False).
    Return:
      Same as the output of parse_file().
    """
    if kw.pop('dedent', None):
        string = textwrap.dedent(string)
    builder = grammar.Builder(report_filename or '<string>')
    _parser.parse_string(string, builder, report_filename=report_filename, **kw)
    return builder.finalize()
Example #8
0
 def test_parse_lineno(self):
     f = io.BytesIO(b"2020-07-30 open Assets:Test")
     builder = grammar.Builder()
     parser = _parser.Parser(builder)
     parser.parse(f, lineno=42)
     self.assertEqual(builder.entries[0].meta['lineno'], 42)