0

SOLUTION: Change ConfigParser.py Everything with \n should be \r\n, this way linux and windows can read the file with line return. This fixed it for us.

I am writing an program in Linux and it communicates with an Windows 10 PC. I get an file from the Windows PC and with Python ConfigParser I set the new values. When I write it from Linux to Windows, the newlines are messed up. Is there a way to handle this nicely in Python 2.7?

EDIT 1: We have a txt file with configuration inside it we read it out from a raspberry Pi 3 running raspbarian.

[header]
source1 = variable1
source2 = variable2

if this is being read and written again the ouput is as folowing:

[header]source1 = variable1source2 = variable2

After this conversion our windows 10 pc txt reader can't read the file anymore.

EDIT 2: maybe this will help. This is the block of code from the ConfigParser.py:

  def write(self, fp):
    """Write an .ini-format representation of the configuration state."""
    if self._defaults:
        fp.write("[%s]\n" % DEFAULTSECT)
        for (key, value) in self._defaults.items():
            fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
        fp.write("\n")
    for section in self._sections:
        fp.write("[%s]\n" % section)
        for (key, value) in self._sections[section].items():
            if key == "__name__":
                continue
            if (value is not None) or (self._optcre == self.OPTCRE):
                    key = " = ".join((key, str(value).replace('\n', '\n\t')))
            fp.write("%s\n" % (key))
        fp.write("\n")
NLxDoDge
  • 189
  • 2
  • 13
  • 2
    Please give an example. You could simply replace `\n` with `\r\n`. – erip Jun 07 '16 at 13:27
  • http://stackoverflow.com/a/13954932/4889267 – Alan Kavanagh Jun 07 '16 at 13:31
  • 1
    Get a real text editor on your windows. It's a shame in 2016 there still are text editors that cannot read both styles. – spectras Jun 07 '16 at 13:32
  • By "the newlines are messedup" do you mean that you want to open that file using Windows Notepad and see the correct line endings? – Bakuriu Jun 07 '16 at 13:32
  • How are you transferring the files between machines? You may find the dos2unix and unix2dos shell commands helpful. – cherdt Jun 07 '16 at 13:33
  • Always open the file in binary mode before writing it. i.e. `open('example.cfg', 'wb')`. – martineau Jun 07 '16 at 13:35
  • Bakuriu this is correct cherdt I transfer them with the ConfigParser from Python 2.7 martineau I did try this but it doesn't seem to work. Can I open it and then just in Python do write(somethingconfigfile)? spectras it isn't just for that program, and I do agree! But the information which is passed there needs too be picked up by another (Windows) program. Is this a problem from the program? Because Notepad does show the correct lines – NLxDoDge Jun 07 '16 at 14:25

2 Answers2

2

In your call to read the file-like object, you should be passing in the U flag for cross-compatibility. e.g.

import ConfigParser

conf = ConfigParser.ConfigParser()
conf.readfp(open('/tmp/settings.cfg', 'U'))
...

Per the 2.7 documentation:

In addition to the standard fopen() values mode may be 'U' or 'rU'. Python is usually built with universal newlines support; supplying 'U' opens the file as a text file, but lines may be terminated by any of the following: the Unix end-of-line convention '\n', the Macintosh convention '\r', or the Windows convention '\r\n'.

  • The problem with this is that in the ConfigParser we do set some values from the Pi. That cannot be done with the U value. And an wU value doesn't excist as far as I know – NLxDoDge Jun 07 '16 at 14:24
  • "Python enforces that the mode, after stripping 'U', begins with 'r', 'w' or 'a'.". If you're reading the text file from some Windows-convention text reader (I think "notepad" is such an example), then either open the file in binary mode ('`b`') (so that newline character conversion doesn't happen), or use the `io` module's `io.open('/settings.cfg', 'rw', newline='\r\n')` construction to force the newline to what you need. –  Jun 07 '16 at 14:37
0

Maybe not exactly the best way but I works now with the following method:

In /usr/lib/python2.7/ConfigParser.py do the following:

"""Write an .ini-format representation of the configuration state."""
        if self._defaults:
            fp.write("[%s]\r\n" % DEFAULTSECT)
            for (key, value) in self._defaults.items():
                fp.write("%s = %s\r\n" % (key, str(value).replace('\n', '\n\t')$
            fp.write("\r\n")
        for section in self._sections:
            fp.write("[%s]\r\n" % section)
            for (key, value) in self._sections[section].items():
                if key == "__name__":
                    continue
                if (value is not None) or (self._optcre == self.OPTCRE):
                        key = " = ".join((key, str(value).replace('\n', '\n\t')$
                fp.write("%s\r\n" % (key))
            fp.write("\r\n")
NLxDoDge
  • 189
  • 2
  • 13