4
4
import binascii
5
5
import datetime
6
6
from decimal import Decimal
7
- import re
8
7
import time
9
8
10
9
from .constants import FIELD_TYPE , FLAG
11
10
from .charset import charset_by_id , charset_to_encoding
12
11
13
12
14
- ESCAPE_REGEX = re .compile (r"[\0\n\r\032\'\"\\]" )
15
- ESCAPE_MAP = {'\0 ' : '\\ 0' , '\n ' : '\\ n' , '\r ' : '\\ r' , '\032 ' : '\\ Z' ,
16
- '\' ' : '\\ \' ' , '"' : '\\ "' , '\\ ' : '\\ \\ ' }
17
-
18
13
def escape_item (val , charset , mapping = None ):
19
14
if mapping is None :
20
15
mapping = encoders
@@ -48,8 +43,7 @@ def escape_sequence(val, charset, mapping=None):
48
43
return "(" + "," .join (n ) + ")"
49
44
50
45
def escape_set (val , charset , mapping = None ):
51
- val = map (lambda x : escape_item (x , charset , mapping ), val )
52
- return ',' .join (val )
46
+ return ',' .join ([escape_item (x , charset , mapping ) for x in val ])
53
47
54
48
def escape_bool (value , mapping = None ):
55
49
return str (int (value ))
@@ -63,20 +57,53 @@ def escape_int(value, mapping=None):
63
57
def escape_float (value , mapping = None ):
64
58
return ('%.15g' % value )
65
59
66
- def escape_string (value , mapping = None ):
67
- return ("%s" % (ESCAPE_REGEX .sub (
68
- lambda match : ESCAPE_MAP .get (match .group (0 )), value ),))
60
+ if PY2 :
61
+ def escape_string (value , mapping = None ):
62
+ """escape_string escapes *value* but not surround it with quotes.
63
+
64
+ Value should be bytes or unicode.
65
+ """
66
+ value = value .replace ('\\ ' , '\\ \\ ' )
67
+ value = value .replace ('\0 ' , '\\ 0' )
68
+ value = value .replace ('\n ' , '\\ n' )
69
+ value = value .replace ('\r ' , '\\ r' )
70
+ value = value .replace ('\032 ' , '\\ Z' )
71
+ value = value .replace ("'" , "\\ '" )
72
+ value = value .replace ('"' , '\\ "' )
73
+ return value
74
+ else :
75
+ _escape_table = [chr (x ) for x in range (128 )]
76
+ _escape_table [0 ] = '\\ 0'
77
+ _escape_table [ord ('\\ ' )] = '\\ \\ '
78
+ _escape_table [ord ('\n ' )] = '\\ n'
79
+ _escape_table [ord ('\r ' )] = '\\ r'
80
+ _escape_table [ord ('\032 ' )] = '\\ Z'
81
+ _escape_table [ord ('"' )] = '\\ "'
82
+ _escape_table [ord ("'" )] = "\\ '"
83
+
84
+ def escape_string (value , mapping = None ):
85
+ """escape_string escapes *value* but not surround it with quotes.
86
+
87
+ Value should be str (unicode).
88
+ """
89
+ return value .translate (_escape_table )
90
+
91
+ # On Python ~3.5, str.decode('ascii', 'surrogateescape') is slow.
92
+ # (fixed in Python 3.6, http://bugs.python.org/issue24870)
93
+ # Workaround is str.decode('latin1') then translate 0x80-0xff into 0udc80-0udcff.
94
+ # We can escape special chars and surrogateescape at once.
95
+ _escape_bytes_table = _escape_table + [chr (i ) for i in range (0xdc80 , 0xdd00 )]
96
+
97
+ def escape_bytes (value , mapping = None ):
98
+ return "'%s'" % value .decode ('latin1' ).translate (_escape_bytes_table )
99
+
69
100
70
101
def escape_str (value , mapping = None ):
71
102
return "'%s'" % escape_string (value , mapping )
72
103
73
104
def escape_unicode (value , mapping = None ):
74
105
return escape_str (value , mapping )
75
106
76
- def escape_bytes (value , mapping = None ):
77
- # escape_bytes is calld only on Python 3.
78
- return escape_str (value .decode ('ascii' , 'surrogateescape' ), mapping )
79
-
80
107
def escape_None (value , mapping = None ):
81
108
return 'NULL'
82
109
0 commit comments