-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversion of None to "null" string inconsistency #23
Comments
In general, the TOML v1.0.0 specification does not allow serialization/deserialization of NoneType. Therefore, NoneType is converted to a string type with a value of 'null'. Until the author decides to add such functionality, it is possible to simulate the expected behavior at the Python level, for example like this: import traceback
from pathlib import Path
from typing import Dict, Any
import rtoml
def load_config(toml_path: str, encoding='utf-8-sig', errors='ignore') -> Dict[str, Any]:
"""
Custom loader for deserializing a TOML file with recursively
replaced 'null' strings in Python NoneType
:param toml_path: string path;
:param encoding: source TOML encoding (Default opens UTF-8 with/without BOM);
:param errors: 'strict' or 'ignore' encoding errors;
:return: Deserialized TOML as Python dict
"""
def dict_replace_null(_dict: dict) -> dict:
x = {}
for k, v in _dict.items():
if isinstance(v, dict):
v = dict_replace_null(v)
elif isinstance(v, list):
v = list_replace_null(v)
elif isinstance(v, str) and v == 'null':
v = None
x[k] = v
return x
def list_replace_null(_list: list) -> list:
x = []
for e in _list:
if isinstance(e, list):
e = list_replace_null(e)
elif isinstance(e, dict):
e = dict_replace_null(e)
elif isinstance(e, str) and e == 'null':
e = None
x.append(e)
return x
try:
data = rtoml.load(Path(toml_path).read_text(
encoding=encoding,
errors=errors
))
return dict_replace_null(data)
except FileNotFoundError:
print(traceback.format_exc()) # Del 'print()' and wrap in a logging
return {} # Return empty dict without stopping the program |
toml-lang/toml#30 is the discussion about this for the TOML spec. I happen to disagree with them, but that's doesn't really matter much. If we follow their suggestions we should remove any I therefore think we should either:
I guess we could also have another argument " I'm a bit busy, but happy to review a PR to add |
I am too!
But then such behavior would break the logic, IMHO. Perhaps not everyone needs this functionality, but having it allows to migrate from JSON painlessly.
Personally, I prefer this option, but at the level of Rust to preserve the integrity of the code and performance.
I still think that "
If you don't mind, I can suggest PR but at Python code level - implement my example in |
@samuelcolvin I also disagree, not having proper I think the best solution is to have at least those two modes:
This "json-null" would be easier to use than "string-null" for uses cases similar to json / yaml use cases. Having all 3 of those modes available of course won't hurt. |
@ma1ex I would like to give a little feedback to your solution you provided in #23 (comment) In this case, as you need to modify only the current item, it is safe to modify directly dict/list which you are iterating over without creating second dict/list. Not sure if it would save any memory though, because I suspect that Python isn't doubling anything in memory anyway. (?) |
Currently,
rtoml
converts fields with valueNone
to a value of string "null" in the dumped string.Loading the string back in results in a "null" string in python instead of
None
.I can only imagine two possible correct behaviors for loading "null" strings instead:
None
in python, orConversely, for dumping
None
values:None
at allHere are two tests demonstrating the failing scenario with
rtoml
and the passing example usingtoml
:The text was updated successfully, but these errors were encountered: