deadline 10 deadline ini not compatible with python ConfigParser?

One of our scripts ensures the health of the deadline.ini file. We realized its failing with deadline 10 (unable to parse it):

MissingSectionHeaderError: File contains no section headers. file: C:\ProgramData\Thinkbox\Deadline10\deadline.ini, line: 1 '\xef\xbb\xbf[Deadline]\n'

Seems that the deadline.ini is encoded utf8. Is that an intended change?

We can probably tweak the script to handle utf8, just wondering if this is normal… On linux it seems to handle slightly differently:

Trying to read via utf8:

>>> oConfig.readfp(codecs.open(sDeadlineConfigFile,'r','utf8')) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.6/ConfigParser.py", line 315, in readfp self._read(fp, filename) File "/usr/lib64/python2.6/ConfigParser.py", line 503, in _read raise MissingSectionHeaderError(fpname, lineno, line) ConfigParser.MissingSectionHeaderError: File contains no section headers. file: /var/lib/Thinkbox/Deadline10/deadline.ini, line: 1 u'\ufeff[Deadline]\n'

via default:

>>> oConfig.read(sDeadlineConfigFile)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/ConfigParser.py", line 296, in read
    self._read(fp, filename)
  File "/usr/lib64/python2.6/ConfigParser.py", line 503, in _read
    raise MissingSectionHeaderError(fpname, lineno, line)
ConfigParser.MissingSectionHeaderError: File contains no section headers.
file: /var/lib/Thinkbox/Deadline10/deadline.ini, line: 1
'\xef\xbb\xbf[Deadline]\n'

My preference would be no special encoding for ini type files

Actually, seems like those first characters are the byte order mark? (linux and windows handles my attempts at simply reading as utf8 the same way: with failure)

Yeah, that’s the byte order magic header.

We’re trying to use UTF-8 everywhere so if you decided to use something outside of the ASCII range it would work. Here’s what mine looks like via less -S:

<U+FEFF>[Deadline]
LicenseMode=Standard
LicenseServer=@some.server
Region=
LauncherListeningPort=17000
LauncherServiceStartupDelay=60
...

Looks like this’ll get you there:

stackoverflow.com/a/46557458/187769

Mushing examples together, this worked for me:

import codecs
import ConfigParser

cfg = ConfigParser.ConfigParser()
cfg.readfp(codecs.open("deadline.ini", "r", "utf-8-sig"))
print(cfg.sections())

Yeah i’m implementing something along those lines at the moment. It will have to be encapsulated in try/catches, cause the ini reader mostly deals with pure text, so this is adding a special case. Deadline’s is the first unicode ini config file i’ve seen to be honest.

Just passing through,

I’d recommend going with io.open instead of codecs.open. Reason being that codecs was really just leftovers of python2’s built-in open being less than ideal (ie. can’t specify encoding), whereas io.open is python3’s built-in open function (if you use io.open in python3, it points to the built-in). Codecs is also now deprecated: bugs.python.org/issue8796

It looks pretty much the same (and I haven’t tested this code I’m about to write), so it’s not too drastic of a change:

import io
...
# Edwin's stuff
...
cfg.readfp(io.open("deadline.ini", mode="r", encoding="utf-8-sig"))

Thanks Morgan!

Thanks Morgan, i’ll take a look at that!