##// END OF EJS Templates
pycompat: add bytestr wrapper which mostly acts as a Python 2 str...
Yuya Nishihara -
r31439:b70407bd default
parent child Browse files
Show More
@@ -76,6 +76,67 if ispy3:
76
76
77 bytechr = struct.Struct('>B').pack
77 bytechr = struct.Struct('>B').pack
78
78
79 class bytestr(bytes):
80 """A bytes which mostly acts as a Python 2 str
81
82 >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
83 (b'', b'foo', b'ascii', b'1')
84 >>> s = bytestr(b'foo')
85 >>> assert s is bytestr(s)
86
87 There's no implicit conversion from non-ascii str as its encoding is
88 unknown:
89
90 >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
91 Traceback (most recent call last):
92 ...
93 UnicodeEncodeError: ...
94
95 Comparison between bytestr and bytes should work:
96
97 >>> assert bytestr(b'foo') == b'foo'
98 >>> assert b'foo' == bytestr(b'foo')
99 >>> assert b'f' in bytestr(b'foo')
100 >>> assert bytestr(b'f') in b'foo'
101
102 Sliced elements should be bytes, not integer:
103
104 >>> s[1], s[:2]
105 (b'o', b'fo')
106 >>> list(s), list(reversed(s))
107 ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
108
109 As bytestr type isn't propagated across operations, you need to cast
110 bytes to bytestr explicitly:
111
112 >>> s = bytestr(b'foo').upper()
113 >>> t = bytestr(s)
114 >>> s[0], t[0]
115 (70, b'F')
116
117 Be careful to not pass a bytestr object to a function which expects
118 bytearray-like behavior.
119
120 >>> t = bytes(t) # cast to bytes
121 >>> assert type(t) is bytes
122 """
123
124 def __new__(cls, s=b''):
125 if isinstance(s, bytestr):
126 return s
127 if not isinstance(s, (bytes, bytearray)):
128 s = str(s).encode(u'ascii')
129 return bytes.__new__(cls, s)
130
131 def __getitem__(self, key):
132 s = bytes.__getitem__(self, key)
133 if not isinstance(s, bytes):
134 s = bytechr(s)
135 return s
136
137 def __iter__(self):
138 return iterbytestr(bytes.__iter__(self))
139
79 def iterbytestr(s):
140 def iterbytestr(s):
80 """Iterate bytes as if it were a str object of Python 2"""
141 """Iterate bytes as if it were a str object of Python 2"""
81 return map(bytechr, s)
142 return map(bytechr, s)
@@ -146,6 +207,7 else:
146 import cStringIO
207 import cStringIO
147
208
148 bytechr = chr
209 bytechr = chr
210 bytestr = str
149 iterbytestr = iter
211 iterbytestr = iter
150
212
151 def sysstr(s):
213 def sysstr(s):
@@ -34,6 +34,7 testmod('mercurial.minirst')
34 testmod('mercurial.patch')
34 testmod('mercurial.patch')
35 testmod('mercurial.pathutil')
35 testmod('mercurial.pathutil')
36 testmod('mercurial.parser')
36 testmod('mercurial.parser')
37 testmod('mercurial.pycompat', py3=True)
37 testmod('mercurial.revsetlang')
38 testmod('mercurial.revsetlang')
38 testmod('mercurial.smartset')
39 testmod('mercurial.smartset')
39 testmod('mercurial.store')
40 testmod('mercurial.store')
General Comments 0
You need to be logged in to leave comments. Login now