Fix the tag.
[python/dscho.git] / Lib / lib2to3 / pgen2 / literals.py
blob4f50d31e6baf921757a757c41aafa6eca9d360d8
1 # Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
2 # Licensed to PSF under a Contributor Agreement.
4 """Safely evaluate Python string literals without using eval()."""
6 import re
8 simple_escapes = {"a": "\a",
9 "b": "\b",
10 "f": "\f",
11 "n": "\n",
12 "r": "\r",
13 "t": "\t",
14 "v": "\v",
15 "'": "'",
16 '"': '"',
17 "\\": "\\"}
19 def escape(m):
20 all, tail = m.group(0, 1)
21 assert all.startswith("\\")
22 esc = simple_escapes.get(tail)
23 if esc is not None:
24 return esc
25 if tail.startswith("x"):
26 hexes = tail[1:]
27 if len(hexes) < 2:
28 raise ValueError("invalid hex string escape ('\\%s')" % tail)
29 try:
30 i = int(hexes, 16)
31 except ValueError:
32 raise ValueError("invalid hex string escape ('\\%s')" % tail)
33 else:
34 try:
35 i = int(tail, 8)
36 except ValueError:
37 raise ValueError("invalid octal string escape ('\\%s')" % tail)
38 return chr(i)
40 def evalString(s):
41 assert s.startswith("'") or s.startswith('"'), repr(s[:1])
42 q = s[0]
43 if s[:3] == q*3:
44 q = q*3
45 assert s.endswith(q), repr(s[-len(q):])
46 assert len(s) >= 2*len(q)
47 s = s[len(q):-len(q)]
48 return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s)
50 def test():
51 for i in range(256):
52 c = chr(i)
53 s = repr(c)
54 e = evalString(s)
55 if e != c:
56 print(i, c, s, e)
59 if __name__ == "__main__":
60 test()