/* Absolute value of the number x */
#define Py_ABS(x) ((x) < 0 ? -(x) : (x))
+/* Safer implementation that avoids an undefined behavior for the minimal
+ value of the signed integer type if its absolute value is larger than
+ the maximal value of the signed integer type (in the two's complement
+ representations, which is common).
+ */
+#define _Py_ABS_CAST(T, x) ((x) >= 0 ? ((T) (x)) : ((T) (((T) -((x) + 1)) + 1u)))
#define _Py_XSTRINGIFY(x) #x
self.assertEqual(three_bytes.hex(':', 2), 'b9:01ef')
self.assertEqual(three_bytes.hex(':', 1), 'b9:01:ef')
self.assertEqual(three_bytes.hex('*', -2), 'b901*ef')
+ self.assertEqual(three_bytes.hex(sep=':', bytes_per_sep=2), 'b9:01ef')
+ self.assertEqual(three_bytes.hex(sep='*', bytes_per_sep=-2), 'b901*ef')
+ for bytes_per_sep in 3, -3, 2**31-1, -(2**31-1):
+ with self.subTest(bytes_per_sep=bytes_per_sep):
+ self.assertEqual(three_bytes.hex(':', bytes_per_sep), 'b901ef')
+ for bytes_per_sep in 2**31, -2**31, 2**1000, -2**1000:
+ with self.subTest(bytes_per_sep=bytes_per_sep):
+ try:
+ self.assertEqual(three_bytes.hex(':', bytes_per_sep), 'b901ef')
+ except OverflowError:
+ pass
value = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000'
self.assertEqual(value.hex('.', 8), '7b7305000000776f.726c646902000000.730500000068656c.6c6f690100000030')
for expected in (-n, n):
self.helper(expected)
n = n >> 1
+ n = 1 << 100
+ while n:
+ for expected in (-n, -n+1, n-1, n):
+ self.helper(expected)
+ n = n >> 1
def test_int64(self):
# Simulate int marshaling with TYPE_INT64.
m2 = m1[::-1]
self.assertEqual(m2.hex(), '30' * 200000)
+ def test_memoryview_hex_separator(self):
+ x = bytes(range(97, 102))
+ m1 = memoryview(x)
+ m2 = m1[::-1]
+ self.assertEqual(m2.hex(':'), '65:64:63:62:61')
+ self.assertEqual(m2.hex(':', 2), '65:6463:6261')
+ self.assertEqual(m2.hex(':', -2), '6564:6362:61')
+ self.assertEqual(m2.hex(sep=':', bytes_per_sep=2), '65:6463:6261')
+ self.assertEqual(m2.hex(sep=':', bytes_per_sep=-2), '6564:6362:61')
+ for bytes_per_sep in 5, -5, 2**31-1, -(2**31-1):
+ with self.subTest(bytes_per_sep=bytes_per_sep):
+ self.assertEqual(m2.hex(':', bytes_per_sep), '6564636261')
+ for bytes_per_sep in 2**31, -2**31, 2**1000, -2**1000:
+ with self.subTest(bytes_per_sep=bytes_per_sep):
+ try:
+ self.assertEqual(m2.hex(':', bytes_per_sep), '6564636261')
+ except OverflowError:
+ pass
+
def test_copy(self):
m = memoryview(b'abc')
with self.assertRaises(TypeError):
}
if (!long_export.digits) {
int8_t sign = long_export.value < 0 ? -1 : 1;
- uint64_t abs_value = Py_ABS(long_export.value);
+ uint64_t abs_value = _Py_ABS_CAST(uint64_t, long_export.value);
uint64_t d = abs_value;
long l = 0;
else {
bytes_per_sep_group = 0;
}
-
- unsigned int abs_bytes_per_sep = Py_ABS(bytes_per_sep_group);
+ unsigned int abs_bytes_per_sep = _Py_ABS_CAST(unsigned int, bytes_per_sep_group);
Py_ssize_t resultlen = 0;
if (bytes_per_sep_group && arglen > 0) {
/* How many sep characters we'll be inserting. */