Skip to content

dumps() does not quote values containing '#', '{', '}', newline, or carriage return #19

@anthonyoteri

Description

@anthonyoteri

Bug

dumps() does not quote string values that contain #, {, }, \n, or \r. Each of these is a special character in the lexer:

  • # begins a comment — everything after it on the line is discarded
  • { / } are block delimiters
  • \n / \r terminate a bare term

Values containing these characters are emitted unquoted, and the parser cannot recover the original value.

Reproducer

import structprop

# '#' truncates the value to a comment
out = structprop.dumps({"k": "foo#bar"})
print(repr(out))          # 'k = foo#bar\n'
back = structprop.loads(out)
print(back)               # {'k': 'foo'}  — 'bar' silently lost

# '{' / '}' break the block structure
out = structprop.dumps({"k": "v{x}"})
print(repr(out))          # 'k = v{x}\n'
back = structprop.loads(out)  # ParserError or wrong structure

Root cause

_ESCAPE_CHARACTERS is defined as ' \t' — only space and tab. The characters #, {, }, \n, and \r are all special in the lexer but are absent from the escape set, so _escape() never wraps values containing them in double quotes.

Fix

Extend _ESCAPE_CHARACTERS to cover all lexer-special characters:

_ESCAPE_CHARACTERS = ' \t\n\r#{}='

This is consistent with what the lexer already recognises as terminators/specials in both whitespace and term states.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions