Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Bugs

[issue7382] bytes.__getnewargs__ is broken; copy.copy() therefore doesn't work on bytes, and bytes subclasses can't be pickled by default

 

 

Python bugs RSS feed   Index | Next | Previous | View Threaded


report at bugs

Nov 23, 2009, 7:17 AM

Post #1 of 4 (215 views)
Permalink
[issue7382] bytes.__getnewargs__ is broken; copy.copy() therefore doesn't work on bytes, and bytes subclasses can't be pickled by default

New submission from Sebastian Hagen <sh_pybugs [at] memespace>:

In either python 3.0, bytes instances cannot be copied, and (even
trivial) bytes subclasses cannot be unpickled unless they explicitly
override __getnewargs__() or __reduce_ex__().

Copy problem:
>>> import copy; copy.copy(b'foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.1/copy.py", line 96, in copy
return _reconstruct(x, rv, 0)
File "/usr/lib/python3.1/copy.py", line 280, in _reconstruct
y = callable(*args)
File "/usr/lib/python3.1/copyreg.py", line 88, in __newobj__
return cls.__new__(cls, *args)
TypeError: string argument without an encoding

Bytes subclass unpickle problem:
>>> class B(bytes):
... pass
...
>>> import pickle; pickle.loads(pickle.dumps(B(b'foo')))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.1/pickle.py", line 1373, in loads
encoding=encoding, errors=errors).load()
TypeError: string argument without an encoding


AFAICT, the problem is that bytes.__getnewargs__() returns a tuple with
a single argument - a string - and bytes.__new__() refuses to
reconstruct the instance when called with in that manner. That is,
"bytes.__new__(bytes, *b'foo'.__getnewargs__())" fails with a TypeError.

This does not cause a problem for pickling bytes instances (as opposed
to instances of a subclass of bytes), because both the Python and C
versions of pickle shipped with Python 3.[01] have built-in magic
(_Pickler.save_bytes() and save_bytes(), respectively) to deal with
bytes instances, and therefore never call their __getnewargs__().

The pickle case, in particular, is highly irritating; the error message
doesn't indicate which object is causing the problem, and until you
actually try to load the pickle, there's nothing to indicate that
there's anything problematic about pickling an instance of a subclass of
bytes.

----------
components: Library (Lib)
files: pickle_bytes_subclass.py
messages: 95632
nosy: sh
severity: normal
status: open
title: bytes.__getnewargs__ is broken; copy.copy() therefore doesn't work on bytes, and bytes subclasses can't be pickled by default
type: behavior
versions: Python 3.0, Python 3.1
Added file: http://bugs.python.org/file15387/pickle_bytes_subclass.py

_______________________________________
Python tracker <report [at] bugs>
<http://bugs.python.org/issue7382>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com


report at bugs

Nov 23, 2009, 7:56 AM

Post #2 of 4 (204 views)
Permalink
[issue7382] bytes.__getnewargs__ is broken; copy.copy() therefore doesn't work on bytes, and bytes subclasses can't be pickled by default [In reply to]

R. David Murray <rdmurray [at] bitdance> added the comment:

Confirmed on py3k trunk. We no longer do bug fixes in 3.0, which is why
I'm removing it from versions.

----------
keywords: +easy
nosy: +r.david.murray
priority: -> high
stage: -> test needed
versions: +Python 3.2 -Python 3.0

_______________________________________
Python tracker <report [at] bugs>
<http://bugs.python.org/issue7382>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com


report at bugs

Nov 24, 2009, 4:50 AM

Post #3 of 4 (192 views)
Permalink
[issue7382] bytes.__getnewargs__ is broken; copy.copy() therefore doesn't work on bytes, and bytes subclasses can't be pickled by default [In reply to]

Changes by Antoine Pitrou <pitrou [at] free>:


----------
nosy: +alexandre.vassalotti

_______________________________________
Python tracker <report [at] bugs>
<http://bugs.python.org/issue7382>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com


report at bugs

Nov 24, 2009, 9:42 AM

Post #4 of 4 (190 views)
Permalink
[issue7382] bytes.__getnewargs__ is broken; copy.copy() therefore doesn't work on bytes, and bytes subclasses can't be pickled by default [In reply to]

Alexandre Vassalotti <alexandre [at] peadrop> added the comment:

We just need make __getnewargs__ return bytes, instead of a unicode
string. So this is a single character fix.

I think we should reuse the ByteArraySubclass test case in test_bytes.py
to test for this bug. Incidentally, the reduce method of bytearray
should also be changed to emit bytes instead of a unicode string.

----------
keywords: +patch
Added file: http://bugs.python.org/file15394/fix_bytes_reduce.diff

_______________________________________
Python tracker <report [at] bugs>
<http://bugs.python.org/issue7382>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/list-python-bugs%40lists.gossamer-threads.com

Python bugs RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.