Search code examples
pythonpython-3.xstring-formatting

Unexpected '{' in field name when doing string formatting


I'm trying to write a small script that will automate some PHP boilerplate that I need to write. It should write a copy of the string code to the output file with the various replacement fields filled in for each dict in the fields list.

However, I'm getting the error:

Traceback (most recent call last):
    File "writefields.py", line 43, in <module>
        formatted = code.format(**field)
ValueError: unexpected '{' in field name

As far as I can tell, there are no extra braces in either the replacement fields or the dicts that should be causing issues, so any help would be appreciated.

code = '''
// {label}
add_filter( 'submit_job_form_fields', 'frontend_add_{fieldname}_field' );
function frontend_add_{fieldname}_field($fields) {
    $fields['job']['job_{fieldname}'] = array(
        'label' => __('{label}', 'job_manager'),
        'type' => 'text',
        'required' => {required},
        'priority' => 7,
        'placeholder' => '{placeholder}'
    );
    return $fields;
}
add_filter( 'job_manager_job_listing_data_fields', 'admin_add_{fieldname}_field' );
function admin_add_{fieldname}_field( $fields ) {
  $fields['_job_{fieldname}'] = array(
    'label'       => __( '{label}', 'job_manager' ),
    'type'        => 'text',
    'placeholder' => '{placeholder}',
    'description' => ''
  );
  return $fields;
}
'''

fields = [
    {
        'fieldname': 'salary',
        'label': 'Salary ($)',
        'required': 'true',
        'placeholder': 'e.g. 20000',
    },
    {
        'fieldname': 'test',
        'label': 'Test Field',
        'required': 'true',
        'placeholder': '',
    }
]

with open('field-out.txt', 'w') as f:
    for field in fields:
        formatted = code.format(**field)
        f.write(formatted)
        f.write('\n')

Solution

  • You need to double any { or } that are not part of a formatting placeholder. For example, you have:

    function admin_add_{fieldname}_field( $fields ) {
        [....]
    }
    

    in the string. The { at the end of the first line and } on the last are not part of a placeholder. Replace them with {{ and }} respectively:

    function admin_add_{fieldname}_field( $fields ) {{
        [....]
    }}
    

    Doubling up those curly braces escapes them; the final output will contain single { and } characters again.

    In the full string you used, that'd be:

    code = '''
    // {label}
    add_filter( 'submit_job_form_fields', 'frontend_add_{fieldname}_field' );
    function frontend_add_{fieldname}_field($fields) {{
        $fields['job']['job_{fieldname}'] = array(
            'label' => __('{label}', 'job_manager'),
            'type' => 'text',
            'required' => {required},
            'priority' => 7,
            'placeholder' => '{placeholder}'
        );
        return $fields;
    }}
    add_filter( 'job_manager_job_listing_data_fields', 'admin_add_{fieldname}_field' );
    function admin_add_{fieldname}_field( $fields ) {{
      $fields['_job_{fieldname}'] = array(
        'label'       => __( '{label}', 'job_manager' ),
        'type'        => 'text',
        'placeholder' => '{placeholder}',
        'description' => ''
      );
      return $fields;
    }}
    '''