-
Notifications
You must be signed in to change notification settings - Fork 295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
newbytes not fully compatible with bytes: newbytes(newstr(...), '<encoding>') looks like it produces something similar to (but not quite the same as) newbytes(repr(newstr(...)), '<encoding>') #171
Comments
Thanks, Matt! I'll look into this ASAP.
|
The good news is that there's an easy work around (modified from above): from builtins import *
s = str(...) # make a newstr on Python 2
# Instead of bytes(s, u'utf_8'), do:
s.encode(u'utf_8') # will return newbytes object on Python 2 So this issue is really about interface compatibility rather than about available functionality. My guess is that most people use the |
I think I see what is happening here. (The following code snippets are all from Python 2, in case that wasn't obvious.) Consider: >>> from future.types.newstr import newstr
>>> isinstance(newstr(u'asdf'), unicode)
True From class newbytes(with_metaclass(BaseNewBytes, _builtin_bytes)):
...
def __new__(cls, *args, **kwargs):
... # gets `encoding` from *args, **kwargs
elif isinstance(args[0], unicode):
...
newargs = [encoding]
...
value = args[0].encode(*newargs)
...
return super(newbytes, cls).__new__(cls, value) Which, in the case of value = <newstr>.encode(u'utf_8') # returns instance of <class 'future.types.newbytes.newbytes'>
value = super(<newbytes>, cls).__new__(cls, value) # but see below So >>> nativebytes = bytes ; nativestr = str ; from builtins import *
>>> bytes(bytes(b'asdf'))
b'asdf'
*>>> bytes(nativebytes(b'asdf'))
b'asdf'
>>> nativebytes(bytes(b'asdf'))
"b'asdf'" # whoops! From def __str__(self):
return 'b' + "'{0}'".format(super(newbytes, self).__str__()) This behavior mirrors Python 3, so it's correct. However, because the native <newbytes> = <newstr>.encode(u'utf_8') # returns instance of <class 'future.types.newbytes.newbytes'>
value = super(<newbytes>, cls).__new__(cls, <newbytes>.__str__()) I'm not quite sure what the correct fix is if one wants to safely allow for the ability derive subclasses from both |
Matt, thanks for filing this issue and your pull request! The tests that this issue mentions actually seem to be passing on the |
@edschofield, my apologies for the delay. After some investigation, it looks like #193 is a duplicate of this issue. In response to your question, I no longer see the behavior addressed by #173 after abf19bb. 👍 I'll close #173, but please bear in mind that some of the errant (or at least confusing) behavior still exists. From #173 (comment):
That behavior remains and is not addressed by either #173 or abf19bb. I'll leave it to you as to whether you want to close this issue and track the above via #193. |
This is still an issue. Running |
Hmmm. I'm not sure this is broken. Or at least if it is, it might be broken semi-consistently with Python 3.x: $ python -c 'import sys ; print(sys.version) ; c = "type(bytes)" ; print("{}: {}".format(c, eval(c))) ; c = "type(str)" ; print("{}: {}".format(c, eval(c))) ; c = "str(b\"asdf\")" ; print("{}: {}".format(c, eval(c))) ; nativestr = str ; nativebytes = bytes ; from builtins import * ; c = "type(bytes)" ; print("{}: {}".format(c, eval(c))) ; c = "type(str)" ; print("{}: {}".format(c, eval(c))) ; c = "str(b\"asdf\")" ; print("{}: {}".format(c, eval(c))) ; c = "str(nativebytes(b\"asdf\"))" ; print("{}: {}".format(c, eval(c))) ; c = "nativestr(bytes(b\"asdf\"))" ; print("{}: {}".format(c, eval(c))) ; c = "str(bytes(b\"asdf\"))" ; print("{}: {}".format(c, eval(c)))'
2.7.13 (default, Dec 18 2016, 17:56:59)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
type(bytes): <type 'type'>
type(str): <type 'type'>
str(b"asdf"): asdf
type(bytes): <class 'future.types.newbytes.BaseNewBytes'>
type(str): <class 'future.types.newstr.BaseNewStr'>
str(b"asdf"): asdf
str(nativebytes(b"asdf")): asdf
nativestr(bytes(b"asdf")): b'asdf'
str(bytes(b"asdf")): b'asdf'
$ python3.5 -c 'import sys ; print(sys.version) ; c = "type(bytes)" ; print("{}: {}".format(c, eval(c))) ; c = "type(str)" ; print("{}: {}".format(c, eval(c))) ; c = "str(b\"asdf\")" ; print("{}: {}".format(c, eval(c))) ; c = "str(bytes(b\"asdf\"))" ; print("{}: {}".format(c, eval(c)))'
3.5.3 (default, Feb 1 2017, 17:52:10)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
type(bytes): <class 'type'>
type(str): <class 'type'>
str(b"asdf"): b'asdf'
str(bytes(b"asdf")): b'asdf' So @Depaulicious, also note that the original issue was about passing a Unicode value to |
The encoding to bytes in getModelMimeData implementations is still problematic due to a bug in future.builtins.str (PythonCharmers/python-future#171) Avoid it by using the encode method of str instead in the getModelMimeData implementations of: - TaurusBaseComponent - TaurusJDrawSynopticsView - TaurusValue
I'm hitting this in Python 2 (passing an encoded string into a library that uses native Python 2 urllib): import urllib
from future import standard_library
standard_library.install_aliases()
from builtins import *
d = {"k": str('a@b').encode("utf-8")}
urllib.urlencode(d, doseq=True) Traceback (most recent call last):
File "/tmp/f.py", line 10, in <module>
urllib.urlencode(d, doseq=True)
File "/usr/lib/python2.7/urllib.py", line 1348, in urlencode
v = quote_plus(v)
File "/usr/lib/python2.7/urllib.py", line 1305, in quote_plus
return quote(s, safe)
File "/usr/lib/python2.7/urllib.py", line 1298, in quote
return ''.join(map(quoter, s))
KeyError: 97 Is there a workaround for this? |
So >>> from future import standard_library
>>> standard_library.install_aliases()
>>> from builtins import *
>>> [c for c in 'a@b']
['a', '@', 'b']
>>> [c for c in str('a@b').encode("utf-8")]
[97, 64, 98] So if I |
…ytes" builtin with "builtins.bytes" during serialization. This manifested itself due to the proxy-oriented providers explicitly using "builtin.bytes" to convert a bytearray to bytes and only occurs in Py2 (when "builtins" actualy does things). It's probably related to PythonCharmers/python-future#171, but I didn't check too hard.
On Python 3.4:
On Python 2.7:
The text was updated successfully, but these errors were encountered: