Closed altendky closed 4 years ago
So there's an exemplary fix (in the bad way, not the good way). Basically, seems that toml.dumps()
isn't handling the tomlkit.items.String
well.
class String(unicode, Item):
Ok, this time I looked sensibly at toml
and I think I found it... and it's not isinstance()
since that would work.
https://github.com/uiri/toml/blob/f4f0b84fd84265b296312153628cd9dbd5961664/toml/encoder.py#L134-L145
self.dump_funcs = {
str: _dump_str,
unicode: _dump_str,
list: self.dump_list,
bool: lambda v: unicode(v).lower(),
int: lambda v: v,
float: _dump_float,
Decimal: _dump_float,
datetime.datetime: lambda v: v.isoformat().replace('+00:00', 'Z'),
datetime.time: _dump_time,
datetime.date: lambda v: v.isoformat()
}
https://github.com/uiri/toml/blob/f4f0b84fd84265b296312153628cd9dbd5961664/toml/encoder.py#L176-L178
dump_fn = self.dump_funcs.get(type(v))
if dump_fn is None and hasattr(v, '__iter__'):
dump_fn = self.dump_funcs[list]
So it's checking for str
by way of the dict lookup rather than issubclass()
or isinstance()
being involved then noting that it is in fact iterable and using the list dumper.
So the question is, where do we want to solve this? Depending on response to uiri/toml#273, maybe I'll PR. But maybe we want to keep controlled elsewhere for some reason.
It looks like a customized encoder should be easy too. Something like at least.
class TomlEncoderForTomlkitTypes(TomlEncoder):
def __init__(self, _dict=dict, preserve=False):
super(TomlEncoderForTomlkitTypes, self).__init__(*args, **kwargs)
self.dump_funcs[tomlkit.items.String] = self.dump_funcs[str]
dumped = toml.dumps(d, encoder=TomlEncoderForTomlkitTypes())
To be honest, given that the installed.toml
code has to be rewritten anyways to use _config.Config
, and that this use case really doesn't need TOML (it's not for humans, it's just a cache) my plan was to replace things with JSON (basically we need to write out a lockfile equivalent of a _config.Config
, and then just simply check against it when converging).
See #92