Skip to content

CSVReader ignores dialect.lineterminator #81890

Closed

Description

@BenjaminSchollnick
BPO 37709
Nosy @smontanaro, @warsaw, @bitdancer, @tirkarthi
Superseder
  • bpo-45544: Close 2to3 issues and list them here
  • Files
  • CSV_SAMPLE.CSV: Sample data
  • bell.csv: example CSV file with \x07 as the line terminator
  • lfmapper.py
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2021-10-20.23:11:45.060>
    created_at = <Date 2019-07-29.19:32:08.446>
    labels = ['3.7', 'expert-2to3', 'expert-email', 'type-feature', 'library', 'docs']
    title = 'CSVReader ignores dialect.lineterminator'
    updated_at = <Date 2021-10-20.23:11:45.060>
    user = 'https://bugs.python.org/BenjaminSchollnick'

    bugs.python.org fields:

    activity = <Date 2021-10-20.23:11:45.060>
    actor = 'iritkatriel'
    assignee = 'docs@python'
    closed = True
    closed_date = <Date 2021-10-20.23:11:45.060>
    closer = 'iritkatriel'
    components = ['Documentation', 'Library (Lib)', '2to3 (2.x to 3.x conversion tool)', 'email']
    creation = <Date 2019-07-29.19:32:08.446>
    creator = 'Benjamin Schollnick'
    dependencies = []
    files = ['48518', '48521', '48522']
    hgrepos = []
    issue_num = 37709
    keywords = []
    message_count = 5.0
    messages = ['348681', '348683', '348711', '348738', '348778']
    nosy_count = 6.0
    nosy_names = ['skip.montanaro', 'barry', 'r.david.murray', 'docs@python', 'xtreak', 'Benjamin Schollnick']
    pr_nums = []
    priority = 'normal'
    resolution = 'wont fix'
    stage = 'resolved'
    status = 'closed'
    superseder = '45544'
    type = 'enhancement'
    url = 'https://bugs.python.org/issue37709'
    versions = ['Python 3.7']

    Activity

    1. BenjaminSchollnick commented on Jul 29, 2019

      BenjaminSchollnickmannequin
      MannequinAuthor

      I've run into a situation where the CSV input file is very unusual. The Delimiter is "\x06" and the lineterminator is "\x07".

      While I've written code to work around this, it would be significantly nicer if the CSV Reader code actually paid attention to the dialect's lineterminator value.

    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-featureA feature request or enhancement
      on Jul 29, 2019
    3. tirkarthi commented on Jul 29, 2019

      @tirkarthi
      Member

      Seems related : https://bugs.python.org/issue1072404 . There is a note on docs that it's ignored and may be changed in future.
      https://docs.python.org/3/library/csv.html

    4. smontanaro commented on Jul 30, 2019

      @smontanaro
      Contributor

      I imagine this is a corner case which will continue to cause problems. At the time the csv module was originally written, I believe the authors' intent was to read and write CSV files which were compatible with Excel. In Python 3, you have to open input files in text mode (that provides the underlying line splitting behavior). Consequently, you're not going to see proper line splitting with unadorned files.

      Have you only tried this with Python 3? If you have tried Python 2, were you able to get it to work without your workaround?

    5. BenjaminSchollnick commented on Jul 30, 2019

      BenjaminSchollnickmannequin
      MannequinAuthor

      This is tested under python 3...

      filename = "csv_Sample.csv"
      from csv import DictReader
      datafile = open(filename, 'r')
      data = csv.DictReader(datafile, lineterminator = '\x07', delimiter='\x06')
      print(next(data))
          OrderedDict([('Field1', 'A'), ('Field2', 'B'), ('Field3', 'C'), ('Field4', 'D'), ('Field5', 'E'), ('Field6', 'F'), ('Field7', 'G'), ('Field8', 'H'), ('Field9', 'I'), ('Field10\x07', 'J\x07')])
      print(ord(data.reader.dialect.lineterminator))

      So it's untested under python 2, since I've stopped developing under Py2.

      I noticed the note in the CSV reader documentation, *AFTER* I diagnosed the issue with the CSV reader... Which is why I opened the bug / feature enhancement request, since this is an very odd edge case.

      I agree 90+% of all CSVs are going to be \n line terminated, but if we offer it for writing, we should offer it for reading.

      The main emphasis here is this code will not working in the real world, eg.

      filename = "csvFile.csv"
      from csv import DictReader, DictWriter
      import csv
      with open(filename, mode='w') as output_file:
          outcsv = csv.writer(output_file, delimiter=',', lineterminator=";")
          outcsv.writerow(['John Cleese', 'CEO', 'March'])
          outcsv.writerow(['Graham Chapman', 'CFO', 'November'])
          outcsv.writerow(['Terry Jones', 'Animation', 'March'])
          outcsv.writerow(['Eric Idle', 'Laugh Track', 'November'])
          outcsv.writerow(['Michael Palin', 'Snake Wrangler', 'March'])
      
      with open(filename, mode='r') as input_file:
          csv_reader = csv.reader(input_file, delimiter=',', lineterminator=";")
          for row in csv_reader:
              print(row)
    6. smontanaro commented on Jul 31, 2019

      @smontanaro
      Contributor

      Looking at your sample file, it seems stranger than you first indicated. Your line terminator actually appears to be '\x07\r\n', not just '\x07'. Opening your file in text mode will leave you with '\x07' as the last character of the last cell in each row. I've attached two files, bell.csv, which has just '\x07' as the line terminator, and lfmapper.py, which provides a class (suboptimally named LFMapper) which takes a file object opened in binary mode and optional line_terminator and encoding args, and performs the necessary slicing of the input bytes, decoding them and returning strings.

      Unless Python grows a way for you to tell the open() function what string to use as the line terminator in text mode, I don't think your example is ever going to work without some sort of shim class.

    7. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.7 (EOL)end of lifedocsDocumentation in the Doc dirstdlibStandard Library Python modules in the Lib/ directorytopic-2to3topic-emailtype-featureA feature request or enhancement

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions