diff --git a/src/future/types/newbytes.py b/src/future/types/newbytes.py index 85e6501c..8a937a6d 100644 --- a/src/future/types/newbytes.py +++ b/src/future/types/newbytes.py @@ -100,6 +100,8 @@ def __new__(cls, *args, **kwargs): newargs.append(errors) value = args[0].encode(*newargs) ### + elif hasattr(args[0], '__bytes__'): + value = args[0].__bytes__() elif isinstance(args[0], Iterable): if len(args[0]) == 0: # This could be an empty list or tuple. Return b'' as on Py3. diff --git a/tests/test_future/test_bytes.py b/tests/test_future/test_bytes.py index 5254a9be..e852a0bd 100644 --- a/tests/test_future/test_bytes.py +++ b/tests/test_future/test_bytes.py @@ -707,6 +707,31 @@ def test_issue_171_part_b(self): b = nativebytes(bytes(b'asdf')) self.assertEqual(b, b'asdf') + def test_cast_to_bytes(self): + """ + Tests whether __bytes__ method is called + """ + + class TestObject: + def __bytes__(self): + return b'asdf' + + self.assertEqual(bytes(TestObject()), b'asdf') + + def test_cast_to_bytes_iter_precedence(self): + """ + Tests that call to __bytes__ is preferred to iteration + """ + + class TestObject: + def __bytes__(self): + return b'asdf' + + def __iter__(self): + return iter(b'hjkl') + + self.assertEqual(bytes(TestObject()), b'asdf') + if __name__ == '__main__': unittest.main()