Terry J. Reedy added the comment:

The library doc says that if the source argument for bytes() or bytearray() is 
a string or integer it is treated a certain way. I believe 'string' and 
'integer' are meant to include subclasses of str and int, else it should have 
said str or int. You have verified that int subclass instances are indeed 
treated as integers. The following shows that str subclass instances are 
treated as strings.

class mystr(str):
    def __bytes__(self): return b'hello'
print(bytes(mystr('a')))
raises TypeError: string argument without an encoding

The language reference says "object.__bytes__(self): Called by bytes() to 
compute a byte-string representation of an object." No exception is given. I 
see this as a contradiction in the manual, in which case the current behavior 
rules and the contradiction is removed by changing the doc part that conflicts 
with behavior. That would mean extending the doc sentence with 'that is not a 
string or integer'.

However, I am waiting for other opinions for two reasons.

1. The doc also specified special treatment for buffer interface and iterable 
objects. However, __bytes__ *is* checked first for those objects. 

class myit(list):
    def __bytes__(self): return b'hello'
print (bytes (myit([1,2,3])))
# b'hello'

class mybit(bytes):  # example 
    def __bytes__(self): return b'hello'
print (bytes (mybit(b'a')))
# b'hello'

So the exception is limited to 'strings' and 'integers', making it somewhat 
inconsistent.

2. If someone gives an str or int subclass a __bytes__ method, they can only 
mean for it to be called by bytes(), as there is no other use of that special 
method.

On the third hand, a user of a class who tests its instances before calling 
bytes with "isinstance(x, (str, int))" instead of "type(x) is str or type(x) is 
int", likely expects getting normal string or integer behavior. Of course, the 
same might be true if the test is 'isiterable(x)'.

If behavior were changed, I think it should wait for 3.4 since the current 
behavior is not clearly a bug to me.

----------
assignee:  -> docs@python
components: +Documentation -Interpreter Core
nosy: +docs@python, terry.reedy
title: __bytes__ doesn't work in subclass of int -> __bytes__ doesn't work in 
subclass of int and str
versions: +Python 2.7, Python 3.3, Python 3.4

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue17309>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to