mirror of https://github.com/python/cpython
Issue #13748: Raw bytes literals can now be written with the `rb` prefix as well as `br`.
This commit is contained in:
parent
b63a450cc4
commit
3a5d4cb940
|
@ -412,7 +412,7 @@ String literals are described by the following lexical definitions:
|
||||||
|
|
||||||
.. productionlist::
|
.. productionlist::
|
||||||
bytesliteral: `bytesprefix`(`shortbytes` | `longbytes`)
|
bytesliteral: `bytesprefix`(`shortbytes` | `longbytes`)
|
||||||
bytesprefix: "b" | "B" | "br" | "Br" | "bR" | "BR"
|
bytesprefix: "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"
|
||||||
shortbytes: "'" `shortbytesitem`* "'" | '"' `shortbytesitem`* '"'
|
shortbytes: "'" `shortbytesitem`* "'" | '"' `shortbytesitem`* '"'
|
||||||
longbytes: "'''" `longbytesitem`* "'''" | '"""' `longbytesitem`* '"""'
|
longbytes: "'''" `longbytesitem`* "'''" | '"""' `longbytesitem`* '"""'
|
||||||
shortbytesitem: `shortbyteschar` | `bytesescapeseq`
|
shortbytesitem: `shortbyteschar` | `bytesescapeseq`
|
||||||
|
@ -446,6 +446,10 @@ or ``'R'``; such strings are called :dfn:`raw strings` and treat backslashes as
|
||||||
literal characters. As a result, in string literals, ``'\U'`` and ``'\u'``
|
literal characters. As a result, in string literals, ``'\U'`` and ``'\u'``
|
||||||
escapes in raw strings are not treated specially.
|
escapes in raw strings are not treated specially.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
The ``'rb'`` prefix of raw bytes literals has been added as a synonym
|
||||||
|
of ``'br'``.
|
||||||
|
|
||||||
In triple-quoted strings, unescaped newlines and quotes are allowed (and are
|
In triple-quoted strings, unescaped newlines and quotes are allowed (and are
|
||||||
retained), except that three unescaped quotes in a row terminate the string. (A
|
retained), except that three unescaped quotes in a row terminate the string. (A
|
||||||
"quote" is the character used to open the string, i.e. either ``'`` or ``"``.)
|
"quote" is the character used to open the string, i.e. either ``'`` or ``"``.)
|
||||||
|
|
|
@ -2,10 +2,10 @@ r"""Test correct treatment of various string literals by the parser.
|
||||||
|
|
||||||
There are four types of string literals:
|
There are four types of string literals:
|
||||||
|
|
||||||
'abc' -- normal str
|
'abc' -- normal str
|
||||||
r'abc' -- raw str
|
r'abc' -- raw str
|
||||||
b'xyz' -- normal bytes
|
b'xyz' -- normal bytes
|
||||||
br'xyz' -- raw bytes
|
br'xyz' | rb'xyz' -- raw bytes
|
||||||
|
|
||||||
The difference between normal and raw strings is of course that in a
|
The difference between normal and raw strings is of course that in a
|
||||||
raw string, \ escapes (while still used to determine the end of the
|
raw string, \ escapes (while still used to determine the end of the
|
||||||
|
@ -103,12 +103,25 @@ class TestLiterals(unittest.TestCase):
|
||||||
|
|
||||||
def test_eval_bytes_raw(self):
|
def test_eval_bytes_raw(self):
|
||||||
self.assertEqual(eval(""" br'x' """), b'x')
|
self.assertEqual(eval(""" br'x' """), b'x')
|
||||||
|
self.assertEqual(eval(""" rb'x' """), b'x')
|
||||||
self.assertEqual(eval(r""" br'\x01' """), b'\\' + b'x01')
|
self.assertEqual(eval(r""" br'\x01' """), b'\\' + b'x01')
|
||||||
|
self.assertEqual(eval(r""" rb'\x01' """), b'\\' + b'x01')
|
||||||
self.assertEqual(eval(""" br'\x01' """), byte(1))
|
self.assertEqual(eval(""" br'\x01' """), byte(1))
|
||||||
|
self.assertEqual(eval(""" rb'\x01' """), byte(1))
|
||||||
self.assertEqual(eval(r""" br'\x81' """), b"\\" + b"x81")
|
self.assertEqual(eval(r""" br'\x81' """), b"\\" + b"x81")
|
||||||
|
self.assertEqual(eval(r""" rb'\x81' """), b"\\" + b"x81")
|
||||||
self.assertRaises(SyntaxError, eval, """ br'\x81' """)
|
self.assertRaises(SyntaxError, eval, """ br'\x81' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ rb'\x81' """)
|
||||||
self.assertEqual(eval(r""" br'\u1881' """), b"\\" + b"u1881")
|
self.assertEqual(eval(r""" br'\u1881' """), b"\\" + b"u1881")
|
||||||
|
self.assertEqual(eval(r""" rb'\u1881' """), b"\\" + b"u1881")
|
||||||
self.assertRaises(SyntaxError, eval, """ br'\u1881' """)
|
self.assertRaises(SyntaxError, eval, """ br'\u1881' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ rb'\u1881' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ bb'' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ rr'' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ brr'' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ bbr'' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ rrb'' """)
|
||||||
|
self.assertRaises(SyntaxError, eval, """ rbb'' """)
|
||||||
|
|
||||||
def check_encoding(self, encoding, extra=""):
|
def check_encoding(self, encoding, extra=""):
|
||||||
modname = "xx_" + encoding.replace("-", "_")
|
modname = "xx_" + encoding.replace("-", "_")
|
||||||
|
|
|
@ -114,8 +114,12 @@ x = b'abc' + B'ABC'
|
||||||
y = b"abc" + B"ABC"
|
y = b"abc" + B"ABC"
|
||||||
x = br'abc' + Br'ABC' + bR'ABC' + BR'ABC'
|
x = br'abc' + Br'ABC' + bR'ABC' + BR'ABC'
|
||||||
y = br"abc" + Br"ABC" + bR"ABC" + BR"ABC"
|
y = br"abc" + Br"ABC" + bR"ABC" + BR"ABC"
|
||||||
|
x = rb'abc' + rB'ABC' + Rb'ABC' + RB'ABC'
|
||||||
|
y = rb"abc" + rB"ABC" + Rb"ABC" + RB"ABC"
|
||||||
x = br'\\' + BR'\\'
|
x = br'\\' + BR'\\'
|
||||||
|
x = rb'\\' + RB'\\'
|
||||||
x = br'\'' + ''
|
x = br'\'' + ''
|
||||||
|
x = rb'\'' + ''
|
||||||
y = br'''
|
y = br'''
|
||||||
foo bar \\
|
foo bar \\
|
||||||
baz''' + BR'''
|
baz''' + BR'''
|
||||||
|
@ -124,6 +128,10 @@ y = Br"""foo
|
||||||
bar \\ baz
|
bar \\ baz
|
||||||
""" + bR'''spam
|
""" + bR'''spam
|
||||||
'''
|
'''
|
||||||
|
y = rB"""foo
|
||||||
|
bar \\ baz
|
||||||
|
""" + Rb'''spam
|
||||||
|
'''
|
||||||
|
|
||||||
# Indentation
|
# Indentation
|
||||||
if 1:
|
if 1:
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #13748: Raw bytes literals can now be written with the ``rb`` prefix
|
||||||
|
as well as ``br``.
|
||||||
|
|
||||||
- Issue #12736: Use full unicode case mappings for upper, lower, and title case.
|
- Issue #12736: Use full unicode case mappings for upper, lower, and title case.
|
||||||
|
|
||||||
- Issue #12760: Add a create mode to open(). Patch by David Townshend.
|
- Issue #12760: Add a create mode to open(). Patch by David Townshend.
|
||||||
|
|
|
@ -1412,13 +1412,15 @@ tok_get(register struct tok_state *tok, char **p_start, char **p_end)
|
||||||
/* Identifier (most frequent token!) */
|
/* Identifier (most frequent token!) */
|
||||||
nonascii = 0;
|
nonascii = 0;
|
||||||
if (is_potential_identifier_start(c)) {
|
if (is_potential_identifier_start(c)) {
|
||||||
/* Process b"", r"" and br"" */
|
/* Process b"", r"", br"" and rb"" */
|
||||||
if (c == 'b' || c == 'B') {
|
int saw_b = 0, saw_r = 0;
|
||||||
c = tok_nextc(tok);
|
while (1) {
|
||||||
if (c == '"' || c == '\'')
|
if (!saw_b && (c == 'b' || c == 'B'))
|
||||||
goto letter_quote;
|
saw_b = 1;
|
||||||
}
|
else if (!saw_r && (c == 'r' || c == 'R'))
|
||||||
if (c == 'r' || c == 'R') {
|
saw_r = 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
c = tok_nextc(tok);
|
c = tok_nextc(tok);
|
||||||
if (c == '"' || c == '\'')
|
if (c == '"' || c == '\'')
|
||||||
goto letter_quote;
|
goto letter_quote;
|
||||||
|
|
19
Python/ast.c
19
Python/ast.c
|
@ -3744,13 +3744,18 @@ parsestr(struct compiling *c, const node *n, int *bytesmode)
|
||||||
int rawmode = 0;
|
int rawmode = 0;
|
||||||
int need_encoding;
|
int need_encoding;
|
||||||
if (isalpha(quote)) {
|
if (isalpha(quote)) {
|
||||||
if (quote == 'b' || quote == 'B') {
|
while (!*bytesmode || !rawmode) {
|
||||||
quote = *++s;
|
if (quote == 'b' || quote == 'B') {
|
||||||
*bytesmode = 1;
|
quote = *++s;
|
||||||
}
|
*bytesmode = 1;
|
||||||
if (quote == 'r' || quote == 'R') {
|
}
|
||||||
quote = *++s;
|
else if (quote == 'r' || quote == 'R') {
|
||||||
rawmode = 1;
|
quote = *++s;
|
||||||
|
rawmode = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (quote != '\'' && quote != '\"') {
|
if (quote != '\'' && quote != '\"') {
|
||||||
|
|
Loading…
Reference in New Issue