Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store or read a literal carriage return and newline from yaml in python

Tags:

python

yaml

I have been struggling with this problem all day. I couldn't seem to find the answer online either. I have a yaml document that stores some server config for my message/response server and one of the parameters is "message_terminator". As you can guess, this is what my server knows to look for as a message terminator of the messages sent by clients.

\r\n 

is the default sent by telnet, so i have set it as such.

Yaml Document:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: \r\n

What i want to do is to either read the message_terminator value as a actual carriage return and newline or convert it from its string representation to its binary escape codes: return and newline, not the string representation "\r\n"

For instance, if i do in python:

print('\r\n')

It prints a carriage return and newline, not the characters. But if i read the value from the yaml config in python with:

print(config['global']['message_terminator'])

It prints out the characters:

\r\n

Changing the Yaml documents and adding quotes like:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: '\r\n'

and

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: b'\r\n'

or even

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: !!str \r\n

or

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: !!python/bytes b'\r\n'

has no effect. When the message terminator is printed out its prints the characters. When its sent over the network to the clients, its the characters.

I have also tried things like:

print(bytes(config['global']['message_terminator'], 'utf-8').encode('unicode_escape'))

which still just prints out the characters.

Please excuse me if i just have it totally wrong or am missing something big. I'm still working out the whole difference between strings, bytes, raw strings, etc. Any advice or pointers welcome. Thanks for your time.

Edit @Jan: When do that in the in the interpreter it works. I get a carriage and newline printed. Not the characters.

>>> text = """
... val: "hello\\n\\rnew line"
... """
>>> text
'\nval: "hello\\n\\rnew line"\n'
>>> print(text)

val: "hello\n\rnew line"

>>> import yaml
>>> data = yaml.load(text)
>>> data
{'val': 'hello\n\rnew line'}
>>> print(data['val'])
hello
new line
>>> 

But in my main code, when i load from the yaml file it prints the \r\n not a an actual carriage return and newline. This python code:

TERM = config['global']['message_terminator']
print(TERM)
print(config['global']['message_terminator'])
print("netcmd server started on port", PORT)

Prints this in the terminal:

$ python3 netcmd.py
\r\n
\r\n
netcmd server started on port 7040

To clarify, I want the action of carriage return and newline, not there character representation.

Edit 2: Problem solved. I change the yaml file after Jan's Update from:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: "\\r\\n"

to

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: "\r\n"

Everything's working now and the python code prints out an actually carriage return and newline read from the yaml file.

like image 442
Rudker Avatar asked Jun 18 '14 17:06

Rudker


1 Answers

YAML allows escaping using \ character, but you have to put the value into quotes:

>>> text = """
... val: "hello\\n\\rnew line"
... """
...
>>> text
'\nval: "hello\\n\\rnew line"\n'
>>> data = yaml.load(text)
>>> data
{'val': 'hello\n\rnew line'}

So your file with global would work as follows:

global:
    server_port: 7040
    bound_ip: 0.0.0.0
    message_terminator: "\r\n"

Section 5.7 of YAML spec 1.2:

5.7. Escaped Characters

All non-printable characters must be escaped. YAML escape sequences use the “\” notation common to most modern computer languages. Each escape sequence must be parsed into the appropriate Unicode character. The original escape sequence is a presentation detail and must not be used to convey content information.

Note that escape sequences are only interpreted in double-quoted scalars. In all other scalar styles, the “\” character has no special meaning and non-printable characters are not available.

like image 62
Jan Vlcinsky Avatar answered Oct 22 '22 08:10

Jan Vlcinsky