Override {} placeholders in python string format method - python

I am trying to use python format method to do format my placeholder in a string.
The issue is the string contains {} internally and the string method is unable to resolve it.
my_value='v'
'{"k":"{value}"}'.format(value=my_value) # This results in error due to outside {}
# Desired Output '{"k":"v"}'
How would I resolve this ?
I can convert this to json and then substitute but I prefer if the string format can do it

You don't need to override something, you can just escape the curly brackets by doubling them, as stated in the documentation for the format string syntax:
If you need to include a brace character in the literal text, it can be escaped by doubling: {{ and }}.
>>> '{{"k":"{value}"}}'.format(value=my_value)
'{"k":"v"}'
This equally applies for formatted string literals if you plan on using them at some point:
>>> f'{{"k": "{my_value}"}}'
'{"k": "v"}'

Related

How to get raid of double quotes when dumping a string that includes single quotes

I am trying to add single quotes in dumping the following yaml string:
yaml_str = 'Type: modified'
But the output includes double quotes which are not required.
Here is my code:
import sys
import ruamel.yaml
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
data['Type'] = f"'{data['Type']}'"
yaml.dump(data, sys.stdout)
The output:
Type: "'modified'"
The expected output:
Type: 'modified'
Any ideas, please?
I tried all kinds of string formatting, nothing helped.
I also tried to add yaml.preserve_quotes = True which also didn't do any good.
Your expectation is completely wrong, so string formatting is not going to help you at all. YAML, like many other languages need to be able to handle scalars that have embedded quotes and YAML has multiple ways to handle that:
if a string to be dumped into a scalar has special characters that need backslash escaping (e.g. the audible bell \a), the scalar needs to be between double quotes (and double quotes in the string escaped in the scalar)
if a string to be dumped into a scalar has no special characters, but starts with a double quote, the whole scalar can be single quoted (and any existing single quotes in the string, will need to be duplicated '' in the scalar)
If you want to force single quotes in ruamel.yaml, even if they are superfluous, you can use:
data['Type'] = ruamel.yaml.scalarstring.SingleQuotedScalarString('{data['Type']}')
although the much better solution would be to get rid of the program that reads your output file and requires the unnecessary quotes to be there in the first place.
Please note that having quotes in a string doesn't necessarily require the corresponding scalar to have quotes. E.g. a string that has no spaces and a quote somewhere between normal readable characters can be dumped without (extra) quotes.

Is there a way to append r' to a sting in Python dynamically?

I am new to Python and I am working to calculate checksum of a string that has backslashes (). I was able to come up with a logic to calculate the checksum but that function needs the string to be in raw format (r') to calculate the correct checksum. However this function will be invoked by another function and I will not be able to convert the string to raw string manually. Can someone please help me on how to achieve this dynamically.
Here is the string:
raw_message1 = '=K+8\\\08|'
This string has 3 backslashes however it shows only 2 after saving and this string may vary again so replacing after processing will not help.
And when I print the result:
print(message1)
=K+8\ 8|
What I need is to have something that retains the backslashes as is. I cannot go for any other character as every character has its own ASCII value and checksum would differ. I tried all the other options mentioned before and see different result for each case.
You can define the string as so:
message1 = r'=K+8\\08|'
This should make the string message1 be in raw form.
Let me know if this helps. I don't really understand what you mean by converting to raw string manually and converting it dynamically. This is the most I can help with for now.
All the r prefix does is manually add backslashes so you don't have to, it doesn't "magically" retain the backslashes, instead it replaces them with double backslashes so they are interpreted as single backslashes.
Look at the following example:
>>> s = r"\rando\\\mst\ri\ngo\\flet\ters"
>>> s
'\\rando\\\\\\mst\\ri\\ngo\\\\flet\\ters'
>>> print(s)
\rando\\\mst\ri\ngo\\flet\ters
>>>
The string actually contains double backslashes and when printed they are interpreted as single backslashes.

Using '{' as a string in the format method python

I want to be able to print something like such "{x}" using the format method, but the nature of the curly braces is messing me up.
I tried
'{{}}'.format(x)
however that returned a value error. Is there a way to tell python that the curly brace is meant to be used as a string rather than an argument for the format?
{{ is converted into {by format, so use this:
'{{{}}}'.format(x)
(note the three braces)
However, in this case, I would use the older C-style format string:
'{%s}' % x
It is a lot clearer.

Decode a string - Quote marks issue

I am supposed to decode the string below in a script I have made (it is a task from a webpage). In order to ensure that the decoded word will be correct, I can not change the string in any way. Since the quote marks affects the string, parts like q90:;AI is not a string, which results in a syntax error.
q0Ø:;AI"E47FRBQNBG4WNB8B4LQN8ERKC88U8GEN?T6LaNBG4GØ""N6K086HB"Ø8CRHW"+LS79Ø""N29QCLN5WNEBS8GENBG4FØ47a
Is there a way I can decode the encrypted message without changing it? As of now I am just getting syntax error when I define the string in a variable.
You can surround the string with single quotes, since double quotes are used in the string already:
>>> print 'q0Ø:;AI"E47FRBQNBG4WNB8B4LQN8ERKC88U8GEN?T6LaNBG4GØ""N6K086HB"Ø8CRHW"+LS79Ø""N29QCLN5WNEBS8GENBG4FØ47a'
q0Ã:;AI"E47FRBQNBG4WNB8B4LQN8ERKC88U8GEN?T6LaNBG4GÃ""N6K086HB"Ã8CRHW"+LS79Ã""N29QCLN5WNEBS8GENBG4FÃ47a
>>>

Loading document as raw string in yaml with PyYAML

I want to parse yaml documents like the following
meta-info-1: val1
meta-info-2: val2
---
Plain text/markdown content!
jhaha
If I load_all this with PyYAML, I get the following
>>> list(yaml.load_all(open('index.yml')))
[{'meta-info-1': 'val1', 'meta-info-2': 'val2'}, 'Plain text/markdown content! jhaha']
What I am trying to achieve here is that the yaml file should contain two documents, and the second one is supposed to be interpreted as a single string document, more specifically any large body of text with markdown formatting. I don't want it to be parsed as YAML syntax.
In the above example, PyYAML returns the second document as a single string. But if the second document has a : character in place of the ! for instance, I get a syntax error. This is because PyYAML is parsing the stuff in that document.
Is there a way I can tell PyYAML that the second document is a just a raw string and not to parse it?
Edit: A few excellent answers there. While using quotes or the literal syntax solves the said problem, I'd like the users to be able to write the plain text without any extra cruft. Just the three -'s (or .'s) and write away a large body of plain text. Which might also include quotes too. So, I'd like to know if I can tell PyYAML to parse only one document, and give the second to me raw.
Eidt 2: So, adapting agf's idea, instead of using a try/except as the second document could be valid yaml syntax,
config_content, body_content = open(filename).read().split('\n---')
config = yaml.loads(config_content)
body = yaml.loads(body_content)
Thanks agf.
You can do
raw = open(filename).read()
docs = []
for raw_doc in raw.split('\n---'):
try:
docs.append(yaml.load(raw_doc))
except SyntaxError:
docs.append(raw_doc)
If you won't have control over the format of the original document.
From the PyYAML docs,
Double-quoted is the most powerful style and the only style that can express any scalar value. Double-quoted scalars allow escaping. Using escaping sequences \x** and \u****, you may express any ASCII or Unicode character.
So it sounds like there is no way to represent an arbitrary scalar in the parsing if it's not double quoted.
If all you want is to escape the colon character in YAML, then enclose it within single or double quotes. Also, you can try literal style for your second document which should be treated as single scalar.

Categories