1.1 --- a/lib/__builtins__/str.py Sun Jan 29 01:33:14 2017 +0100
1.2 +++ b/lib/__builtins__/str.py Sun Jan 29 18:52:35 2017 +0100
1.3 @@ -56,11 +56,7 @@
1.4 else:
1.5 self.__key__ = None
1.6
1.7 - def __hash__(self):
1.8 -
1.9 - "Return a value for hashing purposes."
1.10 -
1.11 - return self._hashvalue(ord)
1.12 + # Internal methods.
1.13
1.14 def _binary_op(self, op, other):
1.15
1.16 @@ -90,6 +86,99 @@
1.17 else:
1.18 return op(other.__data__, self.__data__)
1.19
1.20 + def _quote(self, quote):
1.21 +
1.22 + "Return a quoted representation of this string."
1.23 +
1.24 + b = buffer([quote])
1.25 + i = last = 0
1.26 + end = self.__len__()
1.27 +
1.28 + while i < end:
1.29 + c = self[i]
1.30 + n = ord(c)
1.31 +
1.32 + # Extended unquoted text.
1.33 +
1.34 + if 32 <= n < 128:
1.35 + i += 1
1.36 + continue
1.37 +
1.38 + # Before quoting, emit unquoted text.
1.39 +
1.40 + b.append(self[last:i])
1.41 +
1.42 + # Add quoted value.
1.43 +
1.44 + if c == quote:
1.45 + b.append("\\")
1.46 + b.append(quote)
1.47 + elif c == "\t":
1.48 + b.append("\\t")
1.49 + elif c == "\n":
1.50 + b.append("\\n")
1.51 + elif c == "\r":
1.52 + b.append("\\r")
1.53 + else:
1.54 + if n < 0:
1.55 + n += 256
1.56 + b.append("\\x")
1.57 + x = hex(n, "")
1.58 + if len(x) < 2:
1.59 + b.append("0")
1.60 + b.append(x)
1.61 +
1.62 + i += 1
1.63 + last = i
1.64 +
1.65 + # Emit remaining unquoted text.
1.66 +
1.67 + b.append(self[last:])
1.68 + b.append(quote)
1.69 + return str(b)
1.70 +
1.71 + def bytelength(self):
1.72 +
1.73 + "Return the number of bytes in this string."
1.74 +
1.75 + return str_len(self.__data__)
1.76 +
1.77 + # General type methods.
1.78 +
1.79 + def __bool__(self):
1.80 +
1.81 + "Return whether the string provides any data."
1.82 +
1.83 + return str_nonempty(self.__data__)
1.84 +
1.85 + def __contains__(self, value):
1.86 +
1.87 + "Return whether this string contains 'value'."
1.88 +
1.89 + return self.find(value) != -1
1.90 +
1.91 + def __hash__(self):
1.92 +
1.93 + "Return a value for hashing purposes."
1.94 +
1.95 + return self._hashvalue(ord)
1.96 +
1.97 + __len__ = bytelength
1.98 +
1.99 + def __repr__(self):
1.100 +
1.101 + "Return a program representation."
1.102 +
1.103 + return self._quote('"')
1.104 +
1.105 + def __str__(self):
1.106 +
1.107 + "Return a string representation."
1.108 +
1.109 + return self
1.110 +
1.111 + # Operator methods.
1.112 +
1.113 def __iadd__(self, other):
1.114
1.115 "Return a string combining this string with 'other'."
1.116 @@ -104,6 +193,9 @@
1.117
1.118 return self._binary_op_rev(str_add, other)
1.119
1.120 + def __mod__(self, other): pass
1.121 + def __rmod__(self, other): pass
1.122 +
1.123 def __mul__(self, other):
1.124
1.125 "Multiply the string by 'other'."
1.126 @@ -118,14 +210,19 @@
1.127
1.128 __rmul__ = __mul__
1.129
1.130 - def __mod__(self, other): pass
1.131 - def __rmod__(self, other): pass
1.132 + # Comparison methods.
1.133 +
1.134 + def __eq__(self, other):
1.135 +
1.136 + "Return whether this string is equal to 'other'."
1.137
1.138 - def __lt__(self, other):
1.139 + return self._binary_op(str_eq, other)
1.140 +
1.141 + def __ge__(self, other):
1.142
1.143 - "Return whether this string is less than 'other'."
1.144 + "Return whether this string is greater than or equal to 'other'."
1.145
1.146 - return self._binary_op(str_lt, other)
1.147 + return _negate(self.__lt__(other))
1.148
1.149 def __gt__(self, other):
1.150
1.151 @@ -139,17 +236,11 @@
1.152
1.153 return _negate(self.__gt__(other))
1.154
1.155 - def __ge__(self, other):
1.156 -
1.157 - "Return whether this string is greater than or equal to 'other'."
1.158 -
1.159 - return _negate(self.__lt__(other))
1.160 + def __lt__(self, other):
1.161
1.162 - def __eq__(self, other):
1.163 + "Return whether this string is less than 'other'."
1.164
1.165 - "Return whether this string is equal to 'other'."
1.166 -
1.167 - return self._binary_op(str_eq, other)
1.168 + return self._binary_op(str_lt, other)
1.169
1.170 def __ne__(self, other):
1.171
1.172 @@ -157,39 +248,7 @@
1.173
1.174 return _negate(self.__eq__(other))
1.175
1.176 - def bytelength(self):
1.177 -
1.178 - "Return the number of bytes in this string."
1.179 -
1.180 - return str_len(self.__data__)
1.181 -
1.182 - __len__ = bytelength
1.183 -
1.184 - def __str__(self):
1.185 -
1.186 - "Return a string representation."
1.187 -
1.188 - return self
1.189 -
1.190 - def __repr__(self):
1.191 -
1.192 - "Return a program representation."
1.193 -
1.194 - # NOTE: To be implemented with proper quoting.
1.195 - b = buffer(['"', self, '"'])
1.196 - return str(b)
1.197 -
1.198 - def __bool__(self):
1.199 -
1.200 - "Return whether the string provides any data."
1.201 -
1.202 - return str_nonempty(self.__data__)
1.203 -
1.204 - def __contains__(self, value):
1.205 -
1.206 - "Return whether this string contains 'value'."
1.207 -
1.208 - return self.find(value) != -1
1.209 + # String-specific methods.
1.210
1.211 def endswith(self, s):
1.212
2.1 --- a/tests/string.py Sun Jan 29 01:33:14 2017 +0100
2.2 +++ b/tests/string.py Sun Jan 29 18:52:35 2017 +0100
2.3 @@ -18,7 +18,7 @@
2.4 try:
2.5 print s.index("p") # should raise an exception
2.6 except ValueError, exc:
2.7 - print 's.index("p"): value is not appropriate', exc.value
2.8 + print 's.index("p"): value is not appropriate', repr(exc.value)
2.9
2.10 print s.startswith("Hello") # True
2.11 print s.startswith("world") # False
2.12 @@ -43,7 +43,7 @@
2.13 try:
2.14 print ord(s) # should raise an exception
2.15 except ValueError, exc:
2.16 - print "ord(s): value is not appropriate", exc.value
2.17 + print "ord(s): value is not appropriate", repr(exc.value)
2.18
2.19 l = ["Hello", "world!"]
2.20 s3 = " ".join(l)
2.21 @@ -101,3 +101,7 @@
2.22 print repr(s9.strip("xyYZ")) # "zHello worldX"
2.23 print repr(s9.lstrip("xyYZ")) # "zHello worldXYZ"
2.24 print repr(s9.rstrip("xyYZ")) # "xyzHello worldX"
2.25 +
2.26 +# Test quoting of strings.
2.27 +
2.28 +print repr('æ\nø\rå\t"') # "\xe6\n\xf8\r\xe5\t\""