DiffSK / configobj

Python 3+ compatible port of the configobj library
https://configobj.readthedocs.org
Other
322 stars 76 forks source link

Reader and writer must use the same list_values setting to avoid spurious quotes #207

Open stefanor opened 4 years ago

stefanor commented 4 years ago

From an ancient Debian bug report by @spanezz. It was forwarded to the sourceforge mailing list, back in the day, and then forgotten.

While merging between list_values=False and list_values=True ConfigObj instances appears to work correctly, the config file needs to be read with the same list_values setting as it was written with, to be parsed correctly, if a string contains a comma.

The documentation doesn't say that explicitly, just:

ConfigObj doesn't quote and unquote values if list_values=False. This means that leading or trailing whitespace in values will be lost when writing. (Unless you manually quote).

Example:

from configobj import ConfigObj
from io import BytesIO
import sys

co1 = ConfigObj(list_values=False)
co1["foo"] = "bar, baz"

print("list_values=False:")
co1.write(sys.stdout.buffer)
# -> list_values=False:
# -> foo = bar, baz

co2 = ConfigObj(list_values=True)  # the default
co2["test"] = dict()
co2["test"].merge(co1)

print("\nmerged into list_values=True:")
co2.write(sys.stdout.buffer)
# -> merged into list_values=True:
# -> [test]
# -> foo = "bar, baz"

# Write it out
buf = BytesIO()
co2.write(buf)

# Read it again
buf.seek(0)
co3 = ConfigObj(infile=buf, list_values=False)

print("\nRead with list_values=False: test.foo:")
print(co3["test"]["foo"])
# -> Read with list_values=False: test.foo:
# -> "bar, baz"

buf.seek(0)
co4 = ConfigObj(infile=buf, list_values=True)

print("\nRead with list_values=True: test.foo:")
print(co4["test"]["foo"])
# -> Read with list_values=True: test.foo:
# -> bar, baz

I guess the thing to do here is to document this behaviour. (And maybe deprecate list_values=False, but that means config file format migrations...)

jhermann commented 4 years ago

As you said a docs warning / deprecation, and also make merge raise a ValueError when both are mixed.