Search code examples
pythoncommand-line-interfacefile-handling

Use newline='' with click.open_file() to support OS-indepent new-lines & CSVs


The PyPi click library has an open_file() function which is preferred over Python's open() function since it can "intelligently open stdin/stdout as well as any other file" (e.g. when the filename is specified as -).

Unfortunately, it doesn't seem to support the newline argument of Python's built-in open() function which is required by Python's standard CSV module to properly handle new-lines in an OS-independent manner. Without this, CSVs generated on Windows have extra empty lines between each row.

Is it possible to use click's open_file() to read/write CSVs in an OS-independent manner?


Solution

  • According to the issue discussions on Github this is not something click will natively support:

    I've found the following work-around to work for me:

    if output_path == '-':
        # Specifically use click's open_file only for its stdout stream
        file_ctx_manager = click.open_file(output_path, 'w', encoding='utf-8')
    else:
        # Use open() directly for actual files because the CSV requires newline='' to be OS-independent
        file_ctx_manager = open(output_path, 'w', newline='', encoding='utf-8')
    
    with file_ctx_manager as csv_file:
        writer = csv.writer(csv_file, quoting=csv.QUOTE_MINIMAL)
        writer.writerow([])