Changeset 1155:6f7b16432a38


Ignore:
Timestamp:
Dec 28, 2012, 6:10:41 PM (9 years ago)
Author:
Stefan Schwarzer <sschwarzer@…>
Branch:
default
Message:
Allow custom parsers to ignore invalid lines, i. e. those which would
normally raise a `ParserError`.

I'm not really sure whether I like the API. It's not intuitive that a
user-supplied parser may ignore invalid lines even though the user's
code in the parser explicitly raises a `ParserError`:

class MyParser(ftp_stat.UnixParser):

    should_ignore_invalid_lines = True

    def parse_line(self, line, time_shift=0.0):
        ...
        raise ftp_error.ParserError("invalid user field")
        ...

This looks somewhat contradictory.
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • ftputil/ftp_stat.py

    r1154 r1155  
    5757    directory formats inherit from this class.
    5858    """
     59
     60    # Set this to `True` if ftputil should ignore directory lines that
     61    # result in a `ParserError`.
     62    should_ignore_invalid_lines = False
    5963
    6064    # Map month abbreviations to month numbers.
     
    342346
    343347
     348class TolerantUnixParser(UnixParser):
     349    """
     350    This parser ignores invalid lines which would otherwise abort
     351    parsing of a directory listing with a `ParserError`.
     352    """
     353
     354    def ignores_line(self, line):
     355        if super(TolerantUnixParser, self).ignores_line(line):
     356            return True
     357        try:
     358            # Time shift shouldn't be of interest here.
     359            self.parse_line(line)
     360        except ftp_error.ParserError:
     361            return True
     362        else:
     363            return False
     364
     365
    344366class MSParser(Parser):
    345367    """`Parser` class for MS-specific directory format."""
     
    444466            # but we use the `time_shift` parameter to have the
    445467            # correct timestamp values in the cache.
    446             stat_result = self._parser.parse_line(line,
    447                                                   self._host.time_shift())
     468            try:
     469                stat_result = self._parser.parse_line(line,
     470                                                      self._host.time_shift())
     471            except ftp_error.ParserError:
     472                if self._parser.should_ignore_invalid_lines:
     473                    continue
     474                else:
     475                    raise
    448476            if stat_result._st_name in [self._host.curdir, self._host.pardir]:
    449477                continue
  • test/test_ftputil.py

    r1150 r1155  
    112112    def delete(self, file_name):
    113113        pass
     114
     115
     116class MockSessionWithBlankFileName(mock_ftplib.MockUnixFormatSession):
     117
     118    dir_contents = {
     119      "/": """\
     120-rwxr-xr-x   2 45854    200           512 May  4  2000 file1
     121-rwxr-xr-x   2 45854    200           512 May  4  2000
     122-rwxr-xr-x   2 45854    200           512 May  4  2000 file2"""
     123    }
    114124
    115125#
     
    216226        self.assertEqual(stat_result, trivial_parser.default_stat_result)
    217227        self.assertEqual(host._stat._allow_parser_switching, False)
     228
     229
     230    class TolerantUnixParser(ftp_stat.UnixParser):
     231
     232        should_ignore_invalid_lines = True
     233
     234    def test_should_ignore_invalid_lines(self):
     235        host = test_base.ftp_host_factory(
     236               session_factory=MockSessionWithBlankFileName)
     237        host.set_parser(TestSetParser.TolerantUnixParser())
     238        files = host.listdir("/")
     239        self.assertEqual(files, ["file1", "file2"])
    218240
    219241
Note: See TracChangeset for help on using the changeset viewer.