/usr/lib/python3/dist-packages/agate/fixed.py is in python3-agate 1.6.0-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #!/usr/bin/env python
"""
This module contains a generic parser for fixed-width files. It operates
similar to Python's built-in CSV reader.
"""
from collections import OrderedDict, namedtuple
import six
Field = namedtuple('Field', ['name', 'start', 'length'])
class Reader(six.Iterator):
"""
Reads a fixed-width file using a column schema in CSV format.
This works almost exactly like Python's built-in CSV reader.
Schemas must be in the "ffs" format, with :code:`column`, :code:`start`,
and :code:`length` columns. There is a repository of such schemas
maintained at `wireservice/ffs <https://github.com/wireservice/ffs>`_.
"""
def __init__(self, f, schema_f):
from agate import csv
self.file = f
self.fields = []
reader = csv.reader(schema_f)
header = next(reader)
if header != ['column', 'start', 'length']:
raise ValueError('Schema must contain exactly three columns: "column", "start", and "length".')
for row in reader:
self.fields.append(Field(row[0], int(row[1]), int(row[2])))
def __iter__(self):
return self
def __next__(self):
line = next(self.file)
values = []
for field in self.fields:
values.append(line[field.start:field.start + field.length].strip())
return values
@property
def fieldnames(self):
"""
The names of the columns read from the schema.
"""
return [field.name for field in self.fields]
class DictReader(Reader):
"""
A fixed-width reader that returns :class:`collections.OrderedDict` rather
than a list.
"""
def __next__(self):
line = next(self.file)
values = OrderedDict()
for field in self.fields:
values[field.name] = line[field.start:field.start + field.length].strip()
return values
def reader(*args, **kwargs):
"""
A wrapper around :class:`.fixed.Reader`, so that it can be used in the same
way as a normal CSV reader.
"""
return Reader(*args, **kwargs)
|