Bug
dumps() does not quote string values that contain =. The resulting output is structurally ambiguous: the parser's lexer treats = as the assignment operator EQ, so a value like foo=bar is tokenized as three separate tokens (foo, EQ, bar) rather than a single value.
The round-trip loads(dumps(data)) == data fails for any value containing =.
Reproducer
import structprop
out = structprop.dumps({"k": "foo=bar"})
print(repr(out)) # 'k = foo=bar\n'
back = structprop.loads(out)
# ParserError or silently wrong result — 'bar' is parsed as a stray token
Root cause
_ESCAPE_CHARACTERS is defined as ' \t' — only space and tab. The = character is a special token in the lexer but is absent from the escape set.
Fix
Extend _ESCAPE_CHARACTERS (or the escape logic) to include all characters that the lexer treats as special: =, {, }, #, newline, and carriage return:
_ESCAPE_CHARACTERS = ' \t\n\r#{}='
Bug
dumps()does not quote string values that contain=. The resulting output is structurally ambiguous: the parser's lexer treats=as the assignment operatorEQ, so a value likefoo=baris tokenized as three separate tokens (foo,EQ,bar) rather than a single value.The round-trip
loads(dumps(data)) == datafails for any value containing=.Reproducer
Root cause
_ESCAPE_CHARACTERSis defined as' \t'— only space and tab. The=character is a special token in the lexer but is absent from the escape set.Fix
Extend
_ESCAPE_CHARACTERS(or the escape logic) to include all characters that the lexer treats as special:=,{,},#, newline, and carriage return: